qena-shared-lib 0.1.23__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.23 → qena_shared_lib-0.1.24}/PKG-INFO +9 -9
  2. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/pyproject.toml +13 -13
  3. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/src/qena_shared_lib/__init__.py +1 -1
  4. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/src/qena_shared_lib/eventbus.py +2 -3
  5. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/src/qena_shared_lib/exceptions.py +4 -4
  6. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/src/qena_shared_lib/http/_exception_handlers.py +1 -1
  7. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/src/qena_shared_lib/mongodb.py +28 -22
  8. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/README.md +0 -0
  9. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/src/qena_shared_lib/alias.py +0 -0
  10. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/src/qena_shared_lib/application.py +0 -0
  11. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/src/qena_shared_lib/background.py +0 -0
  12. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/src/qena_shared_lib/cache.py +0 -0
  13. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/src/qena_shared_lib/dependencies/__init__.py +0 -0
  14. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/src/qena_shared_lib/dependencies/http.py +0 -0
  15. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/src/qena_shared_lib/dependencies/miscellaneous.py +0 -0
  16. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/src/qena_shared_lib/enums.py +0 -0
  17. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/src/qena_shared_lib/exception_handling.py +0 -0
  18. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/src/qena_shared_lib/http/__init__.py +0 -0
  19. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/src/qena_shared_lib/http/_base.py +0 -0
  20. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/src/qena_shared_lib/http/_request.py +0 -0
  21. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/src/qena_shared_lib/http/_response.py +0 -0
  22. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/src/qena_shared_lib/kafka/__init__.py +0 -0
  23. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/src/qena_shared_lib/kafka/_base.py +0 -0
  24. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/src/qena_shared_lib/kafka/_consumer.py +0 -0
  25. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/src/qena_shared_lib/kafka/_exception_handlers.py +0 -0
  26. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/src/qena_shared_lib/kafka/_producer.py +0 -0
  27. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/src/qena_shared_lib/logging.py +0 -0
  28. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/src/qena_shared_lib/py.typed +0 -0
  29. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/src/qena_shared_lib/rabbitmq/__init__.py +0 -0
  30. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/src/qena_shared_lib/rabbitmq/_base.py +0 -0
  31. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/src/qena_shared_lib/rabbitmq/_channel.py +0 -0
  32. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/src/qena_shared_lib/rabbitmq/_exception_handlers.py +0 -0
  33. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/src/qena_shared_lib/rabbitmq/_listener.py +0 -0
  34. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/src/qena_shared_lib/rabbitmq/_pool.py +0 -0
  35. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/src/qena_shared_lib/rabbitmq/_publisher.py +0 -0
  36. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/src/qena_shared_lib/rabbitmq/_rpc_client.py +0 -0
  37. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/src/qena_shared_lib/rabbitmq/message/__init__.py +0 -0
  38. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/src/qena_shared_lib/rabbitmq/message/_inbound.py +0 -0
  39. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/src/qena_shared_lib/rabbitmq/message/_outbound.py +0 -0
  40. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/src/qena_shared_lib/redis.py +0 -0
  41. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/src/qena_shared_lib/remotelogging/__init__.py +0 -0
  42. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/src/qena_shared_lib/remotelogging/_base.py +0 -0
  43. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/src/qena_shared_lib/remotelogging/logstash/__init__.py +0 -0
  44. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/src/qena_shared_lib/remotelogging/logstash/_base.py +0 -0
  45. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/src/qena_shared_lib/remotelogging/logstash/_http_sender.py +0 -0
  46. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/src/qena_shared_lib/remotelogging/logstash/_tcp_sender.py +0 -0
  47. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/src/qena_shared_lib/scheduler.py +0 -0
  48. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/src/qena_shared_lib/security.py +0 -0
  49. {qena_shared_lib-0.1.23 → qena_shared_lib-0.1.24}/src/qena_shared_lib/sync.py +0 -0
  50. {qena_shared_lib-0.1.23 → 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.23
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.23"
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):
@@ -154,7 +154,7 @@ class RequestValidationErrorHandler(AbstractHttpExceptionHandler):
154
154
  "code": 100,
155
155
  "detail": to_jsonable_python(error.errors()),
156
156
  },
157
- status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
157
+ status_code=status.HTTP_422_UNPROCESSABLE_CONTENT,
158
158
  )
159
159
 
160
160
 
@@ -87,9 +87,11 @@ class MongoDBManager:
87
87
 
88
88
  @asynccontextmanager
89
89
  async def transactional(self) -> AsyncGenerator[AsyncClientSession, None]:
90
- async with self.client.start_session() as session:
91
- async with await session.start_transaction():
92
- yield session
90
+ async with (
91
+ self.client.start_session() as session,
92
+ await session.start_transaction(),
93
+ ):
94
+ yield session
93
95
 
94
96
  def __getitem__(self, document: type["Document"]) -> AsyncCollection:
95
97
  return self._db.get_collection(document.get_collection_name())
@@ -257,6 +259,7 @@ class RepositoryBase(Generic[T]):
257
259
  self._db = db
258
260
  self._session = None
259
261
  self._document_type = None
262
+ self._collection = None
260
263
 
261
264
  @property
262
265
  def db(self) -> MongoDBManager:
@@ -264,7 +267,10 @@ class RepositoryBase(Generic[T]):
264
267
 
265
268
  @property
266
269
  def collection(self) -> AsyncCollection:
267
- 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
268
274
 
269
275
  @property
270
276
  def session(self) -> AsyncClientSession | None:
@@ -568,25 +574,25 @@ class RepositoryBase(Generic[T]):
568
574
  limit: int | None = None,
569
575
  session: AsyncClientSession | None = None,
570
576
  ) -> int:
571
- if filter is not None or skip is not None or limit is not None:
572
- options = {}
573
-
574
- if skip is not None:
575
- options["skip"] = skip
576
-
577
- if limit is not None and limit > 0:
578
- options["limit"] = limit
579
-
580
- return cast(
581
- int,
582
- await self.collection.count_documents(
583
- filter=filter or {},
584
- **options,
585
- session=session or self.session,
586
- ),
587
- )
577
+ if filter is None and skip is None and limit is None:
578
+ return cast(int, await self.collection.estimated_document_count())
579
+
580
+ options = {}
588
581
 
589
- return cast(int, await self.collection.estimated_document_count())
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
+ )
590
596
 
591
597
  @overload
592
598
  def aggregate(