factory.py 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. from collections.abc import Mapping
  2. from typing import Any
  3. from core.file.file_obj import FileVar
  4. from .segments import (
  5. ArrayAnySegment,
  6. FileSegment,
  7. FloatSegment,
  8. IntegerSegment,
  9. NoneSegment,
  10. ObjectSegment,
  11. Segment,
  12. StringSegment,
  13. )
  14. from .types import SegmentType
  15. from .variables import (
  16. ArrayFileVariable,
  17. ArrayNumberVariable,
  18. ArrayObjectVariable,
  19. ArrayStringVariable,
  20. FileVariable,
  21. FloatVariable,
  22. IntegerVariable,
  23. ObjectVariable,
  24. SecretVariable,
  25. StringVariable,
  26. Variable,
  27. )
  28. def build_variable_from_mapping(m: Mapping[str, Any], /) -> Variable:
  29. if (value_type := m.get('value_type')) is None:
  30. raise ValueError('missing value type')
  31. if not m.get('name'):
  32. raise ValueError('missing name')
  33. if (value := m.get('value')) is None:
  34. raise ValueError('missing value')
  35. match value_type:
  36. case SegmentType.STRING:
  37. return StringVariable.model_validate(m)
  38. case SegmentType.SECRET:
  39. return SecretVariable.model_validate(m)
  40. case SegmentType.NUMBER if isinstance(value, int):
  41. return IntegerVariable.model_validate(m)
  42. case SegmentType.NUMBER if isinstance(value, float):
  43. return FloatVariable.model_validate(m)
  44. case SegmentType.NUMBER if not isinstance(value, float | int):
  45. raise ValueError(f'invalid number value {value}')
  46. case SegmentType.FILE:
  47. return FileVariable.model_validate(m)
  48. case SegmentType.OBJECT if isinstance(value, dict):
  49. return ObjectVariable.model_validate(
  50. {**m, 'value': {k: build_variable_from_mapping(v) for k, v in value.items()}}
  51. )
  52. case SegmentType.ARRAY_STRING if isinstance(value, list):
  53. return ArrayStringVariable.model_validate({**m, 'value': [build_variable_from_mapping(v) for v in value]})
  54. case SegmentType.ARRAY_NUMBER if isinstance(value, list):
  55. return ArrayNumberVariable.model_validate({**m, 'value': [build_variable_from_mapping(v) for v in value]})
  56. case SegmentType.ARRAY_OBJECT if isinstance(value, list):
  57. return ArrayObjectVariable.model_validate({**m, 'value': [build_variable_from_mapping(v) for v in value]})
  58. case SegmentType.ARRAY_FILE if isinstance(value, list):
  59. return ArrayFileVariable.model_validate({**m, 'value': [build_variable_from_mapping(v) for v in value]})
  60. raise ValueError(f'not supported value type {value_type}')
  61. def build_segment(value: Any, /) -> Segment:
  62. if value is None:
  63. return NoneSegment()
  64. if isinstance(value, str):
  65. return StringSegment(value=value)
  66. if isinstance(value, int):
  67. return IntegerSegment(value=value)
  68. if isinstance(value, float):
  69. return FloatSegment(value=value)
  70. if isinstance(value, dict):
  71. # TODO: Limit the depth of the object
  72. return ObjectSegment(value=value)
  73. if isinstance(value, list):
  74. # TODO: Limit the depth of the array
  75. elements = [build_segment(v) for v in value]
  76. return ArrayAnySegment(value=elements)
  77. if isinstance(value, FileVar):
  78. return FileSegment(value=value)
  79. raise ValueError(f'not supported value {value}')