karrio-server 2025.5rc35__py3-none-any.whl → 2025.5.1__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 +311 -14
- karrio/server/settings/constance.py +29 -5
- karrio/server/static/karrio/js/karrio.js +358 -260
- karrio/server/static/karrio/js/karrio.js.map +1 -1
- karrio/server/urls/__init__.py +1 -0
- karrio/server/urls/tokens.py +237 -0
- {karrio_server-2025.5rc35.dist-info → karrio_server-2025.5.1.dist-info}/METADATA +1 -1
- {karrio_server-2025.5rc35.dist-info → karrio_server-2025.5.1.dist-info}/RECORD +12 -11
- {karrio_server-2025.5rc35.dist-info → karrio_server-2025.5.1.dist-info}/WHEEL +0 -0
- {karrio_server-2025.5rc35.dist-info → karrio_server-2025.5.1.dist-info}/entry_points.txt +0 -0
- {karrio_server-2025.5rc35.dist-info → karrio_server-2025.5.1.dist-info}/top_level.txt +0 -0
karrio/server/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2025.
|
|
1
|
+
2025.5.1
|
karrio/server/settings/apm.py
CHANGED
|
@@ -35,33 +35,192 @@ if POSTHOG_KEY:
|
|
|
35
35
|
posthog.host = POSTHOG_HOST
|
|
36
36
|
|
|
37
37
|
|
|
38
|
-
#
|
|
38
|
+
# =============================================================================
|
|
39
|
+
# Sentry Configuration
|
|
40
|
+
# =============================================================================
|
|
41
|
+
#
|
|
42
|
+
# Sentry provides error tracking, performance monitoring, and distributed
|
|
43
|
+
# tracing for Karrio. When SENTRY_DSN is configured, the following features
|
|
44
|
+
# are enabled:
|
|
45
|
+
#
|
|
46
|
+
# 1. Error Tracking: All unhandled exceptions are captured with full context
|
|
47
|
+
# 2. Performance Monitoring: API endpoints and gateway operations are traced
|
|
48
|
+
# 3. Distributed Tracing: Carrier API calls are linked to parent transactions
|
|
49
|
+
# 4. Metrics: Custom metrics for carrier operations (rates, shipments, etc.)
|
|
50
|
+
# 5. Logging Integration: ERROR/CRITICAL logs are sent to Sentry
|
|
51
|
+
#
|
|
52
|
+
# Environment Variables:
|
|
53
|
+
# SENTRY_DSN - Sentry Data Source Name (required to enable)
|
|
54
|
+
# SENTRY_ENVIRONMENT - Environment name (default: from ENV or "production")
|
|
55
|
+
# SENTRY_RELEASE - Release version (default: VERSION)
|
|
56
|
+
# SENTRY_TRACES_SAMPLE_RATE - Transaction sampling rate 0.0-1.0 (default: 1.0)
|
|
57
|
+
# SENTRY_PROFILES_SAMPLE_RATE - Profile sampling rate 0.0-1.0 (default: 1.0)
|
|
58
|
+
# SENTRY_SEND_PII - Send personally identifiable information (default: true)
|
|
59
|
+
# SENTRY_DEBUG - Enable Sentry debug mode (default: false)
|
|
60
|
+
#
|
|
61
|
+
# =============================================================================
|
|
62
|
+
|
|
39
63
|
sentry_sdk.utils.MAX_STRING_LENGTH = 4096
|
|
40
64
|
SENTRY_DSN = config("SENTRY_DSN", default=None)
|
|
65
|
+
SENTRY_ENVIRONMENT = config("SENTRY_ENVIRONMENT", default=config("ENV", default="production"))
|
|
66
|
+
SENTRY_RELEASE = config("SENTRY_RELEASE", default=config("VERSION", default=None))
|
|
67
|
+
SENTRY_TRACES_SAMPLE_RATE = config("SENTRY_TRACES_SAMPLE_RATE", default=1.0, cast=float)
|
|
68
|
+
SENTRY_PROFILES_SAMPLE_RATE = config("SENTRY_PROFILES_SAMPLE_RATE", default=1.0, cast=float)
|
|
69
|
+
SENTRY_SEND_PII = config("SENTRY_SEND_PII", default=True, cast=bool)
|
|
70
|
+
SENTRY_DEBUG = config("SENTRY_DEBUG", default=False, cast=bool)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def _sentry_before_send(event, hint):
|
|
74
|
+
"""Pre-process events before sending to Sentry.
|
|
75
|
+
|
|
76
|
+
This hook allows us to:
|
|
77
|
+
- Scrub sensitive data (API keys, tokens, passwords)
|
|
78
|
+
- Add custom tags
|
|
79
|
+
- Filter out certain events
|
|
80
|
+
"""
|
|
81
|
+
# Scrub sensitive data from request bodies
|
|
82
|
+
if "request" in event:
|
|
83
|
+
request_data = event["request"]
|
|
84
|
+
|
|
85
|
+
# Scrub headers
|
|
86
|
+
if "headers" in request_data:
|
|
87
|
+
sensitive_headers = ["authorization", "x-api-key", "cookie", "x-csrf-token"]
|
|
88
|
+
for header in sensitive_headers:
|
|
89
|
+
if header in request_data["headers"]:
|
|
90
|
+
request_data["headers"][header] = "[Filtered]"
|
|
91
|
+
|
|
92
|
+
# Scrub POST data
|
|
93
|
+
if "data" in request_data and isinstance(request_data["data"], dict):
|
|
94
|
+
sensitive_fields = [
|
|
95
|
+
"password", "secret", "token", "api_key", "apikey",
|
|
96
|
+
"access_token", "refresh_token", "client_secret",
|
|
97
|
+
"account_number", "meter_number", "license_key",
|
|
98
|
+
]
|
|
99
|
+
for field in sensitive_fields:
|
|
100
|
+
for key in list(request_data["data"].keys()):
|
|
101
|
+
if field.lower() in key.lower():
|
|
102
|
+
request_data["data"][key] = "[Filtered]"
|
|
103
|
+
|
|
104
|
+
return event
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def _sentry_before_send_transaction(event, hint):
|
|
108
|
+
"""Pre-process transactions before sending to Sentry.
|
|
109
|
+
|
|
110
|
+
This hook allows us to:
|
|
111
|
+
- Filter out noisy transactions (health checks, static files)
|
|
112
|
+
- Add custom tags
|
|
113
|
+
"""
|
|
114
|
+
transaction_name = event.get("transaction", "")
|
|
115
|
+
|
|
116
|
+
# Filter out health check and monitoring endpoints
|
|
117
|
+
noisy_endpoints = [
|
|
118
|
+
"/health",
|
|
119
|
+
"/ready",
|
|
120
|
+
"/live",
|
|
121
|
+
"/_health",
|
|
122
|
+
"/favicon.ico",
|
|
123
|
+
"/static/",
|
|
124
|
+
"/robots.txt",
|
|
125
|
+
]
|
|
126
|
+
|
|
127
|
+
for endpoint in noisy_endpoints:
|
|
128
|
+
if transaction_name.startswith(endpoint):
|
|
129
|
+
return None # Drop this transaction
|
|
130
|
+
|
|
131
|
+
return event
|
|
132
|
+
|
|
41
133
|
|
|
42
134
|
if SENTRY_DSN:
|
|
43
135
|
# Build integrations list
|
|
44
|
-
integrations = [
|
|
136
|
+
integrations = [
|
|
137
|
+
DjangoIntegration(
|
|
138
|
+
transaction_style="url", # Use URL patterns for transaction names
|
|
139
|
+
middleware_spans=True, # Create spans for middleware
|
|
140
|
+
signals_spans=True, # Create spans for Django signals
|
|
141
|
+
),
|
|
142
|
+
]
|
|
143
|
+
|
|
144
|
+
# Add PostHog integration if available
|
|
45
145
|
if POSTHOG_KEY and PostHogIntegration is not None:
|
|
46
146
|
integrations.append(PostHogIntegration())
|
|
47
147
|
|
|
148
|
+
# Try to add Redis integration if Redis is configured
|
|
149
|
+
try:
|
|
150
|
+
from sentry_sdk.integrations.redis import RedisIntegration
|
|
151
|
+
if config("REDIS_URL", default=None) or config("REDIS_HOST", default=None):
|
|
152
|
+
integrations.append(RedisIntegration())
|
|
153
|
+
except ImportError:
|
|
154
|
+
pass
|
|
155
|
+
|
|
156
|
+
# Try to add Huey integration for background tasks
|
|
157
|
+
try:
|
|
158
|
+
from sentry_sdk.integrations.huey import HueyIntegration
|
|
159
|
+
integrations.append(HueyIntegration())
|
|
160
|
+
except ImportError:
|
|
161
|
+
pass
|
|
162
|
+
|
|
163
|
+
# Try to add httpx integration for async HTTP clients
|
|
164
|
+
try:
|
|
165
|
+
from sentry_sdk.integrations.httpx import HttpxIntegration
|
|
166
|
+
integrations.append(HttpxIntegration())
|
|
167
|
+
except Exception:
|
|
168
|
+
pass # httpx may not be installed
|
|
169
|
+
|
|
170
|
+
# Try to add Strawberry GraphQL integration
|
|
171
|
+
try:
|
|
172
|
+
from sentry_sdk.integrations.strawberry import StrawberryIntegration
|
|
173
|
+
integrations.append(StrawberryIntegration(async_execution=False))
|
|
174
|
+
except Exception:
|
|
175
|
+
pass # strawberry integration may not be available
|
|
176
|
+
|
|
48
177
|
sentry_sdk.init(
|
|
49
178
|
dsn=SENTRY_DSN,
|
|
50
179
|
integrations=integrations,
|
|
51
|
-
|
|
52
|
-
#
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
180
|
+
|
|
181
|
+
# Environment and release tracking
|
|
182
|
+
environment=SENTRY_ENVIRONMENT,
|
|
183
|
+
release=SENTRY_RELEASE,
|
|
184
|
+
|
|
185
|
+
# Performance monitoring
|
|
186
|
+
traces_sample_rate=SENTRY_TRACES_SAMPLE_RATE,
|
|
187
|
+
profile_session_sample_rate=SENTRY_PROFILES_SAMPLE_RATE,
|
|
59
188
|
profile_lifecycle="trace",
|
|
60
|
-
|
|
61
|
-
#
|
|
62
|
-
send_default_pii=
|
|
63
|
-
|
|
189
|
+
|
|
190
|
+
# Privacy settings
|
|
191
|
+
send_default_pii=SENTRY_SEND_PII,
|
|
192
|
+
|
|
193
|
+
# Logging integration
|
|
64
194
|
enable_logs=True,
|
|
195
|
+
|
|
196
|
+
# Debug mode
|
|
197
|
+
debug=SENTRY_DEBUG,
|
|
198
|
+
|
|
199
|
+
# Event processing hooks
|
|
200
|
+
before_send=_sentry_before_send,
|
|
201
|
+
before_send_transaction=_sentry_before_send_transaction,
|
|
202
|
+
|
|
203
|
+
# Additional options
|
|
204
|
+
max_breadcrumbs=50, # Keep last 50 breadcrumbs for context
|
|
205
|
+
attach_stacktrace=True, # Attach stack traces to messages
|
|
206
|
+
include_source_context=True, # Include source code in stack traces
|
|
207
|
+
include_local_variables=True, # Include local variables in stack traces
|
|
208
|
+
|
|
209
|
+
# Set custom tags
|
|
210
|
+
_experiments={
|
|
211
|
+
"record_sql_params": True, # Record SQL query parameters
|
|
212
|
+
},
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
# Set default tags that will be applied to all events
|
|
216
|
+
sentry_sdk.set_tag("service", "karrio-api")
|
|
217
|
+
sentry_sdk.set_tag("framework", "django")
|
|
218
|
+
|
|
219
|
+
import logging
|
|
220
|
+
logger = logging.getLogger(__name__)
|
|
221
|
+
logger.info(
|
|
222
|
+
f"Sentry initialized: env={SENTRY_ENVIRONMENT}, "
|
|
223
|
+
f"traces_sample_rate={SENTRY_TRACES_SAMPLE_RATE}"
|
|
65
224
|
)
|
|
66
225
|
|
|
67
226
|
|
|
@@ -191,3 +350,141 @@ if OTEL_ENABLED and OTEL_EXPORTER_OTLP_ENDPOINT:
|
|
|
191
350
|
# Log that OpenTelemetry is enabled
|
|
192
351
|
logger = logging.getLogger(__name__)
|
|
193
352
|
logger.info(f"OpenTelemetry enabled: Service={OTEL_SERVICE_NAME}, Endpoint={OTEL_EXPORTER_OTLP_ENDPOINT}")
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
# =============================================================================
|
|
356
|
+
# Datadog Configuration
|
|
357
|
+
# =============================================================================
|
|
358
|
+
#
|
|
359
|
+
# Datadog provides full-stack observability including APM, infrastructure
|
|
360
|
+
# monitoring, logs, and more. When DD_TRACE_ENABLED is set, the following
|
|
361
|
+
# features are enabled:
|
|
362
|
+
#
|
|
363
|
+
# 1. APM Tracing: Distributed tracing for all requests and background tasks
|
|
364
|
+
# 2. Metrics: Custom metrics via DogStatsD
|
|
365
|
+
# 3. Logs: Automatic trace ID injection into logs
|
|
366
|
+
# 4. Profiling: Continuous profiling (optional)
|
|
367
|
+
#
|
|
368
|
+
# Environment Variables:
|
|
369
|
+
# DD_TRACE_ENABLED - Enable Datadog tracing (default: false)
|
|
370
|
+
# DD_SERVICE - Service name (default: karrio-api)
|
|
371
|
+
# DD_ENV - Environment name (default: from ENV or "production")
|
|
372
|
+
# DD_VERSION - Application version (default: VERSION)
|
|
373
|
+
# DD_AGENT_HOST - Datadog agent host (default: localhost)
|
|
374
|
+
# DD_TRACE_AGENT_PORT - Datadog agent port (default: 8126)
|
|
375
|
+
# DD_DOGSTATSD_PORT - DogStatsD port for metrics (default: 8125)
|
|
376
|
+
# DD_TRACE_SAMPLE_RATE - Sampling rate 0.0-1.0 (default: 1.0)
|
|
377
|
+
# DD_PROFILING_ENABLED - Enable continuous profiling (default: false)
|
|
378
|
+
# DD_LOGS_INJECTION - Inject trace IDs into logs (default: true)
|
|
379
|
+
#
|
|
380
|
+
# =============================================================================
|
|
381
|
+
|
|
382
|
+
DD_TRACE_ENABLED = config("DD_TRACE_ENABLED", default=False, cast=bool)
|
|
383
|
+
DATADOG_ENABLED = config("DATADOG_ENABLED", default=False, cast=bool) # Alias
|
|
384
|
+
|
|
385
|
+
# Use either DD_TRACE_ENABLED or DATADOG_ENABLED
|
|
386
|
+
_datadog_enabled = DD_TRACE_ENABLED or DATADOG_ENABLED
|
|
387
|
+
|
|
388
|
+
if _datadog_enabled:
|
|
389
|
+
# Datadog configuration
|
|
390
|
+
DD_SERVICE = config("DD_SERVICE", default="karrio-api")
|
|
391
|
+
DD_ENV = config("DD_ENV", default=config("ENV", default="production"))
|
|
392
|
+
DD_VERSION = config("DD_VERSION", default=config("VERSION", default="unknown"))
|
|
393
|
+
DD_AGENT_HOST = config("DD_AGENT_HOST", default="localhost")
|
|
394
|
+
DD_TRACE_AGENT_PORT = config("DD_TRACE_AGENT_PORT", default=8126, cast=int)
|
|
395
|
+
DD_DOGSTATSD_PORT = config("DD_DOGSTATSD_PORT", default=8125, cast=int)
|
|
396
|
+
DD_TRACE_SAMPLE_RATE = config("DD_TRACE_SAMPLE_RATE", default=1.0, cast=float)
|
|
397
|
+
DD_PROFILING_ENABLED = config("DD_PROFILING_ENABLED", default=False, cast=bool)
|
|
398
|
+
DD_LOGS_INJECTION = config("DD_LOGS_INJECTION", default=True, cast=bool)
|
|
399
|
+
|
|
400
|
+
try:
|
|
401
|
+
import ddtrace
|
|
402
|
+
from ddtrace import config as dd_config, tracer, patch_all
|
|
403
|
+
|
|
404
|
+
# Configure tracer
|
|
405
|
+
ddtrace.config.service = DD_SERVICE
|
|
406
|
+
ddtrace.config.env = DD_ENV
|
|
407
|
+
ddtrace.config.version = DD_VERSION
|
|
408
|
+
|
|
409
|
+
# Configure Django integration
|
|
410
|
+
dd_config.django["service_name"] = DD_SERVICE
|
|
411
|
+
dd_config.django["cache_service_name"] = f"{DD_SERVICE}-cache"
|
|
412
|
+
dd_config.django["database_service_name"] = f"{DD_SERVICE}-db"
|
|
413
|
+
dd_config.django["trace_query_string"] = True
|
|
414
|
+
dd_config.django["analytics_enabled"] = True
|
|
415
|
+
|
|
416
|
+
# Configure trace sampling
|
|
417
|
+
tracer.configure(
|
|
418
|
+
hostname=DD_AGENT_HOST,
|
|
419
|
+
port=DD_TRACE_AGENT_PORT,
|
|
420
|
+
)
|
|
421
|
+
|
|
422
|
+
# Set global sample rate
|
|
423
|
+
from ddtrace.sampler import DatadogSampler
|
|
424
|
+
tracer.configure(sampler=DatadogSampler(default_sample_rate=DD_TRACE_SAMPLE_RATE))
|
|
425
|
+
|
|
426
|
+
# Enable log injection
|
|
427
|
+
if DD_LOGS_INJECTION:
|
|
428
|
+
ddtrace.patch(logging=True)
|
|
429
|
+
|
|
430
|
+
# Patch all supported libraries
|
|
431
|
+
patch_all(
|
|
432
|
+
django=True,
|
|
433
|
+
redis=True,
|
|
434
|
+
psycopg=True,
|
|
435
|
+
requests=True,
|
|
436
|
+
httpx=True,
|
|
437
|
+
logging=DD_LOGS_INJECTION,
|
|
438
|
+
)
|
|
439
|
+
|
|
440
|
+
# Patch Huey for background task tracing
|
|
441
|
+
try:
|
|
442
|
+
from ddtrace import patch
|
|
443
|
+
patch(huey=True)
|
|
444
|
+
except Exception:
|
|
445
|
+
pass # Huey integration may not be available in all ddtrace versions
|
|
446
|
+
|
|
447
|
+
# Enable profiling if configured
|
|
448
|
+
if DD_PROFILING_ENABLED:
|
|
449
|
+
try:
|
|
450
|
+
import ddtrace.profiling.auto # noqa: F401
|
|
451
|
+
except ImportError:
|
|
452
|
+
pass
|
|
453
|
+
|
|
454
|
+
# Configure DogStatsD for metrics
|
|
455
|
+
try:
|
|
456
|
+
from datadog import initialize, statsd
|
|
457
|
+
|
|
458
|
+
initialize(
|
|
459
|
+
statsd_host=DD_AGENT_HOST,
|
|
460
|
+
statsd_port=DD_DOGSTATSD_PORT,
|
|
461
|
+
)
|
|
462
|
+
|
|
463
|
+
# Set default tags for all metrics
|
|
464
|
+
statsd.constant_tags = [
|
|
465
|
+
f"service:{DD_SERVICE}",
|
|
466
|
+
f"env:{DD_ENV}",
|
|
467
|
+
f"version:{DD_VERSION}",
|
|
468
|
+
]
|
|
469
|
+
|
|
470
|
+
except ImportError:
|
|
471
|
+
pass # datadog package not installed, metrics won't work
|
|
472
|
+
|
|
473
|
+
import logging
|
|
474
|
+
logger = logging.getLogger(__name__)
|
|
475
|
+
logger.info(
|
|
476
|
+
f"Datadog APM initialized: service={DD_SERVICE}, env={DD_ENV}, "
|
|
477
|
+
f"agent={DD_AGENT_HOST}:{DD_TRACE_AGENT_PORT}"
|
|
478
|
+
)
|
|
479
|
+
|
|
480
|
+
except ImportError:
|
|
481
|
+
import logging
|
|
482
|
+
logger = logging.getLogger(__name__)
|
|
483
|
+
logger.warning(
|
|
484
|
+
"Datadog tracing enabled but ddtrace package not installed. "
|
|
485
|
+
"Install with: pip install ddtrace"
|
|
486
|
+
)
|
|
487
|
+
except Exception as e:
|
|
488
|
+
import logging
|
|
489
|
+
logger = logging.getLogger(__name__)
|
|
490
|
+
logger.warning(f"Failed to initialize Datadog APM: {e}")
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""Dynamic configuration editable on runtime powered by django-constance."""
|
|
2
2
|
|
|
3
3
|
from decouple import config
|
|
4
4
|
import karrio.references as ref
|
|
@@ -22,6 +22,7 @@ GOOGLE_CLOUD_API_KEY = config("GOOGLE_CLOUD_API_KEY", default="")
|
|
|
22
22
|
CANADAPOST_ADDRESS_COMPLETE_API_KEY = config(
|
|
23
23
|
"CANADAPOST_ADDRESS_COMPLETE_API_KEY", default=""
|
|
24
24
|
)
|
|
25
|
+
|
|
25
26
|
# data retention env in days
|
|
26
27
|
ORDER_DATA_RETENTION = config("ORDER_DATA_RETENTION", default=183, cast=int)
|
|
27
28
|
TRACKER_DATA_RETENTION = config("TRACKER_DATA_RETENTION", default=183, cast=int)
|
|
@@ -29,7 +30,9 @@ SHIPMENT_DATA_RETENTION = config("SHIPMENT_DATA_RETENTION", default=183, cast=in
|
|
|
29
30
|
API_LOGS_DATA_RETENTION = config("API_LOGS_DATA_RETENTION", default=92, cast=int)
|
|
30
31
|
|
|
31
32
|
# registry config
|
|
32
|
-
ENABLE_ALL_PLUGINS_BY_DEFAULT = config(
|
|
33
|
+
ENABLE_ALL_PLUGINS_BY_DEFAULT = config(
|
|
34
|
+
"ENABLE_ALL_PLUGINS_BY_DEFAULT", default=True if base.DEBUG else False, cast=bool
|
|
35
|
+
)
|
|
33
36
|
|
|
34
37
|
# Create feature flags config only for modules that exist
|
|
35
38
|
FEATURE_FLAGS_CONFIG = {
|
|
@@ -161,8 +164,21 @@ PLUGIN_REGISTRY = {
|
|
|
161
164
|
config(f"{ext.upper()}_ENABLED", default=True, cast=bool),
|
|
162
165
|
f"{metadata.get('label')} plugin",
|
|
163
166
|
bool,
|
|
164
|
-
)
|
|
165
|
-
|
|
167
|
+
)
|
|
168
|
+
for ext, metadata in ref.PLUGIN_METADATA.items()
|
|
169
|
+
},
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
# Collect plugin system configs from ref.SYSTEM_CONFIGS
|
|
173
|
+
# Format: Dict[str, Tuple[default_value, description, type]]
|
|
174
|
+
PLUGIN_SYSTEM_CONFIG = {
|
|
175
|
+
key: (config(key, default=default_value, cast=value_type), description, value_type)
|
|
176
|
+
for key, (default_value, description, value_type) in ref.SYSTEM_CONFIGS.items()
|
|
177
|
+
}
|
|
178
|
+
PLUGIN_SYSTEM_CONFIG_FIELDSETS = {
|
|
179
|
+
f"{metadata.get('label')} Config": tuple(metadata.get("system_config", {}).keys())
|
|
180
|
+
for _, metadata in ref.PLUGIN_METADATA.items()
|
|
181
|
+
if metadata.get("system_config")
|
|
166
182
|
}
|
|
167
183
|
|
|
168
184
|
|
|
@@ -218,6 +234,7 @@ CONSTANCE_CONFIG = {
|
|
|
218
234
|
),
|
|
219
235
|
**{k: v for k, v in FEATURE_FLAGS_CONFIG.items() if v is not None},
|
|
220
236
|
**PLUGIN_REGISTRY,
|
|
237
|
+
**PLUGIN_SYSTEM_CONFIG,
|
|
221
238
|
}
|
|
222
239
|
|
|
223
240
|
CONSTANCE_CONFIG_FIELDSETS = {
|
|
@@ -241,5 +258,12 @@ CONSTANCE_CONFIG_FIELDSETS = {
|
|
|
241
258
|
),
|
|
242
259
|
"Feature Flags": tuple(FEATURE_FLAGS_FIELDSET),
|
|
243
260
|
"Registry Config": ("ENABLE_ALL_PLUGINS_BY_DEFAULT",),
|
|
244
|
-
"Registry Plugins": tuple(
|
|
261
|
+
"Registry Plugins": tuple(
|
|
262
|
+
[
|
|
263
|
+
k
|
|
264
|
+
for k in PLUGIN_REGISTRY.keys()
|
|
265
|
+
if not k in ("ENABLE_ALL_PLUGINS_BY_DEFAULT",)
|
|
266
|
+
]
|
|
267
|
+
),
|
|
268
|
+
**PLUGIN_SYSTEM_CONFIG_FIELDSETS,
|
|
245
269
|
}
|