qena-shared-lib 0.1.14__py3-none-any.whl → 0.1.16__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.
- qena_shared_lib/__init__.py +4 -3
- qena_shared_lib/logging.py +3 -7
- qena_shared_lib/rabbitmq/_base.py +26 -13
- qena_shared_lib/rabbitmq/_channel.py +7 -4
- qena_shared_lib/rabbitmq/_listener.py +8 -5
- qena_shared_lib/rabbitmq/_pool.py +4 -1
- qena_shared_lib/rabbitmq/_publisher.py +4 -1
- qena_shared_lib/rabbitmq/_rpc_client.py +11 -6
- qena_shared_lib/scheduler.py +4 -1
- qena_shared_lib/security.py +15 -6
- qena_shared_lib/utils.py +10 -0
- {qena_shared_lib-0.1.14.dist-info → qena_shared_lib-0.1.16.dist-info}/METADATA +21 -17
- {qena_shared_lib-0.1.14.dist-info → qena_shared_lib-0.1.16.dist-info}/RECORD +14 -14
- {qena_shared_lib-0.1.14.dist-info → qena_shared_lib-0.1.16.dist-info}/WHEEL +0 -0
qena_shared_lib/__init__.py
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
try:
|
2
|
+
from . import rabbitmq, scheduler, security
|
3
|
+
except NameError:
|
4
|
+
pass
|
1
5
|
from . import (
|
2
6
|
application,
|
3
7
|
background,
|
@@ -5,10 +9,7 @@ from . import (
|
|
5
9
|
exceptions,
|
6
10
|
http,
|
7
11
|
logging,
|
8
|
-
rabbitmq,
|
9
12
|
remotelogging,
|
10
|
-
scheduler,
|
11
|
-
security,
|
12
13
|
utils,
|
13
14
|
)
|
14
15
|
|
qena_shared_lib/logging.py
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
from functools import lru_cache
|
2
2
|
from logging import (
|
3
|
-
INFO,
|
4
3
|
Formatter,
|
5
4
|
Handler,
|
6
5
|
Logger,
|
@@ -14,15 +13,12 @@ __all__ = [
|
|
14
13
|
"LoggerProvider",
|
15
14
|
]
|
16
15
|
|
17
|
-
ROOT_LOGGER_NAME =
|
16
|
+
ROOT_LOGGER_NAME = (
|
17
|
+
environ.get("QENA_SHARED_LIB_LOGGING_LOGGER_NAME") or "qena_shared_lib"
|
18
|
+
)
|
18
19
|
|
19
20
|
|
20
21
|
class LoggerProvider:
|
21
|
-
def __init__(self) -> None:
|
22
|
-
logger = self.get_logger()
|
23
|
-
|
24
|
-
logger.setLevel(INFO)
|
25
|
-
|
26
22
|
@lru_cache
|
27
23
|
@staticmethod
|
28
24
|
def default() -> "LoggerProvider":
|
@@ -14,10 +14,13 @@ from typing import (
|
|
14
14
|
cast,
|
15
15
|
)
|
16
16
|
|
17
|
-
|
18
|
-
from pika.
|
19
|
-
from pika.
|
20
|
-
from pika.
|
17
|
+
try:
|
18
|
+
from pika.adapters.asyncio_connection import AsyncioConnection
|
19
|
+
from pika.connection import Parameters, URLParameters
|
20
|
+
from pika.exceptions import ChannelClosedByClient, ConnectionClosedByClient
|
21
|
+
from pika.frame import Method
|
22
|
+
except ImportError:
|
23
|
+
pass
|
21
24
|
from prometheus_client import Counter
|
22
25
|
from prometheus_client import Enum as PrometheusEnum
|
23
26
|
from punq import Container, Scope
|
@@ -451,10 +454,12 @@ class RabbitMqManager(AsyncEventLoopMixin):
|
|
451
454
|
).add_done_callback(self._listener_and_service_config_and_init_done)
|
452
455
|
|
453
456
|
def _configure_listeners(self) -> list[Awaitable[Any]]:
|
454
|
-
|
455
|
-
|
457
|
+
assert self._connection is not None
|
458
|
+
|
459
|
+
listeners_configured_coroutines: list[Awaitable[Any]] = []
|
456
460
|
|
457
|
-
|
461
|
+
try:
|
462
|
+
listeners_configured_coroutines.extend(
|
458
463
|
listener.configure(
|
459
464
|
connection=self._connection,
|
460
465
|
channel_pool=self._channel_pool,
|
@@ -464,28 +469,36 @@ class RabbitMqManager(AsyncEventLoopMixin):
|
|
464
469
|
global_retry_policy=self._listener_global_retry_policy,
|
465
470
|
)
|
466
471
|
for listener in self._listeners
|
467
|
-
|
472
|
+
)
|
468
473
|
except Exception as e:
|
469
474
|
listener_configuration_error_future = self.loop.create_future()
|
470
475
|
|
471
476
|
listener_configuration_error_future.set_exception(e)
|
477
|
+
listeners_configured_coroutines.append(
|
478
|
+
listener_configuration_error_future
|
479
|
+
)
|
472
480
|
|
473
|
-
|
481
|
+
return listeners_configured_coroutines
|
474
482
|
|
475
483
|
def _initialize_services(self) -> list[Future[Any]]:
|
476
484
|
assert self._connection is not None
|
477
485
|
|
486
|
+
service_initialization_futures: list[Future[Any]] = []
|
487
|
+
|
478
488
|
try:
|
479
|
-
|
489
|
+
service_initialization_futures.extend(
|
480
490
|
service.initialize(self._connection, self._channel_pool)
|
481
491
|
for service in self._services
|
482
|
-
|
492
|
+
)
|
483
493
|
except Exception as e:
|
484
494
|
service_initialization_error_future = self.loop.create_future()
|
485
495
|
|
486
496
|
service_initialization_error_future.set_exception(e)
|
497
|
+
service_initialization_futures.append(
|
498
|
+
service_initialization_error_future
|
499
|
+
)
|
487
500
|
|
488
|
-
|
501
|
+
return service_initialization_futures
|
489
502
|
|
490
503
|
def _listener_and_service_config_and_init_done(
|
491
504
|
self, future: Future[list[Any]]
|
@@ -521,7 +534,7 @@ class RabbitMqManager(AsyncEventLoopMixin):
|
|
521
534
|
service_count = len(self._services)
|
522
535
|
|
523
536
|
self._logger.info(
|
524
|
-
"
|
537
|
+
"connected to rabbitmq, `%s:%s%s` with `%d` %s and `%d` %s.",
|
525
538
|
params.host,
|
526
539
|
params.port,
|
527
540
|
params.virtual_host,
|
@@ -4,10 +4,13 @@ from random import uniform
|
|
4
4
|
from typing import cast
|
5
5
|
from uuid import UUID, uuid4
|
6
6
|
|
7
|
-
|
8
|
-
from pika.
|
9
|
-
from pika.
|
10
|
-
from pika.
|
7
|
+
try:
|
8
|
+
from pika.adapters.asyncio_connection import AsyncioConnection
|
9
|
+
from pika.channel import Channel
|
10
|
+
from pika.exceptions import ChannelClosedByClient
|
11
|
+
from pika.spec import Basic
|
12
|
+
except ImportError:
|
13
|
+
pass
|
11
14
|
|
12
15
|
from ..logging import LoggerProvider
|
13
16
|
from ..utils import AsyncEventLoopMixin
|
@@ -16,11 +16,14 @@ from time import time
|
|
16
16
|
from types import MappingProxyType
|
17
17
|
from typing import Any, Callable, Collection, TypeVar, cast
|
18
18
|
|
19
|
-
|
20
|
-
from pika
|
21
|
-
from pika.
|
22
|
-
from pika.
|
23
|
-
from pika.
|
19
|
+
try:
|
20
|
+
from pika import BasicProperties
|
21
|
+
from pika.adapters.asyncio_connection import AsyncioConnection
|
22
|
+
from pika.channel import Channel
|
23
|
+
from pika.frame import Method
|
24
|
+
from pika.spec import Basic
|
25
|
+
except ImportError:
|
26
|
+
pass
|
24
27
|
from prometheus_client import Counter, Summary
|
25
28
|
from punq import Container
|
26
29
|
from pydantic import ValidationError
|
@@ -1,7 +1,10 @@
|
|
1
1
|
from asyncio import Lock
|
2
2
|
from uuid import UUID
|
3
3
|
|
4
|
-
|
4
|
+
try:
|
5
|
+
from pika.adapters.asyncio_connection import AsyncioConnection
|
6
|
+
except ImportError:
|
7
|
+
pass
|
5
8
|
|
6
9
|
from ..utils import AsyncEventLoopMixin
|
7
10
|
from ._channel import BaseChannel
|
@@ -5,10 +5,13 @@ from time import time
|
|
5
5
|
from typing import Any, Callable, Generic, TypeVar
|
6
6
|
from uuid import uuid4
|
7
7
|
|
8
|
-
|
9
|
-
from pika
|
10
|
-
from pika.
|
11
|
-
from pika.
|
8
|
+
try:
|
9
|
+
from pika import BasicProperties
|
10
|
+
from pika.channel import Channel
|
11
|
+
from pika.frame import Method
|
12
|
+
from pika.spec import Basic
|
13
|
+
except ImportError:
|
14
|
+
pass
|
12
15
|
from prometheus_client import Counter, Summary
|
13
16
|
from pydantic_core import from_json, to_json
|
14
17
|
|
@@ -166,9 +169,11 @@ class RpcClient(Generic[R], AsyncEventLoopMixin):
|
|
166
169
|
return await self._rpc_future
|
167
170
|
|
168
171
|
def _on_queue_declared(self, message: Any, method: Method) -> None:
|
172
|
+
queue = getattr(method.method, "queue")
|
173
|
+
|
169
174
|
try:
|
170
175
|
self._rpc_reply_consumer_tag = self._channel.basic_consume(
|
171
|
-
queue=
|
176
|
+
queue=queue,
|
172
177
|
on_message_callback=self._on_reply_message,
|
173
178
|
auto_ack=True,
|
174
179
|
)
|
@@ -185,7 +190,7 @@ class RpcClient(Generic[R], AsyncEventLoopMixin):
|
|
185
190
|
routing_key=self._routing_key,
|
186
191
|
properties=BasicProperties(
|
187
192
|
content_type="application/json",
|
188
|
-
reply_to=
|
193
|
+
reply_to=queue,
|
189
194
|
correlation_id=self._correlation_id,
|
190
195
|
headers=self._headers,
|
191
196
|
),
|
qena_shared_lib/scheduler.py
CHANGED
@@ -8,7 +8,10 @@ from os import name as osname
|
|
8
8
|
from typing import Any, Callable, TypeVar, cast
|
9
9
|
from zoneinfo import ZoneInfo
|
10
10
|
|
11
|
-
|
11
|
+
try:
|
12
|
+
from cronsim import CronSim
|
13
|
+
except ImportError:
|
14
|
+
pass
|
12
15
|
from prometheus_client import Enum as PrometheusEnum
|
13
16
|
from punq import Container, Scope
|
14
17
|
|
qena_shared_lib/security.py
CHANGED
@@ -3,11 +3,14 @@ from enum import Enum
|
|
3
3
|
from os import environ
|
4
4
|
from typing import AbstractSet, Annotated, Any, cast
|
5
5
|
|
6
|
+
try:
|
7
|
+
from jwt import JWT, AbstractJWKBase, jwk_from_dict
|
8
|
+
from jwt.exceptions import JWTDecodeError
|
9
|
+
from jwt.utils import get_int_from_datetime, get_time_from_int
|
10
|
+
from passlib.context import CryptContext
|
11
|
+
except ImportError:
|
12
|
+
pass
|
6
13
|
from fastapi import Depends, Header
|
7
|
-
from jwt import JWT, AbstractJWKBase, jwk_from_dict
|
8
|
-
from jwt.exceptions import JWTDecodeError
|
9
|
-
from jwt.utils import get_int_from_datetime, get_time_from_int
|
10
|
-
from passlib.context import CryptContext
|
11
14
|
from pydantic import BaseModel, Field, ValidationError
|
12
15
|
|
13
16
|
from .dependencies.http import DependsOn
|
@@ -27,7 +30,9 @@ __all__ = [
|
|
27
30
|
|
28
31
|
|
29
32
|
MESSAGE = "you are not authorized to access requested resource"
|
30
|
-
RESPONSE_CODE = int(
|
33
|
+
RESPONSE_CODE = int(
|
34
|
+
environ.get("QENA_SHARED_LIB_SECURITY_UNAUTHORIZED_RESPONSE_CODE") or 0
|
35
|
+
)
|
31
36
|
|
32
37
|
|
33
38
|
class PasswordHasher(AsyncEventLoopMixin):
|
@@ -92,7 +97,11 @@ class UserInfo(BaseModel):
|
|
92
97
|
async def extract_user_info(
|
93
98
|
jwt_adapter: Annotated[JwtAdapter, DependsOn(JwtAdapter)],
|
94
99
|
token: Annotated[
|
95
|
-
str | None,
|
100
|
+
str | None,
|
101
|
+
Header(
|
102
|
+
alias=environ.get("QENA_SHARED_LIB_SECURITY_TOKEN_HEADER")
|
103
|
+
or "authorization"
|
104
|
+
),
|
96
105
|
] = None,
|
97
106
|
user_agent: Annotated[
|
98
107
|
str | None, Header(alias="user-agent", include_in_schema=False)
|
qena_shared_lib/utils.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
from asyncio import AbstractEventLoop, get_running_loop
|
2
|
+
from typing import Generator
|
2
3
|
|
3
4
|
from pydantic import TypeAdapter
|
4
5
|
|
@@ -32,3 +33,12 @@ class TypeAdapterCache:
|
|
32
33
|
cls.cache_annotation(annotation)
|
33
34
|
|
34
35
|
return cls._cache[annotation]
|
36
|
+
|
37
|
+
|
38
|
+
class YieldOnce:
|
39
|
+
def __await__(self) -> Generator[None, None, None]:
|
40
|
+
return (yield)
|
41
|
+
|
42
|
+
|
43
|
+
def yield_now() -> YieldOnce:
|
44
|
+
return YieldOnce()
|
@@ -1,17 +1,23 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: qena-shared-lib
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.16
|
4
4
|
Summary: A shared tools for other services
|
5
5
|
Requires-Python: >=3.10
|
6
|
-
Requires-Dist: cronsim==2.6
|
7
6
|
Requires-Dist: fastapi[all]==0.115.6
|
8
|
-
Requires-Dist: httpx==0.27.2
|
9
|
-
Requires-Dist: jwt==1.3.1
|
10
|
-
Requires-Dist: passlib[bcrypt]==1.7.4
|
11
|
-
Requires-Dist: pika==1.3.2
|
12
7
|
Requires-Dist: prometheus-client==0.21.1
|
13
8
|
Requires-Dist: prometheus-fastapi-instrumentator==7.0.2
|
14
9
|
Requires-Dist: punq==0.7.0
|
10
|
+
Requires-Dist: pydantic-core==2.27.1
|
11
|
+
Requires-Dist: pydantic==2.10.3
|
12
|
+
Requires-Dist: starlette==0.41.3
|
13
|
+
Requires-Dist: typing-extensions==4.12.2
|
14
|
+
Provides-Extra: rabbitmq
|
15
|
+
Requires-Dist: pika==1.3.2; extra == 'rabbitmq'
|
16
|
+
Provides-Extra: scheduler
|
17
|
+
Requires-Dist: cronsim==2.6; extra == 'scheduler'
|
18
|
+
Provides-Extra: security
|
19
|
+
Requires-Dist: jwt==1.3.1; extra == 'security'
|
20
|
+
Requires-Dist: passlib[bcrypt]==1.7.4; extra == 'security'
|
15
21
|
Description-Content-Type: text/markdown
|
16
22
|
|
17
23
|
# Qena shared lib
|
@@ -32,9 +38,9 @@ A shared tools for other services. It includes.
|
|
32
38
|
|
33
39
|
## Environment variables
|
34
40
|
|
35
|
-
- `
|
36
|
-
- `
|
37
|
-
- `
|
41
|
+
- `QENA_SHARED_LIB_LOGGING_LOGGER_NAME` root logger name.
|
42
|
+
- `QENA_SHARED_LIB_SECURITY_UNAUTHORIZED_RESPONSE_CODE` an integer response on an authorized access of resource.
|
43
|
+
- `QENA_SHARED_LIB_SECURITY_TOKEN_HEADER` to header key for jwt token.
|
38
44
|
|
39
45
|
## Http
|
40
46
|
|
@@ -51,6 +57,7 @@ def main() -> FastAPI:
|
|
51
57
|
.with_description("A shared tools for other services.")
|
52
58
|
.with_version("0.1.0")
|
53
59
|
.with_environment(Environment.PRODUCTION)
|
60
|
+
.with_default_exception_handlers()
|
54
61
|
)
|
55
62
|
|
56
63
|
app = builder.build()
|
@@ -131,9 +138,7 @@ class UserController(ControllerBase):
|
|
131
138
|
def main() -> FastAPI:
|
132
139
|
...
|
133
140
|
|
134
|
-
builder.with_controllers(
|
135
|
-
UserController
|
136
|
-
])
|
141
|
+
builder.with_controllers(UserController)
|
137
142
|
|
138
143
|
...
|
139
144
|
```
|
@@ -161,9 +166,7 @@ async def login(
|
|
161
166
|
def main() -> FastAPI:
|
162
167
|
...
|
163
168
|
|
164
|
-
builder.with_routers(
|
165
|
-
router
|
166
|
-
])
|
169
|
+
builder.with_routers(router)
|
167
170
|
|
168
171
|
...
|
169
172
|
```
|
@@ -270,6 +273,7 @@ def main() -> FastAPI:
|
|
270
273
|
container=builder.container,
|
271
274
|
)
|
272
275
|
|
276
|
+
rabbitmq.init_default_exception_handlers()
|
273
277
|
rabbitmq.include_listener(UserConsumer)
|
274
278
|
builder.add_singleton(
|
275
279
|
service=RabbitMqManager,
|
@@ -293,7 +297,7 @@ async def store_user(
|
|
293
297
|
publisher = rabbitmq.publisher("UserQueue")
|
294
298
|
|
295
299
|
await publisher.publish(user)
|
296
|
-
# await publisher.
|
300
|
+
# await publisher.publish_as_arguments(user)
|
297
301
|
```
|
298
302
|
|
299
303
|
### RPC client
|
@@ -625,7 +629,7 @@ class UserController(ControllerBase):
|
|
625
629
|
UserInfo,
|
626
630
|
Authorization(
|
627
631
|
user_type="ADMIN",
|
628
|
-
|
632
|
+
persmissions=[
|
629
633
|
"READ"
|
630
634
|
],
|
631
635
|
)
|
@@ -1,31 +1,31 @@
|
|
1
|
-
qena_shared_lib/__init__.py,sha256=
|
1
|
+
qena_shared_lib/__init__.py,sha256=gYwkSbX7aC96BKp7FysOBDOsbli527haUQpaFtSpF7c,418
|
2
2
|
qena_shared_lib/application.py,sha256=4a1RfI9ZqM5iVHCykjQ_zeDfb7lwqqP5uThS1wYWOAU,7111
|
3
3
|
qena_shared_lib/background.py,sha256=A6ohscchVpBzT2igDnAV6WgbJoQtmjqJYLxZBl6HiNE,3323
|
4
4
|
qena_shared_lib/exception_handlers.py,sha256=wEnmWyLZZBnl1zJpkRNr_m_VNdGr85IBWZxhGdlHe-E,7715
|
5
5
|
qena_shared_lib/exceptions.py,sha256=D9Vs2q03VW_Eo7pD_8RYsZGNkVOOQ4Aq9HpUcnxeRlA,11031
|
6
6
|
qena_shared_lib/http.py,sha256=2u5T9aXmUrg5WoRb3uaKUqG_m_mWey_O-KXi_ANVfz4,25047
|
7
|
-
qena_shared_lib/logging.py,sha256=
|
7
|
+
qena_shared_lib/logging.py,sha256=dEDkhBjU5LY7TspdsylO0hCcrPQz-7xiJx6RWKo4otk,1548
|
8
8
|
qena_shared_lib/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
9
|
-
qena_shared_lib/scheduler.py,sha256=
|
10
|
-
qena_shared_lib/security.py,sha256=
|
11
|
-
qena_shared_lib/utils.py,sha256=
|
9
|
+
qena_shared_lib/scheduler.py,sha256=XNXHrUPkYMfV26DQyFJrMJvjXZhFqMoVaknHrE5E_So,13149
|
10
|
+
qena_shared_lib/security.py,sha256=iVk-TUtm9Zl8BZlV51iSyTQOibIiCoHIgVFnXNItrqk,6277
|
11
|
+
qena_shared_lib/utils.py,sha256=yoDbtEAhqa30Fubh6h5w919Vuybq23M8yWG-YOa3Cqc,1032
|
12
12
|
qena_shared_lib/dependencies/__init__.py,sha256=W12RgJbhqZ9GiSV1nLlHmpwPzvQv8t7f4JEoazM_WYg,350
|
13
13
|
qena_shared_lib/dependencies/http.py,sha256=IBsMnRr8Jh8ixf2IcU6n1aYRMazI3fF9GLZxHM2dsXk,1492
|
14
14
|
qena_shared_lib/dependencies/miscellaneous.py,sha256=iGwAjatXb_JVSF13n1vdTRAgSKv19VtHo9ZbjjbkIco,753
|
15
15
|
qena_shared_lib/rabbitmq/__init__.py,sha256=1Rw7OP-A9UacuQWHzKbSOa9zFHa4FsEyFTVgAps01tw,1267
|
16
|
-
qena_shared_lib/rabbitmq/_base.py,sha256=
|
17
|
-
qena_shared_lib/rabbitmq/_channel.py,sha256=
|
16
|
+
qena_shared_lib/rabbitmq/_base.py,sha256=k1RFyMo5zCyUZo7Bn8PPkuCx2pVW9Gb0O08q0WbMFoQ,23125
|
17
|
+
qena_shared_lib/rabbitmq/_channel.py,sha256=IitD3OPgg4dkGq5voSr4U5UOuHmCRGMTi4Gi83_zODk,5932
|
18
18
|
qena_shared_lib/rabbitmq/_exception_handlers.py,sha256=Gc8IXWLddl0qr7KHXWjyq_Rl52zMlb8iQiLO-2zwvlk,5757
|
19
|
-
qena_shared_lib/rabbitmq/_listener.py,sha256=
|
20
|
-
qena_shared_lib/rabbitmq/_pool.py,sha256=
|
21
|
-
qena_shared_lib/rabbitmq/_publisher.py,sha256=
|
22
|
-
qena_shared_lib/rabbitmq/_rpc_client.py,sha256=
|
19
|
+
qena_shared_lib/rabbitmq/_listener.py,sha256=C5J8RqiLCC_ZUMTySqJc3B7fW9_N9cCs2AxsjDeCFyM,48400
|
20
|
+
qena_shared_lib/rabbitmq/_pool.py,sha256=eEJswSoWoWzjh290doFYccn1cwQW6DgbdpHeU-7nZSg,2006
|
21
|
+
qena_shared_lib/rabbitmq/_publisher.py,sha256=aTasICX_XBuq2FEud3luuaLseCkALb8zUt_ht9EjjKs,2506
|
22
|
+
qena_shared_lib/rabbitmq/_rpc_client.py,sha256=BdfsUWRjkmFwD8HLg5Lnrwao98M4Zwj8vS3-Ybk5MmA,9328
|
23
23
|
qena_shared_lib/remotelogging/__init__.py,sha256=DEmzWGadTT9-utyEAAmyVDkWFhsonY4wbWIy1J34C14,245
|
24
24
|
qena_shared_lib/remotelogging/_base.py,sha256=XYd_4iGkXJNT5HC_vLoj5wP4QQp6PCJreVnFv8rQHps,15394
|
25
25
|
qena_shared_lib/remotelogging/logstash/__init__.py,sha256=-sg2V8gYuAKtnHSXfLorpdu_LUB_Gpldw0pCuWIsSc0,186
|
26
26
|
qena_shared_lib/remotelogging/logstash/_base.py,sha256=ZNxE9SjZJW3sWKUUn3i52__X0mZuykaZLL3mp-52EOQ,961
|
27
27
|
qena_shared_lib/remotelogging/logstash/_http_sender.py,sha256=kTUdHE1OOSI72tDbIxmwv1-g8shHldfZ0-nBoSu8TyU,1810
|
28
28
|
qena_shared_lib/remotelogging/logstash/_tcp_sender.py,sha256=hIxDW2zEM07rr7BtgmJ5gR9Cs-MXiPD9qtQoVnrmNJ8,2467
|
29
|
-
qena_shared_lib-0.1.
|
30
|
-
qena_shared_lib-0.1.
|
31
|
-
qena_shared_lib-0.1.
|
29
|
+
qena_shared_lib-0.1.16.dist-info/METADATA,sha256=OgRzBYcHpZnknzpnDXbRRSP7AScsVGvF-rQRV9nUfAc,11819
|
30
|
+
qena_shared_lib-0.1.16.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
31
|
+
qena_shared_lib-0.1.16.dist-info/RECORD,,
|
File without changes
|