fastapi-factory-utilities 0.2.1__tar.gz → 0.2.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of fastapi-factory-utilities might be problematic. Click here for more details.

Files changed (70) hide show
  1. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/PKG-INFO +1 -1
  2. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/pyproject.toml +1 -1
  3. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/core/app/builder.py +4 -2
  4. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/core/plugins/odm_plugin/__init__.py +1 -0
  5. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/core/plugins/odm_plugin/builder.py +50 -29
  6. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/core/plugins/odm_plugin/configs.py +1 -1
  7. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/core/utils/uvicorn.py +36 -0
  8. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/LICENSE +0 -0
  9. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/README.md +0 -0
  10. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/__main__.py +0 -0
  11. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/core/__init__.py +0 -0
  12. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/core/api/__init__.py +0 -0
  13. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/core/api/tags.py +0 -0
  14. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/core/api/v1/sys/__init__.py +0 -0
  15. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/core/api/v1/sys/health.py +0 -0
  16. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/core/api/v1/sys/readiness.py +0 -0
  17. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/core/app/__init__.py +0 -0
  18. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/core/app/application.py +0 -0
  19. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/core/app/config.py +0 -0
  20. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/core/app/enums.py +0 -0
  21. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/core/app/exceptions.py +0 -0
  22. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/core/app/fastapi_builder.py +0 -0
  23. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/core/app/plugin_manager/__init__.py +0 -0
  24. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/core/app/plugin_manager/exceptions.py +0 -0
  25. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/core/app/plugin_manager/plugin_manager.py +0 -0
  26. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/core/exceptions.py +0 -0
  27. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/core/plugins/__init__.py +0 -0
  28. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/core/plugins/example/__init__.py +0 -0
  29. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/core/plugins/httpx_plugin/__init__.py +0 -0
  30. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/core/plugins/odm_plugin/depends.py +0 -0
  31. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/core/plugins/odm_plugin/documents.py +0 -0
  32. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/core/plugins/odm_plugin/exceptions.py +0 -0
  33. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/core/plugins/odm_plugin/repositories.py +0 -0
  34. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/core/plugins/opentelemetry_plugin/__init__.py +0 -0
  35. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/core/plugins/opentelemetry_plugin/builder.py +0 -0
  36. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/core/plugins/opentelemetry_plugin/configs.py +0 -0
  37. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/core/plugins/opentelemetry_plugin/exceptions.py +0 -0
  38. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/core/plugins/opentelemetry_plugin/helpers.py +0 -0
  39. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/core/protocols.py +0 -0
  40. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/core/services/status/__init__.py +0 -0
  41. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/core/services/status/enums.py +0 -0
  42. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/core/services/status/exceptions.py +0 -0
  43. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/core/services/status/health_calculator_strategies.py +0 -0
  44. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/core/services/status/readiness_calculator_strategies.py +0 -0
  45. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/core/services/status/services.py +0 -0
  46. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/core/services/status/types.py +0 -0
  47. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/core/utils/configs.py +0 -0
  48. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/core/utils/importlib.py +0 -0
  49. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/core/utils/log.py +0 -0
  50. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/core/utils/status.py +0 -0
  51. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/core/utils/yaml_reader.py +0 -0
  52. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/example/__init__.py +0 -0
  53. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/example/__main__.py +0 -0
  54. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/example/api/__init__.py +0 -0
  55. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/example/api/books/__init__.py +0 -0
  56. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/example/api/books/responses.py +0 -0
  57. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/example/api/books/routes.py +0 -0
  58. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/example/app.py +0 -0
  59. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/example/application.yaml +0 -0
  60. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/example/entities/books/__init__.py +0 -0
  61. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/example/entities/books/entities.py +0 -0
  62. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/example/entities/books/enums.py +0 -0
  63. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/example/entities/books/types.py +0 -0
  64. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/example/models/__init__.py +0 -0
  65. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/example/models/books/__init__.py +0 -0
  66. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/example/models/books/document.py +0 -0
  67. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/example/models/books/repository.py +0 -0
  68. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/example/services/books/__init__.py +0 -0
  69. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/example/services/books/services.py +0 -0
  70. {fastapi_factory_utilities-0.2.1 → fastapi_factory_utilities-0.2.2}/src/fastapi_factory_utilities/py.typed +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: fastapi_factory_utilities
3
- Version: 0.2.1
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
@@ -3,7 +3,7 @@ name = "fastapi_factory_utilities"
3
3
  homepage = "https://github.com/miragecentury/fastapi_factory_utilities"
4
4
  repository = "https://github.com/miragecentury/fastapi_factory_utilities"
5
5
  keywords = ["python", "fastapi", "beanie", "httpx", "opentelemetry", "microservices"]
6
- version = "0.2.1"
6
+ version = "0.2.2"
7
7
  description = "Consolidate libraries and utilities to create microservices in Python with FastAPI, Beanie, Httpx, AioPika and OpenTelemetry."
8
8
  authors = ["miragecentury <victorien.vanroye@gmail.com>"]
9
9
  maintainers = ["miragecentury <victorien.vanroye@gmail.com>"]
@@ -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
- return UvicornUtils(app=self.build())
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
- @classmethod
128
- def _wait_client_to_be_ready(cls, client: AsyncIOMotorClient[Any], timeout_s: int) -> None:
129
- """Wait for the ODM client to be ready.
130
-
131
- Args:
132
- client (AsyncIOMotorClient): The ODM client.
133
- timeout_s (int): The timeout in seconds.
134
-
135
- Raises:
136
- TimeoutError: If the ODM client is not ready in the given timeout.
137
- """
138
- start_time: float = time.time()
139
- message_time: float = time.time()
140
- while (time.time() - start_time) < (timeout_s):
141
- if len(client.nodes) > 0: # type: ignore
142
- _logger.info(f"Waiting {(time.time() - start_time)*cls.MS_TO_S}ms for the ODM client to be ready.")
143
- return
144
-
145
- if (time.time() - message_time) > 1:
146
- elaps_time: float = time.time() - start_time
147
- _logger.debug(f"Waiting for the ODM client to be ready. (from {int(elaps_time)}s) ")
148
- message_time = time.time()
149
- time.sleep(cls.SLEEP_TIME_S)
150
-
151
- raise TimeoutError("The ODM client is not ready in the given timeout.")
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.connection_timeout_s,
177
- serverSelectionTimeoutMS=self._config.connection_timeout_s,
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
- self._wait_client_to_be_ready(client=self._odm_client, timeout_s=self._config.connection_timeout_s)
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
@@ -12,4 +12,4 @@ class ODMConfig(BaseModel):
12
12
 
13
13
  database: str = "test"
14
14
 
15
- connection_timeout_s: int = 10
15
+ connection_timeout_ms: int = 1000
@@ -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