qena-shared-lib 0.1.22__tar.gz → 0.1.24__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.
Files changed (50) hide show
  1. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/PKG-INFO +9 -9
  2. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/pyproject.toml +13 -13
  3. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/__init__.py +1 -1
  4. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/eventbus.py +2 -3
  5. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/exceptions.py +4 -4
  6. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/http/_exception_handlers.py +1 -9
  7. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/mongodb.py +30 -23
  8. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/README.md +0 -0
  9. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/alias.py +0 -0
  10. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/application.py +0 -0
  11. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/background.py +0 -0
  12. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/cache.py +0 -0
  13. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/dependencies/__init__.py +0 -0
  14. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/dependencies/http.py +0 -0
  15. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/dependencies/miscellaneous.py +0 -0
  16. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/enums.py +0 -0
  17. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/exception_handling.py +0 -0
  18. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/http/__init__.py +0 -0
  19. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/http/_base.py +0 -0
  20. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/http/_request.py +0 -0
  21. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/http/_response.py +0 -0
  22. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/kafka/__init__.py +0 -0
  23. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/kafka/_base.py +0 -0
  24. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/kafka/_consumer.py +0 -0
  25. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/kafka/_exception_handlers.py +0 -0
  26. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/kafka/_producer.py +0 -0
  27. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/logging.py +0 -0
  28. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/py.typed +0 -0
  29. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/rabbitmq/__init__.py +0 -0
  30. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/rabbitmq/_base.py +0 -0
  31. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/rabbitmq/_channel.py +0 -0
  32. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/rabbitmq/_exception_handlers.py +0 -0
  33. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/rabbitmq/_listener.py +0 -0
  34. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/rabbitmq/_pool.py +0 -0
  35. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/rabbitmq/_publisher.py +0 -0
  36. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/rabbitmq/_rpc_client.py +0 -0
  37. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/rabbitmq/message/__init__.py +0 -0
  38. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/rabbitmq/message/_inbound.py +0 -0
  39. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/rabbitmq/message/_outbound.py +0 -0
  40. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/redis.py +0 -0
  41. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/remotelogging/__init__.py +0 -0
  42. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/remotelogging/_base.py +0 -0
  43. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/remotelogging/logstash/__init__.py +0 -0
  44. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/remotelogging/logstash/_base.py +0 -0
  45. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/remotelogging/logstash/_http_sender.py +0 -0
  46. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/remotelogging/logstash/_tcp_sender.py +0 -0
  47. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/scheduler.py +0 -0
  48. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/security.py +0 -0
  49. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/sync.py +0 -0
  50. {qena_shared_lib-0.1.22 → qena_shared_lib-0.1.24}/src/qena_shared_lib/utils.py +0 -0
@@ -1,24 +1,24 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: qena-shared-lib
3
- Version: 0.1.22
3
+ Version: 0.1.24
4
4
  Summary: A shared tools for other services
5
- Requires-Dist: fastapi[all]==0.115.6
6
- Requires-Dist: prometheus-client==0.21.1
5
+ Requires-Dist: fastapi[all]==0.127.1
6
+ Requires-Dist: prometheus-client==0.22.1
7
7
  Requires-Dist: prometheus-fastapi-instrumentator==7.0.2
8
8
  Requires-Dist: punq==0.7.0
9
- Requires-Dist: pydantic-core==2.27.1
10
- Requires-Dist: pydantic==2.10.3
11
- Requires-Dist: starlette==0.41.3
12
- Requires-Dist: typing-extensions==4.12.2
9
+ Requires-Dist: pydantic-core==2.33.2
10
+ Requires-Dist: pydantic==2.11.10
11
+ Requires-Dist: starlette==0.49.3
12
+ Requires-Dist: typing-extensions==4.14.1
13
13
  Requires-Dist: aiokafka==0.12.0 ; extra == 'all'
14
14
  Requires-Dist: cronsim==2.6 ; extra == 'all'
15
15
  Requires-Dist: jwt==1.3.1 ; extra == 'all'
16
16
  Requires-Dist: passlib[bcrypt]==1.7.4 ; extra == 'all'
17
17
  Requires-Dist: pika==1.3.2 ; extra == 'all'
18
- Requires-Dist: pymongo==4.15.3 ; extra == 'all'
18
+ Requires-Dist: pymongo==4.15.5 ; extra == 'all'
19
19
  Requires-Dist: redis==7.1.0 ; extra == 'all'
20
20
  Requires-Dist: aiokafka==0.12.0 ; extra == 'kafka'
21
- Requires-Dist: pymongo==4.15.3 ; extra == 'mongodb'
21
+ Requires-Dist: pymongo==4.15.5 ; extra == 'mongodb'
22
22
  Requires-Dist: pika==1.3.2 ; extra == 'rabbitmq'
23
23
  Requires-Dist: redis==7.1.0 ; extra == 'redis'
24
24
  Requires-Dist: cronsim==2.6 ; extra == 'scheduler'
@@ -1,18 +1,18 @@
1
1
  [project]
2
2
  name = "qena-shared-lib"
3
- version = "0.1.22"
3
+ version = "0.1.24"
4
4
  description = "A shared tools for other services"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
7
7
  dependencies = [
8
- "fastapi[all]==0.115.6",
9
- "prometheus-client==0.21.1",
8
+ "fastapi[all]==0.127.1",
9
+ "prometheus-client==0.22.1",
10
10
  "prometheus-fastapi-instrumentator==7.0.2",
11
11
  "punq==0.7.0",
12
- "pydantic-core==2.27.1",
13
- "pydantic==2.10.3",
14
- "starlette==0.41.3",
15
- "typing-extensions==4.12.2",
12
+ "pydantic-core==2.33.2",
13
+ "pydantic==2.11.10",
14
+ "starlette==0.49.3",
15
+ "typing-extensions==4.14.1",
16
16
  ]
17
17
 
18
18
  [project.optional-dependencies]
@@ -22,14 +22,14 @@ all = [
22
22
  "jwt==1.3.1",
23
23
  "passlib[bcrypt]==1.7.4",
24
24
  "pika==1.3.2",
25
- "pymongo==4.15.3",
25
+ "pymongo==4.15.5",
26
26
  "redis==7.1.0",
27
27
  ]
28
28
  kafka = [
29
29
  "aiokafka==0.12.0",
30
30
  ]
31
31
  mongodb = [
32
- "pymongo==4.15.3",
32
+ "pymongo==4.15.5",
33
33
  ]
34
34
  rabbitmq = [
35
35
  "pika==1.3.2",
@@ -51,13 +51,13 @@ build-backend = "uv_build"
51
51
 
52
52
  [dependency-groups]
53
53
  dev = [
54
- "pre-commit==4.0.1",
54
+ "pre-commit==4.4.0",
55
55
  "pytest-asyncio==1.2.0",
56
- "pytest-cov==6.0.0",
56
+ "pytest-cov==6.3.0",
57
57
  "pytest-env==1.1.5",
58
58
  "pytest-profiling==1.8.1",
59
- "pytest==8.3.3",
60
- "testcontainers==4.8.2",
59
+ "pytest==8.4.2",
60
+ "testcontainers==4.12.0",
61
61
  ]
62
62
 
63
63
  [tool.ruff]
@@ -10,7 +10,7 @@ try:
10
10
  security,
11
11
  sync,
12
12
  )
13
- except NameError:
13
+ except ModuleNotFoundError:
14
14
  pass
15
15
  from . import (
16
16
  application,
@@ -10,13 +10,12 @@ from pika.frame import Method
10
10
  from pika.spec import Basic, BasicProperties
11
11
  from pydantic_core import to_json
12
12
 
13
- from qena_shared_lib.rabbitmq import (
13
+ from .alias import CamelCaseAliasedBaseModel
14
+ from .rabbitmq import (
14
15
  AbstractRabbitMQService,
15
16
  BaseChannel,
16
17
  ChannelPool,
17
18
  )
18
-
19
- from .alias import CamelCaseAliasedBaseModel
20
19
  from .remotelogging import BaseRemoteLogSender
21
20
  from .utils import AsyncEventLoopMixin
22
21
 
@@ -258,11 +258,11 @@ class PreconditionFailed(ClientError):
258
258
 
259
259
 
260
260
  class PayloadTooLarge(ClientError):
261
- GENERAL_STATUS_CODE = status.HTTP_413_REQUEST_ENTITY_TOO_LARGE
261
+ GENERAL_STATUS_CODE = status.HTTP_413_CONTENT_TOO_LARGE
262
262
 
263
263
 
264
264
  class URITooLong(ClientError):
265
- GENERAL_STATUS_CODE = status.HTTP_414_REQUEST_URI_TOO_LONG
265
+ GENERAL_STATUS_CODE = status.HTTP_414_URI_TOO_LONG
266
266
 
267
267
 
268
268
  class UnsupportedMediaType(ClientError):
@@ -270,7 +270,7 @@ class UnsupportedMediaType(ClientError):
270
270
 
271
271
 
272
272
  class RangeNotSatisfiable(ClientError):
273
- GENERAL_STATUS_CODE = status.HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE
273
+ GENERAL_STATUS_CODE = status.HTTP_416_RANGE_NOT_SATISFIABLE
274
274
 
275
275
 
276
276
  class ExpectationFailed(ClientError):
@@ -286,7 +286,7 @@ class MisdirectedRequest(ClientError):
286
286
 
287
287
 
288
288
  class UnprocessableEntity(ClientError):
289
- GENERAL_STATUS_CODE = status.HTTP_422_UNPROCESSABLE_ENTITY
289
+ GENERAL_STATUS_CODE = status.HTTP_422_UNPROCESSABLE_CONTENT
290
290
 
291
291
 
292
292
  class Locked(ClientError):
@@ -94,20 +94,12 @@ class HTTPServiceExceptionHandler(
94
94
 
95
95
  if exception.response_code is not None:
96
96
  content["code"] = exception.response_code
97
- str_response_code = str(exception.response_code)
98
- extra["responseCode"] = str_response_code
99
-
100
- tags.append(str_response_code)
101
97
 
102
98
  if exception.corrective_action is not None:
103
99
  content["correctiveAction"] = exception.corrective_action
104
100
 
105
101
  if exception.status_code is not None:
106
102
  status_code = exception.status_code
107
- str_status_code = str(status_code)
108
- extra["statusCode"] = str_status_code
109
-
110
- tags.append(str_status_code)
111
103
 
112
104
  if exception.headers is not None:
113
105
  headers = exception.headers
@@ -162,7 +154,7 @@ class RequestValidationErrorHandler(AbstractHttpExceptionHandler):
162
154
  "code": 100,
163
155
  "detail": to_jsonable_python(error.errors()),
164
156
  },
165
- status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
157
+ status_code=status.HTTP_422_UNPROCESSABLE_CONTENT,
166
158
  )
167
159
 
168
160
 
@@ -33,8 +33,8 @@ from .alias import CamelCaseAliasedBaseModel
33
33
  from .logging import LoggerFactory
34
34
 
35
35
  __all__ = [
36
- "AggregatedDocument",
37
36
  "ASCENDING",
37
+ "AggregatedDocument",
38
38
  "AsyncClientSession",
39
39
  "DESCENDING",
40
40
  "Document",
@@ -47,6 +47,7 @@ __all__ = [
47
47
  "IndexModel",
48
48
  "MongoDBManager",
49
49
  "MongoDBObjectId",
50
+ "ObjectId",
50
51
  "ProjectedDocument",
51
52
  "RepositoryBase",
52
53
  "TEXT",
@@ -86,9 +87,11 @@ class MongoDBManager:
86
87
 
87
88
  @asynccontextmanager
88
89
  async def transactional(self) -> AsyncGenerator[AsyncClientSession, None]:
89
- async with self.client.start_session() as session:
90
- async with await session.start_transaction():
91
- yield session
90
+ async with (
91
+ self.client.start_session() as session,
92
+ await session.start_transaction(),
93
+ ):
94
+ yield session
92
95
 
93
96
  def __getitem__(self, document: type["Document"]) -> AsyncCollection:
94
97
  return self._db.get_collection(document.get_collection_name())
@@ -256,6 +259,7 @@ class RepositoryBase(Generic[T]):
256
259
  self._db = db
257
260
  self._session = None
258
261
  self._document_type = None
262
+ self._collection = None
259
263
 
260
264
  @property
261
265
  def db(self) -> MongoDBManager:
@@ -263,7 +267,10 @@ class RepositoryBase(Generic[T]):
263
267
 
264
268
  @property
265
269
  def collection(self) -> AsyncCollection:
266
- return self._db[self.document_type]
270
+ if self._collection is None:
271
+ self._collection = self._db[self.document_type]
272
+
273
+ return self._collection
267
274
 
268
275
  @property
269
276
  def session(self) -> AsyncClientSession | None:
@@ -567,25 +574,25 @@ class RepositoryBase(Generic[T]):
567
574
  limit: int | None = None,
568
575
  session: AsyncClientSession | None = None,
569
576
  ) -> int:
570
- if filter is not None or skip is not None or limit is not None:
571
- options = {}
572
-
573
- if skip is not None:
574
- options["skip"] = skip
575
-
576
- if limit is not None and limit > 0:
577
- options["limit"] = limit
578
-
579
- return cast(
580
- int,
581
- await self.collection.count_documents(
582
- filter=filter or {},
583
- **options,
584
- session=session or self.session,
585
- ),
586
- )
577
+ if filter is None and skip is None and limit is None:
578
+ return cast(int, await self.collection.estimated_document_count())
587
579
 
588
- return cast(int, await self.collection.estimated_document_count())
580
+ options = {}
581
+
582
+ if skip is not None:
583
+ options["skip"] = skip
584
+
585
+ if limit is not None and limit > 0:
586
+ options["limit"] = limit
587
+
588
+ return cast(
589
+ int,
590
+ await self.collection.count_documents(
591
+ filter=filter or {},
592
+ **options,
593
+ session=session or self.session,
594
+ ),
595
+ )
589
596
 
590
597
  @overload
591
598
  def aggregate(