DefStream 0.1.15__tar.gz → 0.1.16__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.
- {defstream-0.1.15 → defstream-0.1.16}/.github/workflows/ci.yml +1 -1
- {defstream-0.1.15 → defstream-0.1.16}/DefStream.egg-info/PKG-INFO +7 -7
- {defstream-0.1.15 → defstream-0.1.16}/DefStream.egg-info/SOURCES.txt +9 -5
- {defstream-0.1.15 → defstream-0.1.16}/PKG-INFO +7 -7
- {defstream-0.1.15 → defstream-0.1.16}/README.en.md +6 -6
- {defstream-0.1.15 → defstream-0.1.16}/README.md +6 -6
- {defstream-0.1.15 → defstream-0.1.16}/issues/feature/8/REQUIREMENTS.md +3 -3
- defstream-0.1.16/issues/fix/24/IMPLEMENTS.md +25 -0
- defstream-0.1.16/issues/fix/24/ISSUE.md +14 -0
- defstream-0.1.16/issues/fix/24/README.md +7 -0
- defstream-0.1.16/issues/fix/24/REQUIREMENTS.md +48 -0
- {defstream-0.1.15 → defstream-0.1.16}/samples/Worker/RabbitMQ/Worker.py +5 -5
- {defstream-0.1.15 → defstream-0.1.16}/samples/Worker/Redis/Sample.py +5 -5
- {defstream-0.1.15 → defstream-0.1.16}/setup.py +1 -1
- defstream-0.1.15/src/Inspector/Extensions/HealthCheck.py → defstream-0.1.16/src/Inspector/Extensions/Ping.py +8 -8
- defstream-0.1.15/src/Inspector/Extensions/Dashboard.html → defstream-0.1.16/src/Inspector/Extensions/Status.html +2 -2
- defstream-0.1.15/src/Inspector/Extensions/Dashboard.py → defstream-0.1.16/src/Inspector/Extensions/Status.py +13 -13
- {defstream-0.1.15 → defstream-0.1.16}/src/Inspector/Extensions/__init__.py +4 -4
- {defstream-0.1.15 → defstream-0.1.16}/tests/test_inspector.py +21 -21
- {defstream-0.1.15 → defstream-0.1.16}/tests/test_inspector_logging.py +4 -4
- {defstream-0.1.15 → defstream-0.1.16}/tests/test_release_workflow.py +1 -1
- defstream-0.1.15/tests/test_dashboard.py → defstream-0.1.16/tests/test_status.py +30 -17
- defstream-0.1.15/tests/test_dashboard_ui.cjs → defstream-0.1.16/tests/test_status_ui.cjs +2 -2
- {defstream-0.1.15 → defstream-0.1.16}/.github/ISSUE_TEMPLATE/01.feature.yml +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/.github/ISSUE_TEMPLATE/02.bug.yml +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/.github/ISSUE_TEMPLATE/03.fix.yml +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/.github/ISSUE_TEMPLATE/04.task.yml +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/.gitignore +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/DefStream.egg-info/dependency_links.txt +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/DefStream.egg-info/requires.txt +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/DefStream.egg-info/top_level.txt +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/LICENSE +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/issues/bug/16/IMPLEMENTS.md +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/issues/bug/16/ISSUE.md +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/issues/bug/16/README.md +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/issues/bug/16/REQUIREMENTS.md +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/issues/feature/1/IMPLEMENTS.md +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/issues/feature/1/README.md +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/issues/feature/1/REQUIREMENTS.md +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/issues/feature/1/TASK.md +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/issues/feature/1/ci.refs.json +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/issues/feature/8/IMPLEMENTS.md +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/issues/feature/8/README.md +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/issues/feature/8/ci.refs.json +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/issues/fix/10/IMPLEMENTS.md +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/issues/fix/10/README.md +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/issues/fix/10/REQUIREMENTS.md +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/issues/fix/13/README.md +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/issues/fix/21/IMPLEMENTS.md +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/issues/fix/21/ISSUE.md +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/issues/fix/21/README.md +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/issues/fix/21/REQUIREMENTS.md +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/issues/fix/25/IMPLEMENTS.md +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/issues/fix/25/ISSUE.md +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/issues/fix/25/README.md +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/issues/fix/25/REQUIREMENTS.md +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/issues/fix/25/TASK.md +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/issues/fix/3/IMPLEMENTS.md +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/issues/fix/3/README.md +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/issues/fix/3/REQUIREMENTS.md +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/issues/fix/3/ci.refs.json +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/issues/fix/6/IMPLEMENTS.md +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/issues/fix/6/README.md +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/issues/fix/6/REQUIREMENTS.md +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/issues/task/18/IMPLEMENTS.md +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/issues/task/18/README.md +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/issues/task/18/REQUIREMENTS.md +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/samples/Broker/RabbitMQ/Sample.RPC.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/samples/Broker/RabbitMQ/Sample.Stream.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/samples/Broker/RabbitMQ/Sample.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/samples/Broker/Redis/Sample.Stream.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/samples/Broker/Redis/Sample.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/samples/Broker/Sample.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/samples/Worker/RabbitMQ/Client.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/samples/Worker/RabbitMQ/Tasks.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/samples/Worker/Sample.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/setup.cfg +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Broker/Configuration.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Broker/Connection.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Broker/Consumer.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Broker/Errors.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Broker/Event.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Broker/Implements/RabbitMQ/Configuration.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Broker/Implements/RabbitMQ/Connection.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Broker/Implements/RabbitMQ/Consumer.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Broker/Implements/RabbitMQ/Event.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Broker/Implements/RabbitMQ/Exchange.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Broker/Implements/RabbitMQ/Policies.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Broker/Implements/RabbitMQ/Queue.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Broker/Implements/RabbitMQ/Serializer.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Broker/Implements/RabbitMQ/Stream.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Broker/Implements/RabbitMQ/Subscription.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Broker/Implements/RabbitMQ/__init__.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Broker/Implements/Redis/Configuration.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Broker/Implements/Redis/Connection.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Broker/Implements/Redis/Consumer.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Broker/Implements/Redis/Event.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Broker/Implements/Redis/Queue.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Broker/Implements/Redis/Serializer.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Broker/Implements/Redis/Subscription.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Broker/Implements/Redis/__init__.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Broker/Implements/__init__.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Broker/Policies.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Broker/Priority.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Broker/Protocol.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Broker/__init__.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Descriptor/DataObject.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Descriptor/Types.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Descriptor/Value.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Descriptor/__init__.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Inspector/Extension.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Inspector/Extensions/Console.html +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Inspector/Extensions/Console.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Inspector/Extensions/Metrics.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Inspector/Extensions/Specifications.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Inspector/Inspector.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Inspector/Response.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Inspector/__init__.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Validator/Pattern.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Validator/Patterns/Array.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Validator/Patterns/Common.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Validator/Patterns/Compare.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Validator/Patterns/Condition.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Validator/Patterns/DataObject.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Validator/Patterns/DateTime.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Validator/Patterns/Number.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Validator/Patterns/Object.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Validator/Patterns/Size.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Validator/Patterns/String.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Validator/Patterns/Type.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Validator/Patterns/__init__.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Validator/Validate.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Validator/Validator.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Validator/__init__.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Worker/Executor.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Worker/Message.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Worker/Pool.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Worker/Run.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Worker/Specification.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Worker/Startup.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Worker/Worker.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/Worker/__init__.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/src/__init__.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/tests/test_broker_packaging.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/tests/test_descriptor.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/tests/test_inspector_console.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/tests/test_lifecycle_hooks.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/tests/test_logging.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/tests/test_pool_callbacks.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/tests/test_process_signals.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/tests/test_protocol_contracts.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/tests/test_rabbitmq_broker_methods.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/tests/test_rabbitmq_integration.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/tests/test_rabbitmq_logging.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/tests/test_rabbitmq_priorities.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/tests/test_rabbitmq_release_workflow.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/tests/test_rabbitmq_rpc.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/tests/test_rabbitmq_rpc_integration.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/tests/test_rabbitmq_worker.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/tests/test_redis.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/tests/test_redis_integration.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/tests/test_redis_logging.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/tests/test_redis_release_workflow.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/tests/test_runner_hooks.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/tests/test_specifications.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/tests/test_task_messages.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/tests/test_task_priorities.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/tests/test_validator_patterns.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/tests/test_worker.py +0 -0
- {defstream-0.1.15 → defstream-0.1.16}/tests/test_worker_startup.py +0 -0
|
@@ -381,7 +381,7 @@ jobs:
|
|
|
381
381
|
node-version: '22'
|
|
382
382
|
|
|
383
383
|
- name: Test core UI
|
|
384
|
-
run: node --test packages/DefStream/tests/
|
|
384
|
+
run: node --test packages/DefStream/tests/test_status_ui.cjs
|
|
385
385
|
|
|
386
386
|
- name: Preserve verified release distributions
|
|
387
387
|
if: needs.changes.outputs.release == 'true' && matrix.python == '3.13'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: DefStream
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.16
|
|
4
4
|
Summary: Synchronous message processing with pluggable broker adapters
|
|
5
5
|
Home-page: https://github.com/yong5eon/DefStream
|
|
6
6
|
Author: Heo Yongseon
|
|
@@ -602,10 +602,10 @@ class Add(
|
|
|
602
602
|
from DefStream.Inspector import Inspector
|
|
603
603
|
from DefStream.Inspector.Extensions import (
|
|
604
604
|
Console,
|
|
605
|
-
Dashboard,
|
|
606
|
-
HealthCheck,
|
|
607
605
|
Metrics,
|
|
606
|
+
Ping,
|
|
608
607
|
Specifications,
|
|
608
|
+
Status,
|
|
609
609
|
)
|
|
610
610
|
|
|
611
611
|
|
|
@@ -622,9 +622,9 @@ inspector = Inspector(
|
|
|
622
622
|
host='127.0.0.1',
|
|
623
623
|
port=9999,
|
|
624
624
|
exts=(
|
|
625
|
-
|
|
625
|
+
Ping('/ping'),
|
|
626
626
|
Metrics('/metrics'),
|
|
627
|
-
|
|
627
|
+
Status('/status'),
|
|
628
628
|
Specifications('/asyncapi.json'),
|
|
629
629
|
Console(
|
|
630
630
|
'/console',
|
|
@@ -637,9 +637,9 @@ inspector = Inspector(
|
|
|
637
637
|
|
|
638
638
|
| 경로 | 용도 |
|
|
639
639
|
| --- | --- |
|
|
640
|
-
| `/
|
|
640
|
+
| `/ping` | 구독 준비와 소비자 루프 응답성을 검사. 정상 200, 시작·종료·응답 불가 상태 503 |
|
|
641
641
|
| `/metrics` | `defstream_` 접두사의 Prometheus 지표 |
|
|
642
|
-
| `/
|
|
642
|
+
| `/status` | 처리 성공·실패·처리량·소요 시간. `Metrics` 하나와 함께 등록 |
|
|
643
643
|
| `/asyncapi.json` | 등록 작업의 요청·응답 계약을 AsyncAPI JSON으로 제공 |
|
|
644
644
|
| `/console` | 작업 목록·스키마 조회, JSON 메시지 발행, 지원 브로커의 RPC 실행 |
|
|
645
645
|
|
|
@@ -36,6 +36,10 @@ issues/fix/21/IMPLEMENTS.md
|
|
|
36
36
|
issues/fix/21/ISSUE.md
|
|
37
37
|
issues/fix/21/README.md
|
|
38
38
|
issues/fix/21/REQUIREMENTS.md
|
|
39
|
+
issues/fix/24/IMPLEMENTS.md
|
|
40
|
+
issues/fix/24/ISSUE.md
|
|
41
|
+
issues/fix/24/README.md
|
|
42
|
+
issues/fix/24/REQUIREMENTS.md
|
|
39
43
|
issues/fix/25/IMPLEMENTS.md
|
|
40
44
|
issues/fix/25/ISSUE.md
|
|
41
45
|
issues/fix/25/README.md
|
|
@@ -102,11 +106,11 @@ src/Inspector/Response.py
|
|
|
102
106
|
src/Inspector/__init__.py
|
|
103
107
|
src/Inspector/Extensions/Console.html
|
|
104
108
|
src/Inspector/Extensions/Console.py
|
|
105
|
-
src/Inspector/Extensions/Dashboard.html
|
|
106
|
-
src/Inspector/Extensions/Dashboard.py
|
|
107
|
-
src/Inspector/Extensions/HealthCheck.py
|
|
108
109
|
src/Inspector/Extensions/Metrics.py
|
|
110
|
+
src/Inspector/Extensions/Ping.py
|
|
109
111
|
src/Inspector/Extensions/Specifications.py
|
|
112
|
+
src/Inspector/Extensions/Status.html
|
|
113
|
+
src/Inspector/Extensions/Status.py
|
|
110
114
|
src/Inspector/Extensions/__init__.py
|
|
111
115
|
src/Validator/Pattern.py
|
|
112
116
|
src/Validator/Validate.py
|
|
@@ -133,8 +137,6 @@ src/Worker/Startup.py
|
|
|
133
137
|
src/Worker/Worker.py
|
|
134
138
|
src/Worker/__init__.py
|
|
135
139
|
tests/test_broker_packaging.py
|
|
136
|
-
tests/test_dashboard.py
|
|
137
|
-
tests/test_dashboard_ui.cjs
|
|
138
140
|
tests/test_descriptor.py
|
|
139
141
|
tests/test_inspector.py
|
|
140
142
|
tests/test_inspector_console.py
|
|
@@ -159,6 +161,8 @@ tests/test_redis_release_workflow.py
|
|
|
159
161
|
tests/test_release_workflow.py
|
|
160
162
|
tests/test_runner_hooks.py
|
|
161
163
|
tests/test_specifications.py
|
|
164
|
+
tests/test_status.py
|
|
165
|
+
tests/test_status_ui.cjs
|
|
162
166
|
tests/test_task_messages.py
|
|
163
167
|
tests/test_task_priorities.py
|
|
164
168
|
tests/test_validator_patterns.py
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: DefStream
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.16
|
|
4
4
|
Summary: Synchronous message processing with pluggable broker adapters
|
|
5
5
|
Home-page: https://github.com/yong5eon/DefStream
|
|
6
6
|
Author: Heo Yongseon
|
|
@@ -602,10 +602,10 @@ class Add(
|
|
|
602
602
|
from DefStream.Inspector import Inspector
|
|
603
603
|
from DefStream.Inspector.Extensions import (
|
|
604
604
|
Console,
|
|
605
|
-
Dashboard,
|
|
606
|
-
HealthCheck,
|
|
607
605
|
Metrics,
|
|
606
|
+
Ping,
|
|
608
607
|
Specifications,
|
|
608
|
+
Status,
|
|
609
609
|
)
|
|
610
610
|
|
|
611
611
|
|
|
@@ -622,9 +622,9 @@ inspector = Inspector(
|
|
|
622
622
|
host='127.0.0.1',
|
|
623
623
|
port=9999,
|
|
624
624
|
exts=(
|
|
625
|
-
|
|
625
|
+
Ping('/ping'),
|
|
626
626
|
Metrics('/metrics'),
|
|
627
|
-
|
|
627
|
+
Status('/status'),
|
|
628
628
|
Specifications('/asyncapi.json'),
|
|
629
629
|
Console(
|
|
630
630
|
'/console',
|
|
@@ -637,9 +637,9 @@ inspector = Inspector(
|
|
|
637
637
|
|
|
638
638
|
| 경로 | 용도 |
|
|
639
639
|
| --- | --- |
|
|
640
|
-
| `/
|
|
640
|
+
| `/ping` | 구독 준비와 소비자 루프 응답성을 검사. 정상 200, 시작·종료·응답 불가 상태 503 |
|
|
641
641
|
| `/metrics` | `defstream_` 접두사의 Prometheus 지표 |
|
|
642
|
-
| `/
|
|
642
|
+
| `/status` | 처리 성공·실패·처리량·소요 시간. `Metrics` 하나와 함께 등록 |
|
|
643
643
|
| `/asyncapi.json` | 등록 작업의 요청·응답 계약을 AsyncAPI JSON으로 제공 |
|
|
644
644
|
| `/console` | 작업 목록·스키마 조회, JSON 메시지 발행, 지원 브로커의 RPC 실행 |
|
|
645
645
|
|
|
@@ -593,10 +593,10 @@ This snippet reuses the `Connection` and `Configuration` imports from `worker.py
|
|
|
593
593
|
from DefStream.Inspector import Inspector
|
|
594
594
|
from DefStream.Inspector.Extensions import (
|
|
595
595
|
Console,
|
|
596
|
-
Dashboard,
|
|
597
|
-
HealthCheck,
|
|
598
596
|
Metrics,
|
|
597
|
+
Ping,
|
|
599
598
|
Specifications,
|
|
599
|
+
Status,
|
|
600
600
|
)
|
|
601
601
|
|
|
602
602
|
|
|
@@ -613,9 +613,9 @@ inspector = Inspector(
|
|
|
613
613
|
host='127.0.0.1',
|
|
614
614
|
port=9999,
|
|
615
615
|
exts=(
|
|
616
|
-
|
|
616
|
+
Ping('/ping'),
|
|
617
617
|
Metrics('/metrics'),
|
|
618
|
-
|
|
618
|
+
Status('/status'),
|
|
619
619
|
Specifications('/asyncapi.json'),
|
|
620
620
|
Console(
|
|
621
621
|
'/console',
|
|
@@ -628,9 +628,9 @@ inspector = Inspector(
|
|
|
628
628
|
|
|
629
629
|
| Path | Purpose |
|
|
630
630
|
| --- | --- |
|
|
631
|
-
| `/
|
|
631
|
+
| `/ping` | Check subscription readiness and consumer-loop responsiveness: 200 when healthy, 503 during startup/shutdown or when unresponsive |
|
|
632
632
|
| `/metrics` | Prometheus metrics with the `defstream_` prefix |
|
|
633
|
-
| `/
|
|
633
|
+
| `/status` | Successes, failures, throughput, and duration; register with exactly one `Metrics` |
|
|
634
634
|
| `/asyncapi.json` | Registered task request/reply contracts as AsyncAPI JSON |
|
|
635
635
|
| `/console` | Browse tasks and schemas, send JSON messages, and execute RPC on supported brokers |
|
|
636
636
|
|
|
@@ -569,10 +569,10 @@ class Add(
|
|
|
569
569
|
from DefStream.Inspector import Inspector
|
|
570
570
|
from DefStream.Inspector.Extensions import (
|
|
571
571
|
Console,
|
|
572
|
-
Dashboard,
|
|
573
|
-
HealthCheck,
|
|
574
572
|
Metrics,
|
|
573
|
+
Ping,
|
|
575
574
|
Specifications,
|
|
575
|
+
Status,
|
|
576
576
|
)
|
|
577
577
|
|
|
578
578
|
|
|
@@ -589,9 +589,9 @@ inspector = Inspector(
|
|
|
589
589
|
host='127.0.0.1',
|
|
590
590
|
port=9999,
|
|
591
591
|
exts=(
|
|
592
|
-
|
|
592
|
+
Ping('/ping'),
|
|
593
593
|
Metrics('/metrics'),
|
|
594
|
-
|
|
594
|
+
Status('/status'),
|
|
595
595
|
Specifications('/asyncapi.json'),
|
|
596
596
|
Console(
|
|
597
597
|
'/console',
|
|
@@ -604,9 +604,9 @@ inspector = Inspector(
|
|
|
604
604
|
|
|
605
605
|
| 경로 | 용도 |
|
|
606
606
|
| --- | --- |
|
|
607
|
-
| `/
|
|
607
|
+
| `/ping` | 구독 준비와 소비자 루프 응답성을 검사. 정상 200, 시작·종료·응답 불가 상태 503 |
|
|
608
608
|
| `/metrics` | `defstream_` 접두사의 Prometheus 지표 |
|
|
609
|
-
| `/
|
|
609
|
+
| `/status` | 처리 성공·실패·처리량·소요 시간. `Metrics` 하나와 함께 등록 |
|
|
610
610
|
| `/asyncapi.json` | 등록 작업의 요청·응답 계약을 AsyncAPI JSON으로 제공 |
|
|
611
611
|
| `/console` | 작업 목록·스키마 조회, JSON 메시지 발행, 지원 브로커의 RPC 실행 |
|
|
612
612
|
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
- [Worker](../../../src/Worker/Worker.py)의 모듈 로거가 작업 실패, 미확인 메시지를 남긴 종료, 종료 후 메시지 확인 처리 불가를 ERROR로 기록한다.
|
|
34
34
|
- [Inspector](../../../src/Inspector/Inspector.py)의 모듈 로거가 HTTP 접근 기록을 INFO로, 서버 실행 실패를 예외 로그로 기록한다.
|
|
35
35
|
- [Console](../../../src/Inspector/Extensions/Console.py)은 인증·출처·입력 거부, RPC 실패, 내부 요청 처리 실패를 기록한다.
|
|
36
|
-
- [HealthCheck](../../../src/Inspector/Extensions/
|
|
36
|
+
- [HealthCheck](../../../src/Inspector/Extensions/Ping.py)는 상태 확인 작업 예약 실패를 예외 로그로 기록한다.
|
|
37
37
|
- 다른 Worker 모듈과 나머지 Inspector 확장에는 현재 직접적인 로깅 호출이 없다.
|
|
38
38
|
- [Startup](../../../src/Worker/Startup.py)은 로거 대신 `print()`로 시작 배너와 구성을 출력한다.
|
|
39
39
|
|
|
@@ -52,10 +52,10 @@
|
|
|
52
52
|
| 우선 대상 | [Inspector](../../../src/Inspector/Inspector.py) | `DefStream.Inspector` | 확장 등록·시작, HTTP 서버 생명주기와 요청 처리 |
|
|
53
53
|
| 보조 대상 | [Server](../../../src/Inspector/Inspector.py) | `DefStream.Inspector` (공유) | HTTP 서버의 연결 처리 문맥. Inspector와 중복되는 생명주기 로그는 제외 |
|
|
54
54
|
| 보조 대상 | [RequestHandler](../../../src/Inspector/Inspector.py) | `DefStream.Inspector` (공유) | 공통 HTTP 요청 수신(DEBUG)과 응답 상태를 포함한 전송 결과(INFO) |
|
|
55
|
-
| 우선 대상 | [HealthCheck](../../../src/Inspector/Extensions/
|
|
55
|
+
| 우선 대상 | [HealthCheck](../../../src/Inspector/Extensions/Ping.py) | `DefStream.Inspector.Extensions.HealthCheck` | 상태 확인 작업 예약·응답·시간 초과·상태 변화 |
|
|
56
56
|
| 우선 대상 | [Console](../../../src/Inspector/Extensions/Console.py) | `DefStream.Inspector.Extensions.Console` | 요청 검증·발행·RPC·접근 거부·내부 오류 |
|
|
57
57
|
| 우선 대상 | [Metrics](../../../src/Inspector/Extensions/Metrics.py) | `DefStream.Inspector.Extensions.Metrics` | 수집 초기화, 작업 관측 시작·종료, 스냅샷·응답 생성 |
|
|
58
|
-
| 우선 대상 | [Dashboard](../../../src/Inspector/Extensions/
|
|
58
|
+
| 우선 대상 | [Dashboard](../../../src/Inspector/Extensions/Status.py) | `DefStream.Inspector.Extensions.Dashboard` | Metrics 연결, HTML·JSON 응답 생성 |
|
|
59
59
|
| 우선 대상 | [Specifications](../../../src/Inspector/Extensions/Specifications.py) | `DefStream.Inspector.Extensions.Specifications` | 작업 목록의 AsyncAPI 문서 생성과 응답 |
|
|
60
60
|
|
|
61
61
|
### 4.1. 독립 로거를 우선 추가하지 않을 대상
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# 구현 내용
|
|
2
|
+
|
|
3
|
+
## 관련 요구사항
|
|
4
|
+
|
|
5
|
+
- [요구사항 명세서](./REQUIREMENTS.md)
|
|
6
|
+
|
|
7
|
+
## 변경 내용
|
|
8
|
+
|
|
9
|
+
- Inspector 공개 확장을 `Status`와 `Ping`으로 교체하고 확장 모듈 및 Status HTML 리소스 경로를 새 이름으로 변경했습니다.
|
|
10
|
+
- Status의 Metrics JSON·HTML 동작과 Ping의 상태 확인 응답은 유지하면서 각 확장의 새 경로를 문서, 샘플 및 테스트에 반영했습니다.
|
|
11
|
+
- 기존 이름을 호환 별칭으로 노출하지 않도록 공개 내보내기를 갱신했습니다.
|
|
12
|
+
- 한국어·영어 README 예제와 Inspector 엔드포인트 설명을 수정했습니다.
|
|
13
|
+
|
|
14
|
+
## 영향 범위
|
|
15
|
+
|
|
16
|
+
- `Dashboard`와 `HealthCheck`의 기존 import 및 `/dashboard`, 기존 상태 확인 경로를 사용하는 설정은 새 공개 이름과 URL로 변경해야 합니다.
|
|
17
|
+
- Status HTML 정적 리소스 경로는 `Status.html`로 변경되었습니다.
|
|
18
|
+
|
|
19
|
+
## 검증
|
|
20
|
+
|
|
21
|
+
- `python -m unittest discover -s tests -p test_status.py`: 8개 통과
|
|
22
|
+
- `python -m unittest discover -s tests -p test_inspector.py`: 14개 통과, 2개 건너뜀
|
|
23
|
+
- `python -m unittest discover -s tests -p test_inspector_logging.py`: 5개 통과
|
|
24
|
+
- `node --test tests/test_status_ui.cjs`: 5개 통과
|
|
25
|
+
- Pylance 진단: Python 오류 없음. 미사용 인자·변수 경고만 확인됨
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# 변경 사항
|
|
2
|
+
|
|
3
|
+
- Inspector의 대시보드 확장 이름을 `Dashboard`에서 `Status`로, URL을 `/dashboard`에서 `/status`로 변경합니다.
|
|
4
|
+
- 상태 확인 확장 이름을 `HealthCheck`에서 `Ping`으로, URL을 기존 `/status`에서 `/ping`으로 변경합니다.
|
|
5
|
+
- 기존 클래스 이름과 모듈 경로는 호환 별칭으로 제공하지 않습니다. Inspector 설정에서 새 이름과 경로를 사용하도록 수정하세요.
|
|
6
|
+
|
|
7
|
+
상세 요구사항은 [REQUIREMENTS.md](./REQUIREMENTS.md)를 참고하세요.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# 요구사항 명세서: Inspector 확장 이름 변경
|
|
2
|
+
|
|
3
|
+
## 출처
|
|
4
|
+
|
|
5
|
+
- 이슈: [ISSUE.md](./ISSUE.md)
|
|
6
|
+
- 변경 유형: 일반 변경
|
|
7
|
+
|
|
8
|
+
## 목적
|
|
9
|
+
|
|
10
|
+
Inspector 확장의 이름을 역할에 더 자연스럽게 맞춰 사용자가 이해하고 선택하기 쉽게 한다.
|
|
11
|
+
|
|
12
|
+
## 범위
|
|
13
|
+
|
|
14
|
+
- Inspector의 `Dashboard` 확장 이름을 `Status`로 변경한다.
|
|
15
|
+
- Inspector의 `HealthCheck` 확장 이름을 `Ping`으로 변경한다.
|
|
16
|
+
- 대시보드 URL을 `/status`로, 상태 확인 URL을 `/ping`으로 변경한다.
|
|
17
|
+
- 이름 변경에 필요한 공개 API 노출, 문서, 샘플 및 관련 테스트를 일관되게 반영한다.
|
|
18
|
+
|
|
19
|
+
## 확정 요구사항
|
|
20
|
+
|
|
21
|
+
| ID | 요구사항 |
|
|
22
|
+
| --- | --- |
|
|
23
|
+
| RQ-1 | 기존 `Dashboard` 확장은 `Status`라는 이름으로 사용할 수 있어야 한다. |
|
|
24
|
+
| RQ-2 | 기존 `HealthCheck` 확장은 `Ping`이라는 이름으로 사용할 수 있어야 한다. |
|
|
25
|
+
| RQ-3 | 이름 변경으로 각 확장의 기존 동작과 응답 계약이 달라져서는 안 된다. `Status`는 기존 대시보드의 HTML 및 지표 JSON 응답을 제공하고, `Ping`은 기존 상태 확인 결과와 HTTP 응답을 제공한다. |
|
|
26
|
+
| RQ-4 | `Status` 대시보드의 요청 경로는 `/status`로, `Ping` 상태 확인의 요청 경로는 `/ping`으로 한다. |
|
|
27
|
+
| RQ-5 | 패키지에서 제공하는 공개 가져오기 경로, 문서, 샘플 및 관련 테스트에서 새 이름과 URL을 일관되게 사용한다. |
|
|
28
|
+
|
|
29
|
+
## 제약사항
|
|
30
|
+
|
|
31
|
+
- 이슈는 확장 이름과 요청 경로 변경을 요청하므로 그 외의 기능 추가나 응답 형식 변경은 범위에 포함하지 않는다.
|
|
32
|
+
- `Status`와 `Ping`은 기존 확장의 기능 및 설정을 이어받아야 한다.
|
|
33
|
+
- 요청 경로는 이슈의 명시적 변경 사항에 따라 `/status`와 `/ping`으로 변경한다.
|
|
34
|
+
- 이전 공개 이름(`Dashboard`, `HealthCheck`)과 이전 모듈 경로는 호환 별칭으로 유지하지 않는다.
|
|
35
|
+
|
|
36
|
+
## 인수 기준
|
|
37
|
+
|
|
38
|
+
1. `DefStream.Inspector.Extensions`에서 `Status`와 `Ping`을 가져와 Inspector 확장으로 등록할 수 있다.
|
|
39
|
+
2. `Status`는 기존 대시보드와 동일하게 HTML 및 지표 JSON 응답을 제공한다.
|
|
40
|
+
3. `Ping`은 기존 상태 확인과 동일하게 정상일 때 성공 응답을, 비정상일 때 서비스 불가 응답을 제공한다.
|
|
41
|
+
4. `Status`는 `/status`, `Ping`은 `/ping`에서 응답한다.
|
|
42
|
+
5. 샘플, 문서, 공개 내보내기 및 관련 테스트에 새 이름이 반영된다.
|
|
43
|
+
|
|
44
|
+
## 결정 사항
|
|
45
|
+
|
|
46
|
+
- 이전 이름을 호환 별칭으로 제공하지 않고 `Status` 및 `Ping`으로 대체한다.
|
|
47
|
+
- 클래스명에 맞춰 모듈 경로와 대시보드 HTML 리소스도 `Status`로 변경한다.
|
|
48
|
+
- 확장 고유 로거 이름과 로그 메시지도 새 클래스 이름을 사용한다.
|
|
@@ -18,11 +18,11 @@ from DefStream.Broker.Implements.RabbitMQ import (
|
|
|
18
18
|
)
|
|
19
19
|
from DefStream.Inspector import Inspector
|
|
20
20
|
from DefStream.Inspector.Extensions import (
|
|
21
|
-
HealthCheck,
|
|
22
21
|
Metrics,
|
|
22
|
+
Ping,
|
|
23
23
|
Specifications,
|
|
24
24
|
Console,
|
|
25
|
-
|
|
25
|
+
Status,
|
|
26
26
|
)
|
|
27
27
|
from DefStream.Worker import (
|
|
28
28
|
declare,
|
|
@@ -97,10 +97,10 @@ if __name__ == '__main__':
|
|
|
97
97
|
host='127.0.0.1',
|
|
98
98
|
port=9999,
|
|
99
99
|
exts=(
|
|
100
|
-
|
|
100
|
+
Ping('/ping'),
|
|
101
101
|
Metrics('/metrics'),
|
|
102
|
-
|
|
103
|
-
'/
|
|
102
|
+
Status(
|
|
103
|
+
'/status',
|
|
104
104
|
title='DefStream using RabbitMQ Sample',
|
|
105
105
|
description='A sample DefStream worker using RabbitMQ as the broker',
|
|
106
106
|
),
|
|
@@ -19,11 +19,11 @@ from DefStream.Broker.Implements.Redis import (
|
|
|
19
19
|
)
|
|
20
20
|
from DefStream.Inspector import Inspector
|
|
21
21
|
from DefStream.Inspector.Extensions import (
|
|
22
|
-
HealthCheck,
|
|
23
22
|
Metrics,
|
|
23
|
+
Ping,
|
|
24
24
|
Specifications,
|
|
25
25
|
Console,
|
|
26
|
-
|
|
26
|
+
Status,
|
|
27
27
|
)
|
|
28
28
|
from DefStream.Worker import (
|
|
29
29
|
declare,
|
|
@@ -156,10 +156,10 @@ def main() -> None:
|
|
|
156
156
|
host='127.0.0.1',
|
|
157
157
|
port=9999,
|
|
158
158
|
exts=(
|
|
159
|
-
|
|
159
|
+
Ping('/ping'),
|
|
160
160
|
Metrics('/metrics'),
|
|
161
|
-
|
|
162
|
-
'/
|
|
161
|
+
Status(
|
|
162
|
+
'/status',
|
|
163
163
|
title='DefStream using Redis Sample',
|
|
164
164
|
description='A sample DefStream worker using Redis as the broker',
|
|
165
165
|
),
|
|
@@ -17,11 +17,11 @@ if TYPE_CHECKING:
|
|
|
17
17
|
from ..Inspector import Inspector
|
|
18
18
|
|
|
19
19
|
__all__ = (
|
|
20
|
-
'
|
|
20
|
+
'Ping',
|
|
21
21
|
)
|
|
22
22
|
|
|
23
|
-
class
|
|
24
|
-
logger = getLogger('DefStream.Inspector.Extensions.
|
|
23
|
+
class Ping(Extension):
|
|
24
|
+
logger = getLogger('DefStream.Inspector.Extensions.Ping')
|
|
25
25
|
|
|
26
26
|
def __init__(
|
|
27
27
|
self,
|
|
@@ -33,7 +33,7 @@ class HealthCheck(Extension):
|
|
|
33
33
|
timeout,
|
|
34
34
|
bool,
|
|
35
35
|
) or not isfinite(timeout) or timeout <= 0:
|
|
36
|
-
raise ValueError('
|
|
36
|
+
raise ValueError('Ping probe timeout must be finite and positive')
|
|
37
37
|
self.timeout = timeout
|
|
38
38
|
self.lock = Lock()
|
|
39
39
|
self.probe: Optional[Event] = None
|
|
@@ -66,12 +66,12 @@ class HealthCheck(Extension):
|
|
|
66
66
|
if self.probe is None or self.probe.is_set():
|
|
67
67
|
self.probe = Event()
|
|
68
68
|
try:
|
|
69
|
-
self.logger.debug('Scheduling
|
|
69
|
+
self.logger.debug('Scheduling Ping Consumer probe')
|
|
70
70
|
worker.consumer.call(self.probe.set)
|
|
71
71
|
except Exception as error:
|
|
72
72
|
self.probe = None
|
|
73
73
|
self.logger.error(
|
|
74
|
-
'
|
|
74
|
+
'Ping Consumer probe scheduling failed: error=%s',
|
|
75
75
|
type(error).__name__,
|
|
76
76
|
)
|
|
77
77
|
return False
|
|
@@ -79,7 +79,7 @@ class HealthCheck(Extension):
|
|
|
79
79
|
responded = probe.wait(self.timeout)
|
|
80
80
|
healthy = responded and self.state(inspector) == 'running'
|
|
81
81
|
self.logger.debug(
|
|
82
|
-
'
|
|
82
|
+
'Ping Consumer probe completed: responded=%s healthy=%s',
|
|
83
83
|
responded,
|
|
84
84
|
healthy,
|
|
85
85
|
)
|
|
@@ -94,7 +94,7 @@ class HealthCheck(Extension):
|
|
|
94
94
|
if not healthy and state == 'running':
|
|
95
95
|
state = 'unresponsive'
|
|
96
96
|
self.logger.debug(
|
|
97
|
-
'Building
|
|
97
|
+
'Building Ping response: status=%s state=%s',
|
|
98
98
|
'200' if healthy else '503',
|
|
99
99
|
state,
|
|
100
100
|
)
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="utf-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
-
<title>{{
|
|
6
|
+
<title>{{status_title}}</title>
|
|
7
7
|
<style>
|
|
8
8
|
:root { color-scheme: light; font: 14px/1.55 system-ui, -apple-system, sans-serif; color: #263343; background: #f7f8fa; }
|
|
9
9
|
* { box-sizing: border-box; }
|
|
@@ -59,7 +59,7 @@ tr:last-child td { border-bottom: 0; }
|
|
|
59
59
|
</head>
|
|
60
60
|
<body>
|
|
61
61
|
<header><div class="heading">
|
|
62
|
-
<div><h1>{{
|
|
62
|
+
<div><h1>{{status_title}}</h1><p class="subtitle">{{status_description}}</p></div>
|
|
63
63
|
<span class="badge">LIVE DASHBOARD</span>
|
|
64
64
|
</div></header>
|
|
65
65
|
<main>
|
|
@@ -16,12 +16,12 @@ if TYPE_CHECKING:
|
|
|
16
16
|
from ..Inspector import Inspector
|
|
17
17
|
|
|
18
18
|
__all__ = (
|
|
19
|
-
'
|
|
19
|
+
'Status',
|
|
20
20
|
)
|
|
21
21
|
|
|
22
22
|
|
|
23
|
-
class
|
|
24
|
-
logger = getLogger('DefStream.Inspector.Extensions.
|
|
23
|
+
class Status(Extension):
|
|
24
|
+
logger = getLogger('DefStream.Inspector.Extensions.Status')
|
|
25
25
|
|
|
26
26
|
def __init__(
|
|
27
27
|
self,
|
|
@@ -35,12 +35,12 @@ class Dashboard(Extension):
|
|
|
35
35
|
title,
|
|
36
36
|
str,
|
|
37
37
|
) or not title:
|
|
38
|
-
raise ValueError('
|
|
38
|
+
raise ValueError('Status title must be a nonempty string')
|
|
39
39
|
if description is not None and not isinstance(
|
|
40
40
|
description,
|
|
41
41
|
str,
|
|
42
42
|
):
|
|
43
|
-
raise TypeError('
|
|
43
|
+
raise TypeError('Status description must be a string or None')
|
|
44
44
|
self.title = title
|
|
45
45
|
self.description = description
|
|
46
46
|
self.metrics: Optional[Metrics] = None
|
|
@@ -57,10 +57,10 @@ class Dashboard(Extension):
|
|
|
57
57
|
)
|
|
58
58
|
]
|
|
59
59
|
if len(metrics) != 1:
|
|
60
|
-
raise ValueError('
|
|
60
|
+
raise ValueError('Status requires exactly one registered Metrics extension')
|
|
61
61
|
self.metrics = metrics[0]
|
|
62
62
|
self.logger.debug(
|
|
63
|
-
'
|
|
63
|
+
'Status Metrics extension attached: path=%s',
|
|
64
64
|
self.metrics.path,
|
|
65
65
|
)
|
|
66
66
|
|
|
@@ -71,8 +71,8 @@ class Dashboard(Extension):
|
|
|
71
71
|
) -> Response:
|
|
72
72
|
if environ.get('HTTP_ACCEPT') == 'application/json':
|
|
73
73
|
if self.metrics is None:
|
|
74
|
-
raise RuntimeError('
|
|
75
|
-
self.logger.debug('Building
|
|
74
|
+
raise RuntimeError('Status has not been started')
|
|
75
|
+
self.logger.debug('Building Status JSON response')
|
|
76
76
|
return Response(
|
|
77
77
|
'200 OK',
|
|
78
78
|
dumps(
|
|
@@ -86,22 +86,22 @@ class Dashboard(Extension):
|
|
|
86
86
|
'nosniff',
|
|
87
87
|
),),
|
|
88
88
|
)
|
|
89
|
-
self.logger.debug('
|
|
89
|
+
self.logger.debug('Status HTML response requested')
|
|
90
90
|
return self(inspector)
|
|
91
91
|
|
|
92
92
|
def __call__(
|
|
93
93
|
self,
|
|
94
94
|
inspector: 'Inspector',
|
|
95
95
|
) -> Response:
|
|
96
|
-
self.logger.debug('Reading
|
|
96
|
+
self.logger.debug('Reading Status HTML resource')
|
|
97
97
|
values = {
|
|
98
98
|
'title': escape(self.title),
|
|
99
99
|
'description': escape(self.description) if self.description is not None else '',
|
|
100
100
|
}
|
|
101
101
|
page = sub(
|
|
102
|
-
r'\{\{
|
|
102
|
+
r'\{\{status_(title|description)\}\}',
|
|
103
103
|
lambda match: values[match[1]],
|
|
104
|
-
files(__package__).joinpath('
|
|
104
|
+
files(__package__).joinpath('Status.html').read_text(encoding='utf-8'),
|
|
105
105
|
)
|
|
106
106
|
return Response(
|
|
107
107
|
'200 OK',
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
from .
|
|
1
|
+
from .Ping import Ping
|
|
2
2
|
from .Metrics import Metrics
|
|
3
3
|
from .Specifications import Specifications
|
|
4
4
|
from .Console import Console
|
|
5
|
-
from .
|
|
5
|
+
from .Status import Status
|
|
6
6
|
|
|
7
7
|
__all__ = (
|
|
8
|
-
'
|
|
8
|
+
'Ping',
|
|
9
9
|
'Metrics',
|
|
10
10
|
'Specifications',
|
|
11
11
|
'Console',
|
|
12
|
-
'
|
|
12
|
+
'Status',
|
|
13
13
|
)
|