jararaca 0.2.33__tar.gz → 0.3.27__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.

Files changed (125) hide show
  1. jararaca-0.3.27/PKG-INFO +159 -0
  2. jararaca-0.3.27/README.md +121 -0
  3. jararaca-0.3.27/docs/CNAME +1 -0
  4. jararaca-0.3.27/docs/architecture.md +372 -0
  5. jararaca-0.3.27/docs/expose-type.md +221 -0
  6. jararaca-0.3.27/docs/http-rpc.md +564 -0
  7. jararaca-0.3.27/docs/index.md +675 -0
  8. jararaca-0.3.27/docs/interceptors.md +210 -0
  9. jararaca-0.3.27/docs/messagebus.md +485 -0
  10. jararaca-0.3.27/docs/retry.md +79 -0
  11. jararaca-0.3.27/docs/scheduler.md +239 -0
  12. jararaca-0.3.27/docs/stylesheets/custom.css +5 -0
  13. jararaca-0.3.27/docs/websocket.md +362 -0
  14. {jararaca-0.2.33 → jararaca-0.3.27}/pyproject.toml +53 -4
  15. {jararaca-0.2.33 → jararaca-0.3.27}/src/jararaca/__init__.py +274 -16
  16. jararaca-0.3.27/src/jararaca/broker_backend/__init__.py +102 -0
  17. jararaca-0.3.27/src/jararaca/broker_backend/mapper.py +21 -0
  18. jararaca-0.3.27/src/jararaca/broker_backend/redis_broker_backend.py +162 -0
  19. jararaca-0.3.27/src/jararaca/cli.py +1022 -0
  20. jararaca-0.3.27/src/jararaca/core/uow.py +99 -0
  21. jararaca-0.3.27/src/jararaca/messagebus/__init__.py +3 -0
  22. jararaca-0.3.27/src/jararaca/messagebus/bus_message_controller.py +67 -0
  23. jararaca-0.3.27/src/jararaca/messagebus/decorators.py +176 -0
  24. jararaca-0.3.27/src/jararaca/messagebus/implicit_headers.py +45 -0
  25. jararaca-0.3.27/src/jararaca/messagebus/interceptors/aiopika_publisher_interceptor.py +185 -0
  26. jararaca-0.3.27/src/jararaca/messagebus/interceptors/publisher_interceptor.py +38 -0
  27. jararaca-0.3.27/src/jararaca/messagebus/message.py +27 -0
  28. jararaca-0.3.27/src/jararaca/messagebus/publisher.py +78 -0
  29. jararaca-0.3.27/src/jararaca/messagebus/worker.py +1778 -0
  30. jararaca-0.3.27/src/jararaca/microservice.py +418 -0
  31. jararaca-0.3.27/src/jararaca/observability/decorators.py +235 -0
  32. jararaca-0.3.27/src/jararaca/observability/hooks.py +86 -0
  33. {jararaca-0.2.33 → jararaca-0.3.27}/src/jararaca/observability/interceptor.py +4 -2
  34. jararaca-0.3.27/src/jararaca/observability/providers/otel.py +323 -0
  35. {jararaca-0.2.33 → jararaca-0.3.27}/src/jararaca/persistence/base.py +2 -1
  36. jararaca-0.3.27/src/jararaca/persistence/interceptors/aiosqa_interceptor.py +224 -0
  37. jararaca-0.3.27/src/jararaca/persistence/interceptors/constants.py +1 -0
  38. jararaca-0.3.27/src/jararaca/persistence/interceptors/decorators.py +45 -0
  39. {jararaca-0.2.33 → jararaca-0.3.27}/src/jararaca/persistence/sort_filter.py +2 -0
  40. {jararaca-0.2.33 → jararaca-0.3.27}/src/jararaca/persistence/utilities.py +58 -22
  41. {jararaca-0.2.33 → jararaca-0.3.27}/src/jararaca/presentation/decorators.py +148 -22
  42. jararaca-0.3.27/src/jararaca/presentation/server.py +196 -0
  43. {jararaca-0.2.33 → jararaca-0.3.27}/src/jararaca/presentation/websocket/context.py +30 -4
  44. jararaca-0.3.27/src/jararaca/presentation/websocket/redis.py +376 -0
  45. {jararaca-0.2.33 → jararaca-0.3.27}/src/jararaca/presentation/websocket/types.py +2 -2
  46. {jararaca-0.2.33 → jararaca-0.3.27}/src/jararaca/presentation/websocket/websocket_interceptor.py +63 -16
  47. jararaca-0.3.27/src/jararaca/reflect/controller_inspect.py +75 -0
  48. {jararaca-0.2.33/src/jararaca/tools → jararaca-0.3.27/src/jararaca/reflect}/metadata.py +25 -5
  49. jararaca-0.3.27/src/jararaca/rpc/http/__init__.py +97 -0
  50. jararaca-0.3.27/src/jararaca/rpc/http/backends/__init__.py +10 -0
  51. jararaca-0.3.27/src/jararaca/rpc/http/backends/httpx.py +71 -0
  52. {jararaca-0.2.33 → jararaca-0.3.27}/src/jararaca/rpc/http/decorators.py +302 -6
  53. jararaca-0.3.27/src/jararaca/scheduler/beat_worker.py +802 -0
  54. jararaca-0.3.27/src/jararaca/scheduler/decorators.py +131 -0
  55. jararaca-0.3.27/src/jararaca/scheduler/types.py +7 -0
  56. {jararaca-0.2.33 → jararaca-0.3.27}/src/jararaca/tools/app_config/interceptor.py +4 -2
  57. jararaca-0.3.27/src/jararaca/tools/typescript/decorators.py +141 -0
  58. jararaca-0.3.27/src/jararaca/tools/typescript/interface_parser.py +1682 -0
  59. jararaca-0.3.27/src/jararaca/utils/rabbitmq_utils.py +346 -0
  60. jararaca-0.3.27/src/jararaca/utils/retry.py +141 -0
  61. jararaca-0.2.33/PKG-INFO +0 -278
  62. jararaca-0.2.33/README.md +0 -243
  63. jararaca-0.2.33/docs/Architecture/Observability/Decorators.md +0 -0
  64. jararaca-0.2.33/docs/Architecture/Observability/Interceptors.md +0 -0
  65. jararaca-0.2.33/docs/Architecture/Presentation/Decorators.md +0 -0
  66. jararaca-0.2.33/docs/Architecture/RPC/RestClients/Decorators.md +0 -0
  67. jararaca-0.2.33/docs/Architecture/RPC/RestClients/Middlewared.md +0 -0
  68. jararaca-0.2.33/docs/Architecture/Schedule/Decorators.md +0 -0
  69. jararaca-0.2.33/docs/Architecture/Websocket/Decorators.md +0 -0
  70. jararaca-0.2.33/docs/Architecture/Websocket/Interceptors.md +0 -0
  71. jararaca-0.2.33/docs/Concept/Adapters.md +0 -0
  72. jararaca-0.2.33/docs/Concept/Hexagonal Architecture.md +0 -0
  73. jararaca-0.2.33/docs/Concept/Ports.md +0 -0
  74. jararaca-0.2.33/docs/index.md +0 -518
  75. jararaca-0.2.33/src/jararaca/cli.py +0 -251
  76. jararaca-0.2.33/src/jararaca/core/uow.py +0 -66
  77. jararaca-0.2.33/src/jararaca/messagebus/__init__.py +0 -3
  78. jararaca-0.2.33/src/jararaca/messagebus/decorators.py +0 -134
  79. jararaca-0.2.33/src/jararaca/messagebus/interceptors/publisher_interceptor.py +0 -76
  80. jararaca-0.2.33/src/jararaca/messagebus/publisher.py +0 -41
  81. jararaca-0.2.33/src/jararaca/messagebus/types.py +0 -30
  82. jararaca-0.2.33/src/jararaca/messagebus/worker.py +0 -376
  83. jararaca-0.2.33/src/jararaca/microservice.py +0 -243
  84. jararaca-0.2.33/src/jararaca/observability/decorators.py +0 -93
  85. jararaca-0.2.33/src/jararaca/observability/providers/otel.py +0 -182
  86. jararaca-0.2.33/src/jararaca/persistence/interceptors/aiosqa_interceptor.py +0 -64
  87. jararaca-0.2.33/src/jararaca/presentation/server.py +0 -117
  88. jararaca-0.2.33/src/jararaca/presentation/websocket/redis.py +0 -155
  89. jararaca-0.2.33/src/jararaca/rpc/http/backends/httpx.py +0 -41
  90. jararaca-0.2.33/src/jararaca/scheduler/decorators.py +0 -63
  91. jararaca-0.2.33/src/jararaca/scheduler/scheduler.py +0 -154
  92. jararaca-0.2.33/src/jararaca/tools/typescript/interface_parser.py +0 -821
  93. {jararaca-0.2.33 → jararaca-0.3.27}/LICENSE +0 -0
  94. {jararaca-0.2.33 → jararaca-0.3.27}/docs/assets/_f04774c9-7e05-4da4-8b17-8be23f6a1475.jpeg +0 -0
  95. {jararaca-0.2.33 → jararaca-0.3.27}/docs/assets/_f04774c9-7e05-4da4-8b17-8be23f6a1475.webp +0 -0
  96. {jararaca-0.2.33 → jararaca-0.3.27}/docs/assets/tracing_example.png +0 -0
  97. {jararaca-0.2.33 → jararaca-0.3.27}/src/jararaca/__main__.py +0 -0
  98. {jararaca-0.2.33 → jararaca-0.3.27}/src/jararaca/common/__init__.py +0 -0
  99. {jararaca-0.2.33 → jararaca-0.3.27}/src/jararaca/core/__init__.py +0 -0
  100. {jararaca-0.2.33 → jararaca-0.3.27}/src/jararaca/core/providers.py +0 -0
  101. {jararaca-0.2.33 → jararaca-0.3.27}/src/jararaca/di.py +0 -0
  102. {jararaca-0.2.33 → jararaca-0.3.27}/src/jararaca/files/entity.py.mako +0 -0
  103. {jararaca-0.2.33 → jararaca-0.3.27}/src/jararaca/lifecycle.py +0 -0
  104. {jararaca-0.2.33/src/jararaca/messagebus/interceptors → jararaca-0.3.27/src/jararaca/messagebus/consumers}/__init__.py +0 -0
  105. {jararaca-0.2.33/src/jararaca/observability/providers → jararaca-0.3.27/src/jararaca/messagebus/interceptors}/__init__.py +0 -0
  106. {jararaca-0.2.33/src/jararaca/persistence/interceptors → jararaca-0.3.27/src/jararaca/observability/providers}/__init__.py +0 -0
  107. {jararaca-0.2.33 → jararaca-0.3.27}/src/jararaca/persistence/exports.py +0 -0
  108. {jararaca-0.2.33/src/jararaca/presentation → jararaca-0.3.27/src/jararaca/persistence/interceptors}/__init__.py +0 -0
  109. {jararaca-0.2.33 → jararaca-0.3.27}/src/jararaca/persistence/session.py +0 -0
  110. {jararaca-0.2.33/src/jararaca/presentation/websocket → jararaca-0.3.27/src/jararaca/presentation}/__init__.py +0 -0
  111. {jararaca-0.2.33 → jararaca-0.3.27}/src/jararaca/presentation/hooks.py +0 -0
  112. {jararaca-0.2.33 → jararaca-0.3.27}/src/jararaca/presentation/http_microservice.py +0 -0
  113. {jararaca-0.2.33/src/jararaca/rpc → jararaca-0.3.27/src/jararaca/presentation/websocket}/__init__.py +0 -0
  114. {jararaca-0.2.33 → jararaca-0.3.27}/src/jararaca/presentation/websocket/base_types.py +0 -0
  115. {jararaca-0.2.33 → jararaca-0.3.27}/src/jararaca/presentation/websocket/decorators.py +0 -0
  116. {jararaca-0.2.33 → jararaca-0.3.27}/src/jararaca/py.typed +0 -0
  117. {jararaca-0.2.33/src/jararaca/rpc/http → jararaca-0.3.27/src/jararaca/reflect}/__init__.py +0 -0
  118. {jararaca-0.2.33/src/jararaca/rpc/http/backends → jararaca-0.3.27/src/jararaca/rpc}/__init__.py +0 -0
  119. {jararaca-0.2.33 → jararaca-0.3.27}/src/jararaca/rpc/http/backends/otel.py +0 -0
  120. {jararaca-0.2.33 → jararaca-0.3.27}/src/jararaca/rpc/http/httpx.py +0 -0
  121. {jararaca-0.2.33 → jararaca-0.3.27}/src/jararaca/scheduler/__init__.py +0 -0
  122. {jararaca-0.2.33 → jararaca-0.3.27}/src/jararaca/tools/app_config/__init__.py +0 -0
  123. {jararaca-0.2.33 → jararaca-0.3.27}/src/jararaca/tools/app_config/decorators.py +0 -0
  124. /jararaca-0.2.33/docs/Architecture/Message Bus/Decorators.md → /jararaca-0.3.27/src/jararaca/tools/typescript/__init__.py +0 -0
  125. /jararaca-0.2.33/docs/Architecture/Message Bus/Interceptors.md → /jararaca-0.3.27/src/jararaca/utils/__init__.py +0 -0
@@ -0,0 +1,159 @@
1
+ Metadata-Version: 2.1
2
+ Name: jararaca
3
+ Version: 0.3.27
4
+ Summary: A simple and fast API framework for Python
5
+ Home-page: https://github.com/LuscasLeo/jararaca
6
+ Author: Lucas S
7
+ Author-email: me@luscasleo.dev
8
+ Requires-Python: >=3.11,<4.0
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Programming Language :: Python :: 3.11
11
+ Classifier: Programming Language :: Python :: 3.12
12
+ Provides-Extra: docs
13
+ Provides-Extra: http
14
+ Provides-Extra: opentelemetry
15
+ Provides-Extra: watch
16
+ Requires-Dist: aio-pika (>=9.4.3,<10.0.0)
17
+ Requires-Dist: croniter (>=3.0.3,<4.0.0)
18
+ Requires-Dist: fastapi (>=0.113.0,<0.114.0)
19
+ Requires-Dist: frozendict (>=2.4.6,<3.0.0)
20
+ Requires-Dist: mako (>=1.3.5,<2.0.0)
21
+ Requires-Dist: opentelemetry-api (>=1.38.0,<2.0.0) ; extra == "opentelemetry"
22
+ Requires-Dist: opentelemetry-distro (>=0.59b0,<0.60) ; extra == "opentelemetry"
23
+ Requires-Dist: opentelemetry-exporter-otlp (>=1.27.0,<2.0.0) ; extra == "opentelemetry"
24
+ Requires-Dist: opentelemetry-exporter-otlp-proto-http (>=1.27.0,<2.0.0) ; extra == "opentelemetry"
25
+ Requires-Dist: opentelemetry-sdk (>=1.38.0,<2.0.0) ; extra == "opentelemetry"
26
+ Requires-Dist: redis (>=5.0.8,<6.0.0)
27
+ Requires-Dist: sqlalchemy (>=2.0.34,<3.0.0)
28
+ Requires-Dist: types-croniter (>=3.0.3.20240731,<4.0.0.0)
29
+ Requires-Dist: types-redis (>=4.6.0.20240903,<5.0.0.0)
30
+ Requires-Dist: urllib3 (>=2.3.0,<3.0.0)
31
+ Requires-Dist: uvicorn (>=0.30.6,<0.31.0)
32
+ Requires-Dist: uvloop (>=0.20.0,<0.21.0)
33
+ Requires-Dist: watchdog (>=3.0.0,<4.0.0) ; extra == "watch"
34
+ Requires-Dist: websockets (>=13.0.1,<14.0.0)
35
+ Project-URL: Repository, https://github.com/LuscasLeo/jararaca
36
+ Description-Content-Type: text/markdown
37
+
38
+ <img src="https://raw.githubusercontent.com/LuscasLeo/jararaca/main/docs/assets/_f04774c9-7e05-4da4-8b17-8be23f6a1475.jpeg" alt="Jararaca Logo" width="250" float="right">
39
+
40
+ # Jararaca Microservice Framework
41
+
42
+ ## Overview
43
+
44
+ Jararaca is an async-first microservice framework designed to simplify the development of distributed systems. It provides a comprehensive set of tools for building robust, scalable, and maintainable microservices with a focus on developer experience and type safety.
45
+
46
+ ## Key Features
47
+
48
+ ### REST API Development
49
+ - Easy-to-use interfaces for building REST APIs
50
+ - Automatic request/response validation
51
+ - Type-safe endpoints with FastAPI integration
52
+ - Automatic OpenAPI documentation generation
53
+
54
+ ### Message Bus Integration
55
+ - Topic-based message bus for event-driven architecture
56
+ - Support for both worker and publisher patterns
57
+ - Built-in message serialization and deserialization
58
+ - Easy integration with AIO Pika for RabbitMQ
59
+
60
+ ### Distributed WebSocket
61
+ - Room-based WebSocket communication
62
+ - Distributed broadcasting across multiple backend instances
63
+ - Automatic message synchronization between instances
64
+ - Built-in connection management and room handling
65
+
66
+ ### Task Scheduling
67
+ - Cron-based task scheduling
68
+ - Support for overlapping and non-overlapping tasks
69
+ - Distributed task execution
70
+ - Easy integration with message bus for task distribution
71
+
72
+ ### TypeScript Integration
73
+ - Automatic TypeScript interface generation
74
+ - Command-line tool for generating TypeScript types
75
+ - Support for REST endpoints, WebSocket events, and message bus payloads
76
+ - Type-safe frontend-backend communication
77
+ - **`@ExposeType` decorator** - Explicitly expose types for TypeScript generation without needing them in endpoints
78
+
79
+ ### Hexagonal Architecture
80
+ - Clear separation of concerns
81
+ - Business logic isolation from infrastructure
82
+ - Easy testing and maintainability
83
+ - Dependency injection for flexible component management
84
+
85
+ ### Observability
86
+ - Built-in OpenTelemetry integration
87
+ - Distributed tracing support
88
+ - Logging and metrics collection
89
+ - Performance monitoring capabilities
90
+
91
+ ## Quick Start
92
+
93
+ ### Installation
94
+
95
+ ```bash
96
+ pip install jararaca
97
+ ```
98
+
99
+ ### Basic Usage
100
+
101
+ ```python
102
+ from jararaca import Microservice, create_http_server
103
+ from jararaca.presentation.http_microservice import HttpMicroservice
104
+
105
+ # Define your microservice
106
+ app = Microservice(
107
+ providers=[
108
+ # Add your providers here
109
+ ],
110
+ controllers=[
111
+ # Add your controllers here
112
+ ],
113
+ interceptors=[
114
+ # Add your interceptors here
115
+ ],
116
+ )
117
+
118
+ # Create HTTP server
119
+ http_app = HttpMicroservice(app)
120
+ web_app = create_http_server(app)
121
+ ```
122
+
123
+ ### Running the Service
124
+
125
+ ```bash
126
+ # Run as HTTP server
127
+ jararaca server app:http_app
128
+
129
+ # Run as message bus worker
130
+ jararaca worker app:app
131
+
132
+ # Run as scheduler
133
+ jararaca scheduler app:app
134
+
135
+ # Generate TypeScript interfaces
136
+ jararaca gen-tsi app.main:app app.ts
137
+ ```
138
+
139
+ ## Documentation
140
+
141
+ For detailed documentation, please visit our [documentation site](https://luscasleo.github.io/jararaca/).
142
+
143
+ ## Examples
144
+
145
+ Check out the [examples directory](examples/) for complete working examples of:
146
+ - REST API implementation
147
+ - WebSocket usage
148
+ - Message bus integration
149
+ - Task scheduling
150
+ - TypeScript interface generation
151
+
152
+ ## Contributing
153
+
154
+ Contributions are welcome! Please read our [contributing guidelines](.github/CONTRIBUTING.md) for details on our code of conduct and the process for submitting pull requests.
155
+
156
+ ## License
157
+
158
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
159
+
@@ -0,0 +1,121 @@
1
+ <img src="https://raw.githubusercontent.com/LuscasLeo/jararaca/main/docs/assets/_f04774c9-7e05-4da4-8b17-8be23f6a1475.jpeg" alt="Jararaca Logo" width="250" float="right">
2
+
3
+ # Jararaca Microservice Framework
4
+
5
+ ## Overview
6
+
7
+ Jararaca is an async-first microservice framework designed to simplify the development of distributed systems. It provides a comprehensive set of tools for building robust, scalable, and maintainable microservices with a focus on developer experience and type safety.
8
+
9
+ ## Key Features
10
+
11
+ ### REST API Development
12
+ - Easy-to-use interfaces for building REST APIs
13
+ - Automatic request/response validation
14
+ - Type-safe endpoints with FastAPI integration
15
+ - Automatic OpenAPI documentation generation
16
+
17
+ ### Message Bus Integration
18
+ - Topic-based message bus for event-driven architecture
19
+ - Support for both worker and publisher patterns
20
+ - Built-in message serialization and deserialization
21
+ - Easy integration with AIO Pika for RabbitMQ
22
+
23
+ ### Distributed WebSocket
24
+ - Room-based WebSocket communication
25
+ - Distributed broadcasting across multiple backend instances
26
+ - Automatic message synchronization between instances
27
+ - Built-in connection management and room handling
28
+
29
+ ### Task Scheduling
30
+ - Cron-based task scheduling
31
+ - Support for overlapping and non-overlapping tasks
32
+ - Distributed task execution
33
+ - Easy integration with message bus for task distribution
34
+
35
+ ### TypeScript Integration
36
+ - Automatic TypeScript interface generation
37
+ - Command-line tool for generating TypeScript types
38
+ - Support for REST endpoints, WebSocket events, and message bus payloads
39
+ - Type-safe frontend-backend communication
40
+ - **`@ExposeType` decorator** - Explicitly expose types for TypeScript generation without needing them in endpoints
41
+
42
+ ### Hexagonal Architecture
43
+ - Clear separation of concerns
44
+ - Business logic isolation from infrastructure
45
+ - Easy testing and maintainability
46
+ - Dependency injection for flexible component management
47
+
48
+ ### Observability
49
+ - Built-in OpenTelemetry integration
50
+ - Distributed tracing support
51
+ - Logging and metrics collection
52
+ - Performance monitoring capabilities
53
+
54
+ ## Quick Start
55
+
56
+ ### Installation
57
+
58
+ ```bash
59
+ pip install jararaca
60
+ ```
61
+
62
+ ### Basic Usage
63
+
64
+ ```python
65
+ from jararaca import Microservice, create_http_server
66
+ from jararaca.presentation.http_microservice import HttpMicroservice
67
+
68
+ # Define your microservice
69
+ app = Microservice(
70
+ providers=[
71
+ # Add your providers here
72
+ ],
73
+ controllers=[
74
+ # Add your controllers here
75
+ ],
76
+ interceptors=[
77
+ # Add your interceptors here
78
+ ],
79
+ )
80
+
81
+ # Create HTTP server
82
+ http_app = HttpMicroservice(app)
83
+ web_app = create_http_server(app)
84
+ ```
85
+
86
+ ### Running the Service
87
+
88
+ ```bash
89
+ # Run as HTTP server
90
+ jararaca server app:http_app
91
+
92
+ # Run as message bus worker
93
+ jararaca worker app:app
94
+
95
+ # Run as scheduler
96
+ jararaca scheduler app:app
97
+
98
+ # Generate TypeScript interfaces
99
+ jararaca gen-tsi app.main:app app.ts
100
+ ```
101
+
102
+ ## Documentation
103
+
104
+ For detailed documentation, please visit our [documentation site](https://luscasleo.github.io/jararaca/).
105
+
106
+ ## Examples
107
+
108
+ Check out the [examples directory](examples/) for complete working examples of:
109
+ - REST API implementation
110
+ - WebSocket usage
111
+ - Message bus integration
112
+ - Task scheduling
113
+ - TypeScript interface generation
114
+
115
+ ## Contributing
116
+
117
+ Contributions are welcome! Please read our [contributing guidelines](.github/CONTRIBUTING.md) for details on our code of conduct and the process for submitting pull requests.
118
+
119
+ ## License
120
+
121
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
@@ -0,0 +1 @@
1
+ jararaca.luscasleo.dev
@@ -0,0 +1,372 @@
1
+ # Jararaca Architecture
2
+
3
+ ## Core Concept: Unified Runtime Interface
4
+
5
+ Jararaca implements a unified runtime interface that allows different types of applications (REST API, Message Bus Worker, and Scheduler) to share the same utilities and context. This means that utilities like `@use_session` can be used consistently across different runtime contexts, even though they run as separate processes.
6
+
7
+ ## Runtime Types
8
+
9
+ 1. **REST API Runtime**
10
+
11
+ - Handles HTTP requests and WebSocket connections
12
+ - Executes REST controllers
13
+ - Uses `@RestController` decorator for route definitions
14
+
15
+ 2. **Message Bus Worker Runtime**
16
+
17
+ - Processes asynchronous messages and events
18
+ - Handles tasks and events through `@MessageBusController`
19
+ - Manages message queues and event processing
20
+
21
+ 3. **Scheduler Runtime**
22
+ - Executes scheduled tasks at specified intervals
23
+ - Uses `@ScheduledAction` decorator for task definitions
24
+ - Manages cron-based job execution
25
+
26
+ ## Application Structure
27
+
28
+ The application structure follows a hierarchical pattern:
29
+
30
+ 1. **Microservice Declaration**
31
+
32
+ - Uses `@Microservice` class for configuration
33
+ - Declares providers, controllers, and interceptors
34
+ - No execution happens at declaration time
35
+ - Configuration is shared across all runtimes
36
+
37
+ 2. **Application Implementation**
38
+
39
+ - **REST Controllers** (`@RestController`)
40
+
41
+ - Handle HTTP endpoints
42
+ - Run in REST API runtime
43
+ - Support middleware and dependency injection
44
+
45
+ - **Events and Tasks** (`@MessageBusController`)
46
+
47
+ - Handle asynchronous operations
48
+ - Run in Message Bus Worker runtime
49
+ - Support message publishing and consumption
50
+
51
+ - **Scheduled Jobs** (`@ScheduledAction`)
52
+ - Execute at specified intervals
53
+ - Run in Scheduler runtime
54
+ - Support cron-based scheduling
55
+
56
+ ## Architecture Diagram
57
+
58
+ ```mermaid
59
+ graph LR
60
+ subgraph "Runtime Layer"
61
+ REST[REST API Runtime]
62
+ Worker[Message Bus Worker Runtime]
63
+ Scheduler[Scheduler Runtime]
64
+ end
65
+
66
+ subgraph "Application Layer"
67
+ Microservice[Microservice Declaration]
68
+ RESTController[REST Controllers]
69
+ MessageBus[Events & Tasks]
70
+ ScheduledJobs[Scheduled Jobs]
71
+ end
72
+
73
+ subgraph "Shared Utilities"
74
+ Session[use_session]
75
+ Publisher[use_publisher]
76
+ WS[use_ws_manager]
77
+ end
78
+
79
+ Microservice --> REST
80
+ Microservice --> Worker
81
+ Microservice --> Scheduler
82
+
83
+ REST --> RESTController
84
+ Worker --> MessageBus
85
+ Scheduler --> ScheduledJobs
86
+
87
+ RESTController --> Session
88
+ MessageBus --> Session
89
+ ScheduledJobs --> Session
90
+
91
+ RESTController --> Publisher
92
+ MessageBus --> Publisher
93
+ ScheduledJobs --> Publisher
94
+
95
+ RESTController --> WS
96
+ MessageBus --> WS
97
+ ScheduledJobs --> WS
98
+ ```
99
+
100
+ ## Key Features
101
+
102
+ 1. **Shared Context**
103
+
104
+ - All runtimes share the same context and utilities
105
+ - Consistent access to services like database sessions
106
+ - Unified dependency injection system
107
+
108
+ 2. **Declarative Configuration**
109
+
110
+ - Configuration is defined once in `Microservice`
111
+ - Runtime-specific settings are handled separately
112
+ - Easy to maintain and modify
113
+
114
+ 3. **Process Isolation**
115
+
116
+ - Each runtime runs as a separate process
117
+ - Clear separation of concerns
118
+ - Independent scaling and deployment
119
+
120
+ 4. **Unified Utilities**
121
+ - Common utilities like `@use_session` work across all runtimes
122
+ - Consistent API for database access, message publishing, etc.
123
+ - Reduced code duplication
124
+
125
+ ## Usage Example
126
+
127
+ ```python
128
+ from jararaca import (
129
+ AIOPikaConnectionFactory,
130
+ AIOSQAConfig,
131
+ AIOSqlAlchemySessionInterceptor,
132
+ AppConfigurationInterceptor,
133
+ HttpMicroservice,
134
+ MessageBusPublisherInterceptor,
135
+ Microservice,
136
+ ProviderSpec,
137
+ RedisWebSocketConnectionBackend,
138
+ Token,
139
+ WebSocketInterceptor,
140
+ create_http_server,
141
+ )
142
+
143
+
144
+ # Define your application configuration
145
+ class AppConfig:
146
+ DATABASE_URL: str
147
+ REDIS_URL: str
148
+ AMQP_URL: str
149
+
150
+ # Create the microservice with all necessary components
151
+ app = Microservice(
152
+ providers=[
153
+ ProviderSpec(
154
+ provide=Token(Redis, "REDIS"),
155
+ use_factory=lambda config: Redis.from_url(config.REDIS_URL, decode_responses=False),
156
+ after_interceptors=True,
157
+ ),
158
+ ],
159
+ controllers=[
160
+ TasksController, # Your controller class
161
+ ],
162
+ interceptors=[
163
+ # Configuration interceptor
164
+ AppConfigurationInterceptor(
165
+ global_configs=[
166
+ (Token(AppConfig, "APP_CONFIG"), AppConfig),
167
+ ]
168
+ ),
169
+ # Message bus interceptor
170
+ AppFactoryWithAppConfig(
171
+ lambda config: MessageBusPublisherInterceptor(
172
+ connection_factory=AIOPikaConnectionFactory(
173
+ url=config.AMQP_URL,
174
+ exchange="jararaca_ex",
175
+ ),
176
+ )
177
+ ),
178
+ # Database session interceptor
179
+ AppFactoryWithAppConfig(
180
+ lambda config: AIOSqlAlchemySessionInterceptor(
181
+ AIOSQAConfig(
182
+ connection_name="default",
183
+ url=config.DATABASE_URL,
184
+ )
185
+ )
186
+ ),
187
+ # WebSocket interceptor
188
+ AppFactoryWithAppConfig(
189
+ lambda config: WebSocketInterceptor(
190
+ backend=RedisWebSocketConnectionBackend(
191
+ send_pubsub_channel="jararaca:websocket:send",
192
+ broadcast_pubsub_channel="jararaca:websocket:broadcast",
193
+ conn=Redis.from_url(config.REDIS_URL, decode_responses=False),
194
+ )
195
+ ),
196
+ ),
197
+ ],
198
+ )
199
+
200
+ # Create HTTP server for REST API runtime
201
+ http_app = create_http_server(
202
+ HttpMicroservice(
203
+ app=app,
204
+ factory=fastapi_factory,
205
+ )
206
+ )
207
+
208
+
209
+ class HelloTask(Message):
210
+ MESSAGE_TYPE = "task"
211
+ MESSAGE_TOPIC = "task.topic.name"
212
+
213
+ message: str
214
+
215
+ # Example controller showing unified utilities across runtimes
216
+ @MessageBusController()
217
+ @RestController("/tasks")
218
+ class TasksController:
219
+ def __init__(self, redis: Annotated[Redis, Token(Redis, "REDIS")]):
220
+ self.redis = redis
221
+ self.tasks_crud = CRUDOperations(TaskEntity, use_session)
222
+
223
+ @Post("/")
224
+ async def create_task(self, task: CreateTaskSchema) -> Identifiable[TaskSchema]:
225
+ # Use session in REST context
226
+ task_entity = await self.tasks_crud.create(task)
227
+ await use_ws_manager().broadcast(b"New Task Created")
228
+ await use_publisher().publish(task_entity.to_identifiable(TaskSchema), topic="task")
229
+ return task_entity.to_identifiable(TaskSchema)
230
+
231
+ @MessageHandler(HelloTask)
232
+ async def process_task(self, message: MessageOf[HelloTask]) -> None:
233
+ # Use session in Message Bus context
234
+ print(message.message)
235
+
236
+ @ScheduledAction("* * * * * */5")
237
+ async def scheduled_task(self) -> None:
238
+ # Use session in Scheduler context
239
+ pending_tasks = await use_session().execute(select(TaskEntity))
240
+ for task in pending_tasks:
241
+ await use_publisher().publish(task.to_identifiable(TaskSchema), topic="task")
242
+ ```
243
+
244
+ ## Context Hooks and Interceptors
245
+
246
+ Jararaca provides a powerful system of context hooks (like `use_session`, `use_publisher`, `use_ws_manager`) that are managed through Python's `ContextVar` system. These hooks are configured separately for each execution context and are provided by interceptors configured in the `Microservice` instance.
247
+
248
+ > **Important Note on Interceptor Order**
249
+ > The order of interceptors in the `Microservice` instance matters significantly. Interceptors are executed in the order they are defined, meaning:
250
+ >
251
+ > - The first interceptor in the list will set up its context before the subsequent ones
252
+ > - This order affects how dependencies between different context hooks are resolved
253
+ > - For example, if a database session is needed by a message publisher, the session interceptor should be configured before the publisher interceptor
254
+
255
+ ### How Context Hooks Work
256
+
257
+ 1. **Context Isolation**
258
+
259
+ - Each execution (HTTP request, message processing, scheduled job) gets its own isolated context
260
+ - Context hooks provide access to resources specific to that execution
261
+ - Resources are automatically cleaned up when the execution completes
262
+
263
+ 2. **Interceptor-Based Provision**
264
+ - Interceptors are responsible for setting up and managing the context
265
+ - They are configured in the `Microservice` instance
266
+ - Each interceptor handles a specific type of resource
267
+
268
+ ### Example: Database Session Management
269
+
270
+ ```python
271
+ # The AIOSqlAlchemySessionInterceptor manages database sessions
272
+ class AIOSqlAlchemySessionInterceptor(AppInterceptor):
273
+ def __init__(self, config: AIOSQAConfig):
274
+ self.config = config
275
+ self.engine = create_async_engine(self.config.url)
276
+ self.sessionmaker = async_sessionmaker(self.engine)
277
+
278
+ @asynccontextmanager
279
+ async def intercept(self, app_context: AppContext) -> AsyncGenerator[None, None]:
280
+ # Creates a new session for this execution
281
+ async with self.sessionmaker() as session:
282
+ # Provides the session to the context
283
+ with provide_session(self.config.connection_name, session):
284
+ try:
285
+ yield
286
+ await session.commit()
287
+ except Exception as e:
288
+ await session.rollback()
289
+ raise e
290
+ ```
291
+
292
+ ### Context Hook Lifecycle
293
+
294
+ 1. **Configuration**
295
+
296
+ ```python
297
+ app = Microservice(
298
+ interceptors=[
299
+ AIOSqlAlchemySessionInterceptor(
300
+ AIOSQAConfig(
301
+ connection_name="default",
302
+ url=config.DATABASE_URL,
303
+ )
304
+ ),
305
+ # Other interceptors...
306
+ ]
307
+ )
308
+ ```
309
+
310
+ 2. **Execution**
311
+
312
+ - When a request/message/job starts, interceptors are activated
313
+ - Each interceptor sets up its context using `ContextVar`
314
+ - The context is available throughout the execution
315
+
316
+ 3. **Cleanup**
317
+ - When execution completes, interceptors clean up resources
318
+ - Context is automatically reset
319
+ - Resources are properly closed/released
320
+
321
+ ### Available Context Hooks
322
+
323
+ 1. **Database Sessions** (`use_session`)
324
+
325
+ - Provided by `AIOSqlAlchemySessionInterceptor`
326
+ - Creates isolated database sessions per execution
327
+ - Handles transaction management automatically
328
+
329
+ 2. **Message Publishing** (`use_publisher`)
330
+
331
+ - Provided by `MessageBusPublisherInterceptor`
332
+ - Manages message publishing context
333
+ - Ensures proper message delivery
334
+
335
+ 3. **WebSocket Management** (`use_ws_manager`)
336
+ - Provided by `WebSocketInterceptor`
337
+ - Handles WebSocket connections and broadcasting
338
+ - Manages connection state
339
+
340
+ ### Usage in Different Contexts
341
+
342
+ ```python
343
+ # In a REST Controller
344
+ @RestController("/tasks")
345
+ @MessageBusController()
346
+ class TasksController:
347
+ @Get("/")
348
+ async def get_tasks(self):
349
+ # Gets a session specific to this HTTP request
350
+ session = use_session()
351
+ return await session.execute(select(TaskEntity))
352
+
353
+
354
+ @MessageHandler(SomeTask)
355
+ async def process_task(self, message: MessageOf[SomeTask]):
356
+ # Gets a session specific to this message processing
357
+ session = use_session()
358
+
359
+ # In a Scheduled Job
360
+ @ScheduledAction("* * * * *")
361
+ async def scheduled_task(self):
362
+ # Gets a session specific to this job execution
363
+ session = use_session()
364
+ await session.execute(select(TaskEntity))
365
+ ```
366
+
367
+ This system ensures that:
368
+
369
+ - Each execution has its own isolated resources
370
+ - Resources are properly managed and cleaned up
371
+ - The same utilities can be used consistently across different runtime contexts
372
+ - Dependencies are properly injected and managed