karrio-server 2025.5rc31__py3-none-any.whl → 2025.5rc32__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.
- karrio/server/VERSION +1 -1
- karrio/server/settings/apm.py +1 -1
- karrio/server/settings/base.py +85 -46
- karrio/server/settings/cache.py +44 -9
- karrio/server/settings/workers.py +29 -6
- {karrio_server-2025.5rc31.dist-info → karrio_server-2025.5rc32.dist-info}/METADATA +2 -1
- {karrio_server-2025.5rc31.dist-info → karrio_server-2025.5rc32.dist-info}/RECORD +10 -10
- {karrio_server-2025.5rc31.dist-info → karrio_server-2025.5rc32.dist-info}/WHEEL +0 -0
- {karrio_server-2025.5rc31.dist-info → karrio_server-2025.5rc32.dist-info}/entry_points.txt +0 -0
- {karrio_server-2025.5rc31.dist-info → karrio_server-2025.5rc32.dist-info}/top_level.txt +0 -0
karrio/server/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2025.
|
|
1
|
+
2025.5rc32
|
karrio/server/settings/apm.py
CHANGED
|
@@ -164,7 +164,7 @@ if OTEL_ENABLED and OTEL_EXPORTER_OTLP_ENDPOINT:
|
|
|
164
164
|
pass # Psycopg2 might not be installed
|
|
165
165
|
|
|
166
166
|
# Instrument Redis if configured
|
|
167
|
-
if config("REDIS_HOST", default=None):
|
|
167
|
+
if config("REDIS_URL", default=None) or config("REDIS_HOST", default=None):
|
|
168
168
|
try:
|
|
169
169
|
RedisInstrumentor().instrument()
|
|
170
170
|
except Exception:
|
karrio/server/settings/base.py
CHANGED
|
@@ -31,9 +31,11 @@ config = decouple.AutoConfig(search_path=Path().resolve())
|
|
|
31
31
|
|
|
32
32
|
if not config("SECRET_KEY", default=None):
|
|
33
33
|
try:
|
|
34
|
+
# Note: Using print here intentionally as logging isn't configured yet
|
|
34
35
|
print("> fallback .env.sample...")
|
|
35
36
|
config = decouple.Config(decouple.RepositoryEnv(".env.sample"))
|
|
36
37
|
except Exception as e:
|
|
38
|
+
# Note: Using print here intentionally as logging isn't configured yet
|
|
37
39
|
print(f"> error: {e}")
|
|
38
40
|
|
|
39
41
|
|
|
@@ -353,7 +355,7 @@ if config("DATABASE_URL", default=None):
|
|
|
353
355
|
DATABASES["default"].update(db_from_env)
|
|
354
356
|
|
|
355
357
|
# Configure workers database for SQLite storage when Redis is not available
|
|
356
|
-
if not config("REDIS_HOST", default=None):
|
|
358
|
+
if not config("REDIS_URL", default=None) and not config("REDIS_HOST", default=None):
|
|
357
359
|
_WORKER_DB_DIR = config("WORKER_DB_DIR", default=WORK_DIR)
|
|
358
360
|
_WORKER_DB_FILE_NAME = os.path.join(_WORKER_DB_DIR, "tasks.sqlite3")
|
|
359
361
|
DATABASES["workers"] = {
|
|
@@ -581,54 +583,91 @@ LOG_FILE_DIR = config("LOG_DIR", default=WORK_DIR)
|
|
|
581
583
|
LOG_FILE_NAME = os.path.join(LOG_FILE_DIR, "debug.log")
|
|
582
584
|
DRF_TRACKING_ADMIN_LOG_READONLY = True
|
|
583
585
|
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
586
|
+
# Option to use Loguru (default: True)
|
|
587
|
+
USE_LOGURU = config("USE_LOGURU", default=True, cast=bool)
|
|
588
|
+
|
|
589
|
+
if USE_LOGURU:
|
|
590
|
+
# Minimal LOGGING config - will be intercepted by Loguru
|
|
591
|
+
LOGGING = {
|
|
592
|
+
"version": 1,
|
|
593
|
+
"disable_existing_loggers": False,
|
|
594
|
+
"handlers": {
|
|
595
|
+
"console": {
|
|
596
|
+
"class": "logging.StreamHandler",
|
|
597
|
+
},
|
|
591
598
|
},
|
|
592
|
-
"
|
|
593
|
-
"format": "{levelname} {filename} {lineno} {message}",
|
|
594
|
-
"style": "{",
|
|
595
|
-
},
|
|
596
|
-
},
|
|
597
|
-
"handlers": {
|
|
598
|
-
"file": {
|
|
599
|
-
"level": "DEBUG",
|
|
600
|
-
"class": "logging.handlers.TimedRotatingFileHandler",
|
|
601
|
-
"formatter": "verbose",
|
|
602
|
-
"filename": LOG_FILE_NAME,
|
|
603
|
-
"when": "D",
|
|
604
|
-
"interval": 1,
|
|
605
|
-
"backupCount": 20,
|
|
606
|
-
},
|
|
607
|
-
"console": {
|
|
608
|
-
"class": "logging.StreamHandler",
|
|
609
|
-
"formatter": "simple",
|
|
610
|
-
},
|
|
611
|
-
},
|
|
612
|
-
"loggers": {
|
|
613
|
-
"oauth2_provider": {
|
|
614
|
-
"level": "DEBUG",
|
|
599
|
+
"root": {
|
|
615
600
|
"handlers": ["console"],
|
|
616
|
-
"
|
|
601
|
+
"level": "INFO",
|
|
617
602
|
},
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
603
|
+
}
|
|
604
|
+
else:
|
|
605
|
+
# Traditional Django logging configuration
|
|
606
|
+
LOGGING = {
|
|
607
|
+
"version": 1,
|
|
608
|
+
"disable_existing_loggers": False,
|
|
609
|
+
"formatters": {
|
|
610
|
+
"verbose": {
|
|
611
|
+
"format": "{levelname} {asctime} {module} {process:d} {thread:d} {message}",
|
|
612
|
+
"style": "{",
|
|
613
|
+
},
|
|
614
|
+
"simple": {
|
|
615
|
+
"format": "{levelname} {filename} {lineno} {message}",
|
|
616
|
+
"style": "{",
|
|
617
|
+
},
|
|
622
618
|
},
|
|
623
|
-
"
|
|
624
|
-
"
|
|
625
|
-
|
|
626
|
-
|
|
619
|
+
"handlers": {
|
|
620
|
+
"file": {
|
|
621
|
+
"level": "DEBUG",
|
|
622
|
+
"class": "logging.handlers.TimedRotatingFileHandler",
|
|
623
|
+
"formatter": "verbose",
|
|
624
|
+
"filename": LOG_FILE_NAME,
|
|
625
|
+
"when": "D",
|
|
626
|
+
"interval": 1,
|
|
627
|
+
"backupCount": 20,
|
|
628
|
+
},
|
|
629
|
+
"console": {
|
|
630
|
+
"class": "logging.StreamHandler",
|
|
631
|
+
"formatter": "simple",
|
|
632
|
+
},
|
|
627
633
|
},
|
|
628
|
-
"
|
|
629
|
-
"
|
|
630
|
-
|
|
631
|
-
|
|
634
|
+
"loggers": {
|
|
635
|
+
"oauth2_provider": {
|
|
636
|
+
"level": "DEBUG",
|
|
637
|
+
"handlers": ["console"],
|
|
638
|
+
"propagate": True,
|
|
639
|
+
},
|
|
640
|
+
"django": {
|
|
641
|
+
"handlers": ["file", "console"],
|
|
642
|
+
"level": DJANGO_LOG_LEVEL,
|
|
643
|
+
"propagate": False,
|
|
644
|
+
},
|
|
645
|
+
"karrio": {
|
|
646
|
+
"handlers": ["file", "console"],
|
|
647
|
+
"level": LOG_LEVEL,
|
|
648
|
+
"propagate": False,
|
|
649
|
+
},
|
|
650
|
+
"karrio.server.core.exceptions": {
|
|
651
|
+
"handlers": ["file", "console"],
|
|
652
|
+
"level": "DEBUG",
|
|
653
|
+
"propagate": False,
|
|
654
|
+
},
|
|
632
655
|
},
|
|
633
|
-
}
|
|
634
|
-
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
# Initialize Loguru if enabled
|
|
659
|
+
if USE_LOGURU:
|
|
660
|
+
try:
|
|
661
|
+
from karrio.server.core.logging import setup_django_loguru, logger
|
|
662
|
+
|
|
663
|
+
setup_django_loguru(
|
|
664
|
+
level=LOG_LEVEL,
|
|
665
|
+
log_file=LOG_FILE_NAME,
|
|
666
|
+
intercept_django=True,
|
|
667
|
+
enqueue=True, # Thread-safe async logging
|
|
668
|
+
)
|
|
669
|
+
except ImportError as e:
|
|
670
|
+
# Note: Using print here as Loguru failed to load
|
|
671
|
+
print(f"Warning: Failed to initialize Loguru: {e}")
|
|
672
|
+
print("Falling back to standard Django logging")
|
|
673
|
+
USE_LOGURU = False
|
karrio/server/settings/cache.py
CHANGED
|
@@ -2,28 +2,63 @@
|
|
|
2
2
|
from decouple import config
|
|
3
3
|
from karrio.server.settings.base import *
|
|
4
4
|
from karrio.server.settings.apm import HEALTH_CHECK_APPS
|
|
5
|
+
from karrio.server.core.logging import logger
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
CACHE_TTL = 60 * 15
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
REDIS_USERNAME = config("REDIS_USERNAME", default="default")
|
|
9
|
+
|
|
10
|
+
# Redis configuration - REDIS_URL takes precedence and supersedes granular env vars
|
|
11
|
+
REDIS_URL = config("REDIS_URL", default=None)
|
|
12
12
|
REDIS_PREFIX = config("REDIS_PREFIX", default="karrio")
|
|
13
|
+
REDIS_SSL = config("REDIS_SSL", default=False, cast=bool)
|
|
14
|
+
|
|
15
|
+
# Parse REDIS_URL or construct from individual parameters
|
|
16
|
+
if REDIS_URL is not None:
|
|
17
|
+
from urllib.parse import urlparse, urlunparse
|
|
18
|
+
import re
|
|
19
|
+
|
|
20
|
+
parsed = urlparse(REDIS_URL)
|
|
21
|
+
|
|
22
|
+
# Extract values from REDIS_URL (these supersede granular env vars)
|
|
23
|
+
REDIS_HOST = parsed.hostname
|
|
24
|
+
REDIS_PORT = parsed.port or 6379
|
|
25
|
+
REDIS_USERNAME = parsed.username or "default"
|
|
26
|
+
REDIS_PASSWORD = parsed.password
|
|
27
|
+
|
|
28
|
+
# Determine SSL from URL scheme (rediss:// means SSL is enabled)
|
|
29
|
+
REDIS_SCHEME = parsed.scheme if parsed.scheme in ("redis", "rediss") else "redis"
|
|
30
|
+
REDIS_SSL = REDIS_SCHEME == "rediss"
|
|
13
31
|
|
|
14
|
-
#
|
|
32
|
+
# Build connection URL with database 1 for cache
|
|
33
|
+
REDIS_AUTH = f"{REDIS_USERNAME}:{REDIS_PASSWORD}@" if REDIS_PASSWORD else ""
|
|
34
|
+
REDIS_CONNECTION_URL = f'{REDIS_SCHEME}://{REDIS_AUTH}{REDIS_HOST}:{REDIS_PORT}/1'
|
|
35
|
+
|
|
36
|
+
else:
|
|
37
|
+
# Fall back to individual parameters
|
|
38
|
+
REDIS_HOST = config("REDIS_HOST", default=None)
|
|
39
|
+
REDIS_PORT = config("REDIS_PORT", default=None)
|
|
40
|
+
REDIS_PASSWORD = config("REDIS_PASSWORD", default=None)
|
|
41
|
+
REDIS_USERNAME = config("REDIS_USERNAME", default="default")
|
|
42
|
+
|
|
43
|
+
if REDIS_HOST is not None:
|
|
44
|
+
REDIS_AUTH = f"{REDIS_USERNAME}:{REDIS_PASSWORD}@" if REDIS_PASSWORD else ""
|
|
45
|
+
REDIS_SCHEME = "rediss" if REDIS_SSL else "redis"
|
|
46
|
+
REDIS_CONNECTION_URL = f'{REDIS_SCHEME}://{REDIS_AUTH}{REDIS_HOST}:{REDIS_PORT or "6379"}/1'
|
|
47
|
+
|
|
48
|
+
# Configure Django cache if Redis is available
|
|
15
49
|
if REDIS_HOST is not None:
|
|
16
50
|
HEALTH_CHECK_APPS += ["health_check.contrib.redis"]
|
|
17
51
|
INSTALLED_APPS += ["health_check.contrib.redis"]
|
|
18
|
-
REDIS_AUTH = f"{REDIS_USERNAME}:{REDIS_PASSWORD}@" if REDIS_PASSWORD else ""
|
|
19
52
|
|
|
20
|
-
REDIS_CONNECTION_URL = f'redis://{REDIS_AUTH}{REDIS_HOST}:{REDIS_PORT or "6379"}/1'
|
|
21
53
|
CACHES = {
|
|
22
54
|
"default": {
|
|
23
55
|
"BACKEND": "django_redis.cache.RedisCache",
|
|
24
56
|
"LOCATION": REDIS_CONNECTION_URL,
|
|
25
|
-
"OPTIONS": {
|
|
57
|
+
"OPTIONS": {
|
|
58
|
+
"CLIENT_CLASS": "django_redis.client.DefaultClient",
|
|
59
|
+
**({"CONNECTION_POOL_KWARGS": {"ssl_cert_reqs": None}} if REDIS_SSL else {}),
|
|
60
|
+
},
|
|
26
61
|
"KEY_PREFIX": REDIS_PREFIX,
|
|
27
62
|
}
|
|
28
63
|
}
|
|
29
|
-
|
|
64
|
+
logger.info("Redis connection initialized", redis_url=REDIS_CONNECTION_URL)
|
|
@@ -16,18 +16,40 @@ WORKER_IMMEDIATE_MODE = decouple.config(
|
|
|
16
16
|
"WORKER_IMMEDIATE_MODE", default=False, cast=bool
|
|
17
17
|
)
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
REDIS_PASSWORD = decouple.config("REDIS_PASSWORD", default=None)
|
|
22
|
-
REDIS_USERNAME = decouple.config("REDIS_USERNAME", default="default")
|
|
19
|
+
# Redis configuration - REDIS_URL takes precedence and supersedes granular env vars
|
|
20
|
+
REDIS_URL = decouple.config("REDIS_URL", default=None)
|
|
23
21
|
|
|
22
|
+
# Parse REDIS_URL or construct from individual parameters
|
|
23
|
+
if REDIS_URL is not None:
|
|
24
|
+
from urllib.parse import urlparse
|
|
24
25
|
|
|
25
|
-
|
|
26
|
+
parsed = urlparse(REDIS_URL)
|
|
27
|
+
|
|
28
|
+
# Extract values from REDIS_URL (these supersede granular env vars)
|
|
29
|
+
REDIS_HOST = parsed.hostname
|
|
30
|
+
REDIS_PORT = parsed.port or 6379
|
|
31
|
+
REDIS_USERNAME = parsed.username or "default"
|
|
32
|
+
REDIS_PASSWORD = parsed.password
|
|
33
|
+
|
|
34
|
+
# Determine SSL from URL scheme (rediss:// means SSL is enabled)
|
|
35
|
+
REDIS_SCHEME = parsed.scheme if parsed.scheme in ("redis", "rediss") else "redis"
|
|
36
|
+
REDIS_SSL = REDIS_SCHEME == "rediss"
|
|
37
|
+
|
|
38
|
+
else:
|
|
39
|
+
# Fall back to individual parameters
|
|
40
|
+
REDIS_HOST = decouple.config("REDIS_HOST", default=None)
|
|
41
|
+
REDIS_PORT = decouple.config("REDIS_PORT", default=None)
|
|
42
|
+
REDIS_PASSWORD = decouple.config("REDIS_PASSWORD", default=None)
|
|
43
|
+
REDIS_USERNAME = decouple.config("REDIS_USERNAME", default="default")
|
|
44
|
+
REDIS_SSL = decouple.config("REDIS_SSL", default=False, cast=bool)
|
|
45
|
+
|
|
46
|
+
# Configure HUEY based on available Redis configuration
|
|
26
47
|
if REDIS_HOST is not None:
|
|
27
48
|
pool = redis.ConnectionPool(
|
|
28
49
|
host=REDIS_HOST,
|
|
29
|
-
port=REDIS_PORT
|
|
50
|
+
port=REDIS_PORT,
|
|
30
51
|
max_connections=20,
|
|
52
|
+
**({"ssl": REDIS_SSL} if REDIS_SSL else {}),
|
|
31
53
|
**({"password": REDIS_PASSWORD} if REDIS_PASSWORD else {}),
|
|
32
54
|
**({"username": REDIS_USERNAME} if REDIS_USERNAME else {}),
|
|
33
55
|
)
|
|
@@ -38,6 +60,7 @@ if REDIS_HOST is not None:
|
|
|
38
60
|
)
|
|
39
61
|
|
|
40
62
|
else:
|
|
63
|
+
# No Redis configured, use SQLite
|
|
41
64
|
WORKER_DB_DIR = decouple.config("WORKER_DB_DIR", default=settings.WORK_DIR)
|
|
42
65
|
WORKER_DB_FILE_NAME = os.path.join(WORKER_DB_DIR, "tasks.sqlite3")
|
|
43
66
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: karrio_server
|
|
3
|
-
Version: 2025.
|
|
3
|
+
Version: 2025.5rc32
|
|
4
4
|
Summary: Multi-carrier shipping API
|
|
5
5
|
Author-email: karrio <hello@karrio.io>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -42,6 +42,7 @@ Requires-Dist: opentelemetry-instrumentation-logging
|
|
|
42
42
|
Requires-Dist: opentelemetry-instrumentation-psycopg2
|
|
43
43
|
Requires-Dist: opentelemetry-instrumentation-redis
|
|
44
44
|
Requires-Dist: opentelemetry-semantic-conventions
|
|
45
|
+
Requires-Dist: loguru
|
|
45
46
|
|
|
46
47
|
# <a href="https://karrio.io" target="_blank"><img alt="Karrio" src="https://docs.karrio.io/img/logo.svg" height="50px" /></a>
|
|
47
48
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
karrio/server/VERSION,sha256=
|
|
1
|
+
karrio/server/VERSION,sha256=XNzgmUDikIDatuZ8iDHbUCq5nJQzGvX4ntLiAGaC9vE,10
|
|
2
2
|
karrio/server/__init__.py,sha256=iOEMwnlORWezdO8-2vxBIPSR37D7JGjluZ8f55vzxls,81
|
|
3
3
|
karrio/server/__main__.py,sha256=hy2-Zb2wSVe_Pu6zWZ-BhiM4rBaGZ3D16HSuhudygqg,632
|
|
4
4
|
karrio/server/asgi.py,sha256=LsZYMWo8U9zURVPdHnvUsziOhMjdCdQoD2-gMJbS2U0,462
|
|
@@ -6,13 +6,13 @@ karrio/server/workers.py,sha256=wOlWmXC7zRJV86IfbQnfUZsnCIvvWtXzFHH_EIkg1J0,179
|
|
|
6
6
|
karrio/server/wsgi.py,sha256=SpWqkEYlMsj89_znZ8p8IjH3EgTVRWRq_9eS8t64dMw,403
|
|
7
7
|
karrio/server/lib/otel_huey.py,sha256=6MP6vX6b6x6RPF2K1m8B8L8S9GK1Q3vANmLidsxh65k,5428
|
|
8
8
|
karrio/server/settings/__init__.py,sha256=iw-NBcReOnDYpnvSEBdYDfV7jC0040jYdupnmSdElec,866
|
|
9
|
-
karrio/server/settings/apm.py,sha256=
|
|
10
|
-
karrio/server/settings/base.py,sha256=
|
|
11
|
-
karrio/server/settings/cache.py,sha256=
|
|
9
|
+
karrio/server/settings/apm.py,sha256=fp9_CVzNfQ8MvNp1-WQbCILzLU3RSJeeu1vYAtdrgfs,7415
|
|
10
|
+
karrio/server/settings/base.py,sha256=311L71Lxk-9tv0nqeERtKIrWjvEhD9g2LmUcpd0MkoA,22246
|
|
11
|
+
karrio/server/settings/cache.py,sha256=wiuhbTPjEyHY5xgvVfwNV0-QxsFN5kTI8sSwnibCSVI,2502
|
|
12
12
|
karrio/server/settings/constance.py,sha256=wKi7u-NORAPjIJMIbl3k5kPRkUA6jJJWe9kxsV3aoeA,7113
|
|
13
13
|
karrio/server/settings/debug.py,sha256=fFyK2XX47UGeK0eRNSV-9ZLaComay5QvJW0692vaH98,527
|
|
14
14
|
karrio/server/settings/email.py,sha256=bHBLKM_v3HTkmjrz_Msdj_Z7_kMzAb7i6pvJCZuzu1E,1403
|
|
15
|
-
karrio/server/settings/workers.py,sha256=
|
|
15
|
+
karrio/server/settings/workers.py,sha256=snzAxzZLxP5i0mTNEE6AD3bHT7WBjh-fe-A-vT0cQIE,2666
|
|
16
16
|
karrio/server/static/extra/branding/android-chrome-192x192.png,sha256=qSwEKKBtk4udSHb0OWGC5-jfkP5cVpULDD1Cdkuk8PU,7005
|
|
17
17
|
karrio/server/static/extra/branding/android-chrome-512x512.png,sha256=YFwVPnPChO30tTuyrwSc_z548H7C6OFXh4CCu2krvHA,21062
|
|
18
18
|
karrio/server/static/extra/branding/favicon-16x16.png,sha256=wkELpij29bIvvKr5sDcjfNeYvj7i0yk-__bJbZckEK8,1085
|
|
@@ -73,8 +73,8 @@ karrio/server/templates/admin/base_site.html,sha256=kbcdvehXZ1EHaw07JL7fSZmjrnVM
|
|
|
73
73
|
karrio/server/templates/openapi/openapi.html,sha256=3ApCZ5pE6Wjv7CJllVbqD2WiDQuLy-BFS-IIHurXhBY,1133
|
|
74
74
|
karrio/server/urls/__init__.py,sha256=Ah-XqaqRsfecQgCGRHjxmXe8O7a0avq5ocU90tkVwQI,1998
|
|
75
75
|
karrio/server/urls/jwt.py,sha256=QN2L-EpUEQCF2UGYPu_VVlA49Fc0BtcY7Ov3-xpp7_U,6772
|
|
76
|
-
karrio_server-2025.
|
|
77
|
-
karrio_server-2025.
|
|
78
|
-
karrio_server-2025.
|
|
79
|
-
karrio_server-2025.
|
|
80
|
-
karrio_server-2025.
|
|
76
|
+
karrio_server-2025.5rc32.dist-info/METADATA,sha256=FoCDlHgfC1ctngm3M4xIDcTCajXjxQFYiWGouGBgklA,4305
|
|
77
|
+
karrio_server-2025.5rc32.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
78
|
+
karrio_server-2025.5rc32.dist-info/entry_points.txt,sha256=c2eftt6MpJjyp0OFv1OmO9nUYSDemt9fGq_RDdvpGLw,55
|
|
79
|
+
karrio_server-2025.5rc32.dist-info/top_level.txt,sha256=D1D7x8R3cTfjF_15mfiO7wCQ5QMtuM4x8GaPr7z5i78,12
|
|
80
|
+
karrio_server-2025.5rc32.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|