fastapi-factory-utilities 0.4.0__py3-none-any.whl → 0.7.1__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 fastapi-factory-utilities might be problematic. Click here for more details.
- fastapi_factory_utilities/core/api/__init__.py +1 -1
- fastapi_factory_utilities/core/api/v1/sys/health.py +1 -1
- fastapi_factory_utilities/core/app/__init__.py +4 -4
- fastapi_factory_utilities/core/app/application.py +22 -26
- fastapi_factory_utilities/core/app/builder.py +8 -32
- fastapi_factory_utilities/core/app/fastapi_builder.py +3 -2
- fastapi_factory_utilities/core/exceptions.py +55 -28
- fastapi_factory_utilities/core/plugins/__init__.py +2 -31
- fastapi_factory_utilities/core/plugins/abstracts.py +40 -0
- fastapi_factory_utilities/core/plugins/aiopika/__init__.py +25 -0
- fastapi_factory_utilities/core/plugins/aiopika/abstract.py +48 -0
- fastapi_factory_utilities/core/plugins/aiopika/configs.py +85 -0
- fastapi_factory_utilities/core/plugins/aiopika/depends.py +20 -0
- fastapi_factory_utilities/core/plugins/aiopika/exceptions.py +29 -0
- fastapi_factory_utilities/core/plugins/aiopika/exchange.py +70 -0
- fastapi_factory_utilities/core/plugins/aiopika/listener/__init__.py +7 -0
- fastapi_factory_utilities/core/plugins/aiopika/listener/abstract.py +72 -0
- fastapi_factory_utilities/core/plugins/aiopika/message.py +86 -0
- fastapi_factory_utilities/core/plugins/aiopika/plugins.py +84 -0
- fastapi_factory_utilities/core/plugins/aiopika/publisher/__init__.py +7 -0
- fastapi_factory_utilities/core/plugins/aiopika/publisher/abstract.py +66 -0
- fastapi_factory_utilities/core/plugins/aiopika/queue.py +86 -0
- fastapi_factory_utilities/core/plugins/odm_plugin/__init__.py +14 -157
- fastapi_factory_utilities/core/plugins/odm_plugin/builder.py +3 -3
- fastapi_factory_utilities/core/plugins/odm_plugin/configs.py +1 -1
- fastapi_factory_utilities/core/plugins/odm_plugin/documents.py +1 -1
- fastapi_factory_utilities/core/plugins/odm_plugin/helpers.py +16 -0
- fastapi_factory_utilities/core/plugins/odm_plugin/plugins.py +155 -0
- fastapi_factory_utilities/core/plugins/odm_plugin/repositories.py +1 -0
- fastapi_factory_utilities/core/plugins/opentelemetry_plugin/__init__.py +8 -121
- fastapi_factory_utilities/core/plugins/opentelemetry_plugin/instruments/__init__.py +85 -0
- fastapi_factory_utilities/core/plugins/opentelemetry_plugin/plugins.py +137 -0
- fastapi_factory_utilities/core/plugins/taskiq_plugins/__init__.py +29 -0
- fastapi_factory_utilities/core/plugins/taskiq_plugins/configs.py +12 -0
- fastapi_factory_utilities/core/plugins/taskiq_plugins/depends.py +51 -0
- fastapi_factory_utilities/core/plugins/taskiq_plugins/exceptions.py +13 -0
- fastapi_factory_utilities/core/plugins/taskiq_plugins/plugin.py +41 -0
- fastapi_factory_utilities/core/plugins/taskiq_plugins/schedulers.py +187 -0
- fastapi_factory_utilities/core/protocols.py +1 -54
- fastapi_factory_utilities/core/security/jwt.py +6 -5
- fastapi_factory_utilities/core/services/status/__init__.py +2 -2
- fastapi_factory_utilities/core/utils/status.py +2 -1
- fastapi_factory_utilities/core/utils/yaml_reader.py +1 -1
- fastapi_factory_utilities/example/app.py +15 -5
- fastapi_factory_utilities/example/entities/books/__init__.py +1 -1
- fastapi_factory_utilities/example/models/books/__init__.py +1 -1
- {fastapi_factory_utilities-0.4.0.dist-info → fastapi_factory_utilities-0.7.1.dist-info}/METADATA +14 -8
- {fastapi_factory_utilities-0.4.0.dist-info → fastapi_factory_utilities-0.7.1.dist-info}/RECORD +51 -32
- {fastapi_factory_utilities-0.4.0.dist-info → fastapi_factory_utilities-0.7.1.dist-info}/WHEEL +1 -1
- fastapi_factory_utilities/core/app/plugin_manager/__init__.py +0 -15
- fastapi_factory_utilities/core/app/plugin_manager/exceptions.py +0 -33
- fastapi_factory_utilities/core/app/plugin_manager/plugin_manager.py +0 -190
- fastapi_factory_utilities/core/plugins/example/__init__.py +0 -31
- fastapi_factory_utilities/core/plugins/httpx_plugin/__init__.py +0 -31
- {fastapi_factory_utilities-0.4.0.dist-info → fastapi_factory_utilities-0.7.1.dist-info}/entry_points.txt +0 -0
- {fastapi_factory_utilities-0.4.0.dist-info → fastapi_factory_utilities-0.7.1.dist-info/licenses}/LICENSE +0 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""Provides the exceptions for the Taskiq plugin."""
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from fastapi_factory_utilities.core.exceptions import FastAPIFactoryUtilitiesError
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class TaskiqPluginBaseError(FastAPIFactoryUtilitiesError):
|
|
9
|
+
"""Base class for all exceptions raised by the Taskiq plugin."""
|
|
10
|
+
|
|
11
|
+
def __init__(self, message: str, **kwargs: Any) -> None:
|
|
12
|
+
"""Initialize the Taskiq plugin base exception."""
|
|
13
|
+
super().__init__(message, **kwargs)
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""Provides the Taskiq plugin."""
|
|
2
|
+
|
|
3
|
+
from collections.abc import Callable
|
|
4
|
+
|
|
5
|
+
from fastapi_factory_utilities.core.plugins.abstracts import PluginAbstract
|
|
6
|
+
|
|
7
|
+
from .configs import RedisCredentialsConfig
|
|
8
|
+
from .depends import DEPENDS_SCHEDULER_COMPONENT_KEY
|
|
9
|
+
from .schedulers import SchedulerComponent
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class TaskiqPlugin(PluginAbstract):
|
|
13
|
+
"""Taskiq plugin."""
|
|
14
|
+
|
|
15
|
+
def __init__(
|
|
16
|
+
self, redis_credentials_config: RedisCredentialsConfig, register_hook: Callable[[SchedulerComponent], None]
|
|
17
|
+
) -> None:
|
|
18
|
+
"""Initialize the Taskiq plugin."""
|
|
19
|
+
super().__init__()
|
|
20
|
+
self._redis_credentials_config: RedisCredentialsConfig = redis_credentials_config
|
|
21
|
+
self._register_hook: Callable[[SchedulerComponent], None] = register_hook
|
|
22
|
+
self._scheduler_component: SchedulerComponent = SchedulerComponent()
|
|
23
|
+
|
|
24
|
+
def on_load(self) -> None:
|
|
25
|
+
"""On load."""
|
|
26
|
+
assert self._application is not None
|
|
27
|
+
self._scheduler_component.configure(
|
|
28
|
+
redis_connection_string=self._redis_credentials_config.url, app=self._application.get_asgi_app()
|
|
29
|
+
)
|
|
30
|
+
self._add_to_state(key=DEPENDS_SCHEDULER_COMPONENT_KEY, value=self._scheduler_component)
|
|
31
|
+
self._register_hook(self._scheduler_component)
|
|
32
|
+
|
|
33
|
+
async def on_startup(self) -> None:
|
|
34
|
+
"""On startup."""
|
|
35
|
+
assert self._application is not None
|
|
36
|
+
await self._scheduler_component.startup(app=self._application.get_asgi_app())
|
|
37
|
+
|
|
38
|
+
async def on_shutdown(self) -> None:
|
|
39
|
+
"""On shutdown."""
|
|
40
|
+
assert self._application is not None
|
|
41
|
+
await self._scheduler_component.shutdown()
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
"""Scheduler module for fastapi_factory_utilities.
|
|
2
|
+
|
|
3
|
+
This module provides components and utilities for scheduling tasks using Taskiq, FastAPI, and Redis.
|
|
4
|
+
It enables registration, configuration, and management of scheduled tasks in FastAPI applications.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import asyncio
|
|
8
|
+
from collections.abc import Coroutine
|
|
9
|
+
from typing import Any, Self, cast
|
|
10
|
+
|
|
11
|
+
import taskiq_fastapi
|
|
12
|
+
from fastapi import FastAPI
|
|
13
|
+
from structlog.stdlib import get_logger
|
|
14
|
+
from taskiq import (
|
|
15
|
+
AsyncBroker,
|
|
16
|
+
AsyncTaskiqDecoratedTask,
|
|
17
|
+
ScheduleSource,
|
|
18
|
+
TaskiqScheduler,
|
|
19
|
+
)
|
|
20
|
+
from taskiq.api import run_receiver_task, run_scheduler_task
|
|
21
|
+
from taskiq.scheduler.created_schedule import CreatedSchedule
|
|
22
|
+
from taskiq.scheduler.scheduled_task import ScheduledTask
|
|
23
|
+
from taskiq_redis import (
|
|
24
|
+
ListRedisScheduleSource,
|
|
25
|
+
RedisAsyncResultBackend,
|
|
26
|
+
RedisStreamBroker,
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
_logger = get_logger(__package__)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class SchedulerComponent:
|
|
33
|
+
"""Scheduler component."""
|
|
34
|
+
|
|
35
|
+
NAME_SUFFIX: str = "tiktok_integration"
|
|
36
|
+
|
|
37
|
+
def __init__(self) -> None:
|
|
38
|
+
"""Initialize the scheduler component."""
|
|
39
|
+
self._result_backend: RedisAsyncResultBackend[Any] | None = None
|
|
40
|
+
self._stream_broker: RedisStreamBroker | None = None
|
|
41
|
+
self._scheduler: TaskiqScheduler | None = None
|
|
42
|
+
self._scheduler_source: ListRedisScheduleSource | None = None
|
|
43
|
+
self._dyn_task: AsyncTaskiqDecoratedTask[Any, Any] | None = None
|
|
44
|
+
self._schedule_cron: ScheduledTask | None = None
|
|
45
|
+
self._schedulers_tasks: dict[str, AsyncTaskiqDecoratedTask[Any, Any]] = {}
|
|
46
|
+
|
|
47
|
+
def register_task(self, task: Coroutine[Any, Any, Any], task_name: str) -> None:
|
|
48
|
+
"""Register a task.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
task: The task to register.
|
|
52
|
+
task_name: The name of the task.
|
|
53
|
+
|
|
54
|
+
Raises:
|
|
55
|
+
ValueError: If the task is already registered.
|
|
56
|
+
ValueError: If the stream broker is not initialized.
|
|
57
|
+
"""
|
|
58
|
+
if self._stream_broker is None:
|
|
59
|
+
raise ValueError("Stream broker is not initialized")
|
|
60
|
+
|
|
61
|
+
if task_name in self._schedulers_tasks:
|
|
62
|
+
raise ValueError(f"Task {task_name} already registered")
|
|
63
|
+
|
|
64
|
+
self._schedulers_tasks[task_name] = self._stream_broker.register_task(task, task_name) # type: ignore
|
|
65
|
+
|
|
66
|
+
def get_task(self, task_name: str) -> AsyncTaskiqDecoratedTask[Any, Any]:
|
|
67
|
+
"""Get a task.
|
|
68
|
+
|
|
69
|
+
Args:
|
|
70
|
+
task_name: The name of the task.
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
AsyncTaskiqDecoratedTask: The task.
|
|
74
|
+
|
|
75
|
+
Raises:
|
|
76
|
+
ValueError: If the task is not registered.
|
|
77
|
+
"""
|
|
78
|
+
if task_name not in self._schedulers_tasks:
|
|
79
|
+
raise ValueError(f"Task {task_name} not registered")
|
|
80
|
+
return self._schedulers_tasks[task_name]
|
|
81
|
+
|
|
82
|
+
def configure(self, redis_connection_string: str, app: FastAPI) -> Self:
|
|
83
|
+
"""Configure the scheduler component."""
|
|
84
|
+
self._result_backend = RedisAsyncResultBackend(
|
|
85
|
+
redis_url=redis_connection_string,
|
|
86
|
+
prefix_str=f"velmios_taskiq_result_backend_{self.NAME_SUFFIX}",
|
|
87
|
+
result_ex_time=120,
|
|
88
|
+
)
|
|
89
|
+
self._stream_broker = RedisStreamBroker(
|
|
90
|
+
url=redis_connection_string,
|
|
91
|
+
queue_name=f"velmios_taskiq_stream_broker_{self.NAME_SUFFIX}",
|
|
92
|
+
consumer_group_name=f"velmios_taskiq_consumer_group_{self.NAME_SUFFIX}",
|
|
93
|
+
).with_result_backend(self._result_backend)
|
|
94
|
+
|
|
95
|
+
taskiq_fastapi.populate_dependency_context(self._stream_broker, app)
|
|
96
|
+
|
|
97
|
+
self._scheduler_source = ListRedisScheduleSource(
|
|
98
|
+
url=redis_connection_string,
|
|
99
|
+
prefix=f"velmios_taskiq_schedule_source_{self.NAME_SUFFIX}",
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
self._scheduler = TaskiqScheduler(
|
|
103
|
+
broker=self._stream_broker,
|
|
104
|
+
sources=[self._scheduler_source],
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
return self
|
|
108
|
+
|
|
109
|
+
async def startup(self, app: FastAPI) -> None:
|
|
110
|
+
"""Start the scheduler."""
|
|
111
|
+
if self._result_backend is None:
|
|
112
|
+
raise ValueError("Result backend is not initialized")
|
|
113
|
+
if self._stream_broker is None:
|
|
114
|
+
raise ValueError("Stream broker is not initialized")
|
|
115
|
+
if self._scheduler is None:
|
|
116
|
+
raise ValueError("Scheduler is not initialized")
|
|
117
|
+
if self._scheduler_source is None:
|
|
118
|
+
raise ValueError("Scheduler source is not initialized")
|
|
119
|
+
|
|
120
|
+
_logger.info("Starting scheduler")
|
|
121
|
+
await self._result_backend.startup()
|
|
122
|
+
await self._stream_broker.startup()
|
|
123
|
+
await self._scheduler.startup()
|
|
124
|
+
_logger.info("Scheduler started")
|
|
125
|
+
_logger.info("Scheduling task")
|
|
126
|
+
schedules: list[ScheduledTask] = await self._scheduler_source.get_schedules()
|
|
127
|
+
_logger.info("Schedules retrieved", schedules=schedules)
|
|
128
|
+
|
|
129
|
+
self._schedule_cron = next(filter(lambda x: x.task_name == "heartbeat", schedules), None)
|
|
130
|
+
|
|
131
|
+
if self._schedule_cron is None:
|
|
132
|
+
_logger.info("No schedules found, scheduling task")
|
|
133
|
+
self._dyn_task = self.get_task("heartbeat")
|
|
134
|
+
task_created: CreatedSchedule[Any] = await self._dyn_task.schedule_by_cron(
|
|
135
|
+
source=self._scheduler_source, cron="* * * * *", msg="every minute"
|
|
136
|
+
)
|
|
137
|
+
self._schedule_cron = task_created.task
|
|
138
|
+
_logger.info("Task scheduled")
|
|
139
|
+
else:
|
|
140
|
+
_logger.info("Schedules found, skipping scheduling")
|
|
141
|
+
|
|
142
|
+
_logger.info("Starting worker and scheduler tasks")
|
|
143
|
+
taskiq_fastapi.populate_dependency_context(self._stream_broker, app, app.state) # type: ignore
|
|
144
|
+
self._worker_task: asyncio.Task[None] = asyncio.create_task(run_receiver_task(self._stream_broker))
|
|
145
|
+
self._scheduler_task: asyncio.Task[None] = asyncio.create_task(run_scheduler_task(self._scheduler))
|
|
146
|
+
_logger.info("Worker and scheduler tasks started")
|
|
147
|
+
|
|
148
|
+
async def shutdown(self) -> None:
|
|
149
|
+
"""Stop the scheduler."""
|
|
150
|
+
_logger.info("Stopping worker")
|
|
151
|
+
self._worker_task.cancel()
|
|
152
|
+
self._scheduler_task.cancel()
|
|
153
|
+
try:
|
|
154
|
+
await self._worker_task
|
|
155
|
+
except (asyncio.CancelledError, RuntimeError) as e:
|
|
156
|
+
_logger.info("Worker task cancelled", error=e)
|
|
157
|
+
try:
|
|
158
|
+
await self._scheduler_task
|
|
159
|
+
except (asyncio.CancelledError, RuntimeError) as e:
|
|
160
|
+
_logger.info("Scheduler task cancelled", error=e)
|
|
161
|
+
|
|
162
|
+
while not self._worker_task.done() or not self._scheduler_task.done():
|
|
163
|
+
await asyncio.sleep(0.1)
|
|
164
|
+
|
|
165
|
+
_logger.info("Stopping scheduler")
|
|
166
|
+
if self._scheduler is not None:
|
|
167
|
+
await self._scheduler.shutdown()
|
|
168
|
+
if self._stream_broker is not None:
|
|
169
|
+
await self._stream_broker.shutdown()
|
|
170
|
+
if self._result_backend is not None:
|
|
171
|
+
await self._result_backend.shutdown()
|
|
172
|
+
_logger.info("Scheduler stopped")
|
|
173
|
+
|
|
174
|
+
@property
|
|
175
|
+
def scheduler(self) -> TaskiqScheduler:
|
|
176
|
+
"""Get the scheduler."""
|
|
177
|
+
return cast(TaskiqScheduler, self._scheduler)
|
|
178
|
+
|
|
179
|
+
@property
|
|
180
|
+
def broker(self) -> AsyncBroker:
|
|
181
|
+
"""Get the broker."""
|
|
182
|
+
return cast(AsyncBroker, self._stream_broker)
|
|
183
|
+
|
|
184
|
+
@property
|
|
185
|
+
def scheduler_source(self) -> ScheduleSource:
|
|
186
|
+
"""Get the scheduler source."""
|
|
187
|
+
return cast(ScheduleSource, self._scheduler_source)
|
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
"""Protocols for the base application."""
|
|
2
2
|
|
|
3
3
|
from abc import abstractmethod
|
|
4
|
-
from typing import TYPE_CHECKING, ClassVar, Protocol
|
|
4
|
+
from typing import TYPE_CHECKING, ClassVar, Protocol
|
|
5
5
|
|
|
6
6
|
from beanie import Document
|
|
7
7
|
from fastapi import FastAPI
|
|
8
8
|
|
|
9
|
-
from fastapi_factory_utilities.core.plugins import PluginsEnum
|
|
10
9
|
from fastapi_factory_utilities.core.services.status.services import StatusService
|
|
11
10
|
|
|
12
11
|
if TYPE_CHECKING:
|
|
13
12
|
from fastapi_factory_utilities.core.app.config import RootConfig
|
|
14
|
-
from fastapi_factory_utilities.core.plugins import PluginState
|
|
15
13
|
|
|
16
14
|
|
|
17
15
|
class ApplicationAbstractProtocol(Protocol):
|
|
@@ -21,8 +19,6 @@ class ApplicationAbstractProtocol(Protocol):
|
|
|
21
19
|
|
|
22
20
|
ODM_DOCUMENT_MODELS: ClassVar[list[type[Document]]]
|
|
23
21
|
|
|
24
|
-
DEFAULT_PLUGINS_ACTIVATED: ClassVar[list[PluginsEnum]]
|
|
25
|
-
|
|
26
22
|
@abstractmethod
|
|
27
23
|
def get_config(self) -> "RootConfig":
|
|
28
24
|
"""Get the application configuration."""
|
|
@@ -34,52 +30,3 @@ class ApplicationAbstractProtocol(Protocol):
|
|
|
34
30
|
@abstractmethod
|
|
35
31
|
def get_status_service(self) -> StatusService:
|
|
36
32
|
"""Get the status service."""
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
@runtime_checkable
|
|
40
|
-
class PluginProtocol(Protocol):
|
|
41
|
-
"""Defines the protocol for the plugins."""
|
|
42
|
-
|
|
43
|
-
@abstractmethod
|
|
44
|
-
def pre_conditions_check(self, application: ApplicationAbstractProtocol) -> bool:
|
|
45
|
-
"""Check the pre-conditions for the plugin.
|
|
46
|
-
|
|
47
|
-
Args:
|
|
48
|
-
application (BaseApplicationProtocol): The application.
|
|
49
|
-
|
|
50
|
-
Returns:
|
|
51
|
-
bool: True if the pre-conditions are met, False otherwise.
|
|
52
|
-
"""
|
|
53
|
-
|
|
54
|
-
@abstractmethod
|
|
55
|
-
def on_load(self, application: ApplicationAbstractProtocol) -> list["PluginState"] | None:
|
|
56
|
-
"""The actions to perform on load for the plugin.
|
|
57
|
-
|
|
58
|
-
Args:
|
|
59
|
-
application (BaseApplicationProtocol): The application.
|
|
60
|
-
|
|
61
|
-
Returns:
|
|
62
|
-
None
|
|
63
|
-
"""
|
|
64
|
-
|
|
65
|
-
@abstractmethod
|
|
66
|
-
async def on_startup(self, application: ApplicationAbstractProtocol) -> list["PluginState"] | None:
|
|
67
|
-
"""The actions to perform on startup for the plugin.
|
|
68
|
-
|
|
69
|
-
Args:
|
|
70
|
-
application (BaseApplicationProtocol): The application.
|
|
71
|
-
|
|
72
|
-
Returns:
|
|
73
|
-
None
|
|
74
|
-
"""
|
|
75
|
-
|
|
76
|
-
@abstractmethod
|
|
77
|
-
async def on_shutdown(self, application: ApplicationAbstractProtocol) -> None:
|
|
78
|
-
"""The actions to perform on shutdown for the plugin.
|
|
79
|
-
|
|
80
|
-
Args:
|
|
81
|
-
application (BaseApplicationProtocol): The application.
|
|
82
|
-
|
|
83
|
-
Returns:
|
|
84
|
-
None
|
|
85
|
-
"""
|
|
@@ -140,11 +140,12 @@ class JWTBearerAuthentication:
|
|
|
140
140
|
# by the request or by the jwt parameter
|
|
141
141
|
if self.jwt_raw is None and request is None:
|
|
142
142
|
raise HTTPException(status_code=HTTPStatus.UNAUTHORIZED, detail="Missing Credentials")
|
|
143
|
-
jwt_raw: str
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
143
|
+
jwt_raw: str
|
|
144
|
+
if self.jwt_raw is None:
|
|
145
|
+
jwt_raw = self._extract_raw_token(request=request) # type: ignore[arg-type]
|
|
146
|
+
else:
|
|
147
|
+
jwt_raw = self.jwt_raw
|
|
148
|
+
|
|
148
149
|
# Execute the io bound and cpu bound tasks in parallel
|
|
149
150
|
async with TaskGroup() as tg:
|
|
150
151
|
# TODO: Can be disabled by configuration (for operation purposes)
|
|
@@ -5,10 +5,10 @@ from .services import StatusService
|
|
|
5
5
|
from .types import ComponentInstanceType, Status
|
|
6
6
|
|
|
7
7
|
__all__: list[str] = [
|
|
8
|
-
"ComponentTypeEnum",
|
|
9
8
|
"ComponentInstanceType",
|
|
9
|
+
"ComponentTypeEnum",
|
|
10
10
|
"HealthStatusEnum",
|
|
11
11
|
"ReadinessStatusEnum",
|
|
12
|
-
"StatusService",
|
|
13
12
|
"Status",
|
|
13
|
+
"StatusService",
|
|
14
14
|
]
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
```python
|
|
4
4
|
# Example of using the MonitoredAbstract
|
|
5
5
|
|
|
6
|
+
|
|
6
7
|
class MyMonitored(MonitoredAbstract):
|
|
7
8
|
def __init__(self, status_service: StatusService) -> None:
|
|
8
9
|
super().__init__(
|
|
@@ -63,9 +64,9 @@ class MonitoredAbstract(ABC):
|
|
|
63
64
|
|
|
64
65
|
|
|
65
66
|
__all__: list[str] = [
|
|
66
|
-
"MonitoredAbstract",
|
|
67
67
|
"ComponentInstanceType",
|
|
68
68
|
"ComponentTypeEnum",
|
|
69
|
+
"MonitoredAbstract",
|
|
69
70
|
"Status",
|
|
70
71
|
"StatusService",
|
|
71
72
|
]
|
|
@@ -72,7 +72,7 @@ class YamlFileReader:
|
|
|
72
72
|
try:
|
|
73
73
|
yaml_data = yaml_data[key]
|
|
74
74
|
except KeyError:
|
|
75
|
-
logger.warning(f"Base key {key}
|
|
75
|
+
logger.warning(f"Base key {key} not found in YAML file" + " from {self._yaml_base_key}")
|
|
76
76
|
return dict()
|
|
77
77
|
return yaml_data
|
|
78
78
|
|
|
@@ -7,7 +7,9 @@ from beanie import Document
|
|
|
7
7
|
from fastapi_factory_utilities.core.app.application import ApplicationAbstract
|
|
8
8
|
from fastapi_factory_utilities.core.app.builder import ApplicationGenericBuilder
|
|
9
9
|
from fastapi_factory_utilities.core.app.config import RootConfig
|
|
10
|
-
from fastapi_factory_utilities.core.plugins import
|
|
10
|
+
from fastapi_factory_utilities.core.plugins.abstracts import PluginAbstract
|
|
11
|
+
from fastapi_factory_utilities.core.plugins.odm_plugin import ODMPlugin
|
|
12
|
+
from fastapi_factory_utilities.core.plugins.opentelemetry_plugin import OpenTelemetryPlugin
|
|
11
13
|
from fastapi_factory_utilities.example.models.books.document import BookDocument
|
|
12
14
|
|
|
13
15
|
|
|
@@ -26,12 +28,11 @@ class App(ApplicationAbstract):
|
|
|
26
28
|
|
|
27
29
|
ODM_DOCUMENT_MODELS: ClassVar[list[type[Document]]] = [BookDocument]
|
|
28
30
|
|
|
29
|
-
DEFAULT_PLUGINS_ACTIVATED: ClassVar[list[PluginsEnum]] = [PluginsEnum.OPENTELEMETRY_PLUGIN, PluginsEnum.ODM_PLUGIN]
|
|
30
|
-
|
|
31
31
|
def configure(self) -> None:
|
|
32
32
|
"""Configure the application."""
|
|
33
33
|
# Prevent circular import
|
|
34
|
-
|
|
34
|
+
# pylint: disable=import-outside-toplevel
|
|
35
|
+
from .api import api_router # noqa: PLC0415
|
|
35
36
|
|
|
36
37
|
self.get_asgi_app().include_router(router=api_router)
|
|
37
38
|
|
|
@@ -47,4 +48,13 @@ class App(ApplicationAbstract):
|
|
|
47
48
|
class AppBuilder(ApplicationGenericBuilder[App]):
|
|
48
49
|
"""Application builder for the App application."""
|
|
49
50
|
|
|
50
|
-
|
|
51
|
+
def get_default_plugins(self) -> list[PluginAbstract]:
|
|
52
|
+
"""Get the default plugins."""
|
|
53
|
+
return [ODMPlugin(), OpenTelemetryPlugin()]
|
|
54
|
+
|
|
55
|
+
def __init__(self, plugins: list[PluginAbstract] | None = None) -> None:
|
|
56
|
+
"""Initialize the AppBuilder."""
|
|
57
|
+
# If no plugins are provided, use the default plugins
|
|
58
|
+
if plugins is None:
|
|
59
|
+
plugins = self.get_default_plugins()
|
|
60
|
+
super().__init__(plugins=plugins)
|
{fastapi_factory_utilities-0.4.0.dist-info → fastapi_factory_utilities-0.7.1.dist-info}/METADATA
RENAMED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: fastapi_factory_utilities
|
|
3
|
-
Version: 0.
|
|
4
|
-
Summary: Consolidate libraries and utilities to create microservices in Python with FastAPI, Beanie,
|
|
3
|
+
Version: 0.7.1
|
|
4
|
+
Summary: Consolidate libraries and utilities to create microservices in Python with FastAPI, Beanie, Taskiq, AioPika and OpenTelemetry.
|
|
5
5
|
License: MIT
|
|
6
|
-
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Keywords: python,fastapi,beanie,taskiq,opentelemetry,microservices
|
|
7
8
|
Author: miragecentury
|
|
8
9
|
Author-email: victorien.vanroye@gmail.com
|
|
9
10
|
Maintainer: miragecentury
|
|
@@ -18,12 +19,14 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
18
19
|
Classifier: Topic :: Software Development :: Libraries
|
|
19
20
|
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
|
20
21
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
22
|
+
Requires-Dist: aio-pika (>=9.5.7,<10.0.0)
|
|
21
23
|
Requires-Dist: aiohttp[speedups] (>=3.12.13,<4.0.0)
|
|
22
24
|
Requires-Dist: beanie (>=1.30.0,<2.0.0)
|
|
23
25
|
Requires-Dist: fastapi (>=0.115.13,<1)
|
|
24
26
|
Requires-Dist: opentelemetry-exporter-otlp-proto-grpc (>=1.26.0,<2.0.0)
|
|
25
27
|
Requires-Dist: opentelemetry-exporter-otlp-proto-http (>=1.26.0,<2.0.0)
|
|
26
|
-
Requires-Dist: opentelemetry-instrumentation-
|
|
28
|
+
Requires-Dist: opentelemetry-instrumentation-aio-pika (>=0.59b0,<0.60)
|
|
29
|
+
Requires-Dist: opentelemetry-instrumentation-aiohttp-client (>=0,<1)
|
|
27
30
|
Requires-Dist: opentelemetry-instrumentation-fastapi (>=0,<1)
|
|
28
31
|
Requires-Dist: opentelemetry-instrumentation-pymongo (>=0,<1)
|
|
29
32
|
Requires-Dist: opentelemetry-propagator-b3 (>=1.26.0,<2.0.0)
|
|
@@ -31,13 +34,16 @@ Requires-Dist: opentelemetry-sdk (>=1.26.0,<2.0.0)
|
|
|
31
34
|
Requires-Dist: pyaml (>=25.1.0,<26.0.0)
|
|
32
35
|
Requires-Dist: pydantic (>=2.8.2,<3.0.0)
|
|
33
36
|
Requires-Dist: pyjwt (>=2.10.1,<3.0.0)
|
|
34
|
-
Requires-Dist: pymongo (>=4.9.2,<4.
|
|
37
|
+
Requires-Dist: pymongo (>=4.9.2,<4.16.0)
|
|
35
38
|
Requires-Dist: reactivex (>=4.0.4,<5.0.0)
|
|
36
39
|
Requires-Dist: structlog (>=24.1,<26.0)
|
|
40
|
+
Requires-Dist: taskiq-dependencies (>=1.5.8,<2.0.0)
|
|
41
|
+
Requires-Dist: taskiq-fastapi (>=0.3.5,<0.4.0)
|
|
42
|
+
Requires-Dist: taskiq-redis (>=1.0.9,<2.0.0)
|
|
37
43
|
Requires-Dist: typer (>=0,<1)
|
|
38
44
|
Requires-Dist: uvicorn (>=0.34.3,<1)
|
|
39
|
-
Project-URL: Homepage, https://github.com/
|
|
40
|
-
Project-URL: Repository, https://github.com/
|
|
45
|
+
Project-URL: Homepage, https://github.com/DeerHide/fastapi_factory_utilities
|
|
46
|
+
Project-URL: Repository, https://github.com/DeerHide/fastapi_factory_utilities
|
|
41
47
|
Description-Content-Type: text/markdown
|
|
42
48
|
|
|
43
49
|
# fastapi_factory_utilities
|
{fastapi_factory_utilities-0.4.0.dist-info → fastapi_factory_utilities-0.7.1.dist-info}/RECORD
RENAMED
|
@@ -1,38 +1,57 @@
|
|
|
1
1
|
fastapi_factory_utilities/__main__.py,sha256=w8o9KpyHcxGyLHmTK8ixbIqJIsB3NbIGuAMY7OfnxrA,147
|
|
2
2
|
fastapi_factory_utilities/core/__init__.py,sha256=tt5a-MgeFt_oACkc9K5xl2rynIbca9DGqsKBDEqGzto,34
|
|
3
|
-
fastapi_factory_utilities/core/api/__init__.py,sha256=
|
|
3
|
+
fastapi_factory_utilities/core/api/__init__.py,sha256=fAwgRcRry1nIyAL7CsCbpwR87n5tWnBWKEPH6QZCpp8,542
|
|
4
4
|
fastapi_factory_utilities/core/api/tags.py,sha256=3hQcTeW0FS78sPTJ2PB44dMDTSkoW-xKj7rrfKX2Lk0,154
|
|
5
5
|
fastapi_factory_utilities/core/api/v1/sys/__init__.py,sha256=mTXhpn3_KgQ1snt0-0PFmGvFr4n5srQRRADEdRSGFJM,345
|
|
6
|
-
fastapi_factory_utilities/core/api/v1/sys/health.py,sha256=
|
|
6
|
+
fastapi_factory_utilities/core/api/v1/sys/health.py,sha256=LILUwfyqeBDlf4GSpkU_3bxMjZPCLanOBkMGDKtQufY,2867
|
|
7
7
|
fastapi_factory_utilities/core/api/v1/sys/readiness.py,sha256=xIY8pQLShU7KWRtlOUK5gTDyZ8aB1KBvLczC6boT-tg,1711
|
|
8
|
-
fastapi_factory_utilities/core/app/__init__.py,sha256=
|
|
9
|
-
fastapi_factory_utilities/core/app/application.py,sha256=
|
|
10
|
-
fastapi_factory_utilities/core/app/builder.py,sha256=
|
|
8
|
+
fastapi_factory_utilities/core/app/__init__.py,sha256=6Ee_zK-KzJWoOElsAnGdBz8giRJlhAPMaEzs0I3gvrA,596
|
|
9
|
+
fastapi_factory_utilities/core/app/application.py,sha256=fJTKgfqBWD1xzE7Y9ToZEBDrd1PxHtnZ7SHLmkS1S1M,4737
|
|
10
|
+
fastapi_factory_utilities/core/app/builder.py,sha256=gkmhGVYFu2zbW5sxWyh6Pn5ysdCIvn1_WqNJMKls54s,3820
|
|
11
11
|
fastapi_factory_utilities/core/app/config.py,sha256=MuV4G_M4QgZWYHoulusJLv_m4Qr2php-Cg9Jum4qkNA,7303
|
|
12
12
|
fastapi_factory_utilities/core/app/enums.py,sha256=X1upnaehYU0eHExXTde5xsH-pI9q7HZDNsOEF5PApdg,226
|
|
13
13
|
fastapi_factory_utilities/core/app/exceptions.py,sha256=tQDf0_4j5xgCbku7TL7JaZGs3_bjsWG2YLBCydQJpPw,664
|
|
14
|
-
fastapi_factory_utilities/core/app/fastapi_builder.py,sha256=
|
|
15
|
-
fastapi_factory_utilities/core/
|
|
16
|
-
fastapi_factory_utilities/core/
|
|
17
|
-
fastapi_factory_utilities/core/
|
|
18
|
-
fastapi_factory_utilities/core/
|
|
19
|
-
fastapi_factory_utilities/core/plugins/
|
|
20
|
-
fastapi_factory_utilities/core/plugins/
|
|
21
|
-
fastapi_factory_utilities/core/plugins/
|
|
22
|
-
fastapi_factory_utilities/core/plugins/
|
|
23
|
-
fastapi_factory_utilities/core/plugins/
|
|
24
|
-
fastapi_factory_utilities/core/plugins/
|
|
14
|
+
fastapi_factory_utilities/core/app/fastapi_builder.py,sha256=7egWkS98nTiVBe2Bw5dQzDBryQCkz4w7gnY9HA24NFg,2855
|
|
15
|
+
fastapi_factory_utilities/core/exceptions.py,sha256=9s-i_RHPCsOswQPRvK8tyy-smE1118pytxWDJMNEl0M,2670
|
|
16
|
+
fastapi_factory_utilities/core/plugins/__init__.py,sha256=7ctIv2Jx2uOUpgm8ITFRuZxHi6OXvlVS0VcbszVzvis,114
|
|
17
|
+
fastapi_factory_utilities/core/plugins/abstracts.py,sha256=p5iXmeOVD737G73I2keKV0Y-jLGQf2vYbTSR1LgrA14,1165
|
|
18
|
+
fastapi_factory_utilities/core/plugins/aiopika/__init__.py,sha256=flXanbhbjFaOsgx7jZvtW0bVLT_NXHypIPFO1tIHoCM,705
|
|
19
|
+
fastapi_factory_utilities/core/plugins/aiopika/abstract.py,sha256=TcvDwdaLV0UqFHQy6Sn3Y5Fp-1463dhL7VNB9LTKL5I,1682
|
|
20
|
+
fastapi_factory_utilities/core/plugins/aiopika/configs.py,sha256=BEPE8Ss7q_yCyuii4nywmIgh67iNLdhKxUm8tC0PdCY,3706
|
|
21
|
+
fastapi_factory_utilities/core/plugins/aiopika/depends.py,sha256=5xna571hCIdqzbo0t1CW-yzmJMSpEw_KUeJh5nBXjwQ,761
|
|
22
|
+
fastapi_factory_utilities/core/plugins/aiopika/exceptions.py,sha256=AkBKT8HVPpJDAntLNlOLp6lpQpKI-k8gxNzU24FsOF0,985
|
|
23
|
+
fastapi_factory_utilities/core/plugins/aiopika/exchange.py,sha256=tQfrv7-mX4lrHY1OTXB_aTkbg_brYniIuFisfFDSTT8,2509
|
|
24
|
+
fastapi_factory_utilities/core/plugins/aiopika/listener/__init__.py,sha256=LsTyu6kGoUm7c5OvSQTDJL7d8CG9TeARBHHVe_HGsHY,148
|
|
25
|
+
fastapi_factory_utilities/core/plugins/aiopika/listener/abstract.py,sha256=cMRQwqCwa1kGs2PHXR5ws0-HLzqHC_XFZtu43Y7iTpA,2577
|
|
26
|
+
fastapi_factory_utilities/core/plugins/aiopika/message.py,sha256=Tn9pLZlkx238GA6SEav15Npq3TWu_dQ0NtzFWvPcPTM,2861
|
|
27
|
+
fastapi_factory_utilities/core/plugins/aiopika/plugins.py,sha256=0lLYt-ZG3g3m8wi1tCCPEhTUBqaXuEJOwHEcrvP7FYc,3284
|
|
28
|
+
fastapi_factory_utilities/core/plugins/aiopika/publisher/__init__.py,sha256=MGGdygH72xHZ4QAwvbUZKQt-_mPzLmMxHyAACSNnZ_c,151
|
|
29
|
+
fastapi_factory_utilities/core/plugins/aiopika/publisher/abstract.py,sha256=PmIG5zlx-tFUAneHtbknR0Ik5flz8pMTzxcreY2hZ7s,2494
|
|
30
|
+
fastapi_factory_utilities/core/plugins/aiopika/queue.py,sha256=u7iOOnv8EHO7q2qM6jDlYimajrjlQN8R3ftL61XgQIE,2794
|
|
31
|
+
fastapi_factory_utilities/core/plugins/odm_plugin/__init__.py,sha256=JsVz4GBiZRmm4qpUD1-Wsg2tRXTn-VO5fU-W1whZo4E,683
|
|
32
|
+
fastapi_factory_utilities/core/plugins/odm_plugin/builder.py,sha256=MdO1D0C9LQpoqtNFqgPwSYedLzXR6PArhkoJw6wzykg,8761
|
|
33
|
+
fastapi_factory_utilities/core/plugins/odm_plugin/configs.py,sha256=5bVbtsLwJhuIvt8FCzOvk002G8qFmZumWkN75bPKatc,331
|
|
25
34
|
fastapi_factory_utilities/core/plugins/odm_plugin/depends.py,sha256=OcLsfTLzMBk_xFV6qsMy_-qFkiphEbbEuaHUooagxg8,730
|
|
26
|
-
fastapi_factory_utilities/core/plugins/odm_plugin/documents.py,sha256=
|
|
35
|
+
fastapi_factory_utilities/core/plugins/odm_plugin/documents.py,sha256=4aQNrD26d0S542_LYmxxm07Q8SWzbGe3PCpho6iWY5Q,1102
|
|
27
36
|
fastapi_factory_utilities/core/plugins/odm_plugin/exceptions.py,sha256=acnKJB0lGAzDs-7-LjBap8shjP3iV1a7dw7ouPVF27o,551
|
|
28
|
-
fastapi_factory_utilities/core/plugins/odm_plugin/
|
|
29
|
-
fastapi_factory_utilities/core/plugins/
|
|
37
|
+
fastapi_factory_utilities/core/plugins/odm_plugin/helpers.py,sha256=s9iEujDZbTmTb9FByJAVUzLkjQpsciQT9dytkeosKuE,463
|
|
38
|
+
fastapi_factory_utilities/core/plugins/odm_plugin/plugins.py,sha256=0jsLtw4NxZB6bDcBLBvWHqB-RELoewsSXTJdAOGunSY,6443
|
|
39
|
+
fastapi_factory_utilities/core/plugins/odm_plugin/repositories.py,sha256=GJ3ovlxzTpiJ2_XlgARtwn6j0SbQxxAray_r8QWvGok,11313
|
|
40
|
+
fastapi_factory_utilities/core/plugins/opentelemetry_plugin/__init__.py,sha256=xXHn5dUxhgdDDQMpTHf3voolzS0E3zE2RFbtFHJzb38,641
|
|
30
41
|
fastapi_factory_utilities/core/plugins/opentelemetry_plugin/builder.py,sha256=9npQImifYAbEg0lFG7KwZ8V78SNrPoaINgd8vKitdMw,12509
|
|
31
42
|
fastapi_factory_utilities/core/plugins/opentelemetry_plugin/configs.py,sha256=pMG9leMB7rtdkdGFLIxXflV7bf9epGrrYPt2N97KZcM,3750
|
|
32
43
|
fastapi_factory_utilities/core/plugins/opentelemetry_plugin/exceptions.py,sha256=CpsHayfQpP0zghN8y5PP6TBy-cXhHoNxBR--I86gAdE,327
|
|
33
44
|
fastapi_factory_utilities/core/plugins/opentelemetry_plugin/helpers.py,sha256=qpTIzX67orJz7vy6SBIwRs24omMBoToJkhpurZRjPuk,1533
|
|
34
|
-
fastapi_factory_utilities/core/
|
|
35
|
-
fastapi_factory_utilities/core/
|
|
45
|
+
fastapi_factory_utilities/core/plugins/opentelemetry_plugin/instruments/__init__.py,sha256=lMtdd1DSDrFcXggf0qMpB1RJC7aBqWMpOBXxC8-bqPY,3307
|
|
46
|
+
fastapi_factory_utilities/core/plugins/opentelemetry_plugin/plugins.py,sha256=v9W4bqEljcRgeSL8pf-4yZ7SGXOFmxVoljthvcLdy6Q,5356
|
|
47
|
+
fastapi_factory_utilities/core/plugins/taskiq_plugins/__init__.py,sha256=6rjQJXYEsOOSP8Fhlc1oJJVnHBOAxkapUKTpbB2X-K0,776
|
|
48
|
+
fastapi_factory_utilities/core/plugins/taskiq_plugins/configs.py,sha256=O2rgFFWJNBUZ7ozfhM0Lj5Te-58qBNrQtw_N0mosAu4,304
|
|
49
|
+
fastapi_factory_utilities/core/plugins/taskiq_plugins/depends.py,sha256=XBxC1uUdMhYtqZDqmUEKI80y5L7mDoXXjN8dZjEvVAo,1602
|
|
50
|
+
fastapi_factory_utilities/core/plugins/taskiq_plugins/exceptions.py,sha256=1Xq_DqDFiQm2YU-2pGxziy-EeMhHiUsUwV0XdY_rQls,456
|
|
51
|
+
fastapi_factory_utilities/core/plugins/taskiq_plugins/plugin.py,sha256=gUlU2s7aLB2lkAAPdLqVc-BY16PessSYTGMGgNcKCSA,1602
|
|
52
|
+
fastapi_factory_utilities/core/plugins/taskiq_plugins/schedulers.py,sha256=82Yh7Y_MUxiWjrHPnsW_Ax-CWREAT6eC_bVl-HW5a3E,7208
|
|
53
|
+
fastapi_factory_utilities/core/protocols.py,sha256=w5FQqMAZ_OulG5hQWkoOapNSnxsjBPq4EjvWNXXdI_c,859
|
|
54
|
+
fastapi_factory_utilities/core/security/jwt.py,sha256=BrP9EmtuOxjafHKluYzRtGdZYankv72iQgG49t9TgJw,5640
|
|
36
55
|
fastapi_factory_utilities/core/security/kratos.py,sha256=yP9-TkELeXRPRYE9aQRlOPlwvaUJ7VQpyAea8ucWUfg,3364
|
|
37
56
|
fastapi_factory_utilities/core/services/hydra/__init__.py,sha256=AKBYNc3zW5OsCLLeFSXqmDbWbQefHUJxstLpsXLQEUQ,369
|
|
38
57
|
fastapi_factory_utilities/core/services/hydra/exceptions.py,sha256=ePMrfZturU2IVcxOebR0CbVKKqprce_fK-4UXbPPgNI,450
|
|
@@ -43,7 +62,7 @@ fastapi_factory_utilities/core/services/kratos/enums.py,sha256=ULJppowlZbOjdnUIX
|
|
|
43
62
|
fastapi_factory_utilities/core/services/kratos/exceptions.py,sha256=xAX01-lQvPpADgcwhB5YWSy1UqAxG38s2rlU9AJBJd8,472
|
|
44
63
|
fastapi_factory_utilities/core/services/kratos/objects.py,sha256=a0npt4Q6d9UbF0w3e6EvyKLwMWO2l639_dFjruA8_2c,980
|
|
45
64
|
fastapi_factory_utilities/core/services/kratos/services.py,sha256=RFKrME6M6omWiHORMBCSyvIG0BsimQaCfnmtsOdFfsg,3158
|
|
46
|
-
fastapi_factory_utilities/core/services/status/__init__.py,sha256=
|
|
65
|
+
fastapi_factory_utilities/core/services/status/__init__.py,sha256=kkR2Xx-kbHb_QXkkBSUNIK5y_eNM4YCElFftBAooIY0,370
|
|
47
66
|
fastapi_factory_utilities/core/services/status/enums.py,sha256=IUxWAd0Ecknri4BqzaqoDRRhT_8LdcgtQcNqgNVDXGE,599
|
|
48
67
|
fastapi_factory_utilities/core/services/status/exceptions.py,sha256=_fQFGqHKnG54Hs-ZtC4gs0xwzSH246_WwQOonraoGKw,856
|
|
49
68
|
fastapi_factory_utilities/core/services/status/health_calculator_strategies.py,sha256=p2KKJo-dq1j9iWHT0mvlBKtldH9m8l31aytLkUsb9nQ,1634
|
|
@@ -53,30 +72,30 @@ fastapi_factory_utilities/core/services/status/types.py,sha256=GJOGRra6NtpUS4q1c
|
|
|
53
72
|
fastapi_factory_utilities/core/utils/configs.py,sha256=qM0pCrsK8ZyfCoyova_VrhR4eUX3LSPCbWunGMWcSVg,2581
|
|
54
73
|
fastapi_factory_utilities/core/utils/importlib.py,sha256=DYcPo7K0s95WV5xxtucpufWsTj8Pxv25sWunDmmNUYI,797
|
|
55
74
|
fastapi_factory_utilities/core/utils/log.py,sha256=6V9CL3bQio4e47YxcSXM2JQRGhVxuBfmcEbcF4RtCfQ,6393
|
|
56
|
-
fastapi_factory_utilities/core/utils/status.py,sha256=
|
|
75
|
+
fastapi_factory_utilities/core/utils/status.py,sha256=ADdi4NzkJy0qNVC86tKV09wdpuPhuCKSrvYn9tzNVn8,1934
|
|
57
76
|
fastapi_factory_utilities/core/utils/uvicorn.py,sha256=XThylG-nOPVL00w6MIWGODnweoM7VxmpSFcyoPcmqns,2609
|
|
58
|
-
fastapi_factory_utilities/core/utils/yaml_reader.py,sha256=
|
|
77
|
+
fastapi_factory_utilities/core/utils/yaml_reader.py,sha256=2XenSHqymZsgff70upPZtyx0-BsiUdTENKmrxaOBLeE,6100
|
|
59
78
|
fastapi_factory_utilities/example/__init__.py,sha256=LEKnPTBcgDyfHeOjlVxjK5lFdFqS-7-mHDuVuM2Jh_Y,206
|
|
60
79
|
fastapi_factory_utilities/example/__main__.py,sha256=Iwp_6rK7Lcv2F-XAKn6xjxQHOWjx2OjgwKAr91tfUfk,135
|
|
61
80
|
fastapi_factory_utilities/example/api/__init__.py,sha256=qI82eeSwVjR6jSkX1pxm8ALv9WPQ_iHurFY4G2K7VzE,554
|
|
62
81
|
fastapi_factory_utilities/example/api/books/__init__.py,sha256=zXARBnjywJwg1XsLbcixYWcHH4uC9mF-kbbX4P8cVgA,160
|
|
63
82
|
fastapi_factory_utilities/example/api/books/responses.py,sha256=21WeD6bdg0MCD_0vRHwmsL4W79iDcG9NnDLemXysc84,540
|
|
64
83
|
fastapi_factory_utilities/example/api/books/routes.py,sha256=bwg8Bhvoj9vx2SdwunzFS-Z3cHECtjl_yGdo8MfiGEM,1529
|
|
65
|
-
fastapi_factory_utilities/example/app.py,sha256=
|
|
84
|
+
fastapi_factory_utilities/example/app.py,sha256=MInt71wnDEC9yqVJeT3hChj7DRmg7sI3Ta0KkfubdyU,2076
|
|
66
85
|
fastapi_factory_utilities/example/application.yaml,sha256=5xRyFSuMxmgZ5Mikai94UqKYJ7PxJp8omlXobTjv14M,485
|
|
67
|
-
fastapi_factory_utilities/example/entities/books/__init__.py,sha256=
|
|
86
|
+
fastapi_factory_utilities/example/entities/books/__init__.py,sha256=cpTMhLpenb359lOT9HHUv6DzKX8fKl4WCzcsB3ddk6Q,185
|
|
68
87
|
fastapi_factory_utilities/example/entities/books/entities.py,sha256=rLE01lE7U6WizrD5ZHMRwkynd8_dWF6DltBFH61f-Do,405
|
|
69
88
|
fastapi_factory_utilities/example/entities/books/enums.py,sha256=lXYUvhIkT1pi0teflMpnqeafeiBZMokyWxoFLgzV6a8,330
|
|
70
89
|
fastapi_factory_utilities/example/entities/books/types.py,sha256=7LYGPu-CcI3noIORJyIZlVF-CBugWPXEqgDzWrO3XmQ,1558
|
|
71
90
|
fastapi_factory_utilities/example/models/__init__.py,sha256=RJmp3R9bhbQv7n0WOlsHP65LqbEs_DjF9hzYKwYTRGo,22
|
|
72
|
-
fastapi_factory_utilities/example/models/books/__init__.py,sha256=
|
|
91
|
+
fastapi_factory_utilities/example/models/books/__init__.py,sha256=IPS3rLLnZncV-VAxgsipxUD7l4r04ewo_Hx2Naj2lT0,181
|
|
73
92
|
fastapi_factory_utilities/example/models/books/document.py,sha256=lYJfMGr5GqEEsn7L--PFs75hC2q-jQx77wl7EhTrp5U,568
|
|
74
93
|
fastapi_factory_utilities/example/models/books/repository.py,sha256=7K63uAsSEGZ2EXqufU4Tc8KpymgXK8JX8WjAE2Sw8ok,387
|
|
75
94
|
fastapi_factory_utilities/example/services/books/__init__.py,sha256=Z06yNRoA7Zg3TGN-Q9rrvJg6Bbx-qJw661MVwukV6vQ,148
|
|
76
95
|
fastapi_factory_utilities/example/services/books/services.py,sha256=-x7d4hotUWLzWo5uImMjFmtNcSTHwWv2bfttIbYYKbA,5380
|
|
77
96
|
fastapi_factory_utilities/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
78
|
-
fastapi_factory_utilities-0.
|
|
79
|
-
fastapi_factory_utilities-0.
|
|
80
|
-
fastapi_factory_utilities-0.
|
|
81
|
-
fastapi_factory_utilities-0.
|
|
82
|
-
fastapi_factory_utilities-0.
|
|
97
|
+
fastapi_factory_utilities-0.7.1.dist-info/METADATA,sha256=Qa2ulopX-2Fb4an_JoqjlEMZRwyfeMPKAv0GfCvHv7g,3741
|
|
98
|
+
fastapi_factory_utilities-0.7.1.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
|
99
|
+
fastapi_factory_utilities-0.7.1.dist-info/entry_points.txt,sha256=IK0VcBexXo4uXQmTrbfhhnnfq4GmXPRn0GBB8hzlsq4,101
|
|
100
|
+
fastapi_factory_utilities-0.7.1.dist-info/licenses/LICENSE,sha256=iO1nLzMMst6vEiqgSUrfrbetM7b0bvdzXhbed5tqG8o,1074
|
|
101
|
+
fastapi_factory_utilities-0.7.1.dist-info/RECORD,,
|