fastapi-factory-utilities 0.2.0__py3-none-any.whl → 0.2.2__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/app/builder.py +4 -2
- fastapi_factory_utilities/core/plugins/odm_plugin/__init__.py +1 -0
- fastapi_factory_utilities/core/plugins/odm_plugin/builder.py +50 -29
- fastapi_factory_utilities/core/plugins/odm_plugin/configs.py +1 -1
- fastapi_factory_utilities/core/utils/uvicorn.py +36 -0
- fastapi_factory_utilities/py.typed +0 -0
- {fastapi_factory_utilities-0.2.0.dist-info → fastapi_factory_utilities-0.2.2.dist-info}/METADATA +1 -1
- {fastapi_factory_utilities-0.2.0.dist-info → fastapi_factory_utilities-0.2.2.dist-info}/RECORD +11 -10
- {fastapi_factory_utilities-0.2.0.dist-info → fastapi_factory_utilities-0.2.2.dist-info}/LICENSE +0 -0
- {fastapi_factory_utilities-0.2.0.dist-info → fastapi_factory_utilities-0.2.2.dist-info}/WHEEL +0 -0
- {fastapi_factory_utilities-0.2.0.dist-info → fastapi_factory_utilities-0.2.2.dist-info}/entry_points.txt +0 -0
|
@@ -21,6 +21,7 @@ class ApplicationGenericBuilder(Generic[T]):
|
|
|
21
21
|
|
|
22
22
|
def __init__(self, plugins_activation_list: list[PluginsEnum] | None = None) -> None:
|
|
23
23
|
"""Instanciate the ApplicationGenericBuilder."""
|
|
24
|
+
self._uvicorn_utils: UvicornUtils | None = None
|
|
24
25
|
self._root_config: RootConfig | None = None
|
|
25
26
|
self._plugin_manager: PluginManager | None = None
|
|
26
27
|
self._fastapi_builder: FastAPIBuilder | None = None
|
|
@@ -109,11 +110,12 @@ class ApplicationGenericBuilder(Generic[T]):
|
|
|
109
110
|
|
|
110
111
|
def build_as_uvicorn_utils(self) -> UvicornUtils:
|
|
111
112
|
"""Build the application and provide UvicornUtils."""
|
|
112
|
-
|
|
113
|
+
self._uvicorn_utils = UvicornUtils(app=self.build())
|
|
114
|
+
return self._uvicorn_utils
|
|
113
115
|
|
|
114
116
|
def build_and_serve(self) -> None:
|
|
115
117
|
"""Build the application and serve it with Uvicorn."""
|
|
116
|
-
uvicorn_utils: UvicornUtils = self.build_as_uvicorn_utils()
|
|
118
|
+
uvicorn_utils: UvicornUtils = self._uvicorn_utils or self.build_as_uvicorn_utils()
|
|
117
119
|
|
|
118
120
|
setup_log(mode=LogModeEnum.CONSOLE)
|
|
119
121
|
|
|
@@ -78,6 +78,7 @@ async def on_startup(
|
|
|
78
78
|
|
|
79
79
|
try:
|
|
80
80
|
odm_factory: ODMBuilder = ODMBuilder(application=application).build_all()
|
|
81
|
+
await odm_factory.wait_ping()
|
|
81
82
|
except Exception as exception: # pylint: disable=broad-except
|
|
82
83
|
_logger.error(f"ODM plugin failed to start. {exception}")
|
|
83
84
|
# TODO: Report the error to the status_service
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"""Provides the module for the ODM plugin."""
|
|
2
2
|
|
|
3
|
-
import time
|
|
4
3
|
from typing import Any, ClassVar, Self
|
|
5
4
|
|
|
6
5
|
from motor.motor_asyncio import AsyncIOMotorClient, AsyncIOMotorDatabase
|
|
6
|
+
from pymongo.server_api import ServerApi, ServerApiVersion
|
|
7
7
|
from structlog.stdlib import get_logger
|
|
8
8
|
|
|
9
9
|
from fastapi_factory_utilities.core.protocols import ApplicationAbstractProtocol
|
|
@@ -124,31 +124,34 @@ class ODMBuilder:
|
|
|
124
124
|
raise ODMPluginConfigError("Unable to create the application configuration model.") from exception
|
|
125
125
|
return self
|
|
126
126
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
127
|
+
# ======
|
|
128
|
+
# KEEP IT, Waiting for additional tests
|
|
129
|
+
# @classmethod
|
|
130
|
+
# def _wait_client_to_be_ready(cls, client: AsyncIOMotorClient[Any], timeout_s: int) -> None:
|
|
131
|
+
# """Wait for the ODM client to be ready.
|
|
132
|
+
|
|
133
|
+
# Args:
|
|
134
|
+
# client (AsyncIOMotorClient): The ODM client.
|
|
135
|
+
# timeout_s (int): The timeout in seconds.
|
|
136
|
+
|
|
137
|
+
# Raises:
|
|
138
|
+
# TimeoutError: If the ODM client is not ready in the given timeout.
|
|
139
|
+
# """
|
|
140
|
+
# start_time: float = time.time()
|
|
141
|
+
# message_time: float = time.time()
|
|
142
|
+
# while (time.time() - start_time) < (timeout_s):
|
|
143
|
+
# if len(client.nodes) > 0: # type: ignore
|
|
144
|
+
# _logger.info(f"Waiting {(time.time() - start_time)*cls.MS_TO_S}ms for the ODM client to be ready.")
|
|
145
|
+
# return
|
|
146
|
+
|
|
147
|
+
# if (time.time() - message_time) > 1:
|
|
148
|
+
# elaps_time: float = time.time() - start_time
|
|
149
|
+
# _logger.debug(f"Waiting for the ODM client to be ready. (from {int(elaps_time)}s) ")
|
|
150
|
+
# message_time = time.time()
|
|
151
|
+
# time.sleep(cls.SLEEP_TIME_S)
|
|
152
|
+
|
|
153
|
+
# raise TimeoutError("The ODM client is not ready in the given timeout.")
|
|
154
|
+
# ======
|
|
152
155
|
|
|
153
156
|
def build_client(
|
|
154
157
|
self,
|
|
@@ -173,11 +176,13 @@ class ODMBuilder:
|
|
|
173
176
|
self._odm_client = AsyncIOMotorClient(
|
|
174
177
|
host=self._config.uri,
|
|
175
178
|
connect=True,
|
|
176
|
-
connectTimeoutMS=self._config.
|
|
177
|
-
serverSelectionTimeoutMS=self._config.
|
|
179
|
+
connectTimeoutMS=self._config.connection_timeout_ms,
|
|
180
|
+
serverSelectionTimeoutMS=self._config.connection_timeout_ms,
|
|
181
|
+
server_api=ServerApi(version=ServerApiVersion.V1),
|
|
178
182
|
)
|
|
179
183
|
|
|
180
|
-
|
|
184
|
+
# KEEP IT, Waiting for additional tests
|
|
185
|
+
# self._wait_client_to_be_ready(client=self._odm_client, timeout_s=self._config.connection_timeout_s)
|
|
181
186
|
|
|
182
187
|
return self
|
|
183
188
|
|
|
@@ -229,3 +234,19 @@ class ODMBuilder:
|
|
|
229
234
|
self.build_database()
|
|
230
235
|
|
|
231
236
|
return self
|
|
237
|
+
|
|
238
|
+
async def wait_ping(self):
|
|
239
|
+
"""Wait for the ODM client to be ready.
|
|
240
|
+
|
|
241
|
+
Returns:
|
|
242
|
+
Self: The ODM factory.
|
|
243
|
+
"""
|
|
244
|
+
if self._odm_client is None:
|
|
245
|
+
raise ODMPluginConfigError(
|
|
246
|
+
"ODM client is not set. Provide the ODM client using " "build_client method or through parameter."
|
|
247
|
+
)
|
|
248
|
+
|
|
249
|
+
try:
|
|
250
|
+
await self._odm_client.admin.command("ping")
|
|
251
|
+
except Exception as exception: # pylint: disable=broad-except
|
|
252
|
+
raise ODMPluginConfigError("Unable to ping the ODM client.") from exception
|
|
@@ -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
|
|
File without changes
|
{fastapi_factory_utilities-0.2.0.dist-info → fastapi_factory_utilities-0.2.2.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: fastapi_factory_utilities
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: Consolidate libraries and utilities to create microservices in Python with FastAPI, Beanie, Httpx, AioPika and OpenTelemetry.
|
|
5
5
|
License: MIT
|
|
6
6
|
Keywords: python,fastapi,beanie,httpx,opentelemetry,microservices
|
{fastapi_factory_utilities-0.2.0.dist-info → fastapi_factory_utilities-0.2.2.dist-info}/RECORD
RENAMED
|
@@ -7,7 +7,7 @@ fastapi_factory_utilities/core/api/v1/sys/health.py,sha256=IF51Z1seOFn91m3FC57U8
|
|
|
7
7
|
fastapi_factory_utilities/core/api/v1/sys/readiness.py,sha256=xIY8pQLShU7KWRtlOUK5gTDyZ8aB1KBvLczC6boT-tg,1711
|
|
8
8
|
fastapi_factory_utilities/core/app/__init__.py,sha256=I04abOkkWiY9ChgkUNeiwnuWq8kkBoRAtMLBUKB7J7Y,405
|
|
9
9
|
fastapi_factory_utilities/core/app/application.py,sha256=XdfQRG8IwyukEYXNF6i2s3qq0eAo1_XG9Xa9yV7zKf8,4975
|
|
10
|
-
fastapi_factory_utilities/core/app/builder.py,sha256=
|
|
10
|
+
fastapi_factory_utilities/core/app/builder.py,sha256=VbThqoI1qWnADwPQ61D774oNZ5d6OMxW0tyXr_Yz5E4,4503
|
|
11
11
|
fastapi_factory_utilities/core/app/config.py,sha256=7ELIoCy1AGCD4Zq7O-jZk6VJcqDU8H-00CSrvtwzdZE,6466
|
|
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
|
|
@@ -19,9 +19,9 @@ fastapi_factory_utilities/core/exceptions.py,sha256=7ntbaMptYn5OOPeKPVR4zU98NIC0
|
|
|
19
19
|
fastapi_factory_utilities/core/plugins/__init__.py,sha256=W-BCkqP0xG980980z3mc8T6Vrp1Akv4szA0PRzkUbiU,756
|
|
20
20
|
fastapi_factory_utilities/core/plugins/example/__init__.py,sha256=GF69IygLXxzrCh7VryekEWun663kKBhWtRS3w-1tzBc,1030
|
|
21
21
|
fastapi_factory_utilities/core/plugins/httpx_plugin/__init__.py,sha256=P5FUyv7mQr8RZWQ8ifkoK8GXvqSI71q2b2dm-ag2JhQ,1028
|
|
22
|
-
fastapi_factory_utilities/core/plugins/odm_plugin/__init__.py,sha256=
|
|
23
|
-
fastapi_factory_utilities/core/plugins/odm_plugin/builder.py,sha256=
|
|
24
|
-
fastapi_factory_utilities/core/plugins/odm_plugin/configs.py,sha256=
|
|
22
|
+
fastapi_factory_utilities/core/plugins/odm_plugin/__init__.py,sha256=DwtLFB291G7GQDV8yh_dN7aXPMy6HWvDEh8PbWhbVDA,5316
|
|
23
|
+
fastapi_factory_utilities/core/plugins/odm_plugin/builder.py,sha256=3B5EgY8deS_dr9NYZbeJq9cibPs65kN0Ogg-1yecF3s,8547
|
|
24
|
+
fastapi_factory_utilities/core/plugins/odm_plugin/configs.py,sha256=zQoJC1wLNyq2pZyFhl0bKeNsTl4y_4_82BHCCaOEjCQ,331
|
|
25
25
|
fastapi_factory_utilities/core/plugins/odm_plugin/depends.py,sha256=OcLsfTLzMBk_xFV6qsMy_-qFkiphEbbEuaHUooagxg8,730
|
|
26
26
|
fastapi_factory_utilities/core/plugins/odm_plugin/documents.py,sha256=ENEB-Lm3T7_tN1xuIYPsUh8fpWj4aqh0xmrZt6vJCK0,1075
|
|
27
27
|
fastapi_factory_utilities/core/plugins/odm_plugin/exceptions.py,sha256=acnKJB0lGAzDs-7-LjBap8shjP3iV1a7dw7ouPVF27o,551
|
|
@@ -43,7 +43,7 @@ fastapi_factory_utilities/core/utils/configs.py,sha256=qM0pCrsK8ZyfCoyova_VrhR4e
|
|
|
43
43
|
fastapi_factory_utilities/core/utils/importlib.py,sha256=DYcPo7K0s95WV5xxtucpufWsTj8Pxv25sWunDmmNUYI,797
|
|
44
44
|
fastapi_factory_utilities/core/utils/log.py,sha256=6V9CL3bQio4e47YxcSXM2JQRGhVxuBfmcEbcF4RtCfQ,6393
|
|
45
45
|
fastapi_factory_utilities/core/utils/status.py,sha256=1zxur98Wfum3JzpuzoAPoRIwQmXhFsTS2oxgbn5uFfg,1933
|
|
46
|
-
fastapi_factory_utilities/core/utils/uvicorn.py,sha256=
|
|
46
|
+
fastapi_factory_utilities/core/utils/uvicorn.py,sha256=XThylG-nOPVL00w6MIWGODnweoM7VxmpSFcyoPcmqns,2609
|
|
47
47
|
fastapi_factory_utilities/core/utils/yaml_reader.py,sha256=G7F1SFynghUYjuTZTNotNW9OIiCaeGAWkcYvTFYsCMQ,6101
|
|
48
48
|
fastapi_factory_utilities/example/__init__.py,sha256=LEKnPTBcgDyfHeOjlVxjK5lFdFqS-7-mHDuVuM2Jh_Y,206
|
|
49
49
|
fastapi_factory_utilities/example/__main__.py,sha256=Iwp_6rK7Lcv2F-XAKn6xjxQHOWjx2OjgwKAr91tfUfk,135
|
|
@@ -63,8 +63,9 @@ fastapi_factory_utilities/example/models/books/document.py,sha256=lYJfMGr5GqEEsn
|
|
|
63
63
|
fastapi_factory_utilities/example/models/books/repository.py,sha256=7K63uAsSEGZ2EXqufU4Tc8KpymgXK8JX8WjAE2Sw8ok,387
|
|
64
64
|
fastapi_factory_utilities/example/services/books/__init__.py,sha256=Z06yNRoA7Zg3TGN-Q9rrvJg6Bbx-qJw661MVwukV6vQ,148
|
|
65
65
|
fastapi_factory_utilities/example/services/books/services.py,sha256=-x7d4hotUWLzWo5uImMjFmtNcSTHwWv2bfttIbYYKbA,5380
|
|
66
|
-
fastapi_factory_utilities
|
|
67
|
-
fastapi_factory_utilities-0.2.
|
|
68
|
-
fastapi_factory_utilities-0.2.
|
|
69
|
-
fastapi_factory_utilities-0.2.
|
|
70
|
-
fastapi_factory_utilities-0.2.
|
|
66
|
+
fastapi_factory_utilities/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
67
|
+
fastapi_factory_utilities-0.2.2.dist-info/LICENSE,sha256=iO1nLzMMst6vEiqgSUrfrbetM7b0bvdzXhbed5tqG8o,1074
|
|
68
|
+
fastapi_factory_utilities-0.2.2.dist-info/METADATA,sha256=JBD_XGvdIXLbwNaCe2ozpdlIggjqLRPgKa-THloa1xA,3314
|
|
69
|
+
fastapi_factory_utilities-0.2.2.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
|
|
70
|
+
fastapi_factory_utilities-0.2.2.dist-info/entry_points.txt,sha256=IK0VcBexXo4uXQmTrbfhhnnfq4GmXPRn0GBB8hzlsq4,101
|
|
71
|
+
fastapi_factory_utilities-0.2.2.dist-info/RECORD,,
|
{fastapi_factory_utilities-0.2.0.dist-info → fastapi_factory_utilities-0.2.2.dist-info}/LICENSE
RENAMED
|
File without changes
|
{fastapi_factory_utilities-0.2.0.dist-info → fastapi_factory_utilities-0.2.2.dist-info}/WHEEL
RENAMED
|
File without changes
|
|
File without changes
|