jararaca 0.3.12a19__py3-none-any.whl → 0.3.12a20__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.

Potentially problematic release.


This version of jararaca might be problematic. Click here for more details.

@@ -48,6 +48,35 @@ def is_constant(name: str) -> bool:
48
48
  return CONSTANT_PATTERN.match(name) is not None
49
49
 
50
50
 
51
+ def unwrap_annotated_type(field_type: Any) -> tuple[Any, list[Any]]:
52
+ """
53
+ Recursively unwrap Annotated types to find the real underlying type.
54
+
55
+ Args:
56
+ field_type: The type to unwrap, which may be deeply nested Annotated types
57
+
58
+ Returns:
59
+ A tuple of (unwrapped_type, all_metadata) where:
60
+ - unwrapped_type is the final non-Annotated type
61
+ - all_metadata is a list of all metadata from all Annotated layers
62
+ """
63
+ all_metadata = []
64
+ current_type = field_type
65
+
66
+ while get_origin(current_type) == Annotated:
67
+ # Collect metadata from current layer
68
+ if hasattr(current_type, "__metadata__"):
69
+ all_metadata.extend(current_type.__metadata__)
70
+
71
+ # Move to the next inner type
72
+ if hasattr(current_type, "__args__") and len(current_type.__args__) > 0:
73
+ current_type = current_type.__args__[0]
74
+ else:
75
+ break
76
+
77
+ return current_type, all_metadata
78
+
79
+
51
80
  def is_upload_file_type(field_type: Any) -> bool:
52
81
  """
53
82
  Check if a type is UploadFile or a list/array of UploadFile.
@@ -110,7 +139,8 @@ def should_exclude_field(
110
139
 
111
140
  # Check for Annotated types with Field metadata
112
141
  if get_origin(field_type) == Annotated:
113
- for metadata in field_type.__metadata__:
142
+ unwrapped_type, all_metadata = unwrap_annotated_type(field_type)
143
+ for metadata in all_metadata:
114
144
  # Check if this is a Pydantic Field by looking for expected attributes
115
145
  if hasattr(metadata, "exclude") or hasattr(metadata, "alias"):
116
146
  # Check if Field has exclude=True
@@ -205,7 +235,8 @@ def has_default_value(
205
235
 
206
236
  # Check for Annotated types with Field metadata that have defaults
207
237
  if get_origin(field_type) == Annotated:
208
- for metadata in field_type.__metadata__:
238
+ unwrapped_type, all_metadata = unwrap_annotated_type(field_type)
239
+ for metadata in all_metadata:
209
240
  # Check if this is a Pydantic Field with a default
210
241
  if hasattr(metadata, "default") and hasattr(
211
242
  metadata, "exclude"
@@ -356,16 +387,18 @@ def get_field_type_for_ts(field_type: Any, context_suffix: str = "") -> Any:
356
387
  [get_field_type_for_ts(x, context_suffix) for x in field_type.__args__]
357
388
  )
358
389
  if (get_origin(field_type) == Annotated) and (len(field_type.__args__) > 0):
390
+ unwrapped_type, all_metadata = unwrap_annotated_type(field_type)
391
+
359
392
  if (
360
393
  plain_validator := next(
361
- (x for x in field_type.__metadata__ if isinstance(x, PlainValidator)),
394
+ (x for x in all_metadata if isinstance(x, PlainValidator)),
362
395
  None,
363
396
  )
364
397
  ) is not None:
365
398
  return get_field_type_for_ts(
366
399
  plain_validator.json_schema_input_type, context_suffix
367
400
  )
368
- return get_field_type_for_ts(field_type.__args__[0], context_suffix)
401
+ return get_field_type_for_ts(unwrapped_type, context_suffix)
369
402
  return "unknown"
370
403
 
371
404
 
@@ -974,15 +1007,16 @@ def extract_parameters(
974
1007
  if is_primitive(member):
975
1008
 
976
1009
  if get_origin(member) is Annotated:
1010
+ unwrapped_type, all_metadata = unwrap_annotated_type(member)
977
1011
  if (
978
1012
  plain_validator := next(
979
- (x for x in member.__metadata__ if isinstance(x, PlainValidator)),
1013
+ (x for x in all_metadata if isinstance(x, PlainValidator)),
980
1014
  None,
981
1015
  )
982
1016
  ) is not None:
983
1017
  mapped_types.add(plain_validator.json_schema_input_type)
984
1018
  return parameters_list, mapped_types
985
- return extract_parameters(member.__args__[0], controller, mapping)
1019
+ return extract_parameters(unwrapped_type, controller, mapping)
986
1020
  return parameters_list, mapped_types
987
1021
 
988
1022
  if hasattr(member, "__bases__"):
@@ -1002,8 +1036,21 @@ def extract_parameters(
1002
1036
  continue
1003
1037
 
1004
1038
  if get_origin(parameter_type) == Annotated:
1005
- annotated_type_hook = parameter_type.__metadata__[0]
1006
- annotated_type = parameter_type.__args__[0]
1039
+ unwrapped_type, all_metadata = unwrap_annotated_type(parameter_type)
1040
+ # Look for FastAPI parameter annotations in all metadata layers
1041
+ annotated_type_hook = None
1042
+ for metadata in all_metadata:
1043
+ if isinstance(
1044
+ metadata, (Header, Cookie, Form, Body, Query, Path, Depends)
1045
+ ):
1046
+ annotated_type_hook = metadata
1047
+ break
1048
+
1049
+ if annotated_type_hook is None and all_metadata:
1050
+ # Fallback to first metadata if no FastAPI annotation found
1051
+ annotated_type_hook = all_metadata[0]
1052
+
1053
+ annotated_type = unwrapped_type
1007
1054
  if isinstance(annotated_type_hook, Header):
1008
1055
  mapped_types.add(str)
1009
1056
  parameters_list.append(
@@ -1270,21 +1317,22 @@ def extract_parameters(
1270
1317
  for _, parameter_type in parameter_members.items():
1271
1318
  if is_primitive(parameter_type.annotation):
1272
1319
  if get_origin(parameter_type.annotation) is not None:
1273
- if (
1274
- get_origin(parameter_type.annotation) == Annotated
1275
- and (
1276
- plain_validator := next(
1277
- (
1278
- x
1279
- for x in parameter_type.annotation.__metadata__
1280
- if isinstance(x, PlainValidator)
1281
- ),
1282
- None,
1283
- )
1320
+ if get_origin(parameter_type.annotation) == Annotated:
1321
+ unwrapped_type, all_metadata = unwrap_annotated_type(
1322
+ parameter_type.annotation
1284
1323
  )
1285
- is not None
1286
- ):
1287
- mapped_types.add(plain_validator.json_schema_input_type)
1324
+ plain_validator = next(
1325
+ (
1326
+ x
1327
+ for x in all_metadata
1328
+ if isinstance(x, PlainValidator)
1329
+ ),
1330
+ None,
1331
+ )
1332
+ if plain_validator is not None:
1333
+ mapped_types.add(
1334
+ plain_validator.json_schema_input_type
1335
+ )
1288
1336
  else:
1289
1337
  args = parameter_type.annotation.__args__
1290
1338
  mapped_types.update(args)
@@ -1315,22 +1363,15 @@ def extract_all_envolved_types(field_type: Any) -> set[Any]:
1315
1363
 
1316
1364
  if is_primitive(field_type):
1317
1365
  if get_origin(field_type) is not None:
1318
- if (
1319
- get_origin(field_type) == Annotated
1320
- and (
1321
- plain_validator := next(
1322
- (
1323
- x
1324
- for x in field_type.__metadata__
1325
- if isinstance(x, PlainValidator)
1326
- ),
1327
- None,
1328
- )
1366
+ if get_origin(field_type) == Annotated:
1367
+ unwrapped_type, all_metadata = unwrap_annotated_type(field_type)
1368
+ plain_validator = next(
1369
+ (x for x in all_metadata if isinstance(x, PlainValidator)),
1370
+ None,
1329
1371
  )
1330
- is not None
1331
- ):
1332
- mapped_types.add(plain_validator.json_schema_input_type)
1333
- return mapped_types
1372
+ if plain_validator is not None:
1373
+ mapped_types.add(plain_validator.json_schema_input_type)
1374
+ return mapped_types
1334
1375
  else:
1335
1376
  mapped_types.update(
1336
1377
  *[extract_all_envolved_types(arg) for arg in field_type.__args__]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: jararaca
3
- Version: 0.3.12a19
3
+ Version: 0.3.12a20
4
4
  Summary: A simple and fast API framework for Python
5
5
  Home-page: https://github.com/LuscasLeo/jararaca
6
6
  Author: Lucas S
@@ -1,6 +1,6 @@
1
1
  LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
2
2
  README.md,sha256=2qMM__t_MoLKZr4IY9tXjo-Jn6LKjuHMb1qbyXpgL08,3401
3
- pyproject.toml,sha256=mgJOhSQjMq5tiTypMWYNHonlLtptX67W82wrg7OUiFg,2041
3
+ pyproject.toml,sha256=uJ0U1QV3oT9pdznIF6jWS3yTivDWOsFWynfAES9yqIU,2041
4
4
  jararaca/__init__.py,sha256=vK3zyIVLckwZgj1FPX6jzSbzaSWmSy3wQ2KMwmpJnmg,22046
5
5
  jararaca/__main__.py,sha256=-O3vsB5lHdqNFjUtoELDF81IYFtR-DSiiFMzRaiSsv4,67
6
6
  jararaca/broker_backend/__init__.py,sha256=GzEIuHR1xzgCJD4FE3harNjoaYzxHMHoEL0_clUaC-k,3528
@@ -70,12 +70,12 @@ jararaca/tools/app_config/decorators.py,sha256=-ckkMZ1dswOmECdo1rFrZ15UAku--txaN
70
70
  jararaca/tools/app_config/interceptor.py,sha256=HV8h4AxqUc_ACs5do4BSVlyxlRXzx7HqJtoVO9tfRnQ,2611
71
71
  jararaca/tools/typescript/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
72
72
  jararaca/tools/typescript/decorators.py,sha256=y1zBq8mBZ8CBXlZ0nKy2RyIgCvP9kp4elACbaC6dptQ,2946
73
- jararaca/tools/typescript/interface_parser.py,sha256=dkM3Nsab_1HDRY_clC6LcZLtDXFHpAqNdcqIC_MzALc,51753
73
+ jararaca/tools/typescript/interface_parser.py,sha256=Nsct1hdF35yAvXrXL-MVIC-uGKeQ3CY3xn-ixXfUidQ,53545
74
74
  jararaca/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
75
75
  jararaca/utils/rabbitmq_utils.py,sha256=ytdAFUyv-OBkaVnxezuJaJoLrmN7giZgtKeet_IsMBs,10918
76
76
  jararaca/utils/retry.py,sha256=DzPX_fXUvTqej6BQ8Mt2dvLo9nNlTBm7Kx2pFZ26P2Q,4668
77
- jararaca-0.3.12a19.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
78
- jararaca-0.3.12a19.dist-info/METADATA,sha256=lpSsuVzfv-LNkPBbg-eFlR-E2PcsCzlNXl0da8gQbQk,4996
79
- jararaca-0.3.12a19.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
80
- jararaca-0.3.12a19.dist-info/entry_points.txt,sha256=WIh3aIvz8LwUJZIDfs4EeH3VoFyCGEk7cWJurW38q0I,45
81
- jararaca-0.3.12a19.dist-info/RECORD,,
77
+ jararaca-0.3.12a20.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
78
+ jararaca-0.3.12a20.dist-info/METADATA,sha256=f2WNsZHRbUMukKcfHiuZ08BNQuziV1ZEjigRDcS9Et8,4996
79
+ jararaca-0.3.12a20.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
80
+ jararaca-0.3.12a20.dist-info/entry_points.txt,sha256=WIh3aIvz8LwUJZIDfs4EeH3VoFyCGEk7cWJurW38q0I,45
81
+ jararaca-0.3.12a20.dist-info/RECORD,,
pyproject.toml CHANGED
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "jararaca"
3
- version = "0.3.12a19"
3
+ version = "0.3.12a20"
4
4
  description = "A simple and fast API framework for Python"
5
5
  authors = ["Lucas S <me@luscasleo.dev>"]
6
6
  readme = "README.md"