jararaca 0.3.12a18__tar.gz → 0.3.12a20__tar.gz
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.
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/PKG-INFO +1 -1
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/pyproject.toml +1 -1
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/tools/typescript/interface_parser.py +171 -56
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/LICENSE +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/README.md +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/docs/CNAME +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/docs/architecture.md +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/docs/assets/_f04774c9-7e05-4da4-8b17-8be23f6a1475.jpeg +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/docs/assets/_f04774c9-7e05-4da4-8b17-8be23f6a1475.webp +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/docs/assets/tracing_example.png +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/docs/http-rpc.md +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/docs/index.md +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/docs/interceptors.md +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/docs/messagebus.md +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/docs/retry.md +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/docs/scheduler.md +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/docs/stylesheets/custom.css +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/docs/websocket.md +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/__init__.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/__main__.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/broker_backend/__init__.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/broker_backend/mapper.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/broker_backend/redis_broker_backend.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/cli.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/common/__init__.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/core/__init__.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/core/providers.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/core/uow.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/di.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/files/entity.py.mako +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/lifecycle.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/messagebus/__init__.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/messagebus/bus_message_controller.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/messagebus/consumers/__init__.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/messagebus/decorators.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/messagebus/interceptors/__init__.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/messagebus/interceptors/aiopika_publisher_interceptor.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/messagebus/interceptors/publisher_interceptor.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/messagebus/message.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/messagebus/publisher.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/messagebus/worker.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/microservice.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/observability/decorators.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/observability/interceptor.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/observability/providers/__init__.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/observability/providers/otel.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/persistence/base.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/persistence/exports.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/persistence/interceptors/__init__.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/persistence/interceptors/aiosqa_interceptor.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/persistence/interceptors/constants.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/persistence/interceptors/decorators.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/persistence/session.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/persistence/sort_filter.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/persistence/utilities.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/presentation/__init__.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/presentation/decorators.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/presentation/hooks.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/presentation/http_microservice.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/presentation/server.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/presentation/websocket/__init__.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/presentation/websocket/base_types.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/presentation/websocket/context.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/presentation/websocket/decorators.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/presentation/websocket/redis.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/presentation/websocket/types.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/presentation/websocket/websocket_interceptor.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/py.typed +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/reflect/__init__.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/reflect/controller_inspect.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/reflect/metadata.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/rpc/__init__.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/rpc/http/__init__.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/rpc/http/backends/__init__.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/rpc/http/backends/httpx.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/rpc/http/backends/otel.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/rpc/http/decorators.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/rpc/http/httpx.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/scheduler/__init__.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/scheduler/beat_worker.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/scheduler/decorators.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/scheduler/types.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/tools/app_config/__init__.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/tools/app_config/decorators.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/tools/app_config/interceptor.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/tools/typescript/__init__.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/tools/typescript/decorators.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/utils/__init__.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/utils/rabbitmq_utils.py +0 -0
- {jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/utils/retry.py +0 -0
|
@@ -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,58 @@ 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
|
+
|
|
80
|
+
def is_upload_file_type(field_type: Any) -> bool:
|
|
81
|
+
"""
|
|
82
|
+
Check if a type is UploadFile or a list/array of UploadFile.
|
|
83
|
+
|
|
84
|
+
Args:
|
|
85
|
+
field_type: The type to check
|
|
86
|
+
|
|
87
|
+
Returns:
|
|
88
|
+
True if it's UploadFile or list[UploadFile], False otherwise
|
|
89
|
+
"""
|
|
90
|
+
if field_type == UploadFile:
|
|
91
|
+
return True
|
|
92
|
+
|
|
93
|
+
# Check for list[UploadFile], List[UploadFile], etc.
|
|
94
|
+
origin = get_origin(field_type)
|
|
95
|
+
if origin in (list, frozenset, set):
|
|
96
|
+
args = getattr(field_type, "__args__", ())
|
|
97
|
+
if args and args[0] == UploadFile:
|
|
98
|
+
return True
|
|
99
|
+
|
|
100
|
+
return False
|
|
101
|
+
|
|
102
|
+
|
|
51
103
|
def should_exclude_field(
|
|
52
104
|
field_name: str, field_type: Any, basemodel_type: Type[Any]
|
|
53
105
|
) -> bool:
|
|
@@ -87,7 +139,8 @@ def should_exclude_field(
|
|
|
87
139
|
|
|
88
140
|
# Check for Annotated types with Field metadata
|
|
89
141
|
if get_origin(field_type) == Annotated:
|
|
90
|
-
|
|
142
|
+
unwrapped_type, all_metadata = unwrap_annotated_type(field_type)
|
|
143
|
+
for metadata in all_metadata:
|
|
91
144
|
# Check if this is a Pydantic Field by looking for expected attributes
|
|
92
145
|
if hasattr(metadata, "exclude") or hasattr(metadata, "alias"):
|
|
93
146
|
# Check if Field has exclude=True
|
|
@@ -182,7 +235,8 @@ def has_default_value(
|
|
|
182
235
|
|
|
183
236
|
# Check for Annotated types with Field metadata that have defaults
|
|
184
237
|
if get_origin(field_type) == Annotated:
|
|
185
|
-
|
|
238
|
+
unwrapped_type, all_metadata = unwrap_annotated_type(field_type)
|
|
239
|
+
for metadata in all_metadata:
|
|
186
240
|
# Check if this is a Pydantic Field with a default
|
|
187
241
|
if hasattr(metadata, "default") and hasattr(
|
|
188
242
|
metadata, "exclude"
|
|
@@ -333,16 +387,18 @@ def get_field_type_for_ts(field_type: Any, context_suffix: str = "") -> Any:
|
|
|
333
387
|
[get_field_type_for_ts(x, context_suffix) for x in field_type.__args__]
|
|
334
388
|
)
|
|
335
389
|
if (get_origin(field_type) == Annotated) and (len(field_type.__args__) > 0):
|
|
390
|
+
unwrapped_type, all_metadata = unwrap_annotated_type(field_type)
|
|
391
|
+
|
|
336
392
|
if (
|
|
337
393
|
plain_validator := next(
|
|
338
|
-
(x for x in
|
|
394
|
+
(x for x in all_metadata if isinstance(x, PlainValidator)),
|
|
339
395
|
None,
|
|
340
396
|
)
|
|
341
397
|
) is not None:
|
|
342
398
|
return get_field_type_for_ts(
|
|
343
399
|
plain_validator.json_schema_input_type, context_suffix
|
|
344
400
|
)
|
|
345
|
-
return get_field_type_for_ts(
|
|
401
|
+
return get_field_type_for_ts(unwrapped_type, context_suffix)
|
|
346
402
|
return "unknown"
|
|
347
403
|
|
|
348
404
|
|
|
@@ -625,6 +681,21 @@ def write_microservice_to_typescript_interface(
|
|
|
625
681
|
// noinspection JSUnusedGlobalSymbols
|
|
626
682
|
|
|
627
683
|
import { HttpService, HttpBackend, HttpBackendRequest, ResponseType, createClassQueryHooks , createClassMutationHooks, createClassInfiniteQueryHooks, paginationModelByFirstArgPaginationFilter } from "@jararaca/core";
|
|
684
|
+
|
|
685
|
+
function makeFormData(data: Record<string, any>): FormData {
|
|
686
|
+
const formData = new FormData();
|
|
687
|
+
for (const key in data) {
|
|
688
|
+
if (Array.isArray(data[key])) {
|
|
689
|
+
data[key].forEach((item: any) => {
|
|
690
|
+
formData.append(key, item);
|
|
691
|
+
});
|
|
692
|
+
} else {
|
|
693
|
+
formData.append(key, data[key]);
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
return formData;
|
|
697
|
+
}
|
|
698
|
+
|
|
628
699
|
export type WebSocketMessageMap = {
|
|
629
700
|
%s
|
|
630
701
|
}
|
|
@@ -768,10 +839,21 @@ def write_rest_controller_to_typescript_interface(
|
|
|
768
839
|
class_buffer.write(f'\t\t\tmethod: "{mapping.method}",\n')
|
|
769
840
|
|
|
770
841
|
endpoint_path = parse_path_with_params(mapping.path, arg_params_spec)
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
842
|
+
|
|
843
|
+
# Properly handle path joining to avoid double slashes
|
|
844
|
+
controller_path = rest_controller.path or ""
|
|
845
|
+
path_parts = []
|
|
846
|
+
|
|
847
|
+
if controller_path and controller_path.strip("/"):
|
|
848
|
+
path_parts.append(controller_path.strip("/"))
|
|
849
|
+
if endpoint_path and endpoint_path.strip("/"):
|
|
850
|
+
path_parts.append(endpoint_path.strip("/"))
|
|
851
|
+
|
|
852
|
+
final_path = "/".join(path_parts) if path_parts else ""
|
|
853
|
+
# Ensure the path starts with a single slash
|
|
854
|
+
formatted_path = f"/{final_path}" if final_path else "/"
|
|
855
|
+
|
|
856
|
+
class_buffer.write(f"\t\t\tpath: `{formatted_path}`,\n")
|
|
775
857
|
|
|
776
858
|
# Sort path params
|
|
777
859
|
path_params = sorted(
|
|
@@ -803,10 +885,25 @@ def write_rest_controller_to_typescript_interface(
|
|
|
803
885
|
class_buffer.write(f'\t\t\t\t"{param.name}": {param.name},\n')
|
|
804
886
|
class_buffer.write("\t\t\t},\n")
|
|
805
887
|
|
|
806
|
-
if (
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
888
|
+
# Check if we need to use FormData (for file uploads or form parameters)
|
|
889
|
+
form_params = [param for param in arg_params_spec if param.type_ == "form"]
|
|
890
|
+
body_param = next((x for x in arg_params_spec if x.type_ == "body"), None)
|
|
891
|
+
|
|
892
|
+
if form_params:
|
|
893
|
+
# Use FormData for file uploads and form parameters
|
|
894
|
+
class_buffer.write("\t\t\tbody: makeFormData({\n")
|
|
895
|
+
|
|
896
|
+
# Add form parameters (including file uploads)
|
|
897
|
+
for param in form_params:
|
|
898
|
+
class_buffer.write(f'\t\t\t\t"{param.name}": {param.name},\n')
|
|
899
|
+
|
|
900
|
+
# Add body parameter if it exists alongside form params
|
|
901
|
+
if body_param:
|
|
902
|
+
class_buffer.write(f"\t\t\t\t...{body_param.name},\n")
|
|
903
|
+
|
|
904
|
+
class_buffer.write("\t\t\t})\n")
|
|
905
|
+
elif body_param is not None:
|
|
906
|
+
class_buffer.write(f"\t\t\tbody: {body_param.name}\n")
|
|
810
907
|
else:
|
|
811
908
|
class_buffer.write("\t\t\tbody: undefined\n")
|
|
812
909
|
|
|
@@ -862,7 +959,7 @@ EXCLUDED_REQUESTS_TYPES = [Request, Response]
|
|
|
862
959
|
|
|
863
960
|
@dataclass
|
|
864
961
|
class HttpParemeterSpec:
|
|
865
|
-
type_: Literal["query", "path", "body", "header", "cookie"]
|
|
962
|
+
type_: Literal["query", "path", "body", "header", "cookie", "form"]
|
|
866
963
|
name: str
|
|
867
964
|
required: bool
|
|
868
965
|
argument_type_str: str
|
|
@@ -910,15 +1007,16 @@ def extract_parameters(
|
|
|
910
1007
|
if is_primitive(member):
|
|
911
1008
|
|
|
912
1009
|
if get_origin(member) is Annotated:
|
|
1010
|
+
unwrapped_type, all_metadata = unwrap_annotated_type(member)
|
|
913
1011
|
if (
|
|
914
1012
|
plain_validator := next(
|
|
915
|
-
(x for x in
|
|
1013
|
+
(x for x in all_metadata if isinstance(x, PlainValidator)),
|
|
916
1014
|
None,
|
|
917
1015
|
)
|
|
918
1016
|
) is not None:
|
|
919
1017
|
mapped_types.add(plain_validator.json_schema_input_type)
|
|
920
1018
|
return parameters_list, mapped_types
|
|
921
|
-
return extract_parameters(
|
|
1019
|
+
return extract_parameters(unwrapped_type, controller, mapping)
|
|
922
1020
|
return parameters_list, mapped_types
|
|
923
1021
|
|
|
924
1022
|
if hasattr(member, "__bases__"):
|
|
@@ -938,8 +1036,21 @@ def extract_parameters(
|
|
|
938
1036
|
continue
|
|
939
1037
|
|
|
940
1038
|
if get_origin(parameter_type) == Annotated:
|
|
941
|
-
|
|
942
|
-
|
|
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
|
|
943
1054
|
if isinstance(annotated_type_hook, Header):
|
|
944
1055
|
mapped_types.add(str)
|
|
945
1056
|
parameters_list.append(
|
|
@@ -960,6 +1071,16 @@ def extract_parameters(
|
|
|
960
1071
|
argument_type_str=get_field_type_for_ts(str),
|
|
961
1072
|
)
|
|
962
1073
|
)
|
|
1074
|
+
elif isinstance(annotated_type_hook, Form):
|
|
1075
|
+
mapped_types.add(annotated_type)
|
|
1076
|
+
parameters_list.append(
|
|
1077
|
+
HttpParemeterSpec(
|
|
1078
|
+
type_="form",
|
|
1079
|
+
name=parameter_name,
|
|
1080
|
+
required=True,
|
|
1081
|
+
argument_type_str=get_field_type_for_ts(annotated_type),
|
|
1082
|
+
)
|
|
1083
|
+
)
|
|
963
1084
|
elif isinstance(annotated_type_hook, Body):
|
|
964
1085
|
mapped_types.update(extract_all_envolved_types(parameter_type))
|
|
965
1086
|
# For body parameters, use Input suffix if it's a split model
|
|
@@ -1067,11 +1188,11 @@ def extract_parameters(
|
|
|
1067
1188
|
)
|
|
1068
1189
|
else:
|
|
1069
1190
|
mapped_types.add(annotated_type)
|
|
1070
|
-
# Special handling for UploadFile - should
|
|
1071
|
-
if annotated_type
|
|
1191
|
+
# Special handling for UploadFile and list[UploadFile] - should be treated as form data
|
|
1192
|
+
if is_upload_file_type(annotated_type):
|
|
1072
1193
|
parameters_list.append(
|
|
1073
1194
|
HttpParemeterSpec(
|
|
1074
|
-
type_="
|
|
1195
|
+
type_="form",
|
|
1075
1196
|
name=parameter_name,
|
|
1076
1197
|
required=True,
|
|
1077
1198
|
argument_type_str=get_field_type_for_ts(annotated_type),
|
|
@@ -1117,12 +1238,12 @@ def extract_parameters(
|
|
|
1117
1238
|
),
|
|
1118
1239
|
)
|
|
1119
1240
|
)
|
|
1120
|
-
elif parameter_type == UploadFile:
|
|
1121
|
-
# UploadFile
|
|
1241
|
+
elif parameter_type == UploadFile or is_upload_file_type(parameter_type):
|
|
1242
|
+
# UploadFile and list[UploadFile] should be treated as form data
|
|
1122
1243
|
mapped_types.add(parameter_type)
|
|
1123
1244
|
parameters_list.append(
|
|
1124
1245
|
HttpParemeterSpec(
|
|
1125
|
-
type_="
|
|
1246
|
+
type_="form",
|
|
1126
1247
|
name=parameter_name,
|
|
1127
1248
|
required=True,
|
|
1128
1249
|
argument_type_str=get_field_type_for_ts(parameter_type),
|
|
@@ -1156,11 +1277,11 @@ def extract_parameters(
|
|
|
1156
1277
|
)
|
|
1157
1278
|
else:
|
|
1158
1279
|
mapped_types.add(parameter_type)
|
|
1159
|
-
# Special handling for UploadFile - should
|
|
1160
|
-
if parameter_type
|
|
1280
|
+
# Special handling for UploadFile and list[UploadFile] - should be treated as form data
|
|
1281
|
+
if is_upload_file_type(parameter_type):
|
|
1161
1282
|
parameters_list.append(
|
|
1162
1283
|
HttpParemeterSpec(
|
|
1163
|
-
type_="
|
|
1284
|
+
type_="form",
|
|
1164
1285
|
name=parameter_name,
|
|
1165
1286
|
required=True,
|
|
1166
1287
|
argument_type_str=get_field_type_for_ts(parameter_type),
|
|
@@ -1196,21 +1317,22 @@ def extract_parameters(
|
|
|
1196
1317
|
for _, parameter_type in parameter_members.items():
|
|
1197
1318
|
if is_primitive(parameter_type.annotation):
|
|
1198
1319
|
if get_origin(parameter_type.annotation) is not None:
|
|
1199
|
-
if (
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
plain_validator := next(
|
|
1203
|
-
(
|
|
1204
|
-
x
|
|
1205
|
-
for x in parameter_type.annotation.__metadata__
|
|
1206
|
-
if isinstance(x, PlainValidator)
|
|
1207
|
-
),
|
|
1208
|
-
None,
|
|
1209
|
-
)
|
|
1320
|
+
if get_origin(parameter_type.annotation) == Annotated:
|
|
1321
|
+
unwrapped_type, all_metadata = unwrap_annotated_type(
|
|
1322
|
+
parameter_type.annotation
|
|
1210
1323
|
)
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
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
|
+
)
|
|
1214
1336
|
else:
|
|
1215
1337
|
args = parameter_type.annotation.__args__
|
|
1216
1338
|
mapped_types.update(args)
|
|
@@ -1241,22 +1363,15 @@ def extract_all_envolved_types(field_type: Any) -> set[Any]:
|
|
|
1241
1363
|
|
|
1242
1364
|
if is_primitive(field_type):
|
|
1243
1365
|
if get_origin(field_type) is not None:
|
|
1244
|
-
if (
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
x
|
|
1250
|
-
for x in field_type.__metadata__
|
|
1251
|
-
if isinstance(x, PlainValidator)
|
|
1252
|
-
),
|
|
1253
|
-
None,
|
|
1254
|
-
)
|
|
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,
|
|
1255
1371
|
)
|
|
1256
|
-
is not None
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
return mapped_types
|
|
1372
|
+
if plain_validator is not None:
|
|
1373
|
+
mapped_types.add(plain_validator.json_schema_input_type)
|
|
1374
|
+
return mapped_types
|
|
1260
1375
|
else:
|
|
1261
1376
|
mapped_types.update(
|
|
1262
1377
|
*[extract_all_envolved_types(arg) for arg in field_type.__args__]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{jararaca-0.3.12a18 → jararaca-0.3.12a20}/docs/assets/_f04774c9-7e05-4da4-8b17-8be23f6a1475.jpeg
RENAMED
|
File without changes
|
{jararaca-0.3.12a18 → jararaca-0.3.12a20}/docs/assets/_f04774c9-7e05-4da4-8b17-8be23f6a1475.webp
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/broker_backend/redis_broker_backend.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/persistence/interceptors/constants.py
RENAMED
|
File without changes
|
{jararaca-0.3.12a18 → jararaca-0.3.12a20}/src/jararaca/persistence/interceptors/decorators.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|