jararaca 0.2.37a11__py3-none-any.whl → 0.3.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.

Potentially problematic release.


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

@@ -1,9 +1,9 @@
1
- LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
2
- README.md,sha256=mte30I-ZEJJp-Oax-OganNgl6G9GaCZPL6JVFAvZGz4,7034
3
- pyproject.toml,sha256=6qmtrXrdw7bJZOL_-RGgWJtkCmz7b42Xbc-NwubeGTQ,1840
4
- jararaca/__init__.py,sha256=VBrN25GHJ3gDG95CcJWe3dmGcA-X2agzOCIBbjzc1Iw,15312
1
+ jararaca/__init__.py,sha256=4WO-Th3vY1_0SKdLyviZN2rftiX7R5yPVNPGJ9Mf5Y0,15633
5
2
  jararaca/__main__.py,sha256=-O3vsB5lHdqNFjUtoELDF81IYFtR-DSiiFMzRaiSsv4,67
6
- jararaca/cli.py,sha256=JKk4xrRbtX2fM8yYw794lbxvJFH73bWw3GGIvrpAkeE,5706
3
+ jararaca/broker_backend/__init__.py,sha256=GzEIuHR1xzgCJD4FE3harNjoaYzxHMHoEL0_clUaC-k,3528
4
+ jararaca/broker_backend/mapper.py,sha256=vTsi7sWpNvlga1PWPFg0rCJ5joJ0cdzykkIc2Tuvenc,696
5
+ jararaca/broker_backend/redis_broker_backend.py,sha256=a7DHchy3NAiD71Ix8SwmQOUnniu7uup-Woa4ON_4J7I,5786
6
+ jararaca/cli.py,sha256=8opY0_YOKGaglDxIg9ijTWKcTvgHlBY9x3xiJGEo1xk,8964
7
7
  jararaca/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
8
  jararaca/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
9
  jararaca/core/providers.py,sha256=wktH84FK7c1s2wNq-fudf1uMfi3CQBR0neU2czJ_L0U,434
@@ -11,15 +11,18 @@ jararaca/core/uow.py,sha256=WrA50VWzfJIyZHeUhSs8IOpSA4T-D8VV6YPLlFTF5V4,2026
11
11
  jararaca/di.py,sha256=h3IsXdYZjJj8PJfnEDn0ZAwdd4EBfh8jU-wWO8ko_t4,76
12
12
  jararaca/files/entity.py.mako,sha256=tjQ-1udAMvVqgRokhsrR4uy3P_OVnbk3XZ8X69ixWhE,3098
13
13
  jararaca/lifecycle.py,sha256=qKlzLQQioS8QkxNJ_FC_5WbmT77cNbc_S7OcQeOoHkI,1895
14
- jararaca/messagebus/__init__.py,sha256=Zdl74HcS9K0FW6XUt7bVvaHEyxL8pWsqqakeRENIn0w,54
14
+ jararaca/messagebus/__init__.py,sha256=5jAqPqdcEMYBfQyfZDWPnplYdrfMyJLMcacf3qLyUhk,56
15
15
  jararaca/messagebus/bus_message_controller.py,sha256=Xd_qwnX5jUvgBTCarHR36fvtol9lPTsYp2IIGKyQQaE,1487
16
- jararaca/messagebus/decorators.py,sha256=GHlaXRuHtrz6R0HgcG2gJybpGYtdts9meDVSRPwN74I,4245
16
+ jararaca/messagebus/consumers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
+ jararaca/messagebus/decorators.py,sha256=y-w4dWbP9ZW3ZJ4mE9iIaxw01ZC5snEbOuBY5NC-Bn0,5626
17
18
  jararaca/messagebus/interceptors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
- jararaca/messagebus/interceptors/aiopika_publisher_interceptor.py,sha256=BPH5wOlj_CyHtJ7W4NWF2h0gYMwzOPNzFhGADk618N4,4373
19
- jararaca/messagebus/publisher.py,sha256=5ay9Znwybqt981OOykdWkFisSvGiTeTpPXDFLMnaiqg,1109
20
- jararaca/messagebus/types.py,sha256=iYLyLxWqOHkDadxyMqQPWy3itLNQfvD6oQe8jcq9nzo,887
21
- jararaca/messagebus/worker.py,sha256=hKACTyrIMHcuaySpmI3UhDCja6va1gGkFRoZJ7kYfoA,13613
22
- jararaca/microservice.py,sha256=1TvDKVMMREH27Ly8eTEheMmSfro4_Az_JKM_NdDvrgc,6636
19
+ jararaca/messagebus/interceptors/aiopika_publisher_interceptor.py,sha256=1pSaifCT6TnuKWH7u80llRcUvyFlS-G9p1AU83CxGuA,5315
20
+ jararaca/messagebus/interceptors/publisher_interceptor.py,sha256=fQFFW9hH6ZU3UOyR7kMPrNp9wA71qEy5XlgrBQdBMS4,1230
21
+ jararaca/messagebus/message.py,sha256=U6cyd2XknX8mtm0333slz5fanky2PFLWCmokAO56vvU,819
22
+ jararaca/messagebus/publisher.py,sha256=K7WsOMVTyLmdms3ZKEshqrQc_DhNreiFK-HnmOT9Ce0,1965
23
+ jararaca/messagebus/worker.py,sha256=SGd7Mng33ivcaAP7cwmF_2loQPuHIfTwkCZtCNJ5G-I,13523
24
+ jararaca/messagebus/worker_v2.py,sha256=F7Hl92h5PezxNUY3_lfv9jNhboyQouuk6hXocPGeyXY,20341
25
+ jararaca/microservice.py,sha256=C_Txqm3xSmdHIghJigKk6TOycL5eTJv9PF6XP7TA8j4,6638
23
26
  jararaca/observability/decorators.py,sha256=XffBinFXdiNkY6eo8_1nkr_GapM0RUGBg0aicBIelag,2220
24
27
  jararaca/observability/interceptor.py,sha256=GHkuGKFWftN7MDjvYeGFGEPnuJETNhtxRK6yuPrCrpU,1462
25
28
  jararaca/observability/providers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -52,15 +55,19 @@ jararaca/rpc/http/backends/otel.py,sha256=Uc6CjHSCZ5hvnK1fNFv3ota5xzUFnvIl1JOpG3
52
55
  jararaca/rpc/http/decorators.py,sha256=oUSzgMGI8w6SoKiz3GltDbd3BWAuyY60F23cdRRNeiw,11897
53
56
  jararaca/rpc/http/httpx.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
54
57
  jararaca/scheduler/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
55
- jararaca/scheduler/decorators.py,sha256=V6VtLA44HPEbevEcEGiHDHM3HZvka1P5kpvIm9nCMkc,2268
56
- jararaca/scheduler/scheduler.py,sha256=r1_OPTOsL9WkxTLBaxLiq1csujUqepvPg-8I4m28amU,4845
58
+ jararaca/scheduler/decorators.py,sha256=cRwnQHtlo9iC-2c30t7GGTEURFmdtDPkkVrr5cRVblM,3645
59
+ jararaca/scheduler/scheduler.py,sha256=ll3ifOZ9QZcyCX1jfuNagHMVAbhRoE9VAl0ox3MWnwo,5295
60
+ jararaca/scheduler/scheduler_v2.py,sha256=5-_O6EzG95y_3aIw5SA4W_ppbPIIszBrCYM7cFvXgBo,11166
61
+ jararaca/scheduler/types.py,sha256=4HEQOmVIDp-BYLSzqmqSFIio1bd51WFmgFPIzPpVu04,135
57
62
  jararaca/tools/app_config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
58
63
  jararaca/tools/app_config/decorators.py,sha256=-ckkMZ1dswOmECdo1rFrZ15UAku--txaNXMp8fd1Ndk,941
59
64
  jararaca/tools/app_config/interceptor.py,sha256=nfFZiS80hrbnL7-XEYrwmp2rwaVYBqxvqu3Y-6o_ov4,2575
60
65
  jararaca/tools/metadata.py,sha256=7nlCDYgItNybentPSSCc2MLqN7IpBd0VyQzfjfQycVI,1402
61
66
  jararaca/tools/typescript/interface_parser.py,sha256=4SHt094P-QawMFHSyMCiujQf8Niw7xACIO1RHBM8-w4,29192
62
- jararaca-0.2.37a11.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
63
- jararaca-0.2.37a11.dist-info/METADATA,sha256=o0sSsRaTx6-ySotULbIhDQtza302CTjxCc9jdAJxbJ8,8555
64
- jararaca-0.2.37a11.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
65
- jararaca-0.2.37a11.dist-info/entry_points.txt,sha256=WIh3aIvz8LwUJZIDfs4EeH3VoFyCGEk7cWJurW38q0I,45
66
- jararaca-0.2.37a11.dist-info/RECORD,,
67
+ jararaca/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
68
+ jararaca/utils/rabbitmq_utils.py,sha256=zFqZE-j6TSWFOEPbkIaB2hy2sqsXup-5421jIiPLfXY,2543
69
+ jararaca-0.3.0.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
70
+ jararaca-0.3.0.dist-info/METADATA,sha256=szUO6pqKIKDGAmJC1ppYnRXm-xVr2hoT49yCqLmf4o0,4951
71
+ jararaca-0.3.0.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
72
+ jararaca-0.3.0.dist-info/entry_points.txt,sha256=WIh3aIvz8LwUJZIDfs4EeH3VoFyCGEk7cWJurW38q0I,45
73
+ jararaca-0.3.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 1.9.1
2
+ Generator: poetry-core 2.1.2
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
README.md DELETED
@@ -1,243 +0,0 @@
1
- <img src="https://raw.githubusercontent.com/LuscasLeo/jararaca/main/docs/assets/_f04774c9-7e05-4da4-8b17-8be23f6a1475.jpeg" alt="README.md" width="250" float="right">
2
-
3
- # Jararaca Microservice Framework
4
-
5
- ## Overview
6
-
7
- Jararaca is a aio-first microservice framework that provides a set of tools to build and deploy microservices in a simple and clear way.
8
-
9
- ## Features
10
-
11
- ### Hexagonal Architecture
12
-
13
- The framework is based on the hexagonal architecture, which allows you to separate the business logic from the infrastructure, making the code more testable and maintainable.
14
-
15
- ### Dependency Injection
16
-
17
- The framework uses the dependency injection pattern to manage the dependencies between the components of the application.
18
-
19
- ```py
20
- app = Microservice(
21
- providers=[
22
- ProviderSpec(
23
- provide=Token(AuthConfig, "AUTH_CONFIG"),
24
- use_value=AuthConfig(
25
- secret="secret",
26
- identity_refresh_token_expires_delta_seconds=60 * 60 * 24 * 30,
27
- identity_token_expires_delta_seconds=60 * 60,
28
- ),
29
- ),
30
- ProviderSpec(
31
- provide=Token(AppConfig, "APP_CONFIG"),
32
- use_factory=AppConfig.provider,
33
- ),
34
- ProviderSpec(
35
- provide=TokenBlackListService,
36
- use_value=InMemoryTokenBlackListService(),
37
- ),
38
- ],
39
- )
40
- ```
41
-
42
- ### Web Server Port
43
-
44
- The framework provides a web server that listens on a specific port and routes the requests to the appropriate handler. It uses [FastAPI](https://fastapi.tiangolo.com/) as the web framework.
45
-
46
- ```py
47
- @Delete("/{task_id}")
48
- async def delete_task(self, task_id: TaskId) -> None:
49
- await self.tasks_crud.delete_by_id(task_id)
50
-
51
- await use_ws_manager().broadcast(("Task %s deleted" % task_id).encode())
52
- ```
53
-
54
- ### Message Bus
55
-
56
- The framework provides a topic-based message bus that allows you to send messages between the components of the application. It uses [AIO Pika](https://aio-pika.readthedocs.io/) as the message broker worker and publisher.
57
-
58
- ```py
59
- @IncomingHandler("task")
60
- async def process_task(self, message: Message[Identifiable[TaskSchema]]) -> None:
61
- name = generate_random_name()
62
- now = asyncio.get_event_loop().time()
63
- print("Processing task: ", name)
64
-
65
- task = message.payload()
66
-
67
- print("Received task: ", task)
68
- await asyncio.sleep(random.randint(1, 5))
69
-
70
- await use_publisher().publish(task, topic="task")
71
-
72
- then = asyncio.get_event_loop().time()
73
- print("Task Finished: ", name, " Time: ", then - now)
74
- ```
75
-
76
- ### Distributed Websocket
77
-
78
- You can setup a room-based websocket server that allows you to send messages to a specific room or broadcast messages to all connected clients. All backend instances communicates with each other using a pub/sub mechanism (such as Redis).
79
-
80
- ```py
81
- @WebSocketEndpoint("/ws")
82
- async def ws_endpoint(self, websocket: WebSocket) -> None:
83
- await websocket.accept()
84
- counter.increment()
85
- await use_ws_manager().add_websocket(websocket)
86
- await use_ws_manager().join(["tasks"], websocket)
87
- await use_ws_manager().broadcast(
88
- ("New Connection (%d) from %s" % (counter.count, self.hostname)).encode()
89
- )
90
-
91
- print("New Connection (%d)" % counter.count)
92
-
93
- while True:
94
- try:
95
- await websocket.receive_text()
96
- except WebSocketDisconnect:
97
- counter.decrement()
98
- await use_ws_manager().remove_websocket(websocket)
99
-
100
- await use_ws_manager().broadcast(
101
- (
102
- "Connection Closed (%d) from %s"
103
- % (counter.count, self.hostname)
104
- ).encode()
105
- )
106
- print("Connection Closed (%d)" % counter.count)
107
- break
108
- ```
109
-
110
- ### Scheduled Routine
111
-
112
- You can setup a scheduled routine that runs a specific task at a specific time or interval.
113
-
114
- ```py
115
- ...
116
- @ScheduledAction("* * * * * */3", allow_overlap=False)
117
- async def scheduled_task(self) -> None:
118
- print("Scheduled Task at ", asyncio.get_event_loop().time())
119
-
120
- print("sleeping")
121
- await asyncio.sleep(5)
122
-
123
- await use_publisher().publish(
124
- message=Identifiable(
125
- id=uuid4(),
126
- data=TaskSchema(name=generate_random_name()),
127
- ),
128
- topic="task",
129
- )
130
- ```
131
-
132
- ### Observability
133
-
134
- You can setup Observability Interceptors for logs, traces and metric collection with [OpenTelemetry](https://opentelemetry.io/docs)-based Protocols
135
-
136
- ```python
137
- class HelloService:
138
- def __init__(
139
- self,
140
- hello_rpc: Annotated[HelloRPC, Token(HelloRPC, "HELLO_RPC")],
141
- ):
142
- self.hello_rpc = hello_rpc
143
-
144
- @TracedFunc("ping") # Decorator for tracing
145
- async def ping(self) -> HelloResponse:
146
- return await self.hello_rpc.ping()
147
-
148
- @TracedFunc("hello-service")
149
- async def hello(
150
- self,
151
- gather: bool,
152
- ) -> HelloResponse:
153
- now = asyncio.get_event_loop().time()
154
- if gather:
155
- await asyncio.gather(*[self.random_await(a) for a in range(10)])
156
- else:
157
- for a in range(10):
158
- await self.random_await(a)
159
- return HelloResponse(
160
- message="Elapsed time: {}".format(asyncio.get_event_loop().time() - now)
161
- )
162
-
163
- @TracedFunc("random-await")
164
- async def random_await(self, index: int) -> None:
165
- logger.info("Random await %s", index, extra={"index": index})
166
- await asyncio.sleep(random.randint(1, 3))
167
- logger.info("Random await %s done", index, extra={"index": index})
168
- ```
169
-
170
- ## Installation
171
-
172
- ```bash
173
- pip install jararaca
174
- ```
175
-
176
- ## Usage
177
-
178
- ### Create a Microservice
179
-
180
- ```python
181
- # app.py
182
-
183
- from jararaca import Microservice, create_http_server, create_messagebus_worker
184
- from jararaca.presentation.http_microservice import HttpMicroservice
185
-
186
- app = Microservice(
187
- providers=[
188
- ProviderSpec(
189
- provide=Token[AppConfig],
190
- use_factory=AppConfig.provider,
191
- )
192
- ],
193
- controllers=[TasksController],
194
- interceptors=[
195
- AIOSqlAlchemySessionInterceptor(
196
- AIOSQAConfig(
197
- connection_name="default",
198
- url="sqlite+aiosqlite:///db.sqlite3",
199
- )
200
- ),
201
- ],
202
- )
203
-
204
-
205
- # App for specific Http Configuration Context
206
- http_app = HttpMicroservice(app)
207
-
208
- web_app = create_http_server(app)
209
-
210
- ```
211
-
212
- ### Run as a Web Server
213
-
214
- ```bash
215
- uvicorn app:web_app --reload
216
- # or
217
- jararaca server app:app
218
- # or
219
- jararaca server app:http_app
220
-
221
- ```
222
-
223
- ### Run as a Message Bus Worker
224
-
225
- ```bash
226
- jararaca worker app:app
227
- ```
228
-
229
- ### Run as a scheduled routine
230
-
231
- ```bash
232
- jararaca scheduler app:app
233
- ```
234
-
235
- ### Generate Typescript intefaces from microservice app controllers
236
-
237
- ```bash
238
- jararaca gen-tsi app.main:app app.ts
239
- ```
240
-
241
- ### Documentation
242
-
243
- Documentation is under construction [here](https://luscasleo.github.io/jararaca/).
@@ -1,30 +0,0 @@
1
- from typing import ClassVar, Generic, Literal, Protocol, TypeVar
2
-
3
- from pydantic import BaseModel
4
-
5
- from jararaca.messagebus.publisher import use_publisher
6
-
7
-
8
- class Message(BaseModel):
9
- """
10
- Base class for messages representing tasks.
11
- A Task is a message that represents a unit of work to be done.
12
- It is published to a TaskPublisher and consumed by a TaskHandler, wrapped in TaskData.
13
- Note: A Task is not an Event.
14
- """
15
-
16
- MESSAGE_TOPIC: ClassVar[str] = "__unset__"
17
-
18
- MESSAGE_TYPE: ClassVar[Literal["task", "event"]] = "task"
19
-
20
- async def publish(self) -> None:
21
- task_publisher = use_publisher()
22
- await task_publisher.publish(self, self.MESSAGE_TOPIC)
23
-
24
-
25
- INHERITS_MESSAGE_CO = TypeVar("INHERITS_MESSAGE_CO", bound=Message, covariant=True)
26
-
27
-
28
- class MessageOf(Protocol, Generic[INHERITS_MESSAGE_CO]):
29
-
30
- def payload(self) -> INHERITS_MESSAGE_CO: ...