skyflow-flowvault-python 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (202) hide show
  1. common/.coveragerc +4 -0
  2. common/__init__.py +3 -0
  3. common/client/__init__.py +0 -0
  4. common/client/base_skyflow.py +345 -0
  5. common/client/utils/__init__.py +1 -0
  6. common/client/utils/_utils.py +127 -0
  7. common/errors/__init__.py +1 -0
  8. common/errors/_skyflow_error.py +17 -0
  9. common/generated/__init__.py +0 -0
  10. common/generated/rest/__init__.py +24 -0
  11. common/generated/rest/authentication/__init__.py +4 -0
  12. common/generated/rest/authentication/client.py +181 -0
  13. common/generated/rest/authentication/raw_client.py +241 -0
  14. common/generated/rest/client.py +153 -0
  15. common/generated/rest/core/__init__.py +52 -0
  16. common/generated/rest/core/api_error.py +23 -0
  17. common/generated/rest/core/client_wrapper.py +86 -0
  18. common/generated/rest/core/datetime_utils.py +28 -0
  19. common/generated/rest/core/file.py +67 -0
  20. common/generated/rest/core/force_multipart.py +16 -0
  21. common/generated/rest/core/http_client.py +543 -0
  22. common/generated/rest/core/http_response.py +55 -0
  23. common/generated/rest/core/jsonable_encoder.py +100 -0
  24. common/generated/rest/core/pydantic_utilities.py +255 -0
  25. common/generated/rest/core/query_encoder.py +58 -0
  26. common/generated/rest/core/remove_none_from_dict.py +11 -0
  27. common/generated/rest/core/request_options.py +35 -0
  28. common/generated/rest/core/serialization.py +276 -0
  29. common/generated/rest/environment.py +8 -0
  30. common/generated/rest/errors/__init__.py +9 -0
  31. common/generated/rest/errors/bad_request_error.py +14 -0
  32. common/generated/rest/errors/not_found_error.py +14 -0
  33. common/generated/rest/errors/unauthorized_error.py +14 -0
  34. common/generated/rest/py.typed +0 -0
  35. common/generated/rest/types/__init__.py +9 -0
  36. common/generated/rest/types/googlerpc_status.py +22 -0
  37. common/generated/rest/types/protobuf_any.py +21 -0
  38. common/generated/rest/types/v_1_get_auth_token_response.py +33 -0
  39. common/generated/rest/version.py +6 -0
  40. common/service_account/__init__.py +1 -0
  41. common/service_account/_utils.py +248 -0
  42. common/service_account/client/__init__.py +0 -0
  43. common/service_account/client/auth_client.py +13 -0
  44. common/utils/__init__.py +4 -0
  45. common/utils/_helpers.py +18 -0
  46. common/utils/_skyflow_messages.py +445 -0
  47. common/utils/_utils.py +50 -0
  48. common/utils/constants.py +291 -0
  49. common/utils/enums/__init__.py +12 -0
  50. common/utils/enums/content_types.py +9 -0
  51. common/utils/enums/detect_entities.py +73 -0
  52. common/utils/enums/detect_output_transcriptions.py +8 -0
  53. common/utils/enums/env.py +13 -0
  54. common/utils/enums/log_level.py +8 -0
  55. common/utils/enums/masking_method.py +5 -0
  56. common/utils/enums/redaction_type.py +7 -0
  57. common/utils/enums/request_method.py +8 -0
  58. common/utils/enums/token_mode.py +6 -0
  59. common/utils/enums/token_type.py +6 -0
  60. common/utils/logger/__init__.py +2 -0
  61. common/utils/logger/_log_helpers.py +47 -0
  62. common/utils/logger/_logger.py +50 -0
  63. common/utils/validations/__init__.py +11 -0
  64. common/utils/validations/_validations.py +267 -0
  65. common/vault/base_vault_client.py +122 -0
  66. common/vault/base_vault_controller.py +58 -0
  67. common/vault/data/__init__.py +2 -0
  68. common/vault/data/_base_insert_request.py +7 -0
  69. common/vault/data/_base_insert_response.py +11 -0
  70. skyflow/__init__.py +2 -0
  71. skyflow/client/__init__.py +1 -0
  72. skyflow/client/_http_config_builder.py +45 -0
  73. skyflow/client/skyflow.py +15 -0
  74. skyflow/error/__init__.py +3 -0
  75. skyflow/generated/__init__.py +0 -0
  76. skyflow/generated/rest/__init__.py +164 -0
  77. skyflow/generated/rest/_default_clients.py +32 -0
  78. skyflow/generated/rest/client.py +385 -0
  79. skyflow/generated/rest/core/__init__.py +127 -0
  80. skyflow/generated/rest/core/api_error.py +23 -0
  81. skyflow/generated/rest/core/client_wrapper.py +148 -0
  82. skyflow/generated/rest/core/datetime_utils.py +70 -0
  83. skyflow/generated/rest/core/file.py +67 -0
  84. skyflow/generated/rest/core/force_multipart.py +18 -0
  85. skyflow/generated/rest/core/http_client.py +940 -0
  86. skyflow/generated/rest/core/http_response.py +63 -0
  87. skyflow/generated/rest/core/http_sse/__init__.py +42 -0
  88. skyflow/generated/rest/core/http_sse/_api.py +455 -0
  89. skyflow/generated/rest/core/http_sse/_decoders.py +74 -0
  90. skyflow/generated/rest/core/http_sse/_exceptions.py +7 -0
  91. skyflow/generated/rest/core/http_sse/_models.py +17 -0
  92. skyflow/generated/rest/core/jsonable_encoder.py +133 -0
  93. skyflow/generated/rest/core/logging.py +107 -0
  94. skyflow/generated/rest/core/parse_error.py +36 -0
  95. skyflow/generated/rest/core/pydantic_utilities.py +486 -0
  96. skyflow/generated/rest/core/query_encoder.py +58 -0
  97. skyflow/generated/rest/core/remove_none_from_dict.py +11 -0
  98. skyflow/generated/rest/core/request_options.py +40 -0
  99. skyflow/generated/rest/core/serialization.py +347 -0
  100. skyflow/generated/rest/environment.py +8 -0
  101. skyflow/generated/rest/errors/__init__.py +53 -0
  102. skyflow/generated/rest/errors/bad_request_error.py +11 -0
  103. skyflow/generated/rest/errors/forbidden_error.py +11 -0
  104. skyflow/generated/rest/errors/internal_server_error.py +11 -0
  105. skyflow/generated/rest/errors/not_found_error.py +11 -0
  106. skyflow/generated/rest/errors/too_many_requests_error.py +11 -0
  107. skyflow/generated/rest/errors/unauthorized_error.py +11 -0
  108. skyflow/generated/rest/py.typed +0 -0
  109. skyflow/generated/rest/query/__init__.py +4 -0
  110. skyflow/generated/rest/query/client.py +139 -0
  111. skyflow/generated/rest/query/raw_client.py +239 -0
  112. skyflow/generated/rest/raw_client.py +86 -0
  113. skyflow/generated/rest/records/__init__.py +34 -0
  114. skyflow/generated/rest/records/client.py +685 -0
  115. skyflow/generated/rest/records/raw_client.py +988 -0
  116. skyflow/generated/rest/records/types/__init__.py +34 -0
  117. skyflow/generated/rest/records/types/update_request_update_type.py +5 -0
  118. skyflow/generated/rest/tokens/__init__.py +4 -0
  119. skyflow/generated/rest/tokens/client.py +246 -0
  120. skyflow/generated/rest/tokens/raw_client.py +507 -0
  121. skyflow/generated/rest/types/__init__.py +116 -0
  122. skyflow/generated/rest/types/column_redactions.py +33 -0
  123. skyflow/generated/rest/types/delete_response.py +23 -0
  124. skyflow/generated/rest/types/delete_response_object.py +42 -0
  125. skyflow/generated/rest/types/detokenize_response.py +23 -0
  126. skyflow/generated/rest/types/detokenize_response_object.py +54 -0
  127. skyflow/generated/rest/types/error_response.py +20 -0
  128. skyflow/generated/rest/types/error_response_error.py +28 -0
  129. skyflow/generated/rest/types/execute_query_record_response.py +22 -0
  130. skyflow/generated/rest/types/execute_query_response.py +26 -0
  131. skyflow/generated/rest/types/execute_query_response_metadata.py +26 -0
  132. skyflow/generated/rest/types/get_request_data.py +60 -0
  133. skyflow/generated/rest/types/get_response.py +23 -0
  134. skyflow/generated/rest/types/get_tokens_from_values_request_object.py +30 -0
  135. skyflow/generated/rest/types/get_tokens_from_values_response.py +23 -0
  136. skyflow/generated/rest/types/google_protobuf_value.py +8 -0
  137. skyflow/generated/rest/types/http_code.py +6 -0
  138. skyflow/generated/rest/types/insert_record_data.py +36 -0
  139. skyflow/generated/rest/types/insert_response.py +23 -0
  140. skyflow/generated/rest/types/record_response_object.py +70 -0
  141. skyflow/generated/rest/types/token_group_redactions.py +33 -0
  142. skyflow/generated/rest/types/tokenize_response_object.py +49 -0
  143. skyflow/generated/rest/types/unique_value.py +22 -0
  144. skyflow/generated/rest/types/update_record_data.py +52 -0
  145. skyflow/generated/rest/types/update_record_data_update_type.py +5 -0
  146. skyflow/generated/rest/types/update_response.py +23 -0
  147. skyflow/generated/rest/types/upsert.py +45 -0
  148. skyflow/generated/rest/types/upsert_update_type.py +5 -0
  149. skyflow/generated/rest/version.py +6 -0
  150. skyflow/service_account/__init__.py +15 -0
  151. skyflow/utils/__init__.py +9 -0
  152. skyflow/utils/_http_config.py +36 -0
  153. skyflow/utils/_response_parsing.py +66 -0
  154. skyflow/utils/_retry.py +97 -0
  155. skyflow/utils/_skyflow_messages.py +114 -0
  156. skyflow/utils/_utils.py +54 -0
  157. skyflow/utils/_version.py +1 -0
  158. skyflow/utils/enums/__init__.py +3 -0
  159. skyflow/utils/enums/_custom_header_key.py +10 -0
  160. skyflow/utils/enums/_env_urls.py +9 -0
  161. skyflow/utils/enums/_upsert_type.py +7 -0
  162. skyflow/utils/validations/__init__.py +9 -0
  163. skyflow/utils/validations/_validations.py +195 -0
  164. skyflow/vault/__init__.py +0 -0
  165. skyflow/vault/client/__init__.py +0 -0
  166. skyflow/vault/client/client.py +102 -0
  167. skyflow/vault/controller/__init__.py +1 -0
  168. skyflow/vault/controller/_vault.py +475 -0
  169. skyflow/vault/data/__init__.py +30 -0
  170. skyflow/vault/data/_column_redactions.py +4 -0
  171. skyflow/vault/data/_delete_options.py +8 -0
  172. skyflow/vault/data/_delete_request.py +5 -0
  173. skyflow/vault/data/_delete_response.py +9 -0
  174. skyflow/vault/data/_delete_response_record.py +9 -0
  175. skyflow/vault/data/_detokenize_options.py +8 -0
  176. skyflow/vault/data/_detokenize_request.py +9 -0
  177. skyflow/vault/data/_detokenize_response.py +9 -0
  178. skyflow/vault/data/_detokenize_response_record.py +16 -0
  179. skyflow/vault/data/_detokenize_response_record_metadata.py +10 -0
  180. skyflow/vault/data/_get_options.py +8 -0
  181. skyflow/vault/data/_get_request.py +17 -0
  182. skyflow/vault/data/_get_request_record.py +13 -0
  183. skyflow/vault/data/_get_response.py +9 -0
  184. skyflow/vault/data/_get_response_record.py +17 -0
  185. skyflow/vault/data/_insert_options.py +8 -0
  186. skyflow/vault/data/_insert_request.py +11 -0
  187. skyflow/vault/data/_insert_request_record.py +9 -0
  188. skyflow/vault/data/_insert_response.py +9 -0
  189. skyflow/vault/data/_insert_response_record.py +17 -0
  190. skyflow/vault/data/_request_context.py +16 -0
  191. skyflow/vault/data/_token.py +8 -0
  192. skyflow/vault/data/_token_group_redactions.py +4 -0
  193. skyflow/vault/data/_update_options.py +8 -0
  194. skyflow/vault/data/_update_request.py +11 -0
  195. skyflow/vault/data/_update_request_record.py +6 -0
  196. skyflow/vault/data/_update_response.py +9 -0
  197. skyflow/vault/data/_update_response_record.py +17 -0
  198. skyflow/vault/data/_upsert_options.py +7 -0
  199. skyflow_flowvault_python-1.0.0.dist-info/METADATA +896 -0
  200. skyflow_flowvault_python-1.0.0.dist-info/RECORD +202 -0
  201. skyflow_flowvault_python-1.0.0.dist-info/WHEEL +5 -0
  202. skyflow_flowvault_python-1.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,347 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import collections
4
+ import inspect
5
+ import typing
6
+
7
+ import pydantic
8
+ import typing_extensions
9
+
10
+
11
+ class FieldMetadata:
12
+ """
13
+ Metadata class used to annotate fields to provide additional information.
14
+
15
+ Example:
16
+ class MyDict(TypedDict):
17
+ field: typing.Annotated[str, FieldMetadata(alias="field_name")]
18
+
19
+ Will serialize: `{"field": "value"}`
20
+ To: `{"field_name": "value"}`
21
+ """
22
+
23
+ alias: str
24
+
25
+ def __init__(self, *, alias: str) -> None:
26
+ self.alias = alias
27
+
28
+
29
+ # Resolving type hints (typing.get_type_hints) is expensive because it eval/compiles
30
+ # forward-reference annotations. The result is constant for a given type, so we cache it.
31
+ # This is critical for hot paths like SSE event parsing, where the same (often large
32
+ # discriminated-union) type is converted on every single event.
33
+ _type_hints_cache: typing.Dict[typing.Any, typing.Dict[str, typing.Any]] = {}
34
+
35
+
36
+ def _get_cached_type_hints(expected_type: typing.Any) -> typing.Dict[str, typing.Any]:
37
+ try:
38
+ cached = _type_hints_cache.get(expected_type)
39
+ except TypeError:
40
+ # Unhashable type; resolve without caching.
41
+ return _resolve_type_hints(expected_type)
42
+ if cached is None:
43
+ cached = _resolve_type_hints(expected_type)
44
+ _type_hints_cache[expected_type] = cached
45
+ return cached
46
+
47
+
48
+ def _resolve_type_hints(expected_type: typing.Any) -> typing.Dict[str, typing.Any]:
49
+ try:
50
+ return typing_extensions.get_type_hints(expected_type, include_extras=True)
51
+ except NameError:
52
+ # The type contains a circular reference, so we use the __annotations__ attribute directly.
53
+ return getattr(expected_type, "__annotations__", {})
54
+
55
+
56
+ # Whether convert_and_respect_annotation_metadata can possibly rewrite anything for a given
57
+ # annotation, i.e. whether any reachable model/TypedDict field carries a FieldMetadata alias.
58
+ # This is constant per type, so we cache it and use it to short-circuit the recursive walk.
59
+ _requires_conversion_cache: typing.Dict[typing.Any, bool] = {}
60
+
61
+
62
+ def _requires_conversion(type_: typing.Any) -> bool:
63
+ try:
64
+ cached = _requires_conversion_cache.get(type_)
65
+ except TypeError:
66
+ # Unhashable annotation; compute without caching.
67
+ return _compute_requires_conversion(type_, set())
68
+ if cached is None:
69
+ cached = _compute_requires_conversion(type_, set())
70
+ _requires_conversion_cache[type_] = cached
71
+ return cached
72
+
73
+
74
+ def _compute_requires_conversion(type_: typing.Any, seen: typing.Set[typing.Any]) -> bool:
75
+ clean_type = _remove_annotations(type_)
76
+
77
+ try:
78
+ if clean_type in seen:
79
+ return False
80
+ seen = seen | {clean_type}
81
+ except TypeError:
82
+ # Unhashable type; skip cycle tracking (the type graph is finite in practice).
83
+ pass
84
+
85
+ # Models / TypedDicts: a field alias here means we must dealias; otherwise recurse into fields.
86
+ if (inspect.isclass(clean_type) and issubclass(clean_type, pydantic.BaseModel)) or typing_extensions.is_typeddict(
87
+ clean_type
88
+ ):
89
+ annotations = _get_cached_type_hints(clean_type)
90
+ if _get_alias_to_field_name(annotations):
91
+ return True
92
+ return any(_compute_requires_conversion(hint, seen) for hint in annotations.values())
93
+
94
+ # Containers / unions: recurse into the type arguments (List/Set/Sequence/Dict/Union/etc.).
95
+ return any(_compute_requires_conversion(arg, seen) for arg in typing_extensions.get_args(clean_type))
96
+
97
+
98
+ def convert_and_respect_annotation_metadata(
99
+ *,
100
+ object_: typing.Any,
101
+ annotation: typing.Any,
102
+ inner_type: typing.Optional[typing.Any] = None,
103
+ direction: typing.Literal["read", "write"],
104
+ ) -> typing.Any:
105
+ """
106
+ Respect the metadata annotations on a field, such as aliasing. This function effectively
107
+ manipulates the dict-form of an object to respect the metadata annotations. This is primarily used for
108
+ TypedDicts, which cannot support aliasing out of the box, and can be extended for additional
109
+ utilities, such as defaults.
110
+
111
+ Parameters
112
+ ----------
113
+ object_ : typing.Any
114
+
115
+ annotation : type
116
+ The type we're looking to apply typing annotations from
117
+
118
+ inner_type : typing.Optional[type]
119
+
120
+ Returns
121
+ -------
122
+ typing.Any
123
+ """
124
+
125
+ if object_ is None:
126
+ return None
127
+ if inner_type is None:
128
+ inner_type = annotation
129
+ # The only thing this function ever rewrites is keys that carry a FieldMetadata
130
+ # alias. If nothing in the (cached) type graph has such an alias, the conversion is
131
+ # a content-identity transform, so we can skip the entire recursive walk. This is
132
+ # the hot path for SSE streaming, where a large discriminated union would otherwise
133
+ # be traversed on every single event.
134
+ if not _requires_conversion(annotation):
135
+ return object_
136
+
137
+ clean_type = _remove_annotations(inner_type)
138
+ # Pydantic models
139
+ if (
140
+ inspect.isclass(clean_type)
141
+ and issubclass(clean_type, pydantic.BaseModel)
142
+ and isinstance(object_, typing.Mapping)
143
+ ):
144
+ return _convert_mapping(object_, clean_type, direction)
145
+ # TypedDicts
146
+ if typing_extensions.is_typeddict(clean_type) and isinstance(object_, typing.Mapping):
147
+ return _convert_mapping(object_, clean_type, direction)
148
+
149
+ if (
150
+ typing_extensions.get_origin(clean_type) == typing.Dict
151
+ or typing_extensions.get_origin(clean_type) == dict
152
+ or clean_type == typing.Dict
153
+ ) and isinstance(object_, typing.Dict):
154
+ key_type = typing_extensions.get_args(clean_type)[0]
155
+ value_type = typing_extensions.get_args(clean_type)[1]
156
+
157
+ return {
158
+ key: convert_and_respect_annotation_metadata(
159
+ object_=value,
160
+ annotation=annotation,
161
+ inner_type=value_type,
162
+ direction=direction,
163
+ )
164
+ for key, value in object_.items()
165
+ }
166
+
167
+ # If you're iterating on a string, do not bother to coerce it to a sequence.
168
+ if not isinstance(object_, str):
169
+ if (
170
+ typing_extensions.get_origin(clean_type) == typing.Set
171
+ or typing_extensions.get_origin(clean_type) == set
172
+ or clean_type == typing.Set
173
+ ) and isinstance(object_, typing.Set):
174
+ inner_type = typing_extensions.get_args(clean_type)[0]
175
+ return {
176
+ convert_and_respect_annotation_metadata(
177
+ object_=item,
178
+ annotation=annotation,
179
+ inner_type=inner_type,
180
+ direction=direction,
181
+ )
182
+ for item in object_
183
+ }
184
+ elif (
185
+ (
186
+ typing_extensions.get_origin(clean_type) == typing.List
187
+ or typing_extensions.get_origin(clean_type) == list
188
+ or clean_type == typing.List
189
+ )
190
+ and isinstance(object_, typing.List)
191
+ ) or (
192
+ (
193
+ typing_extensions.get_origin(clean_type) == typing.Sequence
194
+ or typing_extensions.get_origin(clean_type) == collections.abc.Sequence
195
+ or clean_type == typing.Sequence
196
+ )
197
+ and isinstance(object_, typing.Sequence)
198
+ ):
199
+ inner_type = typing_extensions.get_args(clean_type)[0]
200
+ return [
201
+ convert_and_respect_annotation_metadata(
202
+ object_=item,
203
+ annotation=annotation,
204
+ inner_type=inner_type,
205
+ direction=direction,
206
+ )
207
+ for item in object_
208
+ ]
209
+
210
+ if typing_extensions.get_origin(clean_type) == typing.Union:
211
+ # We should be able to ~relatively~ safely try to convert keys against all
212
+ # member types in the union, the edge case here is if one member aliases a field
213
+ # of the same name to a different name from another member
214
+ # Or if another member aliases a field of the same name that another member does not.
215
+ for member in typing_extensions.get_args(clean_type):
216
+ object_ = convert_and_respect_annotation_metadata(
217
+ object_=object_,
218
+ annotation=annotation,
219
+ inner_type=member,
220
+ direction=direction,
221
+ )
222
+ return object_
223
+
224
+ annotated_type = _get_annotation(annotation)
225
+ if annotated_type is None:
226
+ return object_
227
+
228
+ # If the object is not a TypedDict, a Union, or other container (list, set, sequence, etc.)
229
+ # Then we can safely call it on the recursive conversion.
230
+ return object_
231
+
232
+
233
+ def _convert_mapping(
234
+ object_: typing.Mapping[str, object],
235
+ expected_type: typing.Any,
236
+ direction: typing.Literal["read", "write"],
237
+ ) -> typing.Mapping[str, object]:
238
+ converted_object: typing.Dict[str, object] = {}
239
+ annotations = _get_cached_type_hints(expected_type)
240
+ aliases_to_field_names = _get_alias_to_field_name(annotations)
241
+ for key, value in object_.items():
242
+ if direction == "read" and key in aliases_to_field_names:
243
+ dealiased_key = aliases_to_field_names.get(key)
244
+ if dealiased_key is not None:
245
+ type_ = annotations.get(dealiased_key)
246
+ else:
247
+ type_ = annotations.get(key)
248
+ # Note you can't get the annotation by the field name if you're in read mode, so you must check the aliases map
249
+ #
250
+ # So this is effectively saying if we're in write mode, and we don't have a type, or if we're in read mode and we don't have an alias
251
+ # then we can just pass the value through as is
252
+ if type_ is None:
253
+ converted_object[key] = value
254
+ elif direction == "read" and key not in aliases_to_field_names:
255
+ converted_object[key] = convert_and_respect_annotation_metadata(
256
+ object_=value, annotation=type_, direction=direction
257
+ )
258
+ else:
259
+ converted_object[_alias_key(key, type_, direction, aliases_to_field_names)] = (
260
+ convert_and_respect_annotation_metadata(object_=value, annotation=type_, direction=direction)
261
+ )
262
+ return converted_object
263
+
264
+
265
+ def _get_annotation(type_: typing.Any) -> typing.Optional[typing.Any]:
266
+ maybe_annotated_type = typing_extensions.get_origin(type_)
267
+ if maybe_annotated_type is None:
268
+ return None
269
+
270
+ if maybe_annotated_type == typing_extensions.NotRequired:
271
+ type_ = typing_extensions.get_args(type_)[0]
272
+ maybe_annotated_type = typing_extensions.get_origin(type_)
273
+
274
+ if maybe_annotated_type == typing_extensions.Annotated:
275
+ return type_
276
+
277
+ return None
278
+
279
+
280
+ def _remove_annotations(type_: typing.Any) -> typing.Any:
281
+ maybe_annotated_type = typing_extensions.get_origin(type_)
282
+ if maybe_annotated_type is None:
283
+ return type_
284
+
285
+ if maybe_annotated_type == typing_extensions.NotRequired:
286
+ return _remove_annotations(typing_extensions.get_args(type_)[0])
287
+
288
+ if maybe_annotated_type == typing_extensions.Annotated:
289
+ return _remove_annotations(typing_extensions.get_args(type_)[0])
290
+
291
+ return type_
292
+
293
+
294
+ def get_alias_to_field_mapping(type_: typing.Any) -> typing.Dict[str, str]:
295
+ annotations = _get_cached_type_hints(type_)
296
+ return _get_alias_to_field_name(annotations)
297
+
298
+
299
+ def get_field_to_alias_mapping(type_: typing.Any) -> typing.Dict[str, str]:
300
+ annotations = _get_cached_type_hints(type_)
301
+ return _get_field_to_alias_name(annotations)
302
+
303
+
304
+ def _get_alias_to_field_name(
305
+ field_to_hint: typing.Dict[str, typing.Any],
306
+ ) -> typing.Dict[str, str]:
307
+ aliases = {}
308
+ for field, hint in field_to_hint.items():
309
+ maybe_alias = _get_alias_from_type(hint)
310
+ if maybe_alias is not None:
311
+ aliases[maybe_alias] = field
312
+ return aliases
313
+
314
+
315
+ def _get_field_to_alias_name(
316
+ field_to_hint: typing.Dict[str, typing.Any],
317
+ ) -> typing.Dict[str, str]:
318
+ aliases = {}
319
+ for field, hint in field_to_hint.items():
320
+ maybe_alias = _get_alias_from_type(hint)
321
+ if maybe_alias is not None:
322
+ aliases[field] = maybe_alias
323
+ return aliases
324
+
325
+
326
+ def _get_alias_from_type(type_: typing.Any) -> typing.Optional[str]:
327
+ maybe_annotated_type = _get_annotation(type_)
328
+
329
+ if maybe_annotated_type is not None:
330
+ # The actual annotations are 1 onward, the first is the annotated type
331
+ annotations = typing_extensions.get_args(maybe_annotated_type)[1:]
332
+
333
+ for annotation in annotations:
334
+ if isinstance(annotation, FieldMetadata) and annotation.alias is not None:
335
+ return annotation.alias
336
+ return None
337
+
338
+
339
+ def _alias_key(
340
+ key: str,
341
+ type_: typing.Any,
342
+ direction: typing.Literal["read", "write"],
343
+ aliases_to_field_names: typing.Dict[str, str],
344
+ ) -> str:
345
+ if direction == "read":
346
+ return aliases_to_field_names.get(key, key)
347
+ return _get_alias_from_type(type_=type_) or key
@@ -0,0 +1,8 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import enum
4
+
5
+
6
+ class SkyflowAuthEnvironment(enum.Enum):
7
+ PRODUCTION = "https://%7B%7Bvault_url%7D%7D"
8
+ SANDBOX = "https://%7B%7Bvault_url%7D%7D"
@@ -0,0 +1,53 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ # isort: skip_file
4
+
5
+ import typing
6
+ from importlib import import_module
7
+
8
+ if typing.TYPE_CHECKING:
9
+ from .bad_request_error import BadRequestError
10
+ from .forbidden_error import ForbiddenError
11
+ from .internal_server_error import InternalServerError
12
+ from .not_found_error import NotFoundError
13
+ from .too_many_requests_error import TooManyRequestsError
14
+ from .unauthorized_error import UnauthorizedError
15
+ _dynamic_imports: typing.Dict[str, str] = {
16
+ "BadRequestError": ".bad_request_error",
17
+ "ForbiddenError": ".forbidden_error",
18
+ "InternalServerError": ".internal_server_error",
19
+ "NotFoundError": ".not_found_error",
20
+ "TooManyRequestsError": ".too_many_requests_error",
21
+ "UnauthorizedError": ".unauthorized_error",
22
+ }
23
+
24
+
25
+ def __getattr__(attr_name: str) -> typing.Any:
26
+ module_name = _dynamic_imports.get(attr_name)
27
+ if module_name is None:
28
+ raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}")
29
+ try:
30
+ module = import_module(module_name, __package__)
31
+ if module_name == f".{attr_name}":
32
+ return module
33
+ else:
34
+ return getattr(module, attr_name)
35
+ except ImportError as e:
36
+ raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e
37
+ except AttributeError as e:
38
+ raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e
39
+
40
+
41
+ def __dir__():
42
+ lazy_attrs = list(_dynamic_imports.keys())
43
+ return sorted(lazy_attrs)
44
+
45
+
46
+ __all__ = [
47
+ "BadRequestError",
48
+ "ForbiddenError",
49
+ "InternalServerError",
50
+ "NotFoundError",
51
+ "TooManyRequestsError",
52
+ "UnauthorizedError",
53
+ ]
@@ -0,0 +1,11 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ from ..core.api_error import ApiError
6
+ from ..types.error_response import ErrorResponse
7
+
8
+
9
+ class BadRequestError(ApiError):
10
+ def __init__(self, body: ErrorResponse, headers: typing.Optional[typing.Dict[str, str]] = None):
11
+ super().__init__(status_code=400, headers=headers, body=body)
@@ -0,0 +1,11 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ from ..core.api_error import ApiError
6
+ from ..types.error_response import ErrorResponse
7
+
8
+
9
+ class ForbiddenError(ApiError):
10
+ def __init__(self, body: ErrorResponse, headers: typing.Optional[typing.Dict[str, str]] = None):
11
+ super().__init__(status_code=403, headers=headers, body=body)
@@ -0,0 +1,11 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ from ..core.api_error import ApiError
6
+ from ..types.error_response import ErrorResponse
7
+
8
+
9
+ class InternalServerError(ApiError):
10
+ def __init__(self, body: ErrorResponse, headers: typing.Optional[typing.Dict[str, str]] = None):
11
+ super().__init__(status_code=500, headers=headers, body=body)
@@ -0,0 +1,11 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ from ..core.api_error import ApiError
6
+ from ..types.error_response import ErrorResponse
7
+
8
+
9
+ class NotFoundError(ApiError):
10
+ def __init__(self, body: ErrorResponse, headers: typing.Optional[typing.Dict[str, str]] = None):
11
+ super().__init__(status_code=404, headers=headers, body=body)
@@ -0,0 +1,11 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ from ..core.api_error import ApiError
6
+ from ..types.error_response import ErrorResponse
7
+
8
+
9
+ class TooManyRequestsError(ApiError):
10
+ def __init__(self, body: ErrorResponse, headers: typing.Optional[typing.Dict[str, str]] = None):
11
+ super().__init__(status_code=429, headers=headers, body=body)
@@ -0,0 +1,11 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ from ..core.api_error import ApiError
6
+ from ..types.error_response import ErrorResponse
7
+
8
+
9
+ class UnauthorizedError(ApiError):
10
+ def __init__(self, body: ErrorResponse, headers: typing.Optional[typing.Dict[str, str]] = None):
11
+ super().__init__(status_code=401, headers=headers, body=body)
File without changes
@@ -0,0 +1,4 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ # isort: skip_file
4
+
@@ -0,0 +1,139 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
6
+ from ..core.request_options import RequestOptions
7
+ from ..types.execute_query_response import ExecuteQueryResponse
8
+ from .raw_client import AsyncRawQueryClient, RawQueryClient
9
+
10
+ # this is used as the default value for optional parameters
11
+ OMIT = typing.cast(typing.Any, ...)
12
+
13
+
14
+ class QueryClient:
15
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
16
+ self._raw_client = RawQueryClient(client_wrapper=client_wrapper)
17
+
18
+ @property
19
+ def with_raw_response(self) -> RawQueryClient:
20
+ """
21
+ Retrieves a raw implementation of this client that returns raw responses.
22
+
23
+ Returns
24
+ -------
25
+ RawQueryClient
26
+ """
27
+ return self._raw_client
28
+
29
+ def execute_query(
30
+ self, *, vault_id: str, query: str, request_options: typing.Optional[RequestOptions] = None
31
+ ) -> ExecuteQueryResponse:
32
+ """
33
+ Returns records for a valid SQL query. This endpoint
34
+ - Can return masked record values.
35
+ - Supports only the `SELECT` command.
36
+ - Returns a maximum of 25 records. To return additional records, perform another query using the `OFFSET` keyword.
37
+ - Can't modify the vault or perform transactions.
38
+ - Can't return tokens.
39
+ - Can't return file download or render URLs.
40
+
41
+ Parameters
42
+ ----------
43
+ vault_id : str
44
+ ID of the vault where the query is being performed.
45
+
46
+ query : str
47
+ Query to perform.
48
+
49
+ request_options : typing.Optional[RequestOptions]
50
+ Request-specific configuration.
51
+
52
+ Returns
53
+ -------
54
+ ExecuteQueryResponse
55
+ OK
56
+
57
+ Examples
58
+ --------
59
+ from skyflow import SkyflowAuth
60
+
61
+ client = SkyflowAuth(
62
+ token="YOUR_TOKEN",
63
+ )
64
+ client.query.execute_query(
65
+ vault_id="d408485953784308a000f8dcf81901ef",
66
+ query="query",
67
+ )
68
+ """
69
+ _response = self._raw_client.execute_query(vault_id=vault_id, query=query, request_options=request_options)
70
+ return _response.data
71
+
72
+
73
+ class AsyncQueryClient:
74
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
75
+ self._raw_client = AsyncRawQueryClient(client_wrapper=client_wrapper)
76
+
77
+ @property
78
+ def with_raw_response(self) -> AsyncRawQueryClient:
79
+ """
80
+ Retrieves a raw implementation of this client that returns raw responses.
81
+
82
+ Returns
83
+ -------
84
+ AsyncRawQueryClient
85
+ """
86
+ return self._raw_client
87
+
88
+ async def execute_query(
89
+ self, *, vault_id: str, query: str, request_options: typing.Optional[RequestOptions] = None
90
+ ) -> ExecuteQueryResponse:
91
+ """
92
+ Returns records for a valid SQL query. This endpoint
93
+ - Can return masked record values.
94
+ - Supports only the `SELECT` command.
95
+ - Returns a maximum of 25 records. To return additional records, perform another query using the `OFFSET` keyword.
96
+ - Can't modify the vault or perform transactions.
97
+ - Can't return tokens.
98
+ - Can't return file download or render URLs.
99
+
100
+ Parameters
101
+ ----------
102
+ vault_id : str
103
+ ID of the vault where the query is being performed.
104
+
105
+ query : str
106
+ Query to perform.
107
+
108
+ request_options : typing.Optional[RequestOptions]
109
+ Request-specific configuration.
110
+
111
+ Returns
112
+ -------
113
+ ExecuteQueryResponse
114
+ OK
115
+
116
+ Examples
117
+ --------
118
+ import asyncio
119
+
120
+ from skyflow import AsyncSkyflowAuth
121
+
122
+ client = AsyncSkyflowAuth(
123
+ token="YOUR_TOKEN",
124
+ )
125
+
126
+
127
+ async def main() -> None:
128
+ await client.query.execute_query(
129
+ vault_id="d408485953784308a000f8dcf81901ef",
130
+ query="query",
131
+ )
132
+
133
+
134
+ asyncio.run(main())
135
+ """
136
+ _response = await self._raw_client.execute_query(
137
+ vault_id=vault_id, query=query, request_options=request_options
138
+ )
139
+ return _response.data