jararaca 0.3.12a18__py3-none-any.whl → 0.3.12a19__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.

@@ -24,7 +24,7 @@ from typing import (
24
24
  from uuid import UUID
25
25
 
26
26
  from fastapi import Request, Response, UploadFile
27
- from fastapi.params import Body, Cookie, Depends, Header, Path, Query
27
+ from fastapi.params import Body, Cookie, Depends, Form, Header, Path, Query
28
28
  from fastapi.security.http import HTTPBase
29
29
  from pydantic import BaseModel, PlainValidator
30
30
  from pydantic_core import PydanticUndefined
@@ -48,6 +48,29 @@ def is_constant(name: str) -> bool:
48
48
  return CONSTANT_PATTERN.match(name) is not None
49
49
 
50
50
 
51
+ def is_upload_file_type(field_type: Any) -> bool:
52
+ """
53
+ Check if a type is UploadFile or a list/array of UploadFile.
54
+
55
+ Args:
56
+ field_type: The type to check
57
+
58
+ Returns:
59
+ True if it's UploadFile or list[UploadFile], False otherwise
60
+ """
61
+ if field_type == UploadFile:
62
+ return True
63
+
64
+ # Check for list[UploadFile], List[UploadFile], etc.
65
+ origin = get_origin(field_type)
66
+ if origin in (list, frozenset, set):
67
+ args = getattr(field_type, "__args__", ())
68
+ if args and args[0] == UploadFile:
69
+ return True
70
+
71
+ return False
72
+
73
+
51
74
  def should_exclude_field(
52
75
  field_name: str, field_type: Any, basemodel_type: Type[Any]
53
76
  ) -> bool:
@@ -625,6 +648,21 @@ def write_microservice_to_typescript_interface(
625
648
  // noinspection JSUnusedGlobalSymbols
626
649
 
627
650
  import { HttpService, HttpBackend, HttpBackendRequest, ResponseType, createClassQueryHooks , createClassMutationHooks, createClassInfiniteQueryHooks, paginationModelByFirstArgPaginationFilter } from "@jararaca/core";
651
+
652
+ function makeFormData(data: Record<string, any>): FormData {
653
+ const formData = new FormData();
654
+ for (const key in data) {
655
+ if (Array.isArray(data[key])) {
656
+ data[key].forEach((item: any) => {
657
+ formData.append(key, item);
658
+ });
659
+ } else {
660
+ formData.append(key, data[key]);
661
+ }
662
+ }
663
+ return formData;
664
+ }
665
+
628
666
  export type WebSocketMessageMap = {
629
667
  %s
630
668
  }
@@ -768,10 +806,21 @@ def write_rest_controller_to_typescript_interface(
768
806
  class_buffer.write(f'\t\t\tmethod: "{mapping.method}",\n')
769
807
 
770
808
  endpoint_path = parse_path_with_params(mapping.path, arg_params_spec)
771
- final_path = "/".join(
772
- s.strip("/") for s in [rest_controller.path, endpoint_path]
773
- )
774
- class_buffer.write(f"\t\t\tpath: `/{final_path}`,\n")
809
+
810
+ # Properly handle path joining to avoid double slashes
811
+ controller_path = rest_controller.path or ""
812
+ path_parts = []
813
+
814
+ if controller_path and controller_path.strip("/"):
815
+ path_parts.append(controller_path.strip("/"))
816
+ if endpoint_path and endpoint_path.strip("/"):
817
+ path_parts.append(endpoint_path.strip("/"))
818
+
819
+ final_path = "/".join(path_parts) if path_parts else ""
820
+ # Ensure the path starts with a single slash
821
+ formatted_path = f"/{final_path}" if final_path else "/"
822
+
823
+ class_buffer.write(f"\t\t\tpath: `{formatted_path}`,\n")
775
824
 
776
825
  # Sort path params
777
826
  path_params = sorted(
@@ -803,10 +852,25 @@ def write_rest_controller_to_typescript_interface(
803
852
  class_buffer.write(f'\t\t\t\t"{param.name}": {param.name},\n')
804
853
  class_buffer.write("\t\t\t},\n")
805
854
 
806
- if (
807
- body := next((x for x in arg_params_spec if x.type_ == "body"), None)
808
- ) is not None:
809
- class_buffer.write(f"\t\t\tbody: {body.name}\n")
855
+ # Check if we need to use FormData (for file uploads or form parameters)
856
+ form_params = [param for param in arg_params_spec if param.type_ == "form"]
857
+ body_param = next((x for x in arg_params_spec if x.type_ == "body"), None)
858
+
859
+ if form_params:
860
+ # Use FormData for file uploads and form parameters
861
+ class_buffer.write("\t\t\tbody: makeFormData({\n")
862
+
863
+ # Add form parameters (including file uploads)
864
+ for param in form_params:
865
+ class_buffer.write(f'\t\t\t\t"{param.name}": {param.name},\n')
866
+
867
+ # Add body parameter if it exists alongside form params
868
+ if body_param:
869
+ class_buffer.write(f"\t\t\t\t...{body_param.name},\n")
870
+
871
+ class_buffer.write("\t\t\t})\n")
872
+ elif body_param is not None:
873
+ class_buffer.write(f"\t\t\tbody: {body_param.name}\n")
810
874
  else:
811
875
  class_buffer.write("\t\t\tbody: undefined\n")
812
876
 
@@ -862,7 +926,7 @@ EXCLUDED_REQUESTS_TYPES = [Request, Response]
862
926
 
863
927
  @dataclass
864
928
  class HttpParemeterSpec:
865
- type_: Literal["query", "path", "body", "header", "cookie"]
929
+ type_: Literal["query", "path", "body", "header", "cookie", "form"]
866
930
  name: str
867
931
  required: bool
868
932
  argument_type_str: str
@@ -960,6 +1024,16 @@ def extract_parameters(
960
1024
  argument_type_str=get_field_type_for_ts(str),
961
1025
  )
962
1026
  )
1027
+ elif isinstance(annotated_type_hook, Form):
1028
+ mapped_types.add(annotated_type)
1029
+ parameters_list.append(
1030
+ HttpParemeterSpec(
1031
+ type_="form",
1032
+ name=parameter_name,
1033
+ required=True,
1034
+ argument_type_str=get_field_type_for_ts(annotated_type),
1035
+ )
1036
+ )
963
1037
  elif isinstance(annotated_type_hook, Body):
964
1038
  mapped_types.update(extract_all_envolved_types(parameter_type))
965
1039
  # For body parameters, use Input suffix if it's a split model
@@ -1067,11 +1141,11 @@ def extract_parameters(
1067
1141
  )
1068
1142
  else:
1069
1143
  mapped_types.add(annotated_type)
1070
- # Special handling for UploadFile - should go to body, not query
1071
- if annotated_type == UploadFile:
1144
+ # Special handling for UploadFile and list[UploadFile] - should be treated as form data
1145
+ if is_upload_file_type(annotated_type):
1072
1146
  parameters_list.append(
1073
1147
  HttpParemeterSpec(
1074
- type_="body",
1148
+ type_="form",
1075
1149
  name=parameter_name,
1076
1150
  required=True,
1077
1151
  argument_type_str=get_field_type_for_ts(annotated_type),
@@ -1117,12 +1191,12 @@ def extract_parameters(
1117
1191
  ),
1118
1192
  )
1119
1193
  )
1120
- elif parameter_type == UploadFile:
1121
- # UploadFile should always go to body, not query parameters
1194
+ elif parameter_type == UploadFile or is_upload_file_type(parameter_type):
1195
+ # UploadFile and list[UploadFile] should be treated as form data
1122
1196
  mapped_types.add(parameter_type)
1123
1197
  parameters_list.append(
1124
1198
  HttpParemeterSpec(
1125
- type_="body",
1199
+ type_="form",
1126
1200
  name=parameter_name,
1127
1201
  required=True,
1128
1202
  argument_type_str=get_field_type_for_ts(parameter_type),
@@ -1156,11 +1230,11 @@ def extract_parameters(
1156
1230
  )
1157
1231
  else:
1158
1232
  mapped_types.add(parameter_type)
1159
- # Special handling for UploadFile - should go to body, not query
1160
- if parameter_type == UploadFile:
1233
+ # Special handling for UploadFile and list[UploadFile] - should be treated as form data
1234
+ if is_upload_file_type(parameter_type):
1161
1235
  parameters_list.append(
1162
1236
  HttpParemeterSpec(
1163
- type_="body",
1237
+ type_="form",
1164
1238
  name=parameter_name,
1165
1239
  required=True,
1166
1240
  argument_type_str=get_field_type_for_ts(parameter_type),
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: jararaca
3
- Version: 0.3.12a18
3
+ Version: 0.3.12a19
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=aj3QfPDz-158WddZDVdzbZgEm4SRalAyvU5X0-FpkTU,2041
3
+ pyproject.toml,sha256=mgJOhSQjMq5tiTypMWYNHonlLtptX67W82wrg7OUiFg,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=KSJgJqhZS243L5d005Ph_f-RiZP37rgeF0Ql6iN856w,49016
73
+ jararaca/tools/typescript/interface_parser.py,sha256=dkM3Nsab_1HDRY_clC6LcZLtDXFHpAqNdcqIC_MzALc,51753
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.12a18.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
78
- jararaca-0.3.12a18.dist-info/METADATA,sha256=uDHK7-0B144S_kuJ57BELyRoJDANDRe-3Tib4N4wxXY,4996
79
- jararaca-0.3.12a18.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
80
- jararaca-0.3.12a18.dist-info/entry_points.txt,sha256=WIh3aIvz8LwUJZIDfs4EeH3VoFyCGEk7cWJurW38q0I,45
81
- jararaca-0.3.12a18.dist-info/RECORD,,
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,,
pyproject.toml CHANGED
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "jararaca"
3
- version = "0.3.12a18"
3
+ version = "0.3.12a19"
4
4
  description = "A simple and fast API framework for Python"
5
5
  authors = ["Lucas S <me@luscasleo.dev>"]
6
6
  readme = "README.md"