qena-shared-lib 0.1.18__py3-none-any.whl → 0.1.20__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.
@@ -1,8 +1,7 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.3
2
2
  Name: qena-shared-lib
3
- Version: 0.1.18
3
+ Version: 0.1.20
4
4
  Summary: A shared tools for other services
5
- Requires-Python: >=3.10
6
5
  Requires-Dist: fastapi[all]==0.115.6
7
6
  Requires-Dist: prometheus-client==0.21.1
8
7
  Requires-Dist: prometheus-fastapi-instrumentator==7.0.2
@@ -11,21 +10,28 @@ Requires-Dist: pydantic-core==2.27.1
11
10
  Requires-Dist: pydantic==2.10.3
12
11
  Requires-Dist: starlette==0.41.3
13
12
  Requires-Dist: typing-extensions==4.12.2
13
+ Requires-Dist: aiokafka==0.12.0 ; extra == 'all'
14
+ Requires-Dist: cronsim==2.6 ; extra == 'all'
15
+ Requires-Dist: jwt==1.3.1 ; extra == 'all'
16
+ Requires-Dist: passlib[bcrypt]==1.7.4 ; extra == 'all'
17
+ Requires-Dist: pika==1.3.2 ; extra == 'all'
18
+ Requires-Dist: pymongo==4.15.3 ; extra == 'all'
19
+ Requires-Dist: redis==7.1.0 ; extra == 'all'
20
+ Requires-Dist: aiokafka==0.12.0 ; extra == 'kafka'
21
+ Requires-Dist: pymongo==4.15.3 ; extra == 'mongodb'
22
+ Requires-Dist: pika==1.3.2 ; extra == 'rabbitmq'
23
+ Requires-Dist: redis==7.1.0 ; extra == 'redis'
24
+ Requires-Dist: cronsim==2.6 ; extra == 'scheduler'
25
+ Requires-Dist: jwt==1.3.1 ; extra == 'security'
26
+ Requires-Dist: passlib[bcrypt]==1.7.4 ; extra == 'security'
27
+ Requires-Python: >=3.10
14
28
  Provides-Extra: all
15
- Requires-Dist: aiokafka==0.12.0; extra == 'all'
16
- Requires-Dist: cronsim==2.6; extra == 'all'
17
- Requires-Dist: jwt==1.3.1; extra == 'all'
18
- Requires-Dist: passlib[bcrypt]==1.7.4; extra == 'all'
19
- Requires-Dist: pika==1.3.2; extra == 'all'
20
29
  Provides-Extra: kafka
21
- Requires-Dist: aiokafka==0.12.0; extra == 'kafka'
30
+ Provides-Extra: mongodb
22
31
  Provides-Extra: rabbitmq
23
- Requires-Dist: pika==1.3.2; extra == 'rabbitmq'
32
+ Provides-Extra: redis
24
33
  Provides-Extra: scheduler
25
- Requires-Dist: cronsim==2.6; extra == 'scheduler'
26
34
  Provides-Extra: security
27
- Requires-Dist: jwt==1.3.1; extra == 'security'
28
- Requires-Dist: passlib[bcrypt]==1.7.4; extra == 'security'
29
35
  Description-Content-Type: text/markdown
30
36
 
31
37
  # Qena shared lib
@@ -34,23 +40,66 @@ A shared tools for other services. It includes.
34
40
 
35
41
  - FastAPI app builder
36
42
  - A wrapper around fastapi to make it class based.
37
- - RabbitMQ utility class to listen, respond, publish and make rpc request.
43
+ - RabbitMQ utility class to listen , respond , publish and make rpc request.
38
44
  - Remote logging
39
45
  - Logstash utility class to log message in `ecs` ( elastic common schema ).
40
- - A simple task scheduler, to schedule task to run in specific time.
46
+ - A simple task scheduler , to schedule task to run in specific time.
41
47
  - Background task runner.
42
- - Security tools ( password hasher, jwt, acl ).
43
- - IOC container to manager dependencies used across fastapi, rabbitmq manager and schedule manager.
48
+ - Security tools ( password hasher , jwt , acl ).
49
+ - IOC container to manager dependencies used across fastapi , rabbitmq manager and schedule manager.
50
+ - Kafka producer and consumer wrapper.
51
+ - Mongodb client wrapper , with repository and index manager.
52
+ - Redis wrapper with cache and distributed lock manager.
53
+
54
+ ## Installation
44
55
 
45
- # Usage
56
+ It is prefered to use [astral.sh / uv](https://docs.astral.sh/uv) as a package manager.
46
57
 
47
- ## Environment variables
58
+ ``` sh
59
+ $ uv add qena-shared-lib[all]
60
+ ```
61
+ to install all extras , or specific extras `kafka` , `rabbitmq` , `scheduler` , `security` , `redis` or `mongodb`.
62
+
63
+ ## Usage
64
+
65
+ - [Environment variables](#environment-variables)
66
+ - [Http](#http)
67
+ - [Lifespan](#lifespan)
68
+ - [Dependencies](#dependencies)
69
+ - [Controllers](#controllers)
70
+ - [Routers](#routers)
71
+ - [Remote logging](#remote-logging)
72
+ - [Logstash](#logstash)
73
+ - [Rabbitmq](#rabbitmq)
74
+ - [Publisher](#publisher)
75
+ - [RPC client](#rpc-client)
76
+ - [Flow control](#flow-control)
77
+ - [Rpc reply](#rpc-reply)
78
+ - [Retry consumer](#retry-consumer)
79
+ - [Scheduler](#scheduler)
80
+ - [Background](#background)
81
+ - [Security](#security)
82
+ - [Password hasher](#password-hasher)
83
+ - [JWT](#jwt)
84
+ - [ACL](#acl)
85
+ - [Kafka](#kafka)
86
+ - [Producer](#producer)
87
+ - [Consumer](#consumer)
88
+ - [Mongodb](#mongodb)
89
+ - [Aggregation](#aggregation)
90
+ - [Index](#index)
91
+ - [Crud](#crud)
92
+ - [Redis](#redis)
93
+ - [Cache](#cache)
94
+ - [Distribute lock](#distribute-lock)
95
+
96
+ ### Environment variables
48
97
 
49
98
  - `QENA_SHARED_LIB_LOGGING_LOGGER_NAME` root logger name.
50
99
  - `QENA_SHARED_LIB_SECURITY_UNAUTHORIZED_RESPONSE_CODE` an integer response on an authorized access of resource.
51
100
  - `QENA_SHARED_LIB_SECURITY_TOKEN_HEADER` to header key for jwt token.
52
101
 
53
- ## Http
102
+ ### Http
54
103
 
55
104
  To create fastapi app.
56
105
 
@@ -190,9 +239,10 @@ def main() -> FastAPI:
190
239
  ...
191
240
  ```
192
241
 
193
- ## Remote logging
242
+ ### Remote logging
243
+
244
+ #### Logstash
194
245
 
195
- ### Logstash
196
246
  ``` py
197
247
  from qena_shared_lib.remotelogging import BaseRemoteLogSender
198
248
  from qena_shared_lib.remotelogging.logstash import HTTPSender, # TCPSender
@@ -243,7 +293,7 @@ def log_message(
243
293
  remote_logger.info(message)
244
294
  ```
245
295
 
246
- ## Rabbitmq
296
+ ### Rabbitmq
247
297
 
248
298
  To create rabbitmq connection manager.
249
299
 
@@ -291,7 +341,7 @@ def main() -> FastAPI:
291
341
  ...
292
342
  ```
293
343
 
294
- ### Publisher
344
+ #### Publisher
295
345
 
296
346
  ``` py
297
347
  @router.post("")
@@ -308,7 +358,7 @@ async def store_user(
308
358
  # await publisher.publish_as_arguments(user)
309
359
  ```
310
360
 
311
- ### RPC client
361
+ #### RPC client
312
362
 
313
363
  ``` py
314
364
  @router.get("")
@@ -327,7 +377,7 @@ async def get_user(
327
377
  return user
328
378
  ```
329
379
 
330
- ### Flow control
380
+ #### Flow control
331
381
 
332
382
  ``` py
333
383
  from qena_shared_lib.rabbitmq import ... , ListenerContext
@@ -346,7 +396,7 @@ class UserConsumer(ListenerBase):
346
396
 
347
397
  ```
348
398
 
349
- ### Rpc reply
399
+ #### Rpc reply
350
400
 
351
401
  Optionally it is possible to reply to rpc calls, through.
352
402
 
@@ -366,7 +416,7 @@ class UserWorker(ListenerBase):
366
416
  ...
367
417
  ```
368
418
 
369
- ### Retry consumer
419
+ #### Retry consumer
370
420
 
371
421
  Consumer can retry to consumer a message in an event of failure.
372
422
 
@@ -440,7 +490,7 @@ def main() -> FastAPI:
440
490
 
441
491
 
442
492
 
443
- ## Scheduler
493
+ ### Scheduler
444
494
 
445
495
  ``` py
446
496
  from qena_shared_lib.scheduler import (
@@ -501,7 +551,7 @@ def main() -> FastAPI:
501
551
  ...
502
552
  ```
503
553
 
504
- ## Background
554
+ ### Background
505
555
 
506
556
  ``` py
507
557
  from qena_shared_lib.background import Background
@@ -545,9 +595,9 @@ async def process_data(
545
595
  background.add_task(BackgroundTask(data_processor, data))
546
596
  ```
547
597
 
548
- ## Security
598
+ ### Security
549
599
 
550
- ### Password hasher
600
+ #### Password hasher
551
601
 
552
602
  ``` py
553
603
  from qena_shared_lib.security import PasswordHasher
@@ -579,7 +629,7 @@ def main() -> FastAPI:
579
629
  ...
580
630
  ```
581
631
 
582
- ### JWT
632
+ #### JWT
583
633
 
584
634
  ``` py
585
635
  from qena_shared_lib.security import JwtAdapter
@@ -621,7 +671,7 @@ def main() -> FastAPI:
621
671
  ...
622
672
  ```
623
673
 
624
- ### ACL
674
+ #### ACL
625
675
 
626
676
  ``` py
627
677
  from qena_shared_lib.security import Authorization
@@ -655,3 +705,313 @@ async def get_users(
655
705
  )
656
706
  ...
657
707
  ```
708
+
709
+ ### Kafka
710
+
711
+ ``` py
712
+ from qena_shared_lib.kafka import KafkaManager
713
+
714
+
715
+ @asynccontextmanager
716
+ async def lifespan(app: FastAPI):
717
+ kafka = get_service(KafkaManager)
718
+
719
+ await kafka.connect()
720
+
721
+ yield
722
+
723
+ await kafka.disconnect()
724
+
725
+
726
+ def main() -> FastAPI:
727
+ ...
728
+
729
+ kafka = KafkaManager(
730
+ remote_logger=...,
731
+ bootstrap_servers="127.0.0.1:9092",
732
+ )
733
+
734
+ builder.with_singleton(
735
+ service=KafkaManager,
736
+ instance=kafka,
737
+ )
738
+
739
+ ...
740
+ ```
741
+
742
+ #### Producer
743
+
744
+ ``` py
745
+ class UserService:
746
+ def __init__(self, kafka: KafkaManager):
747
+ self._kafka = kafka
748
+
749
+ async def create_user(self):
750
+ ...
751
+
752
+ async with await self._kafka.producer("user") as producer:
753
+ await producer.send(key="some_key", value=user)
754
+
755
+ ...
756
+ ```
757
+
758
+ #### Consumer
759
+
760
+ ``` py
761
+ from qena_shared_lib.kafka import (
762
+ ConsumerBase,
763
+ consume,
764
+ consumer,
765
+ )
766
+
767
+
768
+ @consumer(["user"])
769
+ class USerConsumer(ConsumerBase):
770
+ def __init__(self, user_service: UserService):
771
+ self._user_service = user_service
772
+
773
+ @consume()
774
+ async def user_created(self, key: Any | None, value: Any | None):
775
+ ...
776
+
777
+ await self._user_service.create_user(...)
778
+
779
+ ...
780
+ ```
781
+
782
+ ### Mongodb
783
+
784
+ ``` py
785
+ from qena_shared_lib.mongodb import MongoDBManager
786
+
787
+
788
+ @asynccontextmanager
789
+ async def lifespan(app: FastAPI):
790
+ db = get_service(MongoDBManager)
791
+
792
+ await db.connect()
793
+
794
+ yield
795
+
796
+ await db.disconnect()
797
+
798
+
799
+ def main() -> FastAPI:
800
+ ...
801
+
802
+ db = MongoDBManager(
803
+ connection_string="mongodb://127.0.0.1:27017",
804
+ db="userDb"
805
+ )
806
+
807
+ builder.with_singleton(
808
+ service=MongoDBManager,
809
+ instance=db
810
+ )
811
+
812
+ ...
813
+ ```
814
+
815
+ #### Crud
816
+
817
+ ``` py
818
+ from qena_shared_lib.mongodb import (
819
+ Document,
820
+ MongoDBManager,
821
+ ProjectedDocument,
822
+ RepositoryBase,
823
+ )
824
+
825
+
826
+ class User(Document):
827
+ __collection_name__ = "users"
828
+
829
+ full_name: str
830
+ phone: str
831
+
832
+
833
+ class FullNameProjectedUser(ProjectedDocument):
834
+ full_name: str
835
+
836
+
837
+ class UserRepository(RepositoryBase[User]):
838
+ pass
839
+
840
+
841
+ class UserService:
842
+ def __init__(self, user_repository: UserRepository):
843
+ self._user_repository = user_repository
844
+
845
+ async def add_user(self):
846
+ await self._user_repository.insert(
847
+ User(
848
+ full_name="user one",
849
+ phone="+251900000000"
850
+ )
851
+ )
852
+
853
+ async def get_user(self):
854
+ user = await self._user_repository.find_by_filter(
855
+ filter={"phone": "+251900000000"}
856
+ )
857
+
858
+ async def get_user_fullname(self):
859
+ user = await self._user_repository.find_by_filter(
860
+ filter={"phone": "+251900000000"}, projection=FullNameProjectedUser
861
+ )
862
+
863
+ async def update_user(self):
864
+ user = await self._user_repository.find_by_filter(
865
+ filter={"phone": "+251900000000"}, projection
866
+ )
867
+ user.phone = "+251900000001"
868
+
869
+ await user_repository.replace(user)
870
+ ```
871
+
872
+ #### Aggregation
873
+
874
+ ``` py
875
+ class AggregatedUser(AggregatedDocument):
876
+ __pipeline__ = [
877
+ {"$match": {"phone": {"$in": ["+251900000000", "+251900000001"]}}},
878
+ {"$project": {"fullName": True}},
879
+ ]
880
+
881
+ full_name: str
882
+
883
+ class UserService:
884
+ ...
885
+
886
+ async def get_user_fullnames(self):
887
+ users = user_repository.aggregate(aggregation=AggregatedUser)
888
+
889
+ ...
890
+ ```
891
+
892
+ #### Index
893
+
894
+ ``` py
895
+ from qena_shared_lib.mongodb import Document, IndexManager, IndexModel
896
+
897
+
898
+ class User(Document):
899
+ __collection_name__ = "users"
900
+ __indexes__ = [IndexModel("phone")]
901
+
902
+ full_name: str
903
+ phone: str
904
+
905
+
906
+ async def manage_indexes():
907
+ ...
908
+
909
+ index_manager = IndexManager(db=db, documents=[User])
910
+
911
+ await index_manager.create_indexes
912
+
913
+ ...
914
+
915
+ await index_manager.drop_indexes()
916
+
917
+ ...
918
+ ```
919
+
920
+ ### Redis
921
+
922
+ ``` py
923
+ from qena_shared_lib.redis import RedisManager
924
+
925
+
926
+ @asynccontextmanager
927
+ async def lifespan(app: FastAPI):
928
+ redis_manager = get_service(RedisManager)
929
+
930
+ await dredis_managerb.connect()
931
+
932
+ yield
933
+
934
+ await redis_manager.disconnect()
935
+
936
+
937
+ def main() -> FastAPI:
938
+ ...
939
+
940
+ redis_manager = RedisManager("redis://127.0.0.1:6379")
941
+
942
+ builder.with_singleton(
943
+ service=RedisManager,
944
+ instance=redis_manager
945
+ )
946
+
947
+ ...
948
+ ```
949
+
950
+ #### Cache
951
+
952
+ ``` py
953
+ from qena_shared_lib.cache import CachedObject, CacheManager
954
+
955
+
956
+ def main() -> FastAPI:
957
+ ...
958
+
959
+ cache_manager = CacheManager()
960
+
961
+ redis_manager.add(cache_manager)
962
+ builder.with_singleton(
963
+ service=CacheManager,
964
+ instance=cache_manager
965
+ )
966
+
967
+ ...
968
+
969
+
970
+ class UserCache(CachedObject):
971
+ full_name: str
972
+
973
+
974
+ class UserService:
975
+ def __init__(self, cache_manager: CacheManager):
976
+ self._cache_manager = cache_manager
977
+
978
+ async def cache_user(self):
979
+ await self._cache_manager.set(
980
+ UserCache(full_name="user one")
981
+ )
982
+
983
+ async def get_cached_user(self):
984
+ user_cache = await self._cache_manager.get(UserCache)
985
+
986
+ async def unset_cached_user(self):
987
+ await self._cache_manager.unset(UserCache)
988
+ ```
989
+
990
+ #### Distribute lock
991
+
992
+ ``` py
993
+ from qena_shared_lib.sync import DistributedLockManager
994
+
995
+
996
+ def main() -> FastAPI:
997
+ ...
998
+
999
+ distributed_lock_manager = DistributedLockManager()
1000
+
1001
+ redis_manager.add(distributed_lock_manager)
1002
+ builder.with_singleton(
1003
+ service=DistributedLockManager,
1004
+ instance=distributed_lock_manager
1005
+ )
1006
+
1007
+ ...
1008
+
1009
+
1010
+ class UserService:
1011
+ def __init__(self, distributed_lock_manager: DistributedLockManager):
1012
+ self._distributed_lock_manager = distributed_lock_manager
1013
+
1014
+ async def create_user(self):
1015
+ async with self._distributed_lock_manager("user_one_create") as _:
1016
+ ...
1017
+ ```
@@ -1,38 +1,50 @@
1
- qena_shared_lib/__init__.py,sha256=1mV9wGMBQc_Hb2NLNJmcAOgjzsno9vnc34o3mRfr7eI,438
1
+ qena_shared_lib/__init__.py,sha256=cAuC24s_ef_CZNAqZpC2SnkfvLcZsUehrfAdQo15t8E,651
2
+ qena_shared_lib/alias.py,sha256=y0qXPNR6CHWYHaci9JgMbnV5x18PHkaTZy03vnpUpXQ,645
2
3
  qena_shared_lib/application.py,sha256=0pvuy5PxH5fw5FptTI4ksUxNAh-hzr_d5beAMDiBzi8,7117
3
4
  qena_shared_lib/background.py,sha256=SCZhZOwWgv5T0X4tMB_aTecKlMdT12bzqpbA4qoZQPA,3473
4
- qena_shared_lib/exception_handling.py,sha256=oiPVaxD74y-dbB8hJsncPNd-Fphot60Q60tZQTbCZ50,13392
5
- qena_shared_lib/exceptions.py,sha256=vKqZjU5XmVNE-zjQ5kZ9HlOELbAD8E6TPP1Kv6tPVKE,14593
6
- qena_shared_lib/logging.py,sha256=HZiqbXpmJsAI7hheAaQ9EA8uj9yU0pMVCg64d_V0wzA,1748
7
- qena_shared_lib/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
- qena_shared_lib/scheduler.py,sha256=Spp5PnpFJ0U4aLeFCNmje9zUA4zwkL-b7X8SSGkGssM,13579
9
- qena_shared_lib/security.py,sha256=RAXBkfhytJl-2SOXYQTJMnUb789-8DNZKRjRtpod16Y,6372
10
- qena_shared_lib/utils.py,sha256=crD8NJD1Se7ZHPCaQBCi3c7Y46lMvk8OsN_bZTbcyto,1184
5
+ qena_shared_lib/cache.py,sha256=tgOqy6fi_fN0EEhclPdlWWVAM2F0rd0eAU7ZyJm4CQQ,1676
11
6
  qena_shared_lib/dependencies/__init__.py,sha256=W12RgJbhqZ9GiSV1nLlHmpwPzvQv8t7f4JEoazM_WYg,350
12
7
  qena_shared_lib/dependencies/http.py,sha256=IBsMnRr8Jh8ixf2IcU6n1aYRMazI3fF9GLZxHM2dsXk,1492
13
8
  qena_shared_lib/dependencies/miscellaneous.py,sha256=iGwAjatXb_JVSF13n1vdTRAgSKv19VtHo9ZbjjbkIco,753
14
- qena_shared_lib/http/__init__.py,sha256=OqKrE7jYFjy4gAYYtjTOp2cZGNU2GIEMFcyOQYdbalk,1599
9
+ qena_shared_lib/enums.py,sha256=qYOZUD8Or0O1uGoNRShMp-SzmkXDQ31djMVTG_yGxL4,107
10
+ qena_shared_lib/eventbus.py,sha256=Qk4TiJHGlnUNQkLTIWEuHe3MPyRmwUmkjbk5Y4dNSxE,11501
11
+ qena_shared_lib/exception_handling.py,sha256=oiPVaxD74y-dbB8hJsncPNd-Fphot60Q60tZQTbCZ50,13392
12
+ qena_shared_lib/exceptions.py,sha256=pByxZnxesxLVyHF2ARd0C0ioWLYZZVOtxPytJnF5EDo,14567
13
+ qena_shared_lib/http/__init__.py,sha256=F6CqzPsRx55fa5ozRkk2lSNJu28KPw9uI8zQwoo4lVU,2055
15
14
  qena_shared_lib/http/_base.py,sha256=5jPAjiDmJIxjtMdhxNHpcTM_xbXC5eBMvy3U0tpB25Q,25199
16
15
  qena_shared_lib/http/_exception_handlers.py,sha256=fkxW7KqyCy923f4f6s1qmd8gO-Oaoi-mLR9gaIWC-PU,6265
16
+ qena_shared_lib/http/_request.py,sha256=kppCnS5zZfvKl-hNO6ysqkVdtoXshFp6Ue_0O5apqXQ,426
17
+ qena_shared_lib/http/_response.py,sha256=sUd2ggu6IeKtNhoYAr-xZmEn40HLq5vLHpRcV7mZFnk,432
17
18
  qena_shared_lib/kafka/__init__.py,sha256=59aii_0Is8cwEVQlK4w9Jk3YrOqojTa6ReJO0SBedog,392
18
19
  qena_shared_lib/kafka/_base.py,sha256=H27YrSgA8iifSDkptFRSTcR4P-hoMqOLqPXpw9WpgvA,8251
19
20
  qena_shared_lib/kafka/_consumer.py,sha256=aEOtAqMhFPIMYbKK_BMDwR2rd_eaDzBJ6xR3Ud5LhPE,19294
20
21
  qena_shared_lib/kafka/_exception_handlers.py,sha256=D7Xh5eSpSkumQKvPfBmVB_E6vQxD58y41bFpP5Jzhqk,4084
21
22
  qena_shared_lib/kafka/_producer.py,sha256=QtYfKzNtxeIT1EtGpS-tvFC342oPoleF1AOl20LfNXs,3941
22
- qena_shared_lib/rabbitmq/__init__.py,sha256=h5mkAbluZBgZZXw52dO4adNjlvhE-qS1LJUPn4Kpvhs,1217
23
+ qena_shared_lib/logging.py,sha256=HZiqbXpmJsAI7hheAaQ9EA8uj9yU0pMVCg64d_V0wzA,1748
24
+ qena_shared_lib/mongodb.py,sha256=CHkegKThenGB4A9bb0wNMLYGdrGo8-jDMx_3wRngIJ4,17056
25
+ qena_shared_lib/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
26
+ qena_shared_lib/rabbitmq/__init__.py,sha256=g15fP9XQ1CHFBXZmeAxQcsppQ0Nx62gJ4VOK8nzW7T4,1254
23
27
  qena_shared_lib/rabbitmq/_base.py,sha256=pKJL0PNrhUOXw4XUJ1iZsuCPVY3ykvO8ebIfeX9HwXo,21502
24
28
  qena_shared_lib/rabbitmq/_channel.py,sha256=l67iMB2NqprQeypHBIS_jLeiQEqYxunh76-wq8zEHLw,5898
25
29
  qena_shared_lib/rabbitmq/_exception_handlers.py,sha256=jL4McHxetlNOTpmnLggg3akwsVkXy8dGQLHHPPEDeiM,3718
26
- qena_shared_lib/rabbitmq/_listener.py,sha256=Nl8-YWxf8xlF70vqtwmJrpkjBDKrcqjJHNRFpAVxS-I,51969
30
+ qena_shared_lib/rabbitmq/_listener.py,sha256=BwZ3YVTGI2sIMJWMoL7SnYN_RGfjBr1tYxaGqPkyrhc,51119
27
31
  qena_shared_lib/rabbitmq/_pool.py,sha256=eEJswSoWoWzjh290doFYccn1cwQW6DgbdpHeU-7nZSg,2006
28
32
  qena_shared_lib/rabbitmq/_publisher.py,sha256=57WruxVlZemA7XVDNHSNB3_2gI-ycIKDobepLGa_QoM,2511
29
33
  qena_shared_lib/rabbitmq/_rpc_client.py,sha256=DKYvyPnmaMfa8Ymw1nLKinuFeG_H0Lc1OL8EUjN8M6U,9353
34
+ qena_shared_lib/rabbitmq/message/__init__.py,sha256=J0wKjSuwOC7urUffWdxGZ7x_F9S5S6EryC9NxuysOhY,439
35
+ qena_shared_lib/rabbitmq/message/_inbound.py,sha256=v744Vr4JZn9iE4GnD8uoQQLiD9TuKGZgLIiMwIcLGp4,272
36
+ qena_shared_lib/rabbitmq/message/_outbound.py,sha256=axf7OF2rA05ixdjM3PiHG33I3dJU2gS8GP-ooefX4Jk,274
37
+ qena_shared_lib/redis.py,sha256=N15rYGX5iMbFvFzCnSTtOBD_EIrdZ9xkoS1Sw9s-3tI,1262
30
38
  qena_shared_lib/remotelogging/__init__.py,sha256=DEmzWGadTT9-utyEAAmyVDkWFhsonY4wbWIy1J34C14,245
31
- qena_shared_lib/remotelogging/_base.py,sha256=NL-eoC9e3nc1757qi3V__-k7hiMwP6_6TkDKXEd7v5E,15376
39
+ qena_shared_lib/remotelogging/_base.py,sha256=XykbHFzzZ7oqUFeuLDUkw1cqkjqzzOt6Cg8hR8aLzDc,15539
32
40
  qena_shared_lib/remotelogging/logstash/__init__.py,sha256=-sg2V8gYuAKtnHSXfLorpdu_LUB_Gpldw0pCuWIsSc0,186
33
- qena_shared_lib/remotelogging/logstash/_base.py,sha256=INDQXgLTLiLx-wTIMw30a_y1Y6bg9mvxKzC5_ZTmvy8,959
41
+ qena_shared_lib/remotelogging/logstash/_base.py,sha256=GCO3P6RSiJO-LT4FIPawPSkjFDt9FZYetl09txQrwpQ,1015
34
42
  qena_shared_lib/remotelogging/logstash/_http_sender.py,sha256=2PUZ526zzLiP6wfW6AeVfzm3qowv5KpHYXMgkd6xrn0,1776
35
43
  qena_shared_lib/remotelogging/logstash/_tcp_sender.py,sha256=s7oW7ovYq8OHqN8tF4rXhPK9knCHx5Dsx5Bu_p4XerQ,2455
36
- qena_shared_lib-0.1.18.dist-info/METADATA,sha256=xFJcPojg9ZwzmVFyH9ipRFdndtZ7zhNE_jifyebqzxM,12142
37
- qena_shared_lib-0.1.18.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
38
- qena_shared_lib-0.1.18.dist-info/RECORD,,
44
+ qena_shared_lib/scheduler.py,sha256=Spp5PnpFJ0U4aLeFCNmje9zUA4zwkL-b7X8SSGkGssM,13579
45
+ qena_shared_lib/security.py,sha256=RAXBkfhytJl-2SOXYQTJMnUb789-8DNZKRjRtpod16Y,6372
46
+ qena_shared_lib/sync.py,sha256=79aGGWGYg_oGY9jTav1kghD8BSRY-_oNYdx3tuExr20,2541
47
+ qena_shared_lib/utils.py,sha256=crD8NJD1Se7ZHPCaQBCi3c7Y46lMvk8OsN_bZTbcyto,1184
48
+ qena_shared_lib-0.1.20.dist-info/WHEEL,sha256=k57ZwB-NkeM_6AsPnuOHv5gI5KM5kPD6Vx85WmGEcI0,78
49
+ qena_shared_lib-0.1.20.dist-info/METADATA,sha256=NXMw-mncYxD5lp76H1gsdJpqoOTmwYldBIkxyXMYNfo,19281
50
+ qena_shared_lib-0.1.20.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: uv 0.9.4
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -1,4 +0,0 @@
1
- Wheel-Version: 1.0
2
- Generator: hatchling 1.27.0
3
- Root-Is-Purelib: true
4
- Tag: py3-none-any