edda-framework 0.3.0__tar.gz → 0.3.1__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.
- {edda_framework-0.3.0 → edda_framework-0.3.1}/PKG-INFO +1 -1
- {edda_framework-0.3.0 → edda_framework-0.3.1}/edda/integrations/mcp/decorators.py +28 -8
- {edda_framework-0.3.0 → edda_framework-0.3.1}/edda/integrations/mcp/server.py +21 -17
- {edda_framework-0.3.0 → edda_framework-0.3.1}/pyproject.toml +1 -1
- {edda_framework-0.3.0 → edda_framework-0.3.1}/uv.lock +1 -1
- {edda_framework-0.3.0 → edda_framework-0.3.1}/.github/workflows/ci.yml +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/.github/workflows/docs.yml +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/.github/workflows/release.yml +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/.gitignore +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/.python-version +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/Justfile +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/LICENSE +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/README.md +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/demo_app.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/docs/core-features/durable-execution/replay.md +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/docs/core-features/events/cloudevents-http-binding.md +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/docs/core-features/events/wait-event.md +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/docs/core-features/hooks.md +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/docs/core-features/retry.md +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/docs/core-features/saga-compensation.md +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/docs/core-features/transactional-outbox.md +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/docs/core-features/workflows-activities.md +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/docs/examples/ecommerce.md +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/docs/examples/events.md +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/docs/examples/fastapi-integration.md +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/docs/examples/saga.md +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/docs/examples/simple.md +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/docs/getting-started/concepts.md +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/docs/getting-started/first-workflow.md +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/docs/getting-started/installation.md +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/docs/getting-started/quick-start.md +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/docs/index.md +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/docs/integrations/mcp.md +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/docs/markdown.md +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/docs/viewer-ui/images/cloudevents-cli-trigger.png +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/docs/viewer-ui/images/compensation-execution.png +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/docs/viewer-ui/images/conditional-branching-diagram.png +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/docs/viewer-ui/images/detail-overview-panel.png +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/docs/viewer-ui/images/execution-history-panel.png +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/docs/viewer-ui/images/form-generation-example.png +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/docs/viewer-ui/images/hybrid-diagram-example.png +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/docs/viewer-ui/images/nested-pydantic-form.png +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/docs/viewer-ui/images/start-workflow-dialog.png +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/docs/viewer-ui/images/status-badges-example.png +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/docs/viewer-ui/images/wait-event-visualization.png +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/docs/viewer-ui/images/workflow-list-view.png +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/docs/viewer-ui/setup.md +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/docs/viewer-ui/visualization.md +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/edda/__init__.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/edda/activity.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/edda/app.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/edda/compensation.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/edda/context.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/edda/events.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/edda/exceptions.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/edda/hooks.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/edda/integrations/__init__.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/edda/integrations/mcp/__init__.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/edda/locking.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/edda/outbox/__init__.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/edda/outbox/relayer.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/edda/outbox/transactional.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/edda/pydantic_utils.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/edda/replay.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/edda/retry.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/edda/serialization/__init__.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/edda/serialization/base.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/edda/serialization/json.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/edda/storage/__init__.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/edda/storage/models.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/edda/storage/protocol.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/edda/storage/sqlalchemy_storage.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/edda/viewer_ui/__init__.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/edda/viewer_ui/app.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/edda/viewer_ui/components.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/edda/viewer_ui/data_service.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/edda/visualizer/__init__.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/edda/visualizer/ast_analyzer.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/edda/visualizer/mermaid_generator.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/edda/workflow.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/edda/wsgi.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/examples/__init__.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/examples/cancellable_workflow.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/examples/compensation_workflow.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/examples/event_waiting_app.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/examples/event_waiting_workflow.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/examples/event_waiting_workflow_complete.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/examples/mcp/README.md +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/examples/mcp/order_processing_mcp.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/examples/mcp/remote_server_example.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/examples/mcp/simple_mcp_server.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/examples/observability_with_logfire.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/examples/pydantic_saga.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/examples/retry_example.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/examples/retry_with_compensation.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/examples/simple_workflow.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/examples/typeddict_example.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/examples/with_outbox.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/__init__.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/conftest.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/integrations/__init__.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/integrations/mcp/__init__.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/integrations/mcp/test_integration.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/integrations/mcp/test_jsonrpc.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/integrations/mcp/test_server.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/test_activity.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/test_activity_retry.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/test_activity_sync.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/test_app.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/test_ast_analyzer.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/test_atomic_wait_event.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/test_binary_data.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/test_cloudevents_http_binding.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/test_compensation.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/test_compensation_crash_recovery.py.wip +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/test_concurrent_outbox.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/test_context.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/test_ctx_session.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/test_distributed_event_delivery.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/test_events.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/test_lock_race_condition.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/test_lock_timeout_customization.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/test_locking.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/test_multidb_storage.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/test_outbox.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/test_pydantic_activity.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/test_pydantic_enum.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/test_pydantic_events.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/test_pydantic_saga.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/test_pydantic_utils.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/test_received_event.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/test_replay.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/test_retry_policy.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/test_saga_parameter_extraction.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/test_serialization.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/test_skip_locked.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/test_stale_workflow_recovery.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/test_storage.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/test_storage_mysql.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/test_storage_postgresql.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/test_transactions.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/test_viewer_pydantic_form.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/test_viewer_start_saga.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/test_wait_timer.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/test_workflow.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/test_workflow_auto_register.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/tests/test_workflow_cancellation.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/viewer_app.py +0 -0
- {edda_framework-0.3.0 → edda_framework-0.3.1}/zensical.toml +0 -0
|
@@ -4,7 +4,7 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
import inspect
|
|
6
6
|
from collections.abc import Callable
|
|
7
|
-
from typing import TYPE_CHECKING, Any
|
|
7
|
+
from typing import TYPE_CHECKING, Any, cast
|
|
8
8
|
|
|
9
9
|
from edda.workflow import workflow
|
|
10
10
|
|
|
@@ -15,7 +15,7 @@ if TYPE_CHECKING:
|
|
|
15
15
|
|
|
16
16
|
def create_durable_tool(
|
|
17
17
|
server: EddaMCPServer,
|
|
18
|
-
func: Callable,
|
|
18
|
+
func: Callable[..., Any],
|
|
19
19
|
*,
|
|
20
20
|
description: str = "",
|
|
21
21
|
) -> Workflow:
|
|
@@ -38,7 +38,7 @@ def create_durable_tool(
|
|
|
38
38
|
Workflow instance
|
|
39
39
|
"""
|
|
40
40
|
# 1. Create Edda workflow
|
|
41
|
-
workflow_instance
|
|
41
|
+
workflow_instance = cast(Workflow, workflow(func, event_handler=False))
|
|
42
42
|
workflow_name = func.__name__
|
|
43
43
|
|
|
44
44
|
# Register in server's workflow registry
|
|
@@ -56,7 +56,7 @@ def create_durable_tool(
|
|
|
56
56
|
]
|
|
57
57
|
|
|
58
58
|
# Create the tool function
|
|
59
|
-
async def start_tool(**kwargs: Any) -> dict:
|
|
59
|
+
async def start_tool(**kwargs: Any) -> dict[str, Any]:
|
|
60
60
|
"""
|
|
61
61
|
Start workflow and return instance_id.
|
|
62
62
|
|
|
@@ -94,11 +94,21 @@ def create_durable_tool(
|
|
|
94
94
|
status_tool_name = f"{workflow_name}_status"
|
|
95
95
|
status_tool_description = f"Check status of {workflow_name} workflow"
|
|
96
96
|
|
|
97
|
-
@server._mcp.tool(name=status_tool_name, description=status_tool_description)
|
|
98
|
-
async def status_tool(instance_id: str) -> dict:
|
|
97
|
+
@server._mcp.tool(name=status_tool_name, description=status_tool_description) # type: ignore[misc]
|
|
98
|
+
async def status_tool(instance_id: str) -> dict[str, Any]:
|
|
99
99
|
"""Check workflow status."""
|
|
100
100
|
try:
|
|
101
101
|
instance = await server._edda_app.storage.get_instance(instance_id)
|
|
102
|
+
if instance is None:
|
|
103
|
+
return {
|
|
104
|
+
"content": [
|
|
105
|
+
{
|
|
106
|
+
"type": "text",
|
|
107
|
+
"text": f"Workflow instance not found: {instance_id}",
|
|
108
|
+
}
|
|
109
|
+
],
|
|
110
|
+
"isError": True,
|
|
111
|
+
}
|
|
102
112
|
|
|
103
113
|
status = instance["status"]
|
|
104
114
|
current_activity_id = instance.get("current_activity_id", "N/A")
|
|
@@ -128,11 +138,21 @@ def create_durable_tool(
|
|
|
128
138
|
result_tool_name = f"{workflow_name}_result"
|
|
129
139
|
result_tool_description = f"Get result of {workflow_name} workflow (if completed)"
|
|
130
140
|
|
|
131
|
-
@server._mcp.tool(name=result_tool_name, description=result_tool_description)
|
|
132
|
-
async def result_tool(instance_id: str) -> dict:
|
|
141
|
+
@server._mcp.tool(name=result_tool_name, description=result_tool_description) # type: ignore[misc]
|
|
142
|
+
async def result_tool(instance_id: str) -> dict[str, Any]:
|
|
133
143
|
"""Get workflow result (if completed)."""
|
|
134
144
|
try:
|
|
135
145
|
instance = await server._edda_app.storage.get_instance(instance_id)
|
|
146
|
+
if instance is None:
|
|
147
|
+
return {
|
|
148
|
+
"content": [
|
|
149
|
+
{
|
|
150
|
+
"type": "text",
|
|
151
|
+
"text": f"Workflow instance not found: {instance_id}",
|
|
152
|
+
}
|
|
153
|
+
],
|
|
154
|
+
"isError": True,
|
|
155
|
+
}
|
|
136
156
|
|
|
137
157
|
status = instance["status"]
|
|
138
158
|
|
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
from collections.abc import Callable
|
|
6
|
-
from typing import Any
|
|
6
|
+
from typing import Any, cast
|
|
7
7
|
|
|
8
8
|
from edda.app import EddaApp
|
|
9
9
|
from edda.workflow import Workflow
|
|
10
10
|
|
|
11
11
|
try:
|
|
12
|
-
from mcp.server.fastmcp import FastMCP
|
|
12
|
+
from mcp.server.fastmcp import FastMCP # type: ignore[import-not-found]
|
|
13
13
|
except ImportError as e:
|
|
14
14
|
raise ImportError(
|
|
15
15
|
"MCP Python SDK is required for MCP integration. "
|
|
@@ -89,7 +89,7 @@ class EddaMCPServer:
|
|
|
89
89
|
service_name=name,
|
|
90
90
|
db_url=db_url,
|
|
91
91
|
outbox_enabled=outbox_enabled,
|
|
92
|
-
broker_url=broker_url,
|
|
92
|
+
broker_url=broker_url or "",
|
|
93
93
|
)
|
|
94
94
|
self._mcp = FastMCP(name, json_response=True, stateless_http=True)
|
|
95
95
|
self._token_verifier = token_verifier
|
|
@@ -99,10 +99,10 @@ class EddaMCPServer:
|
|
|
99
99
|
|
|
100
100
|
def durable_tool(
|
|
101
101
|
self,
|
|
102
|
-
func: Callable | None = None,
|
|
102
|
+
func: Callable[..., Any] | None = None,
|
|
103
103
|
*,
|
|
104
104
|
description: str = "",
|
|
105
|
-
) -> Callable:
|
|
105
|
+
) -> Callable[..., Any]:
|
|
106
106
|
"""
|
|
107
107
|
Decorator to define a durable workflow tool.
|
|
108
108
|
|
|
@@ -128,14 +128,14 @@ class EddaMCPServer:
|
|
|
128
128
|
"""
|
|
129
129
|
from edda.integrations.mcp.decorators import create_durable_tool
|
|
130
130
|
|
|
131
|
-
def decorator(f: Callable) -> Workflow:
|
|
131
|
+
def decorator(f: Callable[..., Any]) -> Workflow:
|
|
132
132
|
return create_durable_tool(self, f, description=description)
|
|
133
133
|
|
|
134
134
|
if func is None:
|
|
135
135
|
return decorator
|
|
136
136
|
return decorator(func)
|
|
137
137
|
|
|
138
|
-
def asgi_app(self) -> Callable:
|
|
138
|
+
def asgi_app(self) -> Callable[..., Any]:
|
|
139
139
|
"""
|
|
140
140
|
Create ASGI application with MCP + CloudEvents support.
|
|
141
141
|
|
|
@@ -150,8 +150,8 @@ class EddaMCPServer:
|
|
|
150
150
|
Returns:
|
|
151
151
|
ASGI callable (Starlette app)
|
|
152
152
|
"""
|
|
153
|
-
from starlette.requests import Request
|
|
154
|
-
from starlette.responses import Response
|
|
153
|
+
from starlette.requests import Request # type: ignore[import-not-found]
|
|
154
|
+
from starlette.responses import Response # type: ignore[import-not-found]
|
|
155
155
|
|
|
156
156
|
# Get MCP's Starlette app (Issue #1367 workaround: use directly)
|
|
157
157
|
app = self._mcp.streamable_http_app()
|
|
@@ -169,9 +169,9 @@ class EddaMCPServer:
|
|
|
169
169
|
scope["path"] = f"/cancel/{instance_id}"
|
|
170
170
|
|
|
171
171
|
# Capture response
|
|
172
|
-
response_data = {"status": 200, "headers": [], "body": b""}
|
|
172
|
+
response_data: dict[str, Any] = {"status": 200, "headers": [], "body": b""}
|
|
173
173
|
|
|
174
|
-
async def send(message: dict) -> None:
|
|
174
|
+
async def send(message: dict[str, Any]) -> None:
|
|
175
175
|
if message["type"] == "http.response.start":
|
|
176
176
|
response_data["status"] = message["status"]
|
|
177
177
|
response_data["headers"] = message.get("headers", [])
|
|
@@ -185,7 +185,7 @@ class EddaMCPServer:
|
|
|
185
185
|
return Response(
|
|
186
186
|
content=response_data["body"],
|
|
187
187
|
status_code=response_data["status"],
|
|
188
|
-
headers=dict(response_data["headers"]),
|
|
188
|
+
headers=cast(dict[str, str], dict(response_data["headers"])),
|
|
189
189
|
)
|
|
190
190
|
|
|
191
191
|
# Add cancel route
|
|
@@ -193,14 +193,18 @@ class EddaMCPServer:
|
|
|
193
193
|
|
|
194
194
|
# Add authentication middleware if token_verifier provided (AFTER adding routes)
|
|
195
195
|
if self._token_verifier is not None:
|
|
196
|
-
from starlette.middleware.base import
|
|
196
|
+
from starlette.middleware.base import ( # type: ignore[import-not-found]
|
|
197
|
+
BaseHTTPMiddleware,
|
|
198
|
+
)
|
|
197
199
|
|
|
198
|
-
class AuthMiddleware(BaseHTTPMiddleware):
|
|
199
|
-
def __init__(self, app: Any, token_verifier: Callable):
|
|
200
|
+
class AuthMiddleware(BaseHTTPMiddleware): # type: ignore[misc]
|
|
201
|
+
def __init__(self, app: Any, token_verifier: Callable[[str], bool]):
|
|
200
202
|
super().__init__(app)
|
|
201
203
|
self.token_verifier = token_verifier
|
|
202
204
|
|
|
203
|
-
async def dispatch(
|
|
205
|
+
async def dispatch(
|
|
206
|
+
self, request: Request, call_next: Callable[..., Any]
|
|
207
|
+
) -> Response:
|
|
204
208
|
auth_header = request.headers.get("authorization", "")
|
|
205
209
|
if auth_header.startswith("Bearer "):
|
|
206
210
|
token = auth_header[7:]
|
|
@@ -211,7 +215,7 @@ class EddaMCPServer:
|
|
|
211
215
|
# Wrap app with auth middleware
|
|
212
216
|
app = AuthMiddleware(app, self._token_verifier)
|
|
213
217
|
|
|
214
|
-
return app
|
|
218
|
+
return cast(Callable[..., Any], app)
|
|
215
219
|
|
|
216
220
|
async def initialize(self) -> None:
|
|
217
221
|
"""
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{edda_framework-0.3.0 → edda_framework-0.3.1}/docs/core-features/durable-execution/replay.md
RENAMED
|
File without changes
|
{edda_framework-0.3.0 → edda_framework-0.3.1}/docs/core-features/events/cloudevents-http-binding.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{edda_framework-0.3.0 → edda_framework-0.3.1}/docs/viewer-ui/images/cloudevents-cli-trigger.png
RENAMED
|
File without changes
|
{edda_framework-0.3.0 → edda_framework-0.3.1}/docs/viewer-ui/images/compensation-execution.png
RENAMED
|
File without changes
|
|
File without changes
|
{edda_framework-0.3.0 → edda_framework-0.3.1}/docs/viewer-ui/images/detail-overview-panel.png
RENAMED
|
File without changes
|
{edda_framework-0.3.0 → edda_framework-0.3.1}/docs/viewer-ui/images/execution-history-panel.png
RENAMED
|
File without changes
|
{edda_framework-0.3.0 → edda_framework-0.3.1}/docs/viewer-ui/images/form-generation-example.png
RENAMED
|
File without changes
|
{edda_framework-0.3.0 → edda_framework-0.3.1}/docs/viewer-ui/images/hybrid-diagram-example.png
RENAMED
|
File without changes
|
{edda_framework-0.3.0 → edda_framework-0.3.1}/docs/viewer-ui/images/nested-pydantic-form.png
RENAMED
|
File without changes
|
{edda_framework-0.3.0 → edda_framework-0.3.1}/docs/viewer-ui/images/start-workflow-dialog.png
RENAMED
|
File without changes
|
{edda_framework-0.3.0 → edda_framework-0.3.1}/docs/viewer-ui/images/status-badges-example.png
RENAMED
|
File without changes
|
{edda_framework-0.3.0 → edda_framework-0.3.1}/docs/viewer-ui/images/wait-event-visualization.png
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|