jararaca 0.3.25__py3-none-any.whl → 0.3.28__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.

jararaca/__init__.py CHANGED
@@ -18,12 +18,17 @@ if TYPE_CHECKING:
18
18
  use_app_type,
19
19
  )
20
20
  from jararaca.observability.decorators import TracedClass, TracedFunc, traced_class
21
+ from jararaca.observability.fastapi_exception_handler import (
22
+ setup_fastapi_exception_handler,
23
+ )
21
24
  from jararaca.observability.hooks import (
22
25
  add_event,
23
26
  get_tracing_provider,
24
27
  record_exception,
28
+ set_span_attribute,
25
29
  set_span_status,
26
30
  spawn_trace,
31
+ start_span,
27
32
  )
28
33
  from jararaca.observability.interceptor import ObservabilityInterceptor
29
34
  from jararaca.observability.providers.otel import OtelObservabilityProvider
@@ -233,8 +238,11 @@ if TYPE_CHECKING:
233
238
  "TracedFunc",
234
239
  "TracedClass",
235
240
  "traced_class",
241
+ "start_span",
236
242
  "spawn_trace",
243
+ "set_span_attribute",
237
244
  "add_event",
245
+ "setup_fastapi_exception_handler",
238
246
  "set_span_status",
239
247
  "record_exception",
240
248
  "get_tracing_provider",
@@ -412,6 +420,13 @@ _dynamic_imports: "dict[str, tuple[str, str, str | None]]" = {
412
420
  "TracedClass": (__SPEC_PARENT__, "observability.decorators", None),
413
421
  "traced_class": (__SPEC_PARENT__, "observability.decorators", None),
414
422
  "spawn_trace": (__SPEC_PARENT__, "observability.hooks", None),
423
+ "setup_fastapi_exception_handler": (
424
+ __SPEC_PARENT__,
425
+ "observability.fastapi_exception_handler",
426
+ None,
427
+ ),
428
+ "set_span_attribute": (__SPEC_PARENT__, "observability.hooks", None),
429
+ "start_span": (__SPEC_PARENT__, "observability.hooks", None),
415
430
  "add_event": (__SPEC_PARENT__, "observability.hooks", None),
416
431
  "set_span_status": (__SPEC_PARENT__, "observability.hooks", None),
417
432
  "record_exception": (__SPEC_PARENT__, "observability.hooks", None),
@@ -0,0 +1,3 @@
1
+ TRACEPARENT_KEY = "traceparent"
2
+
3
+ __all__ = ["TRACEPARENT_KEY"]
@@ -37,7 +37,7 @@ AttributeMap = Mapping[str, AttributeValue]
37
37
 
38
38
  class TracingContextProvider(Protocol):
39
39
 
40
- def start_trace_context(
40
+ def start_span_context(
41
41
  self, trace_name: str, context_attributes: AttributeMap | None
42
42
  ) -> ContextManager[Any]: ...
43
43
 
@@ -56,7 +56,13 @@ class TracingContextProvider(Protocol):
56
56
  escaped: bool = False,
57
57
  ) -> None: ...
58
58
 
59
+ def set_span_attribute(
60
+ self,
61
+ key: str,
62
+ value: AttributeValue,
63
+ ) -> None: ...
59
64
 
65
+ def update_span_name(self, new_name: str) -> None: ...
60
66
  class TracingContextProviderFactory(Protocol):
61
67
 
62
68
  def root_setup(
@@ -117,7 +123,7 @@ class TracedFunc:
117
123
  ) -> Any:
118
124
 
119
125
  if ctx_provider := get_tracing_ctx_provider():
120
- with ctx_provider.start_trace_context(
126
+ with ctx_provider.start_span_context(
121
127
  self.trace_name,
122
128
  self.trace_mapper(*args, **kwargs),
123
129
  ):
@@ -0,0 +1,33 @@
1
+ from fastapi import FastAPI, Request, Response
2
+ from fastapi.exception_handlers import (
3
+ http_exception_handler,
4
+ request_validation_exception_handler,
5
+ )
6
+ from fastapi.exceptions import RequestValidationError
7
+ from fastapi.responses import JSONResponse
8
+ from starlette.exceptions import HTTPException
9
+
10
+ from jararaca.observability.constants import TRACEPARENT_KEY
11
+
12
+
13
+ def setup_fastapi_exception_handler(
14
+ app: FastAPI, trace_header_name: str = "traceparent"
15
+ ) -> None:
16
+ async def base_http_exception_handler(
17
+ request: Request, exc: HTTPException | RequestValidationError
18
+ ) -> JSONResponse | Response:
19
+
20
+ if isinstance(exc, RequestValidationError):
21
+ response = await request_validation_exception_handler(request, exc)
22
+ response.headers[trace_header_name] = request.scope.get(TRACEPARENT_KEY, "")
23
+ return response
24
+ else:
25
+ err_response = await http_exception_handler(request, exc)
26
+
27
+ err_response.headers[trace_header_name] = request.scope.get(
28
+ TRACEPARENT_KEY, ""
29
+ )
30
+ return err_response
31
+
32
+ app.exception_handlers[HTTPException] = base_http_exception_handler
33
+ app.exception_handlers[RequestValidationError] = base_http_exception_handler
@@ -1,21 +1,23 @@
1
+ import logging
1
2
  from contextlib import contextmanager
2
3
  from typing import Any, Generator, Literal
3
4
 
4
5
  from jararaca.observability.decorators import (
5
6
  AttributeMap,
7
+ AttributeValue,
6
8
  TracingContextProvider,
7
9
  get_tracing_ctx_provider,
8
10
  )
9
11
 
10
12
 
11
13
  @contextmanager
12
- def spawn_trace(
14
+ def start_span(
13
15
  name: str,
14
16
  attributes: AttributeMap | None = None,
15
17
  ) -> Generator[None, Any, None]:
16
18
 
17
19
  if trace_context_provider := get_tracing_ctx_provider():
18
- with trace_context_provider.start_trace_context(
20
+ with trace_context_provider.start_span_context(
19
21
  trace_name=name, context_attributes=attributes
20
22
  ):
21
23
  yield
@@ -23,6 +25,19 @@ def spawn_trace(
23
25
  yield
24
26
 
25
27
 
28
+ def spawn_trace(
29
+ name: str,
30
+ attributes: AttributeMap | None = None,
31
+ ) -> None:
32
+ logging.warning(
33
+ "spawn_trace is deprecated, use start_span as context manager instead."
34
+ )
35
+ if trace_context_provider := get_tracing_ctx_provider():
36
+ trace_context_provider.start_span_context(
37
+ trace_name=name, context_attributes=attributes
38
+ )
39
+
40
+
26
41
  def add_event(
27
42
  name: str,
28
43
  attributes: AttributeMap | None = None,
@@ -55,5 +70,17 @@ def record_exception(
55
70
  )
56
71
 
57
72
 
73
+ def set_span_attribute(
74
+ key: str,
75
+ value: AttributeValue,
76
+ ) -> None:
77
+
78
+ if trace_context_provider := get_tracing_ctx_provider():
79
+ trace_context_provider.set_span_attribute(
80
+ key=key,
81
+ value=value,
82
+ )
83
+
84
+
58
85
  def get_tracing_provider() -> TracingContextProvider | None:
59
86
  return get_tracing_ctx_provider()
@@ -34,8 +34,10 @@ from jararaca.microservice import (
34
34
  Microservice,
35
35
  use_app_transaction_context,
36
36
  )
37
+ from jararaca.observability.constants import TRACEPARENT_KEY
37
38
  from jararaca.observability.decorators import (
38
39
  AttributeMap,
40
+ AttributeValue,
39
41
  TracingContextProvider,
40
42
  TracingContextProviderFactory,
41
43
  )
@@ -50,7 +52,7 @@ class OtelTracingContextProvider(TracingContextProvider):
50
52
  self.app_context = app_context
51
53
 
52
54
  @contextmanager
53
- def start_trace_context(
55
+ def start_span_context(
54
56
  self,
55
57
  trace_name: str,
56
58
  context_attributes: AttributeMap | None,
@@ -82,6 +84,14 @@ class OtelTracingContextProvider(TracingContextProvider):
82
84
  span = trace.get_current_span()
83
85
  span.record_exception(exception, attributes=attributes, escaped=escaped)
84
86
 
87
+ def set_span_attribute(self, key: str, value: AttributeValue) -> None:
88
+ span = trace.get_current_span()
89
+ span.set_attribute(key, value)
90
+
91
+ def update_span_name(self, new_name: str) -> None:
92
+ span = trace.get_current_span()
93
+ span.update_name(new_name)
94
+
85
95
 
86
96
  class OtelTracingContextProviderFactory(TracingContextProviderFactory):
87
97
 
@@ -185,10 +195,15 @@ class OtelTracingContextProviderFactory(TracingContextProviderFactory):
185
195
  },
186
196
  ) as root_span:
187
197
  cx = root_span.get_span_context()
198
+ span_traceparent_id = hex(cx.trace_id)[2:].rjust(32, "0")
188
199
  if app_tx_ctx.transaction_data.context_type == "http":
189
- app_tx_ctx.transaction_data.response.headers["traceparent"] = hex(
190
- cx.trace_id
191
- )[2:].rjust(32, "0")
200
+ app_tx_ctx.transaction_data.request.scope[TRACEPARENT_KEY] = (
201
+ span_traceparent_id
202
+ )
203
+ elif app_tx_ctx.transaction_data.context_type == "websocket":
204
+ app_tx_ctx.transaction_data.websocket.scope[TRACEPARENT_KEY] = (
205
+ span_traceparent_id
206
+ )
192
207
  tracing_headers: ImplicitHeaders = {}
193
208
  TraceContextTextMapPropagator().inject(tracing_headers)
194
209
  W3CBaggagePropagator().inject(tracing_headers)
@@ -30,7 +30,7 @@ from pydantic import BaseModel, PlainValidator, RootModel
30
30
  from pydantic_core import PydanticUndefined
31
31
 
32
32
  from jararaca.microservice import Microservice
33
- from jararaca.presentation.decorators import HttpMapping, RestController
33
+ from jararaca.presentation.decorators import HttpMapping, RestController, UseMiddleware
34
34
  from jararaca.presentation.websocket.decorators import RegisterWebSocketMessage
35
35
  from jararaca.presentation.websocket.websocket_interceptor import (
36
36
  WebSocketMessageWrapper,
@@ -841,6 +841,8 @@ def write_rest_controller_to_typescript_interface(
841
841
  inspect.getmembers(controller, predicate=inspect.isfunction), key=lambda x: x[0]
842
842
  )
843
843
 
844
+ class_usemiddlewares = UseMiddleware.get_middlewares(controller)
845
+
844
846
  for name, member in member_items:
845
847
  if (mapping := HttpMapping.get_http_mapping(member)) is not None:
846
848
  return_type = member.__annotations__.get("return")
@@ -862,6 +864,39 @@ def write_rest_controller_to_typescript_interface(
862
864
  member, rest_controller, mapping
863
865
  )
864
866
 
867
+ # Extract parameters from controller-level middlewares
868
+ for middleware_type in rest_controller.middlewares:
869
+ middleware_params, middleware_mapped_types = (
870
+ extract_middleware_parameters(
871
+ middleware_type, rest_controller, mapping
872
+ )
873
+ )
874
+ arg_params_spec.extend(middleware_params)
875
+ parametes_mapped_types.update(middleware_mapped_types)
876
+
877
+ # Extract parameters from class-level UseMiddleware decorators
878
+ for middleware_instance in class_usemiddlewares:
879
+ middleware_params, middleware_mapped_types = (
880
+ extract_middleware_parameters(
881
+ middleware_instance.middleware, rest_controller, mapping
882
+ )
883
+ )
884
+ arg_params_spec.extend(middleware_params)
885
+ parametes_mapped_types.update(middleware_mapped_types)
886
+
887
+ # Extract parameters from method-level middlewares (UseMiddleware)
888
+ # Get the method from the class to access its middleware decorators
889
+ class_method = getattr(controller, name, None)
890
+ if class_method:
891
+ for middleware_instance in UseMiddleware.get_middlewares(class_method):
892
+ middleware_params, middleware_mapped_types = (
893
+ extract_middleware_parameters(
894
+ middleware_instance.middleware, rest_controller, mapping
895
+ )
896
+ )
897
+ arg_params_spec.extend(middleware_params)
898
+ parametes_mapped_types.update(middleware_mapped_types)
899
+
865
900
  for param in parametes_mapped_types:
866
901
  mapped_types.update(extract_all_envolved_types(param))
867
902
 
@@ -882,6 +917,8 @@ def write_rest_controller_to_typescript_interface(
882
917
 
883
918
  # Properly handle path joining to avoid double slashes
884
919
  controller_path = rest_controller.path or ""
920
+ # Also apply path transformation to the controller path
921
+ controller_path = parse_path_with_params(controller_path, arg_params_spec)
885
922
  path_parts = []
886
923
 
887
924
  if controller_path and controller_path.strip("/"):
@@ -1008,8 +1045,6 @@ class HttpParemeterSpec:
1008
1045
  def parse_path_with_params(path: str, parameters: list[HttpParemeterSpec]) -> str:
1009
1046
  # Use a regular expression to match both simple parameters {param} and
1010
1047
  # parameters with converters {param:converter}
1011
- import re
1012
-
1013
1048
  pattern = re.compile(r"{([^:}]+)(?::[^}]*)?}")
1014
1049
 
1015
1050
  # For each parameter found in the path, replace it with :param format
@@ -1022,6 +1057,212 @@ def parse_path_with_params(path: str, parameters: list[HttpParemeterSpec]) -> st
1022
1057
  return path
1023
1058
 
1024
1059
 
1060
+ def extract_middleware_parameters(
1061
+ middleware_type: type,
1062
+ controller: RestController,
1063
+ mapping: HttpMapping,
1064
+ ) -> tuple[list[HttpParemeterSpec], set[Any]]:
1065
+ """
1066
+ Extract parameters from a middleware class's intercept method.
1067
+ """
1068
+ parameters_list: list[HttpParemeterSpec] = []
1069
+ mapped_types: set[Any] = set()
1070
+
1071
+ # Get the intercept method from the middleware class
1072
+ if not hasattr(middleware_type, "intercept"):
1073
+ return parameters_list, mapped_types
1074
+
1075
+ intercept_method = getattr(middleware_type, "intercept")
1076
+
1077
+ # Use the same logic as extract_parameters but specifically for the intercept method
1078
+ try:
1079
+ signature = inspect.signature(intercept_method)
1080
+ for parameter_name, parameter in signature.parameters.items():
1081
+ # Skip 'self' parameter
1082
+ if parameter_name == "self":
1083
+ continue
1084
+
1085
+ parameter_type = parameter.annotation
1086
+ if parameter_type == inspect.Parameter.empty:
1087
+ continue
1088
+
1089
+ if parameter_type in EXCLUDED_REQUESTS_TYPES:
1090
+ continue
1091
+
1092
+ if get_origin(parameter_type) == Annotated:
1093
+ unwrapped_type, all_metadata = unwrap_annotated_type(parameter_type)
1094
+ # Look for FastAPI parameter annotations in all metadata layers
1095
+ annotated_type_hook = None
1096
+ for metadata in all_metadata:
1097
+ if isinstance(
1098
+ metadata, (Header, Cookie, Form, Body, Query, Path, Depends)
1099
+ ):
1100
+ annotated_type_hook = metadata
1101
+ break
1102
+
1103
+ if annotated_type_hook is None and all_metadata:
1104
+ # Fallback to first metadata if no FastAPI annotation found
1105
+ annotated_type_hook = all_metadata[0]
1106
+
1107
+ annotated_type = unwrapped_type
1108
+ if isinstance(annotated_type_hook, Header):
1109
+ mapped_types.add(str)
1110
+ parameters_list.append(
1111
+ HttpParemeterSpec(
1112
+ type_="header",
1113
+ name=parameter_name,
1114
+ required=True,
1115
+ argument_type_str=get_field_type_for_ts(str),
1116
+ )
1117
+ )
1118
+ elif isinstance(annotated_type_hook, Cookie):
1119
+ mapped_types.add(str)
1120
+ parameters_list.append(
1121
+ HttpParemeterSpec(
1122
+ type_="cookie",
1123
+ name=parameter_name,
1124
+ required=True,
1125
+ argument_type_str=get_field_type_for_ts(str),
1126
+ )
1127
+ )
1128
+ elif isinstance(annotated_type_hook, Form):
1129
+ mapped_types.add(annotated_type)
1130
+ parameters_list.append(
1131
+ HttpParemeterSpec(
1132
+ type_="form",
1133
+ name=parameter_name,
1134
+ required=True,
1135
+ argument_type_str=get_field_type_for_ts(annotated_type),
1136
+ )
1137
+ )
1138
+ elif isinstance(annotated_type_hook, Body):
1139
+ mapped_types.update(extract_all_envolved_types(parameter_type))
1140
+ # For body parameters, use Input suffix if it's a split model
1141
+ context_suffix = (
1142
+ "Input"
1143
+ if (
1144
+ inspect.isclass(parameter_type)
1145
+ and hasattr(parameter_type, "__dict__")
1146
+ and SplitInputOutput.is_split_model(parameter_type)
1147
+ )
1148
+ else ""
1149
+ )
1150
+ parameters_list.append(
1151
+ HttpParemeterSpec(
1152
+ type_="body",
1153
+ name=parameter_name,
1154
+ required=True,
1155
+ argument_type_str=get_field_type_for_ts(
1156
+ parameter_type, context_suffix
1157
+ ),
1158
+ )
1159
+ )
1160
+ elif isinstance(annotated_type_hook, Query):
1161
+ mapped_types.add(parameter_type)
1162
+ # For query parameters, use Input suffix if it's a split model
1163
+ context_suffix = (
1164
+ "Input"
1165
+ if (
1166
+ inspect.isclass(parameter_type)
1167
+ and hasattr(parameter_type, "__dict__")
1168
+ and SplitInputOutput.is_split_model(parameter_type)
1169
+ )
1170
+ else ""
1171
+ )
1172
+ parameters_list.append(
1173
+ HttpParemeterSpec(
1174
+ type_="query",
1175
+ name=parameter_name,
1176
+ required=True,
1177
+ argument_type_str=get_field_type_for_ts(
1178
+ parameter_type, context_suffix
1179
+ ),
1180
+ )
1181
+ )
1182
+ elif isinstance(annotated_type_hook, Path):
1183
+ mapped_types.add(parameter_type)
1184
+ # For path parameters, use Input suffix if it's a split model
1185
+ context_suffix = (
1186
+ "Input"
1187
+ if (
1188
+ inspect.isclass(parameter_type)
1189
+ and hasattr(parameter_type, "__dict__")
1190
+ and SplitInputOutput.is_split_model(parameter_type)
1191
+ )
1192
+ else ""
1193
+ )
1194
+ parameters_list.append(
1195
+ HttpParemeterSpec(
1196
+ type_="path",
1197
+ name=parameter_name,
1198
+ required=True,
1199
+ argument_type_str=get_field_type_for_ts(
1200
+ parameter_type, context_suffix
1201
+ ),
1202
+ )
1203
+ )
1204
+ elif isinstance(annotated_type_hook, Depends):
1205
+ # For Dependencies, recursively extract parameters
1206
+ depends_hook = (
1207
+ annotated_type_hook.dependency or parameter_type.__args__[0]
1208
+ )
1209
+ if isinstance(depends_hook, HTTPBase):
1210
+ # Skip HTTP authentication dependencies
1211
+ pass
1212
+ else:
1213
+ # TODO: We might need to recursively extract from dependencies
1214
+ # For now, skip to avoid infinite recursion
1215
+ pass
1216
+ else:
1217
+ # Handle non-annotated parameters - check if they are path parameters
1218
+ mapped_types.add(parameter_type)
1219
+
1220
+ # Check if parameter matches path parameters in controller or method paths
1221
+ if (
1222
+ # Match both simple parameters {param} and parameters with converters {param:converter}
1223
+ re.search(f"{{{parameter_name}(:.*?)?}}", controller.path)
1224
+ is not None
1225
+ or re.search(f"{{{parameter_name}(:.*?)?}}", mapping.path)
1226
+ is not None
1227
+ ):
1228
+ # This is a path parameter
1229
+ context_suffix = (
1230
+ "Input"
1231
+ if (
1232
+ inspect.isclass(parameter_type)
1233
+ and hasattr(parameter_type, "__dict__")
1234
+ and SplitInputOutput.is_split_model(parameter_type)
1235
+ )
1236
+ else ""
1237
+ )
1238
+ parameters_list.append(
1239
+ HttpParemeterSpec(
1240
+ type_="path",
1241
+ name=parameter_name,
1242
+ required=True,
1243
+ argument_type_str=get_field_type_for_ts(
1244
+ parameter_type, context_suffix
1245
+ ),
1246
+ )
1247
+ )
1248
+ elif is_primitive(parameter_type):
1249
+ # Default to query parameters for simple types that aren't in the path
1250
+ parameters_list.append(
1251
+ HttpParemeterSpec(
1252
+ type_="query",
1253
+ name=parameter_name,
1254
+ required=True,
1255
+ argument_type_str=get_field_type_for_ts(parameter_type),
1256
+ )
1257
+ )
1258
+
1259
+ except (ValueError, TypeError):
1260
+ # If we can't inspect the signature, return empty
1261
+ pass
1262
+
1263
+ return parameters_list, mapped_types
1264
+
1265
+
1025
1266
  def mount_parametes_arguments(parameters: list[HttpParemeterSpec]) -> str:
1026
1267
  return ", ".join(
1027
1268
  [f"{parameter.name}: {parameter.argument_type_str}" for parameter in parameters]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: jararaca
3
- Version: 0.3.25
3
+ Version: 0.3.28
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,7 +1,7 @@
1
1
  LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
2
2
  README.md,sha256=YmCngjU8llW0l7L3tuXkkfr8qH7V9aBMgfp2jEzeiKg,3517
3
- pyproject.toml,sha256=iPlQyxxgFBxw9owR11Cxr3UFWKstcQErqL_eGuOXxFg,2739
4
- jararaca/__init__.py,sha256=zQRbt5BrXFVvJW8pKaA9_KdkGFB6Njmr-9SyX0ZfenM,23331
3
+ pyproject.toml,sha256=CEt_9xw3r5w6k6x7hD62Gb3uU3hHAyMaAmldYFK7jjM,2739
4
+ jararaca/__init__.py,sha256=gp2ib_dYm5EP97FY3E8Av4CDCbgX6vuQhGNvNBpu0IQ,23866
5
5
  jararaca/__main__.py,sha256=-O3vsB5lHdqNFjUtoELDF81IYFtR-DSiiFMzRaiSsv4,67
6
6
  jararaca/broker_backend/__init__.py,sha256=GzEIuHR1xzgCJD4FE3harNjoaYzxHMHoEL0_clUaC-k,3528
7
7
  jararaca/broker_backend/mapper.py,sha256=vTsi7sWpNvlga1PWPFg0rCJ5joJ0cdzykkIc2Tuvenc,696
@@ -26,11 +26,13 @@ jararaca/messagebus/message.py,sha256=U6cyd2XknX8mtm0333slz5fanky2PFLWCmokAO56vv
26
26
  jararaca/messagebus/publisher.py,sha256=JTkxdKbvxvDWT8nK8PVEyyX061vYYbKQMxRHXrZtcEY,2173
27
27
  jararaca/messagebus/worker.py,sha256=DiKDUhcU4rEjjA_3KqCmnN3X5yyokZq_-SbLryjS_PM,69237
28
28
  jararaca/microservice.py,sha256=DW4RVeqgrx4J-dAg17sbzTn_sLXuvV1UOQFde2fpqds,11471
29
- jararaca/observability/decorators.py,sha256=xTt4HEmpm_m1OUS29kaoZLMCT2YYToJUzQziepl8qfQ,6062
30
- jararaca/observability/hooks.py,sha256=vQCxb5m4uFse0lJIAuzSd84acu7iGDNgf4kpaWYkju8,1499
29
+ jararaca/observability/constants.py,sha256=quhqXBjDWVrr8Vr3tglgYo7zsQyz_y-z_dtqfUzYaa8,63
30
+ jararaca/observability/decorators.py,sha256=W6RpGBUPJJX-FiYhp3HaCC-fh7-FZwDG4gBVZiE9dKU,6229
31
+ jararaca/observability/fastapi_exception_handler.py,sha256=jSLhuR5Og3vRnIoZucRA5jPnvR6DEsM1ax7tQuEo5rc,1264
32
+ jararaca/observability/hooks.py,sha256=ATGFPQxhkry1NdW18ywJ9onstlnW8Yx2FD487eY9M8o,2156
31
33
  jararaca/observability/interceptor.py,sha256=U4ZLM0f8j6Q7gMUKKnA85bnvD-Qa0ii79Qa_X8KsXAQ,1498
32
34
  jararaca/observability/providers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
- jararaca/observability/providers/otel.py,sha256=DCNjGhcpF-XdlGTiYoQg9F_1ftcggTItDfJ_PjlZm0s,10808
35
+ jararaca/observability/providers/otel.py,sha256=vsaiIDWuSbpZ4UyzRMSH64o4BxzsZzO7P39mJHUD6rU,11442
34
36
  jararaca/persistence/base.py,sha256=xnGUbsLNz3gO-9iJt-Sn5NY13Yc9-misP8wLwQuGGoM,1024
35
37
  jararaca/persistence/exports.py,sha256=Ghx4yoFaB4QVTb9WxrFYgmcSATXMNvrOvT8ybPNKXCA,62
36
38
  jararaca/persistence/interceptors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -72,12 +74,12 @@ jararaca/tools/app_config/decorators.py,sha256=-ckkMZ1dswOmECdo1rFrZ15UAku--txaN
72
74
  jararaca/tools/app_config/interceptor.py,sha256=HV8h4AxqUc_ACs5do4BSVlyxlRXzx7HqJtoVO9tfRnQ,2611
73
75
  jararaca/tools/typescript/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
74
76
  jararaca/tools/typescript/decorators.py,sha256=2NXFI6MiqpjM8rmrje38dR5StRlqdzYOmPASgyLIHeo,4267
75
- jararaca/tools/typescript/interface_parser.py,sha256=yOSuOXKOeG0soGFo0fKiZIabu4YwnvIKk-Zss8UPAuE,55174
77
+ jararaca/tools/typescript/interface_parser.py,sha256=VBx-TYQPjAiHLiYgzGdRl_p4xDbdx4GvJtQhDBrQx7g,66210
76
78
  jararaca/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
77
79
  jararaca/utils/rabbitmq_utils.py,sha256=ytdAFUyv-OBkaVnxezuJaJoLrmN7giZgtKeet_IsMBs,10918
78
80
  jararaca/utils/retry.py,sha256=DzPX_fXUvTqej6BQ8Mt2dvLo9nNlTBm7Kx2pFZ26P2Q,4668
79
- jararaca-0.3.25.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
80
- jararaca-0.3.25.dist-info/METADATA,sha256=NfiyjoAO1CUVU8LTDyIImqCdgUiX7IKrU3XRhcMPTgI,5149
81
- jararaca-0.3.25.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
82
- jararaca-0.3.25.dist-info/entry_points.txt,sha256=WIh3aIvz8LwUJZIDfs4EeH3VoFyCGEk7cWJurW38q0I,45
83
- jararaca-0.3.25.dist-info/RECORD,,
81
+ jararaca-0.3.28.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
82
+ jararaca-0.3.28.dist-info/METADATA,sha256=5yQgnOm6ZduUsne5HQP-uq8_wgAZX-bOA3QeX4oTbgI,5149
83
+ jararaca-0.3.28.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
84
+ jararaca-0.3.28.dist-info/entry_points.txt,sha256=WIh3aIvz8LwUJZIDfs4EeH3VoFyCGEk7cWJurW38q0I,45
85
+ jararaca-0.3.28.dist-info/RECORD,,
pyproject.toml CHANGED
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "jararaca"
3
- version = "0.3.25"
3
+ version = "0.3.28"
4
4
  description = "A simple and fast API framework for Python"
5
5
  authors = ["Lucas S <me@luscasleo.dev>"]
6
6
  readme = "README.md"