fastapi-factory-utilities 0.2.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 +12 -3
- fastapi_factory_utilities/core/app/application.py +24 -26
- fastapi_factory_utilities/core/app/builder.py +23 -37
- fastapi_factory_utilities/core/app/config.py +22 -1
- fastapi_factory_utilities/core/app/fastapi_builder.py +3 -2
- fastapi_factory_utilities/core/exceptions.py +58 -22
- 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 +25 -153
- fastapi_factory_utilities/core/plugins/odm_plugin/builder.py +59 -31
- fastapi_factory_utilities/core/plugins/odm_plugin/configs.py +1 -1
- fastapi_factory_utilities/core/plugins/odm_plugin/documents.py +2 -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 +112 -3
- fastapi_factory_utilities/core/plugins/opentelemetry_plugin/__init__.py +8 -115
- fastapi_factory_utilities/core/plugins/opentelemetry_plugin/builder.py +65 -14
- fastapi_factory_utilities/core/plugins/opentelemetry_plugin/configs.py +13 -0
- 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 +159 -0
- fastapi_factory_utilities/core/security/kratos.py +98 -0
- fastapi_factory_utilities/core/services/hydra/__init__.py +13 -0
- fastapi_factory_utilities/core/services/hydra/exceptions.py +15 -0
- fastapi_factory_utilities/core/services/hydra/objects.py +26 -0
- fastapi_factory_utilities/core/services/hydra/services.py +122 -0
- fastapi_factory_utilities/core/services/kratos/__init__.py +13 -0
- fastapi_factory_utilities/core/services/kratos/enums.py +11 -0
- fastapi_factory_utilities/core/services/kratos/exceptions.py +15 -0
- fastapi_factory_utilities/core/services/kratos/objects.py +43 -0
- fastapi_factory_utilities/core/services/kratos/services.py +86 -0
- fastapi_factory_utilities/core/services/status/__init__.py +2 -2
- fastapi_factory_utilities/core/utils/status.py +2 -1
- fastapi_factory_utilities/core/utils/uvicorn.py +36 -0
- fastapi_factory_utilities/core/utils/yaml_reader.py +2 -2
- 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/py.typed +0 -0
- {fastapi_factory_utilities-0.2.0.dist-info → fastapi_factory_utilities-0.7.1.dist-info}/METADATA +23 -14
- fastapi_factory_utilities-0.7.1.dist-info/RECORD +101 -0
- {fastapi_factory_utilities-0.2.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.2.0.dist-info/RECORD +0 -70
- {fastapi_factory_utilities-0.2.0.dist-info → fastapi_factory_utilities-0.7.1.dist-info}/entry_points.txt +0 -0
- {fastapi_factory_utilities-0.2.0.dist-info → fastapi_factory_utilities-0.7.1.dist-info/licenses}/LICENSE +0 -0
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"""Provides a service to interact with the Hydra service."""
|
|
2
|
+
|
|
3
|
+
from base64 import b64encode
|
|
4
|
+
from http import HTTPStatus
|
|
5
|
+
from typing import Annotated
|
|
6
|
+
|
|
7
|
+
import aiohttp
|
|
8
|
+
from fastapi import Depends
|
|
9
|
+
from pydantic import ValidationError
|
|
10
|
+
|
|
11
|
+
from fastapi_factory_utilities.core.app import (
|
|
12
|
+
DependencyConfig,
|
|
13
|
+
HttpServiceDependencyConfig,
|
|
14
|
+
depends_dependency_config,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
from .exceptions import HydraOperationError, HydraTokenInvalidError
|
|
18
|
+
from .objects import HydraTokenIntrospectObject
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class HydraService:
|
|
22
|
+
"""Service to interact with the Hydra service."""
|
|
23
|
+
|
|
24
|
+
INTROSPECT_ENDPOINT: str = "/admin/oauth2/introspect"
|
|
25
|
+
CLIENT_CREDENTIALS_ENDPOINT: str = "/oauth2/token"
|
|
26
|
+
|
|
27
|
+
def __init__(
|
|
28
|
+
self,
|
|
29
|
+
hydra_admin_http_config: HttpServiceDependencyConfig,
|
|
30
|
+
hydra_public_http_config: HttpServiceDependencyConfig,
|
|
31
|
+
) -> None:
|
|
32
|
+
"""Instanciate the Hydra service.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
hydra_admin_http_config (HttpServiceDependencyConfig): The Hydra admin HTTP configuration.
|
|
36
|
+
hydra_public_http_config (HttpServiceDependencyConfig): The Hydra public HTTP configuration.
|
|
37
|
+
"""
|
|
38
|
+
self._hydra_admin_http_config: HttpServiceDependencyConfig = hydra_admin_http_config
|
|
39
|
+
self._hydra_public_http_config: HttpServiceDependencyConfig = hydra_public_http_config
|
|
40
|
+
|
|
41
|
+
async def introspect(self, token: str) -> HydraTokenIntrospectObject:
|
|
42
|
+
"""Introspects a token using the Hydra service.
|
|
43
|
+
|
|
44
|
+
Args:
|
|
45
|
+
token (str): The token to introspect.
|
|
46
|
+
|
|
47
|
+
Raises:
|
|
48
|
+
HydraOperationError: If the introspection fails.
|
|
49
|
+
HydraTokenInvalidError: If the token is invalid.
|
|
50
|
+
"""
|
|
51
|
+
async with aiohttp.ClientSession(
|
|
52
|
+
base_url=str(self._hydra_admin_http_config.url),
|
|
53
|
+
) as session:
|
|
54
|
+
async with session.post(
|
|
55
|
+
url=self.INTROSPECT_ENDPOINT,
|
|
56
|
+
data={"token": token},
|
|
57
|
+
) as response:
|
|
58
|
+
if response.status != HTTPStatus.OK:
|
|
59
|
+
raise HydraTokenInvalidError()
|
|
60
|
+
|
|
61
|
+
try:
|
|
62
|
+
instrospect: HydraTokenIntrospectObject = HydraTokenIntrospectObject(**await response.json())
|
|
63
|
+
except ValidationError as error:
|
|
64
|
+
raise HydraOperationError() from error
|
|
65
|
+
|
|
66
|
+
return instrospect
|
|
67
|
+
|
|
68
|
+
async def oauth2_client_credentials(self, client_id: str, client_secret: str, scope: str) -> str:
|
|
69
|
+
"""Get the OAuth2 client credentials.
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
client_id (str): The client ID.
|
|
73
|
+
client_secret (str): The client secret.
|
|
74
|
+
scope (str): The scope.
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
str: The access token.
|
|
78
|
+
|
|
79
|
+
Raises:
|
|
80
|
+
HydraOperationError: If the client credentials request fails.
|
|
81
|
+
"""
|
|
82
|
+
# Create base64 encoded Basic Auth header
|
|
83
|
+
auth_string = f"{client_id}:{client_secret}"
|
|
84
|
+
auth_bytes = auth_string.encode("utf-8")
|
|
85
|
+
auth_b64 = b64encode(auth_bytes).decode("utf-8")
|
|
86
|
+
|
|
87
|
+
async with aiohttp.ClientSession(
|
|
88
|
+
base_url=str(self._hydra_public_http_config.url),
|
|
89
|
+
) as session:
|
|
90
|
+
async with session.post(
|
|
91
|
+
url=self.CLIENT_CREDENTIALS_ENDPOINT,
|
|
92
|
+
headers={"Authorization": f"Basic {auth_b64}"},
|
|
93
|
+
data={"grant_type": "client_credentials", "scope": scope},
|
|
94
|
+
) as response:
|
|
95
|
+
response_data = await response.json()
|
|
96
|
+
if response.status != HTTPStatus.OK:
|
|
97
|
+
raise HydraOperationError(f"Failed to get client credentials: {response_data}")
|
|
98
|
+
|
|
99
|
+
return response_data["access_token"]
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def depends_hydra_service(
|
|
103
|
+
dependency_config: Annotated[DependencyConfig, Depends(depends_dependency_config)],
|
|
104
|
+
) -> HydraService:
|
|
105
|
+
"""Dependency injection for the Hydra service.
|
|
106
|
+
|
|
107
|
+
Args:
|
|
108
|
+
dependency_config (DependencyConfig): The dependency configuration.
|
|
109
|
+
|
|
110
|
+
Returns:
|
|
111
|
+
HydraService: The Hydra service instance.
|
|
112
|
+
|
|
113
|
+
Raises:
|
|
114
|
+
HydraOperationError: If the Hydra admin or public dependency is not configured.
|
|
115
|
+
"""
|
|
116
|
+
if dependency_config.hydra_admin is None or dependency_config.hydra_public is None:
|
|
117
|
+
raise HydraOperationError(message="Hydra admin or public dependency not configured")
|
|
118
|
+
|
|
119
|
+
return HydraService(
|
|
120
|
+
hydra_admin_http_config=dependency_config.hydra_admin,
|
|
121
|
+
hydra_public_http_config=dependency_config.hydra_public,
|
|
122
|
+
)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""Kratos service module."""
|
|
2
|
+
|
|
3
|
+
from .exceptions import KratosOperationError, KratosSessionInvalidError
|
|
4
|
+
from .objects import KratosSessionObject
|
|
5
|
+
from .services import KratosService, depends_kratos_service
|
|
6
|
+
|
|
7
|
+
__all__: list[str] = [
|
|
8
|
+
"KratosOperationError",
|
|
9
|
+
"KratosService",
|
|
10
|
+
"KratosSessionInvalidError",
|
|
11
|
+
"KratosSessionObject",
|
|
12
|
+
"depends_kratos_service",
|
|
13
|
+
]
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"""Python exceptions for the Kratos service."""
|
|
2
|
+
|
|
3
|
+
from fastapi_factory_utilities.core.exceptions import FastAPIFactoryUtilitiesError
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class KratosError(FastAPIFactoryUtilitiesError):
|
|
7
|
+
"""Base class for all exceptions raised by the Kratos service."""
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class KratosOperationError(KratosError):
|
|
11
|
+
"""Exception raised when a Kratos operation fails."""
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class KratosSessionInvalidError(KratosOperationError):
|
|
15
|
+
"""Exception raised when a Kratos session is invalid."""
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"""Provides the Kratos Objects."""
|
|
2
|
+
|
|
3
|
+
import datetime
|
|
4
|
+
import uuid
|
|
5
|
+
from typing import ClassVar
|
|
6
|
+
|
|
7
|
+
from pydantic import BaseModel, ConfigDict
|
|
8
|
+
|
|
9
|
+
from .enums import AuthenticatorAssuranceLevelEnum
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class KratosTraitsObject(BaseModel):
|
|
13
|
+
"""Traits for Kratos."""
|
|
14
|
+
|
|
15
|
+
model_config: ClassVar[ConfigDict] = ConfigDict(extra="ignore")
|
|
16
|
+
|
|
17
|
+
email: str
|
|
18
|
+
username: str
|
|
19
|
+
realm_id: uuid.UUID
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class KratosIdentityObject(BaseModel):
|
|
23
|
+
"""Identity for Kratos."""
|
|
24
|
+
|
|
25
|
+
model_config: ClassVar[ConfigDict] = ConfigDict(extra="ignore")
|
|
26
|
+
|
|
27
|
+
id: uuid.UUID
|
|
28
|
+
state: str
|
|
29
|
+
traits: KratosTraitsObject
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class KratosSessionObject(BaseModel):
|
|
33
|
+
"""Session object for Kratos."""
|
|
34
|
+
|
|
35
|
+
model_config: ClassVar[ConfigDict] = ConfigDict(extra="ignore")
|
|
36
|
+
|
|
37
|
+
id: uuid.UUID
|
|
38
|
+
active: bool
|
|
39
|
+
issued_at: datetime.datetime
|
|
40
|
+
expires_at: datetime.datetime
|
|
41
|
+
authenticated_at: datetime.datetime
|
|
42
|
+
authenticator_assurance_level: AuthenticatorAssuranceLevelEnum
|
|
43
|
+
identity: KratosIdentityObject
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"""Provides the KratosService class for handling Kratos operations."""
|
|
2
|
+
|
|
3
|
+
from http import HTTPStatus
|
|
4
|
+
from typing import Annotated
|
|
5
|
+
|
|
6
|
+
import aiohttp
|
|
7
|
+
from fastapi import Depends
|
|
8
|
+
from pydantic import ValidationError
|
|
9
|
+
|
|
10
|
+
from fastapi_factory_utilities.core.app import (
|
|
11
|
+
DependencyConfig,
|
|
12
|
+
HttpServiceDependencyConfig,
|
|
13
|
+
depends_dependency_config,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
from .exceptions import KratosOperationError, KratosSessionInvalidError
|
|
17
|
+
from .objects import KratosSessionObject
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class KratosService:
|
|
21
|
+
"""Service class for handling Kratos operations."""
|
|
22
|
+
|
|
23
|
+
COOKIE_NAME: str = "ory_kratos_session"
|
|
24
|
+
|
|
25
|
+
def __init__(self, kratos_http_config: HttpServiceDependencyConfig) -> None:
|
|
26
|
+
"""Initialize the KratosService class.
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
kratos_http_config (HttpServiceDependencyConfig): Kratos HTTP configuration.
|
|
30
|
+
"""
|
|
31
|
+
self._http_config: HttpServiceDependencyConfig = kratos_http_config
|
|
32
|
+
|
|
33
|
+
async def whoami(self, cookie_value: str) -> KratosSessionObject:
|
|
34
|
+
"""Get the current user session.
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
cookie_value (str): Cookie value.
|
|
38
|
+
|
|
39
|
+
Returns:
|
|
40
|
+
KratosSessionObject: Kratos session object.
|
|
41
|
+
|
|
42
|
+
Raises:
|
|
43
|
+
KratosOperationError: If the Kratos service returns an error.
|
|
44
|
+
KratosSessionInvalidError: If the Kratos session is invalid.
|
|
45
|
+
"""
|
|
46
|
+
cookies: dict[str, str] = {self.COOKIE_NAME: cookie_value}
|
|
47
|
+
async with aiohttp.ClientSession(base_url=str(self._http_config.url), cookies=cookies) as session:
|
|
48
|
+
async with session.get(
|
|
49
|
+
url="/sessions/whoami",
|
|
50
|
+
) as response:
|
|
51
|
+
if response.status >= HTTPStatus.INTERNAL_SERVER_ERROR.value:
|
|
52
|
+
raise KratosOperationError(message=f"Kratos service error: {response.status} - {response.reason}")
|
|
53
|
+
if response.status == HTTPStatus.UNAUTHORIZED:
|
|
54
|
+
raise KratosSessionInvalidError(
|
|
55
|
+
message=f"Kratos session invalid: {response.status} - {response.reason}"
|
|
56
|
+
)
|
|
57
|
+
if response.status != HTTPStatus.OK:
|
|
58
|
+
raise KratosOperationError(message=f"Kratos service error: {response.status} - {response.reason}")
|
|
59
|
+
|
|
60
|
+
try:
|
|
61
|
+
kratos_session: KratosSessionObject = KratosSessionObject(**await response.json())
|
|
62
|
+
except ValidationError as e:
|
|
63
|
+
raise KratosOperationError(message=f"Kratos service error: {e}") from e
|
|
64
|
+
|
|
65
|
+
return kratos_session
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def depends_kratos_service(
|
|
69
|
+
dependency_config: Annotated[DependencyConfig, Depends(depends_dependency_config)],
|
|
70
|
+
) -> KratosService:
|
|
71
|
+
"""Dependency function to get the Kratos service instance.
|
|
72
|
+
|
|
73
|
+
Args:
|
|
74
|
+
dependency_config (DependencyConfig): Dependency configuration.
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
KratosService: Kratos service instance.
|
|
78
|
+
|
|
79
|
+
Raises:
|
|
80
|
+
KratosOperationError: If the Kratos dependency is not configured.
|
|
81
|
+
"""
|
|
82
|
+
if dependency_config.kratos is None:
|
|
83
|
+
raise KratosOperationError(message="Kratos dependency not configured")
|
|
84
|
+
return KratosService(
|
|
85
|
+
kratos_http_config=dependency_config.kratos,
|
|
86
|
+
)
|
|
@@ -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
|
]
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
"""Provides utilities for the application."""
|
|
2
2
|
|
|
3
|
+
import os
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
3
6
|
import uvicorn
|
|
4
7
|
import uvicorn.server
|
|
5
8
|
|
|
@@ -20,6 +23,29 @@ class UvicornUtils:
|
|
|
20
23
|
None
|
|
21
24
|
"""
|
|
22
25
|
self._app: ApplicationAbstractProtocol = app
|
|
26
|
+
self._ssl_keyfile: str | os.PathLike[str] | None = None
|
|
27
|
+
self._ssl_certfile: str | os.PathLike[str] | None = None
|
|
28
|
+
self._ssl_keyfile_password: str | None = None
|
|
29
|
+
|
|
30
|
+
def add_ssl_certificates(
|
|
31
|
+
self,
|
|
32
|
+
ssl_keyfile: str | os.PathLike[str] | None = None,
|
|
33
|
+
ssl_certfile: str | os.PathLike[str] | None = None,
|
|
34
|
+
ssl_keyfile_password: str | None = None,
|
|
35
|
+
) -> None:
|
|
36
|
+
"""Add SSL certificates to the application.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
ssl_keyfile (str | os.PathLike[str] | None): The SSL key file.
|
|
40
|
+
ssl_certfile (str | os.PathLike[str] | None): The SSL certificate file.
|
|
41
|
+
ssl_keyfile_password (str | None): The SSL key file password.
|
|
42
|
+
|
|
43
|
+
Returns:
|
|
44
|
+
None
|
|
45
|
+
"""
|
|
46
|
+
self._ssl_keyfile = ssl_keyfile
|
|
47
|
+
self._ssl_certfile = ssl_certfile
|
|
48
|
+
self._ssl_keyfile_password = ssl_keyfile_password
|
|
23
49
|
|
|
24
50
|
def build_uvicorn_config(self) -> uvicorn.Config:
|
|
25
51
|
"""Build the Uvicorn configuration.
|
|
@@ -27,12 +53,22 @@ class UvicornUtils:
|
|
|
27
53
|
Returns:
|
|
28
54
|
uvicorn.Config: The Uvicorn configuration.
|
|
29
55
|
"""
|
|
56
|
+
kwargs: dict[str, Any] = {}
|
|
57
|
+
|
|
58
|
+
if self._ssl_keyfile:
|
|
59
|
+
kwargs["ssl_keyfile"] = self._ssl_keyfile
|
|
60
|
+
if self._ssl_certfile:
|
|
61
|
+
kwargs["ssl_certfile"] = self._ssl_certfile
|
|
62
|
+
if self._ssl_keyfile_password:
|
|
63
|
+
kwargs["ssl_keyfile_password"] = self._ssl_keyfile_password
|
|
64
|
+
|
|
30
65
|
config = uvicorn.Config(
|
|
31
66
|
app=self._app.get_asgi_app(),
|
|
32
67
|
host=self._app.get_config().server.host,
|
|
33
68
|
port=self._app.get_config().server.port,
|
|
34
69
|
reload=self._app.get_config().development.reload,
|
|
35
70
|
workers=self._app.get_config().server.workers,
|
|
71
|
+
**kwargs,
|
|
36
72
|
)
|
|
37
73
|
clean_uvicorn_logger()
|
|
38
74
|
return config
|
|
@@ -29,7 +29,7 @@ class UnableToReadYamlFileError(Exception):
|
|
|
29
29
|
class YamlFileReader:
|
|
30
30
|
"""Handles reading YAML files and converting them to Pydantic models."""
|
|
31
31
|
|
|
32
|
-
re_pattern: re.Pattern[str] = re.compile(r"\${([A-Za-z0-9\-\_]+):?([A-Za-z0-9\-\_
|
|
32
|
+
re_pattern: re.Pattern[str] = re.compile(r"\${([A-Za-z0-9\-\_]+):?([A-Za-z0-9\-\_\/\:\.]*)?}")
|
|
33
33
|
|
|
34
34
|
def __init__(
|
|
35
35
|
self,
|
|
@@ -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)
|
|
File without changes
|
{fastapi_factory_utilities-0.2.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,23 +19,31 @@ 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
|
|
21
|
-
Requires-Dist:
|
|
22
|
-
Requires-Dist:
|
|
23
|
-
Requires-Dist:
|
|
22
|
+
Requires-Dist: aio-pika (>=9.5.7,<10.0.0)
|
|
23
|
+
Requires-Dist: aiohttp[speedups] (>=3.12.13,<4.0.0)
|
|
24
|
+
Requires-Dist: beanie (>=1.30.0,<2.0.0)
|
|
25
|
+
Requires-Dist: fastapi (>=0.115.13,<1)
|
|
26
|
+
Requires-Dist: opentelemetry-exporter-otlp-proto-grpc (>=1.26.0,<2.0.0)
|
|
24
27
|
Requires-Dist: opentelemetry-exporter-otlp-proto-http (>=1.26.0,<2.0.0)
|
|
25
|
-
Requires-Dist: opentelemetry-instrumentation-
|
|
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)
|
|
30
|
+
Requires-Dist: opentelemetry-instrumentation-fastapi (>=0,<1)
|
|
31
|
+
Requires-Dist: opentelemetry-instrumentation-pymongo (>=0,<1)
|
|
27
32
|
Requires-Dist: opentelemetry-propagator-b3 (>=1.26.0,<2.0.0)
|
|
28
33
|
Requires-Dist: opentelemetry-sdk (>=1.26.0,<2.0.0)
|
|
29
34
|
Requires-Dist: pyaml (>=25.1.0,<26.0.0)
|
|
30
35
|
Requires-Dist: pydantic (>=2.8.2,<3.0.0)
|
|
31
|
-
Requires-Dist:
|
|
36
|
+
Requires-Dist: pyjwt (>=2.10.1,<3.0.0)
|
|
37
|
+
Requires-Dist: pymongo (>=4.9.2,<4.16.0)
|
|
32
38
|
Requires-Dist: reactivex (>=4.0.4,<5.0.0)
|
|
33
39
|
Requires-Dist: structlog (>=24.1,<26.0)
|
|
34
|
-
Requires-Dist:
|
|
35
|
-
Requires-Dist:
|
|
36
|
-
|
|
37
|
-
|
|
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)
|
|
43
|
+
Requires-Dist: typer (>=0,<1)
|
|
44
|
+
Requires-Dist: uvicorn (>=0.34.3,<1)
|
|
45
|
+
Project-URL: Homepage, https://github.com/DeerHide/fastapi_factory_utilities
|
|
46
|
+
Project-URL: Repository, https://github.com/DeerHide/fastapi_factory_utilities
|
|
38
47
|
Description-Content-Type: text/markdown
|
|
39
48
|
|
|
40
49
|
# fastapi_factory_utilities
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
fastapi_factory_utilities/__main__.py,sha256=w8o9KpyHcxGyLHmTK8ixbIqJIsB3NbIGuAMY7OfnxrA,147
|
|
2
|
+
fastapi_factory_utilities/core/__init__.py,sha256=tt5a-MgeFt_oACkc9K5xl2rynIbca9DGqsKBDEqGzto,34
|
|
3
|
+
fastapi_factory_utilities/core/api/__init__.py,sha256=fAwgRcRry1nIyAL7CsCbpwR87n5tWnBWKEPH6QZCpp8,542
|
|
4
|
+
fastapi_factory_utilities/core/api/tags.py,sha256=3hQcTeW0FS78sPTJ2PB44dMDTSkoW-xKj7rrfKX2Lk0,154
|
|
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=LILUwfyqeBDlf4GSpkU_3bxMjZPCLanOBkMGDKtQufY,2867
|
|
7
|
+
fastapi_factory_utilities/core/api/v1/sys/readiness.py,sha256=xIY8pQLShU7KWRtlOUK5gTDyZ8aB1KBvLczC6boT-tg,1711
|
|
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
|
+
fastapi_factory_utilities/core/app/config.py,sha256=MuV4G_M4QgZWYHoulusJLv_m4Qr2php-Cg9Jum4qkNA,7303
|
|
12
|
+
fastapi_factory_utilities/core/app/enums.py,sha256=X1upnaehYU0eHExXTde5xsH-pI9q7HZDNsOEF5PApdg,226
|
|
13
|
+
fastapi_factory_utilities/core/app/exceptions.py,sha256=tQDf0_4j5xgCbku7TL7JaZGs3_bjsWG2YLBCydQJpPw,664
|
|
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
|
|
34
|
+
fastapi_factory_utilities/core/plugins/odm_plugin/depends.py,sha256=OcLsfTLzMBk_xFV6qsMy_-qFkiphEbbEuaHUooagxg8,730
|
|
35
|
+
fastapi_factory_utilities/core/plugins/odm_plugin/documents.py,sha256=4aQNrD26d0S542_LYmxxm07Q8SWzbGe3PCpho6iWY5Q,1102
|
|
36
|
+
fastapi_factory_utilities/core/plugins/odm_plugin/exceptions.py,sha256=acnKJB0lGAzDs-7-LjBap8shjP3iV1a7dw7ouPVF27o,551
|
|
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
|
|
41
|
+
fastapi_factory_utilities/core/plugins/opentelemetry_plugin/builder.py,sha256=9npQImifYAbEg0lFG7KwZ8V78SNrPoaINgd8vKitdMw,12509
|
|
42
|
+
fastapi_factory_utilities/core/plugins/opentelemetry_plugin/configs.py,sha256=pMG9leMB7rtdkdGFLIxXflV7bf9epGrrYPt2N97KZcM,3750
|
|
43
|
+
fastapi_factory_utilities/core/plugins/opentelemetry_plugin/exceptions.py,sha256=CpsHayfQpP0zghN8y5PP6TBy-cXhHoNxBR--I86gAdE,327
|
|
44
|
+
fastapi_factory_utilities/core/plugins/opentelemetry_plugin/helpers.py,sha256=qpTIzX67orJz7vy6SBIwRs24omMBoToJkhpurZRjPuk,1533
|
|
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
|
|
55
|
+
fastapi_factory_utilities/core/security/kratos.py,sha256=yP9-TkELeXRPRYE9aQRlOPlwvaUJ7VQpyAea8ucWUfg,3364
|
|
56
|
+
fastapi_factory_utilities/core/services/hydra/__init__.py,sha256=AKBYNc3zW5OsCLLeFSXqmDbWbQefHUJxstLpsXLQEUQ,369
|
|
57
|
+
fastapi_factory_utilities/core/services/hydra/exceptions.py,sha256=ePMrfZturU2IVcxOebR0CbVKKqprce_fK-4UXbPPgNI,450
|
|
58
|
+
fastapi_factory_utilities/core/services/hydra/objects.py,sha256=2CeV_4zmwwpfbXQ0TM9B_UnNkZuIRXweFP_VALBo57c,601
|
|
59
|
+
fastapi_factory_utilities/core/services/hydra/services.py,sha256=Urc98pM23OatHr_WdgrpK1U4E2qsjF1fpXo0xnNjZ60,4411
|
|
60
|
+
fastapi_factory_utilities/core/services/kratos/__init__.py,sha256=DaC29-Ol0WR5vX56IHLGDXP9UrhISq0Juhg_sJTasw4,368
|
|
61
|
+
fastapi_factory_utilities/core/services/kratos/enums.py,sha256=ULJppowlZbOjdnUIXQyI4_nHmHZoNnv7-M1CYQBYXFY,220
|
|
62
|
+
fastapi_factory_utilities/core/services/kratos/exceptions.py,sha256=xAX01-lQvPpADgcwhB5YWSy1UqAxG38s2rlU9AJBJd8,472
|
|
63
|
+
fastapi_factory_utilities/core/services/kratos/objects.py,sha256=a0npt4Q6d9UbF0w3e6EvyKLwMWO2l639_dFjruA8_2c,980
|
|
64
|
+
fastapi_factory_utilities/core/services/kratos/services.py,sha256=RFKrME6M6omWiHORMBCSyvIG0BsimQaCfnmtsOdFfsg,3158
|
|
65
|
+
fastapi_factory_utilities/core/services/status/__init__.py,sha256=kkR2Xx-kbHb_QXkkBSUNIK5y_eNM4YCElFftBAooIY0,370
|
|
66
|
+
fastapi_factory_utilities/core/services/status/enums.py,sha256=IUxWAd0Ecknri4BqzaqoDRRhT_8LdcgtQcNqgNVDXGE,599
|
|
67
|
+
fastapi_factory_utilities/core/services/status/exceptions.py,sha256=_fQFGqHKnG54Hs-ZtC4gs0xwzSH246_WwQOonraoGKw,856
|
|
68
|
+
fastapi_factory_utilities/core/services/status/health_calculator_strategies.py,sha256=p2KKJo-dq1j9iWHT0mvlBKtldH9m8l31aytLkUsb9nQ,1634
|
|
69
|
+
fastapi_factory_utilities/core/services/status/readiness_calculator_strategies.py,sha256=hA1LX2pSxva-7bVaQ0dw8NpTbl1ZWDtXd9xzqQUGUsI,1354
|
|
70
|
+
fastapi_factory_utilities/core/services/status/services.py,sha256=qtgYdnxNQMbb6q6G9uGasRO3lZcpiWNmw1padPkh6jA,8490
|
|
71
|
+
fastapi_factory_utilities/core/services/status/types.py,sha256=GJOGRra6NtpUS4q1cr4cdWR0BbIUtEwP7vQX-sXX5jQ,3297
|
|
72
|
+
fastapi_factory_utilities/core/utils/configs.py,sha256=qM0pCrsK8ZyfCoyova_VrhR4eUX3LSPCbWunGMWcSVg,2581
|
|
73
|
+
fastapi_factory_utilities/core/utils/importlib.py,sha256=DYcPo7K0s95WV5xxtucpufWsTj8Pxv25sWunDmmNUYI,797
|
|
74
|
+
fastapi_factory_utilities/core/utils/log.py,sha256=6V9CL3bQio4e47YxcSXM2JQRGhVxuBfmcEbcF4RtCfQ,6393
|
|
75
|
+
fastapi_factory_utilities/core/utils/status.py,sha256=ADdi4NzkJy0qNVC86tKV09wdpuPhuCKSrvYn9tzNVn8,1934
|
|
76
|
+
fastapi_factory_utilities/core/utils/uvicorn.py,sha256=XThylG-nOPVL00w6MIWGODnweoM7VxmpSFcyoPcmqns,2609
|
|
77
|
+
fastapi_factory_utilities/core/utils/yaml_reader.py,sha256=2XenSHqymZsgff70upPZtyx0-BsiUdTENKmrxaOBLeE,6100
|
|
78
|
+
fastapi_factory_utilities/example/__init__.py,sha256=LEKnPTBcgDyfHeOjlVxjK5lFdFqS-7-mHDuVuM2Jh_Y,206
|
|
79
|
+
fastapi_factory_utilities/example/__main__.py,sha256=Iwp_6rK7Lcv2F-XAKn6xjxQHOWjx2OjgwKAr91tfUfk,135
|
|
80
|
+
fastapi_factory_utilities/example/api/__init__.py,sha256=qI82eeSwVjR6jSkX1pxm8ALv9WPQ_iHurFY4G2K7VzE,554
|
|
81
|
+
fastapi_factory_utilities/example/api/books/__init__.py,sha256=zXARBnjywJwg1XsLbcixYWcHH4uC9mF-kbbX4P8cVgA,160
|
|
82
|
+
fastapi_factory_utilities/example/api/books/responses.py,sha256=21WeD6bdg0MCD_0vRHwmsL4W79iDcG9NnDLemXysc84,540
|
|
83
|
+
fastapi_factory_utilities/example/api/books/routes.py,sha256=bwg8Bhvoj9vx2SdwunzFS-Z3cHECtjl_yGdo8MfiGEM,1529
|
|
84
|
+
fastapi_factory_utilities/example/app.py,sha256=MInt71wnDEC9yqVJeT3hChj7DRmg7sI3Ta0KkfubdyU,2076
|
|
85
|
+
fastapi_factory_utilities/example/application.yaml,sha256=5xRyFSuMxmgZ5Mikai94UqKYJ7PxJp8omlXobTjv14M,485
|
|
86
|
+
fastapi_factory_utilities/example/entities/books/__init__.py,sha256=cpTMhLpenb359lOT9HHUv6DzKX8fKl4WCzcsB3ddk6Q,185
|
|
87
|
+
fastapi_factory_utilities/example/entities/books/entities.py,sha256=rLE01lE7U6WizrD5ZHMRwkynd8_dWF6DltBFH61f-Do,405
|
|
88
|
+
fastapi_factory_utilities/example/entities/books/enums.py,sha256=lXYUvhIkT1pi0teflMpnqeafeiBZMokyWxoFLgzV6a8,330
|
|
89
|
+
fastapi_factory_utilities/example/entities/books/types.py,sha256=7LYGPu-CcI3noIORJyIZlVF-CBugWPXEqgDzWrO3XmQ,1558
|
|
90
|
+
fastapi_factory_utilities/example/models/__init__.py,sha256=RJmp3R9bhbQv7n0WOlsHP65LqbEs_DjF9hzYKwYTRGo,22
|
|
91
|
+
fastapi_factory_utilities/example/models/books/__init__.py,sha256=IPS3rLLnZncV-VAxgsipxUD7l4r04ewo_Hx2Naj2lT0,181
|
|
92
|
+
fastapi_factory_utilities/example/models/books/document.py,sha256=lYJfMGr5GqEEsn7L--PFs75hC2q-jQx77wl7EhTrp5U,568
|
|
93
|
+
fastapi_factory_utilities/example/models/books/repository.py,sha256=7K63uAsSEGZ2EXqufU4Tc8KpymgXK8JX8WjAE2Sw8ok,387
|
|
94
|
+
fastapi_factory_utilities/example/services/books/__init__.py,sha256=Z06yNRoA7Zg3TGN-Q9rrvJg6Bbx-qJw661MVwukV6vQ,148
|
|
95
|
+
fastapi_factory_utilities/example/services/books/services.py,sha256=-x7d4hotUWLzWo5uImMjFmtNcSTHwWv2bfttIbYYKbA,5380
|
|
96
|
+
fastapi_factory_utilities/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,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,,
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
"""Provide PluginManager."""
|
|
2
|
-
|
|
3
|
-
from .exceptions import (
|
|
4
|
-
InvalidPluginError,
|
|
5
|
-
PluginManagerError,
|
|
6
|
-
PluginPreConditionNotMetError,
|
|
7
|
-
)
|
|
8
|
-
from .plugin_manager import PluginManager
|
|
9
|
-
|
|
10
|
-
__all__: list[str] = [
|
|
11
|
-
"PluginManager",
|
|
12
|
-
"PluginManagerError",
|
|
13
|
-
"InvalidPluginError",
|
|
14
|
-
"PluginPreConditionNotMetError",
|
|
15
|
-
]
|