fastapi-factory-utilities 0.8.2__py3-none-any.whl → 0.9.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.
@@ -3,7 +3,8 @@
3
3
  from typing import Any, ClassVar, Self
4
4
 
5
5
  from bson import CodecOptions
6
- from motor.motor_asyncio import AsyncIOMotorClient, AsyncIOMotorDatabase
6
+ from pymongo.asynchronous.database import AsyncDatabase
7
+ from pymongo.asynchronous.mongo_client import AsyncMongoClient
7
8
  from pymongo.server_api import ServerApi, ServerApiVersion
8
9
  from structlog.stdlib import get_logger
9
10
 
@@ -45,22 +46,22 @@ class ODMBuilder:
45
46
  self,
46
47
  application: ApplicationAbstractProtocol,
47
48
  odm_config: ODMConfig | None = None,
48
- odm_client: AsyncIOMotorClient[Any] | None = None,
49
- odm_database: AsyncIOMotorDatabase[Any] | None = None,
49
+ odm_client: AsyncMongoClient[Any] | None = None,
50
+ odm_database: AsyncDatabase[Any] | None = None,
50
51
  ) -> None:
51
52
  """Initialize the ODMFactory.
52
53
 
53
54
  Args:
54
55
  application (BaseApplicationProtocol): The application.
55
56
  odm_config (ODMConfig): The ODM configuration for injection. (Default is None)
56
- odm_client (AsyncIOMotorClient): The ODM client for injection. (Default is None)
57
- odm_database (AsyncIOMotorDatabase): The ODM database for injection. (Default is None)
57
+ odm_client (AsyncMongoClient): The ODM client for injection. (Default is None)
58
+ odm_database (AsyncDatabase): The ODM database for injection. (Default is None)
58
59
 
59
60
  """
60
61
  self._application: ApplicationAbstractProtocol = application
61
62
  self._config: ODMConfig | None = odm_config
62
- self._odm_client: AsyncIOMotorClient[Any] | None = odm_client
63
- self._odm_database: AsyncIOMotorDatabase[Any] | None = odm_database
63
+ self._odm_client: AsyncMongoClient[Any] | None = odm_client
64
+ self._odm_database: AsyncDatabase[Any] | None = odm_database
64
65
 
65
66
  @property
66
67
  def config(self) -> ODMConfig | None:
@@ -72,20 +73,20 @@ class ODMBuilder:
72
73
  return self._config
73
74
 
74
75
  @property
75
- def odm_client(self) -> AsyncIOMotorClient[Any] | None:
76
+ def odm_client(self) -> AsyncMongoClient[Any] | None:
76
77
  """Provide the ODM client.
77
78
 
78
79
  Returns:
79
- AsyncIOMotorClient | None: The ODM client.
80
+ AsyncMongoClient | None: The ODM client.
80
81
  """
81
82
  return self._odm_client
82
83
 
83
84
  @property
84
- def odm_database(self) -> AsyncIOMotorDatabase[Any] | None:
85
+ def odm_database(self) -> AsyncDatabase[Any] | None:
85
86
  """Provide the ODM database.
86
87
 
87
88
  Returns:
88
- AsyncIOMotorDatabase | None: The ODM database.
89
+ AsyncDatabase | None: The ODM database.
89
90
  """
90
91
  return self._odm_database
91
92
 
@@ -174,7 +175,7 @@ class ODMBuilder:
174
175
  "build_odm_config method or through parameter."
175
176
  )
176
177
 
177
- self._odm_client = AsyncIOMotorClient(
178
+ self._odm_client = AsyncMongoClient(
178
179
  host=self._config.uri,
179
180
  connect=True,
180
181
  connectTimeoutMS=self._config.connection_timeout_ms,
@@ -241,19 +242,3 @@ class ODMBuilder:
241
242
  self.build_database()
242
243
 
243
244
  return self
244
-
245
- async def wait_ping(self) -> None:
246
- """Wait for the ODM client to be ready.
247
-
248
- Returns:
249
- Self: The ODM factory.
250
- """
251
- if self._odm_client is None:
252
- raise ODMPluginConfigError(
253
- "ODM client is not set. Provide the ODM client using build_client method or through parameter."
254
- )
255
-
256
- try:
257
- await self._odm_client.admin.command("ping")
258
- except Exception as exception: # pylint: disable=broad-except
259
- raise ODMPluginConfigError("Unable to ping the ODM client.") from exception
@@ -3,10 +3,11 @@
3
3
  from typing import Any
4
4
 
5
5
  from fastapi import Request
6
- from motor.motor_asyncio import AsyncIOMotorClient, AsyncIOMotorDatabase
6
+ from pymongo.asynchronous.database import AsyncDatabase
7
+ from pymongo.asynchronous.mongo_client import AsyncMongoClient
7
8
 
8
9
 
9
- def depends_odm_client(request: Request) -> AsyncIOMotorClient[Any]:
10
+ def depends_odm_client(request: Request) -> AsyncMongoClient[Any]:
10
11
  """Acquire the ODM client from the request.
11
12
 
12
13
  Args:
@@ -18,7 +19,7 @@ def depends_odm_client(request: Request) -> AsyncIOMotorClient[Any]:
18
19
  return request.app.state.odm_client
19
20
 
20
21
 
21
- def depends_odm_database(request: Request) -> AsyncIOMotorDatabase[Any]:
22
+ def depends_odm_database(request: Request) -> AsyncDatabase[Any]:
22
23
  """Acquire the ODM database from the request.
23
24
 
24
25
  Args:
@@ -1,10 +1,11 @@
1
1
  """Oriented Data Model (ODM) plugin package."""
2
2
 
3
3
  from logging import INFO, Logger, getLogger
4
- from typing import Any, Self
4
+ from typing import Any, Self, cast
5
5
 
6
6
  from beanie import Document, init_beanie # pyright: ignore[reportUnknownVariableType]
7
- from motor.motor_asyncio import AsyncIOMotorClient, AsyncIOMotorDatabase
7
+ from pymongo.asynchronous.database import AsyncDatabase
8
+ from pymongo.asynchronous.mongo_client import AsyncMongoClient
8
9
  from reactivex import Subject
9
10
  from structlog.stdlib import BoundLogger, get_logger
10
11
 
@@ -44,8 +45,8 @@ class ODMPlugin(PluginAbstract):
44
45
  self._monitoring_subject: Subject[Status] | None = None
45
46
  self._document_models: list[type[Document]] | None = document_models
46
47
  self._odm_config: ODMConfig | None = odm_config
47
- self._odm_client: AsyncIOMotorClient[Any] | None = None
48
- self._odm_database: AsyncIOMotorDatabase[Any] | None = None
48
+ self._odm_client: AsyncMongoClient[Any] | None = None
49
+ self._odm_database: AsyncDatabase[Any] | None = None
49
50
 
50
51
  def set_application(self, application: ApplicationAbstractProtocol) -> Self:
51
52
  """Set the application."""
@@ -92,6 +93,8 @@ class ODMPlugin(PluginAbstract):
92
93
 
93
94
  async def on_startup(self) -> None:
94
95
  """Actions to perform on startup for the ODM plugin."""
96
+ host: str
97
+ port: int
95
98
  assert self._application is not None
96
99
  self._setup_status()
97
100
  assert self._monitoring_subject is not None
@@ -99,7 +102,11 @@ class ODMPlugin(PluginAbstract):
99
102
 
100
103
  try:
101
104
  odm_factory: ODMBuilder = ODMBuilder(application=self._application, odm_config=self._odm_config).build_all()
102
- await odm_factory.wait_ping()
105
+ assert odm_factory.odm_client is not None
106
+ assert odm_factory.odm_database is not None
107
+ assert (await odm_factory.odm_client.address) is not None
108
+ host, port = cast(tuple[str, int], await odm_factory.odm_client.address)
109
+ await odm_factory.odm_client.aconnect()
103
110
  self._odm_database = odm_factory.odm_database
104
111
  self._odm_client = odm_factory.odm_client
105
112
  except Exception as exception: # pylint: disable=broad-except
@@ -111,25 +118,16 @@ class ODMPlugin(PluginAbstract):
111
118
  )
112
119
  return None
113
120
 
114
- if self._odm_database is None or self._odm_client is None:
115
- _logger.error(
116
- f"ODM plugin failed to start. Database: {odm_factory.odm_database} - Client: {odm_factory.odm_client}"
117
- )
118
- # TODO: Report the error to the status_service
119
- # this will report the application as unhealthy
120
- self._monitoring_subject.on_next(
121
- value=Status(health=HealthStatusEnum.UNHEALTHY, readiness=ReadinessStatusEnum.NOT_READY)
122
- )
123
- return None
124
-
125
121
  self._add_to_state(key="odm_client", value=odm_factory.odm_client)
126
122
  self._add_to_state(key="odm_database", value=odm_factory.odm_database)
127
123
 
128
124
  await self._setup_beanie()
129
125
 
126
+ assert self._odm_client is not None
127
+
130
128
  _logger.info(
131
129
  f"ODM plugin started. Database: {self._odm_database.name} - "
132
- f"Client: {self._odm_client.address} - "
130
+ f"Client: {host}:{port} - "
133
131
  f"Document models: {self._application.ODM_DOCUMENT_MODELS}"
134
132
  )
135
133
 
@@ -140,7 +138,7 @@ class ODMPlugin(PluginAbstract):
140
138
  async def on_shutdown(self) -> None:
141
139
  """Actions to perform on shutdown for the ODM plugin."""
142
140
  if self._odm_client is not None:
143
- self._odm_client.close()
141
+ await self._odm_client.close()
144
142
  _logger.debug("ODM plugin shutdown.")
145
143
 
146
144
 
@@ -8,8 +8,9 @@ from typing import Any, Generic, TypeVar, get_args
8
8
  from uuid import UUID
9
9
 
10
10
  from beanie import SortDirection
11
- from motor.motor_asyncio import AsyncIOMotorClientSession, AsyncIOMotorDatabase
12
11
  from pydantic import BaseModel
12
+ from pymongo.asynchronous.client_session import AsyncClientSession
13
+ from pymongo.asynchronous.database import AsyncDatabase
13
14
  from pymongo.errors import DuplicateKeyError, PyMongoError
14
15
  from pymongo.results import DeleteResult
15
16
 
@@ -43,28 +44,30 @@ def managed_session() -> Callable[[Callable[..., Any]], Callable[..., Any]]:
43
44
  class AbstractRepository(ABC, Generic[DocumentGenericType, EntityGenericType]):
44
45
  """Abstract class for the repository."""
45
46
 
46
- def __init__(self, database: AsyncIOMotorDatabase[Any]) -> None:
47
+ def __init__(self, database: AsyncDatabase[Any]) -> None:
47
48
  """Initialize the repository."""
48
49
  super().__init__()
49
- self._database: AsyncIOMotorDatabase[Any] = database
50
+ self._database: AsyncDatabase[Any] = database
50
51
  # Retrieve the generic concrete types
51
52
  generic_args: tuple[Any, ...] = get_args(self.__orig_bases__[0]) # type: ignore
52
53
  self._document_type: type[DocumentGenericType] = generic_args[0]
53
54
  self._entity_type: type[EntityGenericType] = generic_args[1]
54
55
 
55
56
  @asynccontextmanager
56
- async def get_session(self) -> AsyncGenerator[AsyncIOMotorClientSession, None]:
57
+ async def get_session(self) -> AsyncGenerator[AsyncClientSession, None]:
57
58
  """Yield a new session."""
59
+ session: AsyncClientSession | None = None
58
60
  try:
59
- async with await self._database.client.start_session() as session:
60
- yield session
61
+ session = self._database.client.start_session()
62
+ yield session
61
63
  except PyMongoError as error:
62
64
  raise OperationError(f"Failed to create session: {error}") from error
65
+ finally:
66
+ if session is not None:
67
+ await session.end_session()
63
68
 
64
69
  @managed_session()
65
- async def insert(
66
- self, entity: EntityGenericType, session: AsyncIOMotorClientSession | None = None
67
- ) -> EntityGenericType:
70
+ async def insert(self, entity: EntityGenericType, session: AsyncClientSession | None = None) -> EntityGenericType:
68
71
  """Insert the entity into the database.
69
72
 
70
73
  Args:
@@ -104,9 +107,7 @@ class AbstractRepository(ABC, Generic[DocumentGenericType, EntityGenericType]):
104
107
  return entity_created
105
108
 
106
109
  @managed_session()
107
- async def update(
108
- self, entity: EntityGenericType, session: AsyncIOMotorClientSession | None = None
109
- ) -> EntityGenericType:
110
+ async def update(self, entity: EntityGenericType, session: AsyncClientSession | None = None) -> EntityGenericType:
110
111
  """Update the entity in the database.
111
112
 
112
113
  Args:
@@ -145,7 +146,7 @@ class AbstractRepository(ABC, Generic[DocumentGenericType, EntityGenericType]):
145
146
  async def get_one_by_id(
146
147
  self,
147
148
  entity_id: UUID,
148
- session: AsyncIOMotorClientSession | None = None,
149
+ session: AsyncClientSession | None = None,
149
150
  ) -> EntityGenericType | None:
150
151
  """Get the entity by its ID.
151
152
 
@@ -179,7 +180,7 @@ class AbstractRepository(ABC, Generic[DocumentGenericType, EntityGenericType]):
179
180
 
180
181
  @managed_session()
181
182
  async def delete_one_by_id(
182
- self, entity_id: UUID, raise_if_not_found: bool = False, session: AsyncIOMotorClientSession | None = None
183
+ self, entity_id: UUID, raise_if_not_found: bool = False, session: AsyncClientSession | None = None
183
184
  ) -> None:
184
185
  """Delete a document by its ID.
185
186
 
@@ -224,7 +225,7 @@ class AbstractRepository(ABC, Generic[DocumentGenericType, EntityGenericType]):
224
225
  skip: int | None = None,
225
226
  limit: int | None = None,
226
227
  sort: None | str | list[tuple[str, SortDirection]] = None,
227
- session: AsyncIOMotorClientSession | None = None,
228
+ session: AsyncClientSession | None = None,
228
229
  ignore_cache: bool = False,
229
230
  fetch_links: bool = False,
230
231
  lazy_parse: bool = False,
@@ -20,16 +20,16 @@ def depends_scheduler_component(
20
20
 
21
21
 
22
22
  if find_spec("beanie") is not None:
23
- from motor.motor_asyncio import AsyncIOMotorDatabase
23
+ from pymongo.asynchronous.database import AsyncDatabase
24
24
 
25
- def depends_odm_database(request: Request = TaskiqDepends()) -> AsyncIOMotorDatabase[Any]:
25
+ def depends_odm_database(request: Request = TaskiqDepends()) -> AsyncDatabase[Any]:
26
26
  """Acquire the ODM database from the request.
27
27
 
28
28
  Args:
29
29
  request (Request): The request.
30
30
 
31
31
  Returns:
32
- AsyncIOMotorClient: The ODM database.
32
+ AsyncDatabase: The ODM database.
33
33
  """
34
34
  return request.app.state.odm_database
35
35
 
@@ -1,10 +1,7 @@
1
1
  """Provides security-related functions for the API."""
2
2
 
3
3
  from .configs import JWTBearerAuthenticationConfig
4
- from .decoders import (
5
- JWTBearerTokenDecoder,
6
- JWTBearerTokenDecoderAbstract,
7
- )
4
+ from .decoders import JWTBearerTokenDecoder, JWTBearerTokenDecoderAbstract, decode_jwt_token_payload
8
5
  from .exceptions import (
9
6
  InvalidJWTError,
10
7
  InvalidJWTPayploadError,
@@ -18,7 +15,7 @@ from .services import (
18
15
  JWTAuthenticationServiceAbstract,
19
16
  )
20
17
  from .stores import JWKStoreAbstract, JWKStoreMemory
21
- from .types import OAuth2Scope
18
+ from .types import JWTToken, OAuth2Audience, OAuth2Issuer, OAuth2Scope, OAuth2Subject
22
19
  from .verifiers import JWTNoneVerifier, JWTVerifierAbstract
23
20
 
24
21
  __all__: list[str] = [
@@ -34,8 +31,13 @@ __all__: list[str] = [
34
31
  "JWTBearerTokenDecoderAbstract",
35
32
  "JWTNoneVerifier",
36
33
  "JWTPayload",
34
+ "JWTToken",
37
35
  "JWTVerifierAbstract",
38
36
  "MissingJWTCredentialsError",
39
37
  "NotVerifiedJWTError",
38
+ "OAuth2Audience",
39
+ "OAuth2Issuer",
40
40
  "OAuth2Scope",
41
+ "OAuth2Subject",
42
+ "decode_jwt_token_payload",
41
43
  ]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastapi_factory_utilities
3
- Version: 0.8.2
3
+ Version: 0.9.1
4
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
@@ -21,7 +21,7 @@ Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
21
21
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
22
  Requires-Dist: aio-pika (>=9.5.7,<10.0.0)
23
23
  Requires-Dist: aiohttp[speedups] (>=3.12.13,<4.0.0)
24
- Requires-Dist: beanie (>=1.30.0,<2.0.0)
24
+ Requires-Dist: beanie (>=2.0.0,<3.0.0)
25
25
  Requires-Dist: fastapi (>=0.115.13,<1)
26
26
  Requires-Dist: opentelemetry-exporter-otlp-proto-grpc (>=1.26.0,<2.0.0)
27
27
  Requires-Dist: opentelemetry-exporter-otlp-proto-http (>=1.26.0,<2.0.0)
@@ -29,14 +29,14 @@ fastapi_factory_utilities/core/plugins/aiopika/publisher/__init__.py,sha256=MGGd
29
29
  fastapi_factory_utilities/core/plugins/aiopika/publisher/abstract.py,sha256=PmIG5zlx-tFUAneHtbknR0Ik5flz8pMTzxcreY2hZ7s,2494
30
30
  fastapi_factory_utilities/core/plugins/aiopika/queue.py,sha256=VivCbsIgqM36P_7VTZdOZ9kGop2m0kPCvDVQ1nEJCTo,2874
31
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
32
+ fastapi_factory_utilities/core/plugins/odm_plugin/builder.py,sha256=uDyfCSoM-pNf1ThKLg21oIjJjwOCxJa28SkBQsB0FhI,8174
33
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
34
+ fastapi_factory_utilities/core/plugins/odm_plugin/depends.py,sha256=gW-mNXmVSa31mYsUJBPX6yu92xyrNwqim5Kq29tOGI4,767
35
35
  fastapi_factory_utilities/core/plugins/odm_plugin/documents.py,sha256=4aQNrD26d0S542_LYmxxm07Q8SWzbGe3PCpho6iWY5Q,1102
36
36
  fastapi_factory_utilities/core/plugins/odm_plugin/exceptions.py,sha256=acnKJB0lGAzDs-7-LjBap8shjP3iV1a7dw7ouPVF27o,551
37
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
38
+ fastapi_factory_utilities/core/plugins/odm_plugin/plugins.py,sha256=PncCn_2Uj7BuYoOYQm8rl9-qcjv-qzGWCLPoNNPH5cw,6299
39
+ fastapi_factory_utilities/core/plugins/odm_plugin/repositories.py,sha256=dCI7oYiWyGOI1LC9JRTNjo74CC5wYsN4WjUN8l4aQ7U,11396
40
40
  fastapi_factory_utilities/core/plugins/opentelemetry_plugin/__init__.py,sha256=xXHn5dUxhgdDDQMpTHf3voolzS0E3zE2RFbtFHJzb38,641
41
41
  fastapi_factory_utilities/core/plugins/opentelemetry_plugin/builder.py,sha256=9npQImifYAbEg0lFG7KwZ8V78SNrPoaINgd8vKitdMw,12509
42
42
  fastapi_factory_utilities/core/plugins/opentelemetry_plugin/configs.py,sha256=pMG9leMB7rtdkdGFLIxXflV7bf9epGrrYPt2N97KZcM,3750
@@ -46,14 +46,14 @@ fastapi_factory_utilities/core/plugins/opentelemetry_plugin/instruments/__init__
46
46
  fastapi_factory_utilities/core/plugins/opentelemetry_plugin/plugins.py,sha256=v9W4bqEljcRgeSL8pf-4yZ7SGXOFmxVoljthvcLdy6Q,5356
47
47
  fastapi_factory_utilities/core/plugins/taskiq_plugins/__init__.py,sha256=zLZh8HU-oY1FL977yXt51AV95p8WCBJY2cleVUU7w6M,850
48
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
49
+ fastapi_factory_utilities/core/plugins/taskiq_plugins/depends.py,sha256=KFYiisQCpkmlqXY0Ma6N6lmJqoM_ukSi24ESqaijaq8,1593
50
50
  fastapi_factory_utilities/core/plugins/taskiq_plugins/exceptions.py,sha256=1Xq_DqDFiQm2YU-2pGxziy-EeMhHiUsUwV0XdY_rQls,456
51
51
  fastapi_factory_utilities/core/plugins/taskiq_plugins/plugin.py,sha256=gUlU2s7aLB2lkAAPdLqVc-BY16PessSYTGMGgNcKCSA,1602
52
52
  fastapi_factory_utilities/core/plugins/taskiq_plugins/schedulers.py,sha256=82Yh7Y_MUxiWjrHPnsW_Ax-CWREAT6eC_bVl-HW5a3E,7208
53
53
  fastapi_factory_utilities/core/protocols.py,sha256=w5FQqMAZ_OulG5hQWkoOapNSnxsjBPq4EjvWNXXdI_c,859
54
54
  fastapi_factory_utilities/core/security/__init__.py,sha256=C_EnEZLMrhmAktNmSD80-0eqhs38AFnTmp-3UC7L0cg,119
55
55
  fastapi_factory_utilities/core/security/abstracts.py,sha256=xas-gFTqWzxWMZNZx4qdtAzYW_XA8vH2N1wlBx0CuN8,1247
56
- fastapi_factory_utilities/core/security/jwt/__init__.py,sha256=yj8OHMAxQyY_vv0CZtSQlBUSchGHomHif2qWPNnv21k,1107
56
+ fastapi_factory_utilities/core/security/jwt/__init__.py,sha256=SffjbZ5eq7ZuJvufBkCpp2wRf5ZTOsiKhwdMpmQ7oHg,1286
57
57
  fastapi_factory_utilities/core/security/jwt/configs.py,sha256=FaqBXdH3W1e95DrFl1QMqF6Teyp5ZvGq42EC8GCwGNM,1367
58
58
  fastapi_factory_utilities/core/security/jwt/decoders.py,sha256=byj--PbnVbBHrZm6lWE2SH3XX37zPuWdujcLgogdB1U,4935
59
59
  fastapi_factory_utilities/core/security/jwt/exceptions.py,sha256=9kxA4JLq9tfBfnwf-Wadpy9RiU8IjcijifqUS8KFhz0,642
@@ -104,8 +104,8 @@ fastapi_factory_utilities/example/models/books/repository.py,sha256=7K63uAsSEGZ2
104
104
  fastapi_factory_utilities/example/services/books/__init__.py,sha256=Z06yNRoA7Zg3TGN-Q9rrvJg6Bbx-qJw661MVwukV6vQ,148
105
105
  fastapi_factory_utilities/example/services/books/services.py,sha256=-x7d4hotUWLzWo5uImMjFmtNcSTHwWv2bfttIbYYKbA,5380
106
106
  fastapi_factory_utilities/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
107
- fastapi_factory_utilities-0.8.2.dist-info/METADATA,sha256=9Di7jC-8E-jnDnihtQw271-alJQBgyCo4VRO4BiHRbc,3741
108
- fastapi_factory_utilities-0.8.2.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
109
- fastapi_factory_utilities-0.8.2.dist-info/entry_points.txt,sha256=IK0VcBexXo4uXQmTrbfhhnnfq4GmXPRn0GBB8hzlsq4,101
110
- fastapi_factory_utilities-0.8.2.dist-info/licenses/LICENSE,sha256=iO1nLzMMst6vEiqgSUrfrbetM7b0bvdzXhbed5tqG8o,1074
111
- fastapi_factory_utilities-0.8.2.dist-info/RECORD,,
107
+ fastapi_factory_utilities-0.9.1.dist-info/METADATA,sha256=u7kvtm77d0XNN9bgzakMsN47MFmaBcQZ2nk18Qxio-8,3740
108
+ fastapi_factory_utilities-0.9.1.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
109
+ fastapi_factory_utilities-0.9.1.dist-info/entry_points.txt,sha256=IK0VcBexXo4uXQmTrbfhhnnfq4GmXPRn0GBB8hzlsq4,101
110
+ fastapi_factory_utilities-0.9.1.dist-info/licenses/LICENSE,sha256=iO1nLzMMst6vEiqgSUrfrbetM7b0bvdzXhbed5tqG8o,1074
111
+ fastapi_factory_utilities-0.9.1.dist-info/RECORD,,