Update ruff checks (#204)

This commit is contained in:
Adrian Lyjak
2025-11-18 14:24:17 -05:00
committed by GitHub
parent f3072532e4
commit 300fd05416
96 changed files with 379 additions and 365 deletions
+6
View File
@@ -0,0 +1,6 @@
---
"llama-index-utils-workflow": patch
"llama-index-workflows": patch
---
Add stricter ruff formatting checks
+1 -1
View File
@@ -17,7 +17,7 @@ repos:
- id: trailing-whitespace
- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: v0.11.13
rev: v0.14.5
hooks:
- id: ruff-format
- id: ruff-check
+2 -2
View File
@@ -64,7 +64,7 @@
"outputs": [],
"source": [
"from llama_index.core.llms import ChatMessage\n",
"from llama_index.core.tools import ToolSelection, ToolOutput\n",
"from llama_index.core.tools import ToolOutput, ToolSelection\n",
"from llama_index.core.workflow import Event\n",
"\n",
"\n",
@@ -108,9 +108,9 @@
"from llama_index.core.tools.types import BaseTool\n",
"from llama_index.core.workflow import (\n",
" Context,\n",
" Workflow,\n",
" StartEvent,\n",
" StopEvent,\n",
" Workflow,\n",
" step,\n",
")\n",
"from llama_index.llms.openai import OpenAI\n",
+4 -6
View File
@@ -1,12 +1,10 @@
import asyncio
from workflows.client import WorkflowClient
from workflows.events import StartEvent
from pydantic import Field
from typing import Literal
from pydantic import Field
from workflows.client import WorkflowClient
from workflows.events import StartEvent
class InputNumbers(StartEvent):
a: int
+5 -5
View File
@@ -1,10 +1,10 @@
from workflows import Workflow, step, Context
from workflows.events import StartEvent, StopEvent, Event
from pydantic import Field
from workflows.server import WorkflowServer
from typing import Literal
from pydantic import Field
from workflows import Context, Workflow, step
from workflows.events import Event, StartEvent, StopEvent
from workflows.server import WorkflowServer
class InputNumbers(StartEvent):
a: int
@@ -2,8 +2,8 @@ import asyncio
from workflows.client import WorkflowClient
from workflows.events import (
StopEvent,
HumanResponseEvent,
StopEvent,
)
@@ -1,10 +1,10 @@
from workflows import Workflow, step
from workflows.context import Context
from workflows.events import (
HumanResponseEvent,
InputRequiredEvent,
StartEvent,
StopEvent,
InputRequiredEvent,
HumanResponseEvent,
)
from workflows.server import WorkflowServer
@@ -145,8 +145,8 @@
},
"outputs": [],
"source": [
"from workflows.events import StartEvent, StopEvent, Event\n",
"from llama_index.llms.openai import OpenAI\n",
"from workflows.events import Event, StartEvent, StopEvent\n",
"\n",
"\n",
"class EmailReceived(StartEvent):\n",
@@ -186,10 +186,10 @@
},
"outputs": [],
"source": [
"from workflows import Workflow, step\n",
"from llama_cloud.client import AsyncLlamaCloud\n",
"from llama_cloud.types import ClassifierRule\n",
"from llama_cloud_services.beta.classifier.client import ClassifyClient\n",
"from llama_cloud.client import AsyncLlamaCloud\n",
"from workflows import Workflow, step\n",
"\n",
"\n",
"class FinanceTeamAgent(Workflow):\n",
+6 -6
View File
@@ -47,14 +47,14 @@
"metadata": {},
"outputs": [],
"source": [
"from openai import AsyncOpenAI\n",
"from llama_cloud_services.extract import (\n",
" LlamaExtract,\n",
" ExtractConfig,\n",
" ExtractMode,\n",
" LlamaExtract,\n",
" SourceText,\n",
")\n",
"from llama_cloud_services.parse import LlamaParse\n",
"from openai import AsyncOpenAI\n",
"\n",
"\n",
"async def get_parse_client(**kwargs):\n",
@@ -166,11 +166,11 @@
"outputs": [],
"source": [
"from workflows.events import (\n",
" Event,\n",
" HumanResponseEvent,\n",
" InputRequiredEvent,\n",
" StartEvent,\n",
" StopEvent,\n",
" Event,\n",
" InputRequiredEvent,\n",
" HumanResponseEvent,\n",
")\n",
"\n",
"\n",
@@ -244,11 +244,11 @@
"import json\n",
"import re\n",
"import uuid\n",
"from typing import Annotated\n",
"\n",
"from jsonschema import Draft202012Validator\n",
"from workflows import Context, Workflow, step\n",
"from workflows.resource import Resource\n",
"from typing import Annotated\n",
"\n",
"\n",
"class IterativeExtractionWorkflow(Workflow):\n",
+4 -4
View File
@@ -110,7 +110,7 @@
}
],
"source": [
"from workflows import Workflow, step, Context\n",
"from workflows import Context, Workflow, step\n",
"from workflows.events import StartEvent, StopEvent\n",
"\n",
"\n",
@@ -167,14 +167,14 @@
}
],
"source": [
"import sqlite3\n",
"import json\n",
"import sqlite3\n",
"from typing import Annotated\n",
"\n",
"from workflows import Workflow, step, Context\n",
"from workflows import Context, Workflow, step\n",
"from workflows.context import JsonSerializer\n",
"from workflows.events import StartEvent, StopEvent\n",
"from workflows.resource import Resource\n",
"from workflows.context import JsonSerializer\n",
"\n",
"\n",
"def get_db() -> sqlite3.Connection:\n",
+5 -4
View File
@@ -474,8 +474,8 @@
"source": [
"from workflows import Workflow, step\n",
"from workflows.events import (\n",
" InputRequiredEvent,\n",
" HumanResponseEvent,\n",
" InputRequiredEvent,\n",
" StartEvent,\n",
" StopEvent,\n",
")\n",
@@ -598,10 +598,11 @@
"metadata": {},
"outputs": [],
"source": [
"from typing import Annotated\n",
"\n",
"from workflows import Workflow, step\n",
"from workflows.events import StartEvent, StopEvent\n",
"from workflows.resource import Resource\n",
"from typing import Annotated\n",
"\n",
"\n",
"# Fake a database connection\n",
@@ -814,10 +815,10 @@
"metadata": {},
"outputs": [],
"source": [
"from llama_index.core.llms import ChatMessage\n",
"from llama_index.llms.openai import OpenAI\n",
"from typing import Annotated\n",
"\n",
"from llama_index.core.llms import ChatMessage\n",
"from llama_index.llms.openai import OpenAI\n",
"from workflows import Workflow, step\n",
"from workflows.events import StartEvent, StopEvent\n",
"from workflows.resource import Resource\n",
@@ -37,13 +37,12 @@
"source": [
"import logging\n",
"from typing import Any, MutableMapping\n",
"import structlog\n",
"\n",
"import structlog\n",
"from llama_index_instrumentation.dispatcher import (\n",
" active_instrument_tags,\n",
" instrument_tags,\n",
")\n",
"\n",
"from workflows import Context, Workflow, step\n",
"from workflows.events import StartEvent, StopEvent"
]
@@ -178,16 +178,15 @@
},
"outputs": [],
"source": [
"import os\n",
"from pathlib import Path\n",
"\n",
"import json\n",
"import os\n",
"from os import linesep\n",
"from pathlib import Path\n",
"from typing import Callable, Optional, Sequence\n",
"\n",
"from llama_index.observability.otel import LlamaIndexOpenTelemetry\n",
"from opentelemetry.sdk.trace.export import SpanExporter, SpanExportResult\n",
"from opentelemetry.sdk.trace import ReadableSpan\n",
"from typing import Optional, Callable, Sequence\n",
"from os import linesep\n",
"from opentelemetry.sdk.trace.export import SpanExporter, SpanExportResult\n",
"\n",
"\n",
"class FileSpanExporter(SpanExporter):\n",
@@ -424,7 +423,7 @@
},
"outputs": [],
"source": [
"from workflows.events import StartEvent, Event, StopEvent\n",
"from workflows.events import Event, StartEvent, StopEvent\n",
"\n",
"\n",
"class InputTextEvent(StartEvent):\n",
@@ -581,11 +580,12 @@
},
"outputs": [],
"source": [
"from workflows import Workflow, step, Context\n",
"from workflows.resource import Resource\n",
"from llama_index.core.llms import ChatMessage\n",
"from typing import Annotated\n",
"\n",
"from llama_index.core.llms import ChatMessage\n",
"from workflows import Context, Workflow, step\n",
"from workflows.resource import Resource\n",
"\n",
"\n",
"class TextAnalysisWorkflow(Workflow):\n",
" @step\n",
@@ -91,16 +91,15 @@
},
"outputs": [],
"source": [
"import os\n",
"from pathlib import Path\n",
"\n",
"import json\n",
"import os\n",
"from os import linesep\n",
"from pathlib import Path\n",
"from typing import Callable, Optional, Sequence\n",
"\n",
"from llama_index.observability.otel import LlamaIndexOpenTelemetry\n",
"from opentelemetry.sdk.trace.export import SpanExporter, SpanExportResult\n",
"from opentelemetry.sdk.trace import ReadableSpan\n",
"from typing import Optional, Callable, Sequence\n",
"from os import linesep\n",
"from opentelemetry.sdk.trace.export import SpanExporter, SpanExportResult\n",
"\n",
"\n",
"class FileSpanExporter(SpanExporter):\n",
@@ -187,14 +186,15 @@
},
"outputs": [],
"source": [
"from typing import Dict, List, Literal\n",
"\n",
"from workflows.events import (\n",
" HumanResponseEvent,\n",
" Event,\n",
" HumanResponseEvent,\n",
" InputRequiredEvent,\n",
" StartEvent,\n",
" StopEvent,\n",
" InputRequiredEvent,\n",
")\n",
"from typing import Literal, List, Dict\n",
"\n",
"\n",
"class EmailEvent(StartEvent):\n",
@@ -443,15 +443,14 @@
"outputs": [],
"source": [
"from llama_cloud import (\n",
" PipelineCreateEmbeddingConfig_OpenaiEmbedding,\n",
" PipelineTransformConfig_Advanced,\n",
" AdvancedModeTransformConfigChunkingConfig_Sentence,\n",
" AdvancedModeTransformConfigSegmentationConfig_Page,\n",
" PipelineCreateEmbeddingConfig_OpenaiEmbedding,\n",
" PipelineTransformConfig_Advanced,\n",
")\n",
"from llama_index.embeddings.openai import OpenAIEmbedding\n",
"from llama_index.indices.managed.llama_cloud import LlamaCloudIndex\n",
"\n",
"\n",
"embed_model = OpenAIEmbedding(\n",
" model=\"text-embedding-3-small\", api_key=os.getenv(\"OPENAI_API_KEY\")\n",
")\n",
@@ -524,12 +523,12 @@
},
"outputs": [],
"source": [
"from llama_cloud_services.extract.extract import ExtractionAgent\n",
"from llama_index.core.llms import LLM\n",
"from llama_index.core.llms.structured_llm import StructuredLLM\n",
"from llama_index.core.query_engine import BaseQueryEngine\n",
"from llama_index.indices.managed.llama_cloud import LlamaCloudIndex\n",
"from llama_index.llms.openai import OpenAIResponses\n",
"from llama_index.core.query_engine import BaseQueryEngine\n",
"from llama_cloud_services.extract.extract import ExtractionAgent\n",
"from llama_index.core.llms.structured_llm import StructuredLLM\n",
"from llama_index.core.llms import LLM\n",
"from pydantic import BaseModel, Field\n",
"\n",
"llm = OpenAIResponses(model=\"gpt-4.1\")\n",
@@ -605,13 +604,13 @@
"outputs": [],
"source": [
"import uuid\n",
"\n",
"from llama_index.core.llms import ChatMessage\n",
"from workflows import Workflow, Context, step\n",
"from workflows.resource import Resource\n",
"from llama_cloud_services.extract import SourceText\n",
"from typing import Annotated, Union\n",
"\n",
"from llama_cloud_services.extract import SourceText\n",
"from llama_index.core.llms import ChatMessage\n",
"from workflows import Context, Workflow, step\n",
"from workflows.resource import Resource\n",
"\n",
"\n",
"class EmailSupportWorkflow(Workflow):\n",
" # remember to use the step decorator!\n",
@@ -1372,8 +1371,8 @@
},
"outputs": [],
"source": [
"from llama_index_instrumentation.base import BaseEvent\n",
"from llama_index_instrumentation import get_dispatcher\n",
"from llama_index_instrumentation.base import BaseEvent\n",
"\n",
"dispatcher = get_dispatcher()\n",
"\n",
@@ -1412,11 +1411,11 @@
"source": [
"import json\n",
"import time\n",
"\n",
"from workflows import Workflow, Context, step\n",
"from workflows.resource import Resource\n",
"from typing import Annotated, Union\n",
"\n",
"from workflows import Context, Workflow, step\n",
"from workflows.resource import Resource\n",
"\n",
"\n",
"class EmailSupportWorkflow(Workflow):\n",
" # remember to use the step decorator!\n",
@@ -91,10 +91,10 @@
"metadata": {},
"outputs": [],
"source": [
"from llama_index.core.llms import ChatMessage\n",
"from llama_index.llms.openai import OpenAI\n",
"from typing import Annotated\n",
"\n",
"from llama_index.core.llms import ChatMessage\n",
"from llama_index.llms.openai import OpenAI\n",
"from workflows import Workflow, step\n",
"from workflows.events import StartEvent, StopEvent\n",
"from workflows.resource import Resource\n",
@@ -208,9 +208,9 @@
}
],
"source": [
"from llama_index.llms.openai import OpenAI\n",
"from typing import Annotated\n",
"\n",
"from llama_index.llms.openai import OpenAI\n",
"from workflows import Workflow, step\n",
"from workflows.events import StartEvent, StopEvent\n",
"from workflows.resource import Resource\n",
@@ -114,10 +114,10 @@
"metadata": {},
"outputs": [],
"source": [
"from llama_index.core.llms import ChatMessage\n",
"from llama_index.llms.openai import OpenAI\n",
"from typing import Annotated\n",
"\n",
"from llama_index.core.llms import ChatMessage\n",
"from llama_index.llms.openai import OpenAI\n",
"from workflows import Workflow, step\n",
"from workflows.events import StartEvent, StopEvent\n",
"from workflows.resource import Resource\n",
@@ -233,9 +233,9 @@
}
],
"source": [
"from llama_index.llms.openai import OpenAI\n",
"from typing import Annotated\n",
"\n",
"from llama_index.llms.openai import OpenAI\n",
"from workflows import Workflow, step\n",
"from workflows.events import StartEvent, StopEvent\n",
"from workflows.resource import Resource\n",
+2 -2
View File
@@ -4,10 +4,10 @@ from workflows import Workflow, step
from workflows.context import Context
from workflows.events import (
Event,
HumanResponseEvent,
InputRequiredEvent,
StartEvent,
StopEvent,
InputRequiredEvent,
HumanResponseEvent,
)
from workflows.server import WorkflowServer
@@ -65,10 +65,10 @@
"outputs": [],
"source": [
"import json\n",
"from typing import Any, Dict, List\n",
"\n",
"from qdrant_client import AsyncQdrantClient, models\n",
"from sentence_transformers import SentenceTransformer\n",
"from typing import List, Dict, Any\n",
"\n",
"\n",
"class QdrantVectorDatabase:\n",
@@ -192,8 +192,9 @@
"outputs": [],
"source": [
"from dataclasses import dataclass\n",
"from openai import AsyncOpenAI\n",
"from typing import Optional\n",
"\n",
"from openai import AsyncOpenAI\n",
"from pydantic import BaseModel, Field\n",
"\n",
"\n",
@@ -351,7 +352,7 @@
},
"outputs": [],
"source": [
"from workflows.events import StartEvent, Event, StopEvent\n",
"from workflows.events import Event, StartEvent, StopEvent\n",
"\n",
"\n",
"class ResearchQuestionEvent(StartEvent):\n",
@@ -378,10 +379,11 @@
},
"outputs": [],
"source": [
"from workflows import Workflow, step, Context\n",
"from workflows.resource import Resource\n",
"from typing import Annotated, Union\n",
"import uuid\n",
"from typing import Annotated, Union\n",
"\n",
"from workflows import Context, Workflow, step\n",
"from workflows.resource import Resource\n",
"\n",
"\n",
"class WorkflowState(BaseModel):\n",
+3 -2
View File
@@ -191,10 +191,11 @@
"metadata": {},
"outputs": [],
"source": [
"from workflows import Workflow, Context, step\n",
"from workflows.resource import Resource\n",
"from typing import Annotated\n",
"\n",
"from workflows import Context, Workflow, step\n",
"from workflows.resource import Resource\n",
"\n",
"\n",
"class SummaryWorkflow(Workflow):\n",
" @step\n",
@@ -2,31 +2,30 @@
# Copyright (c) 2025 LlamaIndex Inc.
from __future__ import annotations
from dataclasses import dataclass
from typing import List, Optional, Dict, Tuple, Union, cast, Any
from workflows.events import (
StartEvent,
StopEvent,
InputRequiredEvent,
HumanResponseEvent,
Event,
)
from workflows.decorators import StepConfig
from workflows.handler import WorkflowHandler
from workflows import Workflow
from dataclasses import dataclass
from typing import Any, Dict, List, Tuple, Union, cast
from llama_index.core.agent.workflow import (
AgentWorkflow,
ReActAgent,
CodeActAgent,
BaseWorkflowAgent,
CodeActAgent,
ReActAgent,
)
from llama_index.core.tools import BaseTool, AsyncBaseTool
from llama_index.core.tools import AsyncBaseTool, BaseTool
from pyvis.network import Network
from workflows.runtime.types.ticks import TickStepResult, TickAddEvent, WorkflowTick
from workflows.runtime.types.results import StepWorkerResult, AddCollectedEvent
from workflows import Workflow
from workflows.decorators import StepConfig
from workflows.events import (
Event,
HumanResponseEvent,
InputRequiredEvent,
StartEvent,
StopEvent,
)
from workflows.handler import WorkflowHandler
from workflows.runtime.types.results import AddCollectedEvent, StepWorkerResult
from workflows.runtime.types.ticks import TickAddEvent, TickStepResult, WorkflowTick
@dataclass
@@ -36,10 +35,8 @@ class DrawWorkflowNode:
id: str
label: str
node_type: str # 'step', 'event', 'external'
title: Optional[str] = None
event_type: Optional[type] = (
None # Store the actual event type for styling decisions
)
title: str | None = None
event_type: type | None = None # Store the actual event type for styling decisions
@dataclass
@@ -64,7 +61,7 @@ def _truncate_label(label: str, max_length: int) -> str:
def _extract_workflow_structure(
workflow: Workflow, max_label_length: Optional[int] = None
workflow: Workflow, max_label_length: int | None = None
) -> DrawWorkflowGraph:
"""Extract workflow structure into an intermediate representation."""
# Get workflow steps
@@ -73,7 +70,7 @@ def _extract_workflow_structure(
edges = []
added_nodes = set() # Track added node IDs to avoid duplicates
step_config: Optional[StepConfig] = None
step_config: StepConfig | None = None
# Only one kind of `StopEvent` is allowed in a `Workflow`.
# Assuming that `Workflow` is validated before drawing, it's enough to find the first one.
@@ -587,7 +584,7 @@ def draw_all_possible_flows(
workflow: Workflow,
filename: str = "workflow_all_flows.html",
notebook: bool = False,
max_label_length: Optional[int] = None,
max_label_length: int | None = None,
) -> None:
"""
Draws all possible flows of the workflow using Pyvis.
@@ -607,7 +604,7 @@ def draw_most_recent_execution(
handler: WorkflowHandler,
filename: str = "workflow_recent_execution.html",
notebook: bool = False,
max_label_length: Optional[int] = None,
max_label_length: int | None = None,
) -> None:
"""
Draws the most recent execution of the workflow.
@@ -626,7 +623,7 @@ def draw_most_recent_execution(
ticks: List[WorkflowTick] = handler.ctx._broker_run._tick_log
# Build execution DAG from ticks
nodes: Dict[str, Tuple[str, str, Optional[type]]] = {}
nodes: Dict[str, Tuple[str, str, type | None]] = {}
edges: List[Tuple[str, str]] = []
event_node_by_identity: Dict[int, str] = {}
step_seq: Dict[str, int] = {}
@@ -718,7 +715,7 @@ def draw_most_recent_execution(
def draw_all_possible_flows_mermaid(
workflow: Workflow,
filename: str = "workflow_all_flows.mermaid",
max_label_length: Optional[int] = None,
max_label_length: int | None = None,
) -> str:
"""
Draws all possible flows of the workflow as a Mermaid diagram.
@@ -1,9 +1,8 @@
import pytest
from workflows.workflow import Workflow
from workflows.decorators import step
from workflows.events import StartEvent, StopEvent, Event
from pydantic import Field
from workflows.decorators import step
from workflows.events import Event, StartEvent, StopEvent
from workflows.workflow import Workflow
class OneTestEvent(Event):
@@ -1,13 +1,12 @@
from unittest.mock import patch, MagicMock, mock_open
from unittest.mock import MagicMock, mock_open, patch
import pytest
from workflows.workflow import Workflow
from llama_index.utils.workflow import (
draw_all_possible_flows,
draw_all_possible_flows_mermaid,
draw_most_recent_execution,
)
from workflows.workflow import Workflow
@pytest.mark.asyncio
@@ -3,26 +3,26 @@
from __future__ import annotations
import httpx
import json
from contextlib import asynccontextmanager
from typing import (
Any,
AsyncGenerator,
AsyncIterator,
overload,
)
from contextlib import asynccontextmanager
from workflows.events import StartEvent, Event
import httpx
from workflows import Context
from workflows.events import Event, StartEvent
from workflows.protocol import (
CancelHandlerResponse,
HandlerData,
HandlersListResponse,
HealthResponse,
SendEventResponse,
Status,
WorkflowsListResponse,
CancelHandlerResponse,
)
from workflows.protocol.serializable_events import (
EventEnvelope,
@@ -242,14 +242,8 @@ class WorkflowClient:
async for line in response.aiter_lines():
if line.strip(): # Skip empty lines
try:
event = EventEnvelopeWithMetadata.model_validate_json(
line
)
yield event
except json.JSONDecodeError as e:
print(f"Failed to parse JSON: {e}, data: {line}")
continue
event = EventEnvelopeWithMetadata.model_validate_json(line)
yield event
except httpx.TimeoutException:
raise TimeoutError(
@@ -30,17 +30,16 @@ from workflows.events import (
StartEvent,
StopEvent,
)
from workflows.runtime.types.internal_state import BrokerState
from workflows.runtime.broker import WorkflowBroker
from workflows.handler import WorkflowHandler
from workflows.plugins.basic import basic_runtime
from workflows.runtime.broker import WorkflowBroker
from workflows.runtime.types.internal_state import BrokerState
from workflows.runtime.types.plugin import Plugin, WorkflowRuntime
from workflows.types import RunResultT
from workflows.handler import WorkflowHandler
from .serializers import BaseSerializer, JsonSerializer
from .state_store import MODEL_T, DictState, InMemoryStateStore
if TYPE_CHECKING: # pragma: no cover
from workflows import Workflow
@@ -1,5 +1,6 @@
from typing import Any, Optional
import json
from typing import Any, Optional
from pydantic import BaseModel, Field
from pydantic.functional_validators import model_validator
@@ -3,6 +3,7 @@
from __future__ import annotations
import sys
from typing import (
TYPE_CHECKING,
Any,
@@ -15,8 +16,6 @@ from typing import (
overload,
)
import sys
if sys.version_info >= (3, 10):
from typing import ParamSpec
else:
@@ -4,7 +4,8 @@
from __future__ import annotations
from _collections_abc import dict_items, dict_keys, dict_values
from typing import Any, Type, Optional
from enum import Enum
from typing import Any, Type
from pydantic import (
BaseModel,
@@ -13,7 +14,6 @@ from pydantic import (
PrivateAttr,
model_serializer,
)
from enum import Enum
class DictLikeModel(BaseModel):
@@ -305,7 +305,7 @@ class StepStateChanged(InternalDispatchEvent):
)
worker_id: str = Field(description="ID of the worker that the step is running on")
input_event_name: str = Field(description="Name of the input event")
output_event_name: Optional[str] = Field(
output_event_name: str | None = Field(
description="Name of the output event", default=None
)
@@ -4,14 +4,12 @@
from __future__ import annotations
import asyncio
from typing import Any, AsyncGenerator, TYPE_CHECKING
from typing import TYPE_CHECKING, Any, AsyncGenerator
from .errors import WorkflowRuntimeError
from .events import Event, StopEvent, InternalDispatchEvent
from .events import Event, InternalDispatchEvent, StopEvent
from .types import RunResultT
if TYPE_CHECKING:
from .context import Context
@@ -7,11 +7,11 @@ import asyncio
import time
from typing import AsyncGenerator, Callable
from workflows.decorators import P, R
from workflows.events import Event, StopEvent
from workflows.runtime.types.plugin import Plugin, SnapshottableRuntime, WorkflowRuntime
from workflows.runtime.types.step_function import StepWorkerFunction
from workflows.runtime.types.ticks import WorkflowTick
from workflows.decorators import P, R
from workflows.workflow import Workflow
@@ -1,6 +1,7 @@
from __future__ import annotations
from typing import Any, Literal
from pydantic import BaseModel
from workflows.protocol.serializable_events import EventEnvelopeWithMetadata
@@ -7,6 +7,7 @@ import json
from typing import Any, Type
from pydantic import BaseModel, ValidationError, model_validator
from workflows.context.utils import import_module_from_qualified_name
from workflows.events import Event
@@ -23,7 +23,6 @@ from llama_index_instrumentation.dispatcher import (
active_instrument_tags,
instrument_tags,
)
from workflows.errors import WorkflowRuntimeError
from workflows.events import (
Event,
@@ -4,11 +4,11 @@
from __future__ import annotations
import asyncio
from dataclasses import replace
import logging
import time
from dataclasses import replace
from typing import TYPE_CHECKING
from workflows.decorators import R
from workflows.errors import (
WorkflowCancelledByUser,
@@ -34,9 +34,9 @@ from workflows.runtime.types.commands import (
indicates_exit,
)
from workflows.runtime.types.internal_state import (
BrokerState,
EventAttempt,
InProgressState,
BrokerState,
InternalStepWorkerState,
)
from workflows.runtime.types.plugin import (
@@ -64,10 +64,8 @@ from workflows.runtime.types.ticks import (
TickTimeout,
WorkflowTick,
)
import logging
from workflows.workflow import Workflow
from workflows.runtime.workflow_registry import workflow_registry
from workflows.workflow import Workflow
if TYPE_CHECKING:
from workflows.context.context import Context
@@ -1,7 +1,7 @@
from __future__ import annotations
from typing import Callable, Generic, TypeVar, overload
import weakref
from typing import Callable, Generic, TypeVar, overload
K = TypeVar("K")
V = TypeVar("V")
@@ -3,29 +3,28 @@
from __future__ import annotations
from dataclasses import dataclass
import dataclasses
from typing import Any, TYPE_CHECKING
import importlib
from dataclasses import dataclass
from typing import TYPE_CHECKING, Any
from workflows.context.context_types import (
SerializedContext,
SerializedEventAttempt,
SerializedStepWorkerState,
SerializedWaiter,
)
from workflows.context.serializers import JsonSerializer
from workflows.decorators import StepConfig
from workflows.events import Event
from workflows.retry_policy import RetryPolicy
from workflows.decorators import StepConfig
from workflows.runtime.types.results import StepWorkerState, StepWorkerWaiter
from workflows.runtime.types.ticks import TickAddEvent, WorkflowTick
from workflows.workflow import Workflow
from workflows.context.context_types import (
SerializedContext,
SerializedStepWorkerState,
SerializedEventAttempt,
SerializedWaiter,
)
from workflows.context.serializers import JsonSerializer
import importlib
if TYPE_CHECKING:
from workflows.context.serializers import BaseSerializer
from workflows.context.context_types import SerializedContext
from workflows.context.serializers import BaseSerializer
@dataclass()
@@ -8,16 +8,14 @@ from __future__ import annotations
from dataclasses import dataclass
from typing import (
TYPE_CHECKING,
AsyncGenerator,
Coroutine,
Protocol,
TYPE_CHECKING,
cast,
)
from workflows.events import Event, StopEvent
from workflows.runtime.types.internal_state import BrokerState
from workflows.runtime.types.step_function import StepWorkerFunction
from workflows.runtime.types.ticks import WorkflowTick
@@ -3,9 +3,9 @@
from __future__ import annotations
import dataclasses
from contextvars import ContextVar
from dataclasses import dataclass
import dataclasses
from typing import (
TYPE_CHECKING,
Any,
@@ -14,8 +14,8 @@ from typing import (
Union,
)
from workflows.events import Event
from workflows.decorators import R
from workflows.events import Event
if TYPE_CHECKING:
pass
@@ -4,11 +4,10 @@
from __future__ import annotations
import asyncio
from contextvars import copy_context
import functools
import time
from typing import Any, Awaitable, Callable, TYPE_CHECKING, Generic, Protocol
from contextvars import copy_context
from typing import TYPE_CHECKING, Any, Awaitable, Callable, Generic, Protocol
from workflows.decorators import P, R, StepConfig
from workflows.errors import WorkflowRuntimeError
@@ -25,7 +24,6 @@ from workflows.runtime.types.results import (
StepWorkerStateContextVar,
WaitingForEvent,
)
from workflows.workflow import Workflow
if TYPE_CHECKING:
@@ -19,8 +19,8 @@ from __future__ import annotations
from dataclasses import dataclass
from typing import Generic, Union
from workflows.events import Event
from workflows.decorators import R
from workflows.events import Event
from workflows.runtime.types.results import StepFunctionResult
@@ -1,6 +1,7 @@
from threading import Lock
from dataclasses import dataclass
from typing import Optional
from threading import Lock
from typing import TYPE_CHECKING, Optional
from workflows.runtime.types._identity_weak_ref import IdentityWeakKeyDict
from workflows.runtime.types.plugin import (
ControlLoopFunction,
@@ -8,9 +9,8 @@ from workflows.runtime.types.plugin import (
RegisteredWorkflow,
WorkflowRuntime,
)
from workflows.workflow import Workflow
from workflows.runtime.types.step_function import StepWorkerFunction
from typing import TYPE_CHECKING
from workflows.workflow import Workflow
if TYPE_CHECKING:
from workflows.context.context import Context
@@ -1,12 +1,12 @@
# SPDX-License-Identifier: MIT
# Copyright (c) 2025 LlamaIndex Inc.
from .server import WorkflowServer
from .abstract_workflow_store import (
AbstractWorkflowStore,
HandlerQuery,
PersistentHandler,
)
from .server import WorkflowServer
from .sqlite.sqlite_workflow_store import SqliteWorkflowStore
__all__ = [
@@ -1,8 +1,10 @@
from __future__ import annotations
from abc import abstractmethod, ABC
from datetime import datetime
from typing import Literal, Optional, List, Any
from abc import ABC, abstractmethod
from dataclasses import dataclass
from datetime import datetime
from typing import Any, List, Literal
from pydantic import (
BaseModel,
field_serializer,
@@ -12,18 +14,17 @@ from pydantic import (
from workflows.context import JsonSerializer
from workflows.events import StopEvent
Status = Literal["running", "completed", "failed", "cancelled"]
@dataclass()
class HandlerQuery:
# Matches if any of the handler_ids match
handler_id_in: Optional[List[str]] = None
handler_id_in: List[str] | None = None
# Matches if any of the workflow_names match
workflow_name_in: Optional[List[str]] = None
workflow_name_in: List[str] | None = None
# Matches if the status flag matches
status_in: Optional[List[Status]] = None
status_in: List[Status] | None = None
class PersistentHandler(BaseModel):
@@ -1,4 +1,5 @@
from typing import Dict, List
from workflows.server.abstract_workflow_store import (
AbstractWorkflowStore,
HandlerQuery,
@@ -1,12 +1,13 @@
from dataclasses import dataclass
from typing import List, Optional
from workflows.events import (
StopEvent,
InputRequiredEvent,
HumanResponseEvent,
)
from workflows import Workflow
from workflows.decorators import StepConfig, StepFunction
from workflows.events import (
HumanResponseEvent,
InputRequiredEvent,
StopEvent,
)
from workflows.protocol import (
WorkflowGraphEdge,
WorkflowGraphNode,
@@ -16,7 +17,6 @@ from workflows.utils import (
get_steps_from_class,
get_steps_from_instance,
)
from workflows import Workflow
@dataclass
@@ -3,17 +3,17 @@
from __future__ import annotations
import asyncio
from contextlib import asynccontextmanager
from dataclasses import dataclass
import json
import logging
from contextlib import asynccontextmanager
from dataclasses import dataclass
from datetime import datetime, timezone
from importlib.metadata import version
from pathlib import Path
from typing import Any, AsyncGenerator, Callable, Awaitable, cast
from datetime import datetime, timezone
from typing import Any, AsyncGenerator, Awaitable, Callable, cast
from llama_index_instrumentation.dispatcher import instrument_tags
import uvicorn
from llama_index_instrumentation.dispatcher import instrument_tags
from starlette.applications import Starlette
from starlette.exceptions import HTTPException
from starlette.middleware import Middleware
@@ -34,8 +34,6 @@ from workflows.events import (
StopEvent,
)
from workflows.handler import WorkflowHandler
from workflows.protocol import (
CancelHandlerResponse,
HandlerData,
@@ -47,6 +45,11 @@ from workflows.protocol import (
WorkflowSchemaResponse,
is_status_completed,
)
from workflows.protocol.serializable_events import (
EventEnvelope,
EventEnvelopeWithMetadata,
EventValidationError,
)
from workflows.server.abstract_workflow_store import (
AbstractWorkflowStore,
HandlerQuery,
@@ -58,12 +61,8 @@ from workflows.types import RunResultT
# Protocol models are used on the client side; server responds with plain dicts
from workflows.utils import _nanoid as nanoid
from .representation_utils import _extract_workflow_structure
from workflows.protocol.serializable_events import (
EventValidationError,
EventEnvelopeWithMetadata,
EventEnvelope,
)
logger = logging.getLogger()
@@ -1677,4 +1676,4 @@ if __name__ == "__main__":
dict_schema = server.openapi_schema()
with open(args.output, "w") as f:
json.dump(dict_schema, indent=2, fp=f)
print(f"OpenAPI schema written to {args.output}")
print(f"OpenAPI schema written to {args.output}") # noqa: T201
@@ -9,7 +9,6 @@ import re
import sqlite3
from importlib import import_module, resources
logger = logging.getLogger(__name__)
@@ -1,3 +1,8 @@
import json
import sqlite3
from datetime import datetime
from typing import List, Optional, Sequence, Tuple
from workflows.context import JsonSerializer
from workflows.server.abstract_workflow_store import (
AbstractWorkflowStore,
@@ -5,10 +10,6 @@ from workflows.server.abstract_workflow_store import (
PersistentHandler,
)
from workflows.server.sqlite.migrate import run_migrations
from typing import List, Optional, Sequence, Tuple
import sqlite3
import json
from datetime import datetime
class SqliteWorkflowStore(AbstractWorkflowStore):
@@ -1,9 +1,9 @@
from typing import Any, Optional
from collections import Counter
from dataclasses import dataclass
from typing import Any, Optional
from workflows import Workflow, Context
from workflows.events import StartEvent, Event, EventType
from workflows import Context, Workflow
from workflows.events import Event, EventType, StartEvent
@dataclass
@@ -3,9 +3,9 @@
from __future__ import annotations
import inspect
import secrets
import string
import inspect
from typing import (
TYPE_CHECKING,
Annotated,
@@ -6,6 +6,7 @@ from __future__ import annotations
import asyncio
import logging
from typing import (
TYPE_CHECKING,
Any,
Tuple,
)
@@ -13,8 +14,6 @@ from typing import (
from llama_index_instrumentation import get_dispatcher
from pydantic import ValidationError
from typing import TYPE_CHECKING
if TYPE_CHECKING: # pragma: no cover
from .context import Context
from .decorators import StepConfig, StepFunction
@@ -1,7 +1,7 @@
import random
from workflows import Workflow, step, Context
from workflows.events import StartEvent, Event, StopEvent
from workflows import Context, Workflow, step
from workflows.events import Event, StartEvent, StopEvent
class InputEvent(StartEvent):
@@ -1,18 +1,18 @@
import pytest
import httpx
import pytest
from httpx import ASGITransport, AsyncClient
from workflows.protocol.serializable_events import EventEnvelopeWithMetadata
from workflows.server.server import WorkflowServer
from workflows.client import WorkflowClient
from workflows.protocol.serializable_events import EventEnvelopeWithMetadata
from workflows.server.memory_workflow_store import MemoryWorkflowStore
from workflows.server.server import WorkflowServer
from .client_workflows import ( # type: ignore[import]
greeting_wf,
crashing_wf,
GreetEvent,
InputEvent,
OutputEvent,
GreetEvent,
crashing_wf,
greeting_wf,
)
from workflows.server.memory_workflow_store import MemoryWorkflowStore
@pytest.fixture()
@@ -2,9 +2,9 @@
# Copyright (c) 2025 LlamaIndex Inc.
from typing import AsyncGenerator
import pytest
from pydantic import Field
from workflows.context import Context
from workflows.decorators import step
from workflows.events import Event, StartEvent, StopEvent
@@ -4,19 +4,10 @@
from __future__ import annotations
import asyncio
from workflows.runtime.types.ticks import TickAddEvent
try:
from typing import Union
except ImportError:
from typing_extensions import Union
from typing import Optional
from typing import Optional, Union
import pytest
from pydantic import BaseModel
from workflows.context import Context
from workflows.context.state_store import DictState
from workflows.decorators import step
@@ -28,6 +19,7 @@ from workflows.events import (
StartEvent,
StopEvent,
)
from workflows.runtime.types.ticks import TickAddEvent
from workflows.testing import WorkflowTestRunner
from workflows.workflow import Workflow
@@ -4,7 +4,6 @@
from __future__ import annotations
import pytest
from workflows.context import Context
from workflows.errors import ContextSerdeError
from workflows.workflow import Workflow
@@ -1,5 +1,4 @@
import pytest
from workflows.context.utils import (
get_qualified_name,
import_module_from_qualified_name,
@@ -1,19 +1,20 @@
# SPDX-License-Identifier: MIT
# Copyright (c) 2025 LlamaIndex Inc.
import json
import pytest
from workflows.events import (
Event,
StopEvent,
StepStateChanged,
StepState,
StepStateChanged,
StopEvent,
)
from workflows.protocol.serializable_events import (
EventEnvelope,
EventEnvelopeWithMetadata,
EventValidationError,
)
import json
def test_envelope_user_defined_event() -> None:
@@ -8,7 +8,6 @@ import time
from typing import Any, AsyncGenerator
import pytest
from workflows.events import Event, StopEvent
from workflows.runtime.types.plugin import ControlLoopFunction, Plugin, WorkflowRuntime
from workflows.runtime.types.step_function import StepWorkerFunction
@@ -16,25 +16,24 @@ import uuid
from typing import Coroutine, Optional, Union
import pytest
from workflows.context import Context
from workflows.decorators import step
from workflows.errors import WorkflowCancelledByUser, WorkflowTimeoutError
from workflows.events import (
Event,
HumanResponseEvent,
InputRequiredEvent,
StartEvent,
StopEvent,
StepStateChanged,
StopEvent,
)
from workflows.errors import WorkflowCancelledByUser, WorkflowTimeoutError
from workflows.retry_policy import ConstantDelayRetryPolicy
from workflows.runtime.control_loop import control_loop
from workflows.runtime.types.internal_state import BrokerState
from workflows.runtime.types.step_function import as_step_worker_function
from workflows.workflow import Workflow
from workflows.context import Context
from workflows.runtime.control_loop import control_loop
from workflows.runtime.workflow_registry import workflow_registry
from workflows.runtime.types.ticks import TickAddEvent, TickCancelRun
from workflows.retry_policy import ConstantDelayRetryPolicy
from workflows.runtime.workflow_registry import workflow_registry
from workflows.workflow import Workflow
from .conftest import MockRuntimePlugin # type: ignore[import]
@@ -9,10 +9,12 @@ testing them in isolation without running the full async control loop.
"""
from __future__ import annotations
from typing import Any, Union
from typing import Any
import pytest
from workflows.decorators import StepConfig
from workflows.errors import WorkflowTimeoutError
from workflows.events import (
Event,
InputRequiredEvent,
@@ -21,7 +23,6 @@ from workflows.events import (
StepStateChanged,
StopEvent,
)
from workflows.errors import WorkflowTimeoutError
from workflows.retry_policy import ConstantDelayRetryPolicy
from workflows.runtime.control_loop import (
_add_or_enqueue_event,
@@ -65,7 +66,6 @@ from workflows.runtime.types.ticks import (
TickStepResult,
TickTimeout,
)
from workflows.decorators import StepConfig
class MyTestEvent(Event):
@@ -142,7 +142,7 @@ def add_worker(state: BrokerState, event: Event, worker_id: int = 0) -> None:
],
)
def test_step_worker_results(
base_state: BrokerState, result: Union[Event, None], expected_commands: list
base_state: BrokerState, result: Event | None, expected_commands: list
) -> None:
"""Test different step worker result types."""
event = MyTestEvent(value=42)
@@ -4,7 +4,6 @@ import gc
import weakref
import pytest
from workflows.runtime.types._identity_weak_ref import IdentityWeakKeyDict
@@ -1,4 +1,5 @@
from json import JSONDecodeError
import pytest
from workflows.context.context_types import SerializedContext, SerializedContextV0
from workflows.workflow import Workflow
@@ -5,7 +5,6 @@
import asyncio
import pytest
from workflows import Context, Workflow, step
from workflows.events import (
Event,
@@ -5,15 +5,14 @@ from __future__ import annotations
import asyncio
import json
from datetime import datetime, timezone
from unittest.mock import MagicMock
import pytest
from unittest.mock import MagicMock
from workflows.context import Context
from workflows.server.memory_workflow_store import MemoryWorkflowStore
from workflows.events import StopEvent, Event
from workflows.events import Event, StopEvent
from workflows.handler import WorkflowHandler
from workflows.protocol import HandlerData
from workflows.server.memory_workflow_store import MemoryWorkflowStore
from workflows.server.server import _WorkflowHandler
@@ -7,7 +7,6 @@ from typing import Any
from unittest.mock import patch
import pytest
from workflows.server.__main__ import run_server
@@ -1,6 +1,6 @@
import pytest
from datetime import datetime, timezone
import pytest
from workflows.events import StopEvent
from workflows.server.abstract_workflow_store import HandlerQuery, PersistentHandler
from workflows.server.memory_workflow_store import MemoryWorkflowStore
@@ -1,7 +1,7 @@
from __future__ import annotations
from pathlib import Path
import sqlite3
from pathlib import Path
from typing import List
from workflows.server.sqlite.migrate import run_migrations
@@ -2,7 +2,6 @@
# Copyright (c) 2025 LlamaIndex Inc.
from workflows import Workflow
from workflows.server import WorkflowServer
@@ -2,9 +2,8 @@ from __future__ import annotations
from typing import Any, cast
from workflows.server.abstract_workflow_store import PersistentHandler
from workflows.events import StopEvent
from workflows.server.abstract_workflow_store import PersistentHandler
def _base_handler_kwargs() -> dict[str, Any]:
@@ -6,7 +6,6 @@ from unittest.mock import AsyncMock, Mock, patch
import pytest
from starlette.middleware import Middleware
from workflows.server import WorkflowServer
from workflows.workflow import Workflow
@@ -2,31 +2,31 @@
# Copyright (c) 2025 LlamaIndex Inc.
from __future__ import annotations
import asyncio
from collections import Counter
import json
from collections import Counter
from contextlib import asynccontextmanager
from datetime import datetime
from types import SimpleNamespace
from typing import Any, AsyncGenerator, AsyncIterator, Optional
from typing import Any, AsyncGenerator, AsyncIterator
import pytest
import pytest_asyncio
from httpx import ASGITransport, AsyncClient, Response
from workflows.events import StopEvent, StartEvent
from .util import wait_for_passing # type: ignore[import]
from llama_index_instrumentation.dispatcher import active_instrument_tags
from workflows import Context, step
from workflows.server import WorkflowServer
from workflows.server.abstract_workflow_store import HandlerQuery, PersistentHandler
from workflows.workflow import Workflow
from datetime import datetime
# Prepare the event to send
from workflows.context.serializers import JsonSerializer
from .conftest import ExternalEvent # type: ignore[import]
from workflows.events import StartEvent, StopEvent
from workflows.server import WorkflowServer
from workflows.server.abstract_workflow_store import HandlerQuery, PersistentHandler
from workflows.server.memory_workflow_store import MemoryWorkflowStore
from llama_index_instrumentation.dispatcher import active_instrument_tags
from workflows.workflow import Workflow
from .conftest import ExternalEvent # type: ignore[import]
from .util import wait_for_passing # type: ignore[import]
class CustomStopEvent(StopEvent):
@@ -70,7 +70,7 @@ async def client(
async def server_with_persisted_handlers(
interactive_workflow: Workflow,
*,
persisted_handlers: Optional[list[PersistentHandler]] = None,
persisted_handlers: list[PersistentHandler] | None = None,
) -> AsyncIterator[tuple[WorkflowServer, AsyncClient, MemoryWorkflowStore]]:
store = MemoryWorkflowStore()
if persisted_handlers is not None:
@@ -12,11 +12,11 @@ from typing import AsyncGenerator
import httpx
import pytest
import uvicorn
from workflows import Workflow
from workflows.client.client import WorkflowClient
from workflows.events import StopEvent
from workflows.server import WorkflowServer
from workflows.client.client import WorkflowClient
from .conftest import ( # type: ignore[import]
ExternalEvent,
RequestedExternalEvent,
@@ -1,22 +1,21 @@
# SPDX-License-Identifier: MIT
# Copyright (c) 2025 LlamaIndex Inc.
import asyncio
import pytest
from typing import AsyncGenerator
from httpx import AsyncClient, ASGITransport
import pytest
from httpx import ASGITransport, AsyncClient
from workflows import Context
from workflows.events import Event, InternalDispatchEvent, StopEvent
from workflows.server import WorkflowServer
from workflows.server.abstract_workflow_store import HandlerQuery, PersistentHandler
from workflows.server.memory_workflow_store import MemoryWorkflowStore
from workflows.workflow import Workflow
from .conftest import ( # type: ignore[import]
ExternalEvent,
RequestedExternalEvent,
)
from workflows.events import Event, InternalDispatchEvent, StopEvent
from workflows.server import WorkflowServer
from workflows import Context
from workflows.workflow import Workflow
from workflows.server.abstract_workflow_store import HandlerQuery, PersistentHandler
from workflows.server.memory_workflow_store import MemoryWorkflowStore
from .util import wait_for_passing # type: ignore[import]
@@ -1,10 +1,9 @@
from pathlib import Path
import pytest
from workflows.events import StopEvent
from workflows.server.abstract_workflow_store import HandlerQuery, PersistentHandler
from workflows.server.sqlite.sqlite_workflow_store import SqliteWorkflowStore
from workflows.events import StopEvent
@pytest.mark.asyncio
@@ -1,7 +1,6 @@
import asyncio
import time
from typing import Callable, Awaitable, TypeVar
from typing import Awaitable, Callable, TypeVar
T = TypeVar("T")
@@ -4,7 +4,6 @@
import re
import pytest
from workflows.decorators import step
from workflows.errors import WorkflowValidationError
from workflows.events import Event, StartEvent, StopEvent
@@ -5,7 +5,6 @@ from typing import Any, cast
import pytest
from pydantic import PrivateAttr
from workflows.context import JsonSerializer
from workflows.events import Event, StopEvent
@@ -4,7 +4,6 @@
from unittest import mock
import pytest
from workflows.context import Context
from workflows.errors import WorkflowRuntimeError
from workflows.handler import WorkflowHandler
@@ -6,7 +6,6 @@ from unittest import mock
import pytest
from pydantic import BaseModel, Field
from workflows.decorators import step
from workflows.events import Event, StartEvent, StopEvent
from workflows.resource import Resource, ResourceManager
@@ -2,13 +2,12 @@
# Copyright (c) 2025 LlamaIndex Inc.
import pytest
from workflows.context import Context
from workflows.decorators import step
from workflows.events import Event, StartEvent, StopEvent
from workflows.retry_policy import ConstantDelayRetryPolicy
from workflows.workflow import Workflow
from workflows.testing import WorkflowTestRunner
from workflows.workflow import Workflow
@pytest.mark.asyncio
@@ -1,3 +1,5 @@
from typing import Any, Type, Union, cast
import pytest
from pydantic import (
BaseModel,
@@ -6,9 +8,7 @@ from pydantic import (
field_serializer,
field_validator,
)
from typing import Union, cast, Type, Any
from workflows.context.serializers import JsonSerializer, BaseSerializer
from workflows.context.serializers import BaseSerializer, JsonSerializer
from workflows.context.state_store import DictState, InMemoryStateStore
@@ -5,12 +5,11 @@ import asyncio
from typing import AsyncGenerator
import pytest
from workflows.context import Context
from workflows.testing import WorkflowTestRunner
from workflows.decorators import step
from workflows.errors import WorkflowRuntimeError, WorkflowTimeoutError
from workflows.events import Event, StartEvent, StopEvent
from workflows.testing import WorkflowTestRunner
from workflows.workflow import Workflow
from .conftest import OneTestEvent # type: ignore[import]
@@ -1,12 +1,11 @@
import pytest
from workflows.events import (
StartEvent,
StopEvent,
Event,
StepStateChanged,
)
from workflows import Context, Workflow, step
from workflows.events import (
Event,
StartEvent,
StepStateChanged,
StopEvent,
)
from workflows.testing import WorkflowTestRunner
from workflows.testing.runner import WorkflowTestResult
@@ -5,7 +5,6 @@ import inspect
from typing import Any, List, Optional, Union, get_type_hints
import pytest
from workflows.context import Context
from workflows.decorators import step
from workflows.errors import WorkflowValidationError
@@ -12,10 +12,9 @@ import weakref
from typing import Any, Callable, Union, cast
from unittest import mock
import pytest
from llama_index_instrumentation.dispatcher import active_instrument_tags
from pydantic import PrivateAttr
import pytest
from workflows.context import Context, PickleSerializer
from workflows.decorators import step
from workflows.errors import (
@@ -452,8 +451,8 @@ async def test_workflow_pickle() -> None:
@pytest.mark.asyncio
async def test_workflow_context_to_dict() -> None:
ctx: Union[Context, None] = None
new_ctx: Union[Context, None] = None
ctx: Context | None = None
new_ctx: Context | None = None
signal_continue = asyncio.Event()
signal_ready = asyncio.Event()
run_count = 0
@@ -1,17 +1,17 @@
import pytest
import asyncio
from workflows import Workflow, Context, step
from workflows.testing import WorkflowTestRunner
from typing import Union
import pytest
from pydantic import BaseModel
from workflows import Context, Workflow, step
from workflows.events import (
StepStateChanged,
StepState,
Event,
StartEvent,
StepState,
StepStateChanged,
StopEvent,
)
from pydantic import BaseModel
from workflows.testing import WorkflowTestRunner
class SomeEvent(Event):
@@ -4,14 +4,13 @@
from __future__ import annotations
import pytest
from workflows.decorators import step
from workflows.events import (
StartEvent,
StopEvent,
)
from workflows.workflow import Workflow
from workflows.testing import WorkflowTestRunner
from workflows.workflow import Workflow
from .conftest import OneTestEvent # type: ignore[import]
@@ -1,12 +1,12 @@
import asyncio
from typing import Optional, Union
import pytest
from pydantic import BaseModel, Field
from typing import Union, Optional
from workflows import Context, Workflow
from workflows.testing import WorkflowTestRunner
from workflows.decorators import step
from workflows.events import StartEvent, StopEvent, Event
from workflows.events import Event, StartEvent, StopEvent
from workflows.testing import WorkflowTestRunner
class MyState(BaseModel):
+2 -1
View File
@@ -23,7 +23,8 @@ dependencies = [
"httpx>=0.28.1",
"packaging>=24.1",
"pydantic>=2.12.3",
"tomlkit>=0.13.3"
"tomlkit>=0.13.3",
"tomli>=2.3.0"
]
[project.scripts]
@@ -9,19 +9,19 @@ There's 2 things this does:
from __future__ import annotations
from dataclasses import dataclass
import json
import os
import subprocess
import urllib.error
import urllib.request
from dataclasses import dataclass
from pathlib import Path
from typing import Any, Generator, List, cast
import urllib.request
import urllib.error
from pydantic import BaseModel
import click
import tomlkit
from packaging.version import Version
from pydantic import BaseModel
def run_command(
@@ -2,11 +2,10 @@ from __future__ import annotations
import os
from pathlib import Path
from typing import Optional
import click
from . import git_utils, gha, index_html, versioning, changesets
from . import changesets, gha, git_utils, index_html, versioning
@click.group()
@@ -21,7 +20,7 @@ def cli() -> None:
help="Full git tag to inspect (e.g. llama-index-workflows@v1.2.3).",
)
@click.option("--output", type=click.Path(), default=None)
def compute_tag_metadata(tag: str, output: Optional[Path]) -> None:
def compute_tag_metadata(tag: str, output: Path | None) -> None:
"""Compute semantic metadata and change classification for a tag.
Writes tag_suffix, semver, change_type, and change_description to outputs.
@@ -69,7 +68,7 @@ def compute_tag_metadata(tag: str, output: Optional[Path]) -> None:
default=None,
help="Optional custom index.html path.",
)
def update_index_html_cmd(js_url: str, css_url: str, index_path: Optional[str]) -> None:
def update_index_html_cmd(js_url: str, css_url: str, index_path: str | None) -> None:
"""Update debugger asset URLs in the server index.html file."""
try:
index_html.update_index_html(js_url, css_url, index_path)
@@ -2,7 +2,7 @@ from __future__ import annotations
import subprocess
from pathlib import Path
from typing import Iterable, Optional
from typing import Iterable
def list_tags(repo: str | Path, tag_glob: str) -> list[str]:
@@ -26,7 +26,7 @@ def list_tags(repo: str | Path, tag_glob: str) -> list[str]:
return [line.strip() for line in result.stdout.splitlines() if line.strip()]
def previous_tag(current_tag: str, tags: Iterable[str]) -> Optional[str]:
def previous_tag(current_tag: str, tags: Iterable[str]) -> str | None:
"""Return the tag immediately after the current entry in the sorted list."""
tags_list = list(tags)
if current_tag in tags_list:
@@ -1,11 +1,10 @@
from __future__ import annotations
import sys
from dataclasses import dataclass
from pathlib import Path
from typing import Optional
from packaging.version import Version
import sys
if sys.version_info >= (3, 11):
import tomllib
@@ -96,7 +95,7 @@ def compute_suffix_and_version(tag: str, tag_prefix: str) -> tuple[str, str]:
return suffix, semver
def detect_change_type(current_version: str, previous_version: Optional[str]) -> str:
def detect_change_type(current_version: str, previous_version: str | None) -> str:
"""Return the semantic change classification between two versions."""
if not previous_version:
return "major"
@@ -7,7 +7,6 @@ from unittest.mock import Mock, patch
from urllib.error import HTTPError
from click.testing import CliRunner
from workflows_dev.changesets import (
PackageJson,
PyProjectContainer,
+34 -4
View File
@@ -4,7 +4,9 @@ build-backend = "uv_build"
[dependency-groups]
dev = [
"pytest-xdist>=3.8.0"
"pytest-xdist>=3.8.0",
"ruff>=0.14.5",
"ty>=0.0.1a26"
]
[project]
@@ -14,9 +16,6 @@ description = "Monorepo workspace for the LlamaIndex Workflows packages."
readme = "README.md"
license = "MIT"
requires-python = ">=3.9"
dependencies = [
"tomli>=2.3.0"
]
[tool.basedpyright]
typeCheckingMode = "standard"
@@ -43,6 +42,37 @@ omit = ["**/tests/*"]
[tool.pytest.ini_options]
asyncio_mode = "auto"
[tool.ruff.lint]
select = [
# default flake8 rules
"E4",
"E7",
"E9",
"F", # Pyflakes rules https://docs.astral.sh/ruff/rules/#pyflakes-f
"I", # sort imports https://docs.astral.sh/ruff/rules/#isort-i
"UP007", # Use X | Y for type annotations
"UP045", # Use X | None for type annotations
"ANN001", # Missing type annotation for function argument {name}
"ANN002", # Missing type annotation for *{name}
"ANN003", # Missing type annotation for **{name}
"T201" # no print statements
]
[tool.ruff.lint.per-file-ignores]
# "tests/*" = ["D", "D100", "D101"]
"examples/**/*" = ["T201"]
"packages/*/tests/**/*" = [
"T201",
"ANN001",
"ANN002",
"ANN003",
# remove UP007 and UP045 after removing 3.9 support
"UP007",
"UP045"
]
"*.ipynb" = ["T201", "ANN001", "ANN002", "ANN003"]
"__main__.py" = ["T201"]
[tool.uv.sources]
llama-index-workflows = {workspace = true}
llama-index-utils-workflow = {workspace = true}
Generated
+35 -5
View File
@@ -1567,20 +1567,22 @@ wheels = [
name = "llama-agents-workspace"
version = "0.1.0"
source = { editable = "." }
dependencies = [
{ name = "tomli" },
]
[package.dev-dependencies]
dev = [
{ name = "pytest-xdist" },
{ name = "ruff" },
{ name = "ty" },
]
[package.metadata]
requires-dist = [{ name = "tomli", specifier = ">=2.3.0" }]
[package.metadata.requires-dev]
dev = [{ name = "pytest-xdist", specifier = ">=3.8.0" }]
dev = [
{ name = "pytest-xdist", specifier = ">=3.8.0" },
{ name = "ruff", specifier = ">=0.14.5" },
{ name = "ty", specifier = ">=0.0.1a26" },
]
[[package]]
name = "llama-index-core"
@@ -3593,6 +3595,32 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/25/7a/b0178788f8dc6cafce37a212c99565fa1fe7872c70c6c9c1e1a372d9d88f/rich-14.2.0-py3-none-any.whl", hash = "sha256:76bc51fe2e57d2b1be1f96c524b890b816e334ab4c1e45888799bfaab0021edd", size = 243393, upload-time = "2025-10-09T14:16:51.245Z" },
]
[[package]]
name = "ruff"
version = "0.14.5"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/82/fa/fbb67a5780ae0f704876cb8ac92d6d76da41da4dc72b7ed3565ab18f2f52/ruff-0.14.5.tar.gz", hash = "sha256:8d3b48d7d8aad423d3137af7ab6c8b1e38e4de104800f0d596990f6ada1a9fc1", size = 5615944, upload-time = "2025-11-13T19:58:51.155Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/68/31/c07e9c535248d10836a94e4f4e8c5a31a1beed6f169b31405b227872d4f4/ruff-0.14.5-py3-none-linux_armv6l.whl", hash = "sha256:f3b8248123b586de44a8018bcc9fefe31d23dda57a34e6f0e1e53bd51fd63594", size = 13171630, upload-time = "2025-11-13T19:57:54.894Z" },
{ url = "https://files.pythonhosted.org/packages/8e/5c/283c62516dca697cd604c2796d1487396b7a436b2f0ecc3fd412aca470e0/ruff-0.14.5-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:f7a75236570318c7a30edd7f5491945f0169de738d945ca8784500b517163a72", size = 13413925, upload-time = "2025-11-13T19:57:59.181Z" },
{ url = "https://files.pythonhosted.org/packages/b6/f3/aa319f4afc22cb6fcba2b9cdfc0f03bbf747e59ab7a8c5e90173857a1361/ruff-0.14.5-py3-none-macosx_11_0_arm64.whl", hash = "sha256:6d146132d1ee115f8802356a2dc9a634dbf58184c51bff21f313e8cd1c74899a", size = 12574040, upload-time = "2025-11-13T19:58:02.056Z" },
{ url = "https://files.pythonhosted.org/packages/f9/7f/cb5845fcc7c7e88ed57f58670189fc2ff517fe2134c3821e77e29fd3b0c8/ruff-0.14.5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2380596653dcd20b057794d55681571a257a42327da8894b93bbd6111aa801f", size = 13009755, upload-time = "2025-11-13T19:58:05.172Z" },
{ url = "https://files.pythonhosted.org/packages/21/d2/bcbedbb6bcb9253085981730687ddc0cc7b2e18e8dc13cf4453de905d7a0/ruff-0.14.5-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2d1fa985a42b1f075a098fa1ab9d472b712bdb17ad87a8ec86e45e7fa6273e68", size = 12937641, upload-time = "2025-11-13T19:58:08.345Z" },
{ url = "https://files.pythonhosted.org/packages/a4/58/e25de28a572bdd60ffc6bb71fc7fd25a94ec6a076942e372437649cbb02a/ruff-0.14.5-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88f0770d42b7fa02bbefddde15d235ca3aa24e2f0137388cc15b2dcbb1f7c7a7", size = 13610854, upload-time = "2025-11-13T19:58:11.419Z" },
{ url = "https://files.pythonhosted.org/packages/7d/24/43bb3fd23ecee9861970978ea1a7a63e12a204d319248a7e8af539984280/ruff-0.14.5-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:3676cb02b9061fee7294661071c4709fa21419ea9176087cb77e64410926eb78", size = 15061088, upload-time = "2025-11-13T19:58:14.551Z" },
{ url = "https://files.pythonhosted.org/packages/23/44/a022f288d61c2f8c8645b24c364b719aee293ffc7d633a2ca4d116b9c716/ruff-0.14.5-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b595bedf6bc9cab647c4a173a61acf4f1ac5f2b545203ba82f30fcb10b0318fb", size = 14734717, upload-time = "2025-11-13T19:58:17.518Z" },
{ url = "https://files.pythonhosted.org/packages/58/81/5c6ba44de7e44c91f68073e0658109d8373b0590940efe5bd7753a2585a3/ruff-0.14.5-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f55382725ad0bdb2e8ee2babcbbfb16f124f5a59496a2f6a46f1d9d99d93e6e2", size = 14028812, upload-time = "2025-11-13T19:58:20.533Z" },
{ url = "https://files.pythonhosted.org/packages/ad/ef/41a8b60f8462cb320f68615b00299ebb12660097c952c600c762078420f8/ruff-0.14.5-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7497d19dce23976bdaca24345ae131a1d38dcfe1b0850ad8e9e6e4fa321a6e19", size = 13825656, upload-time = "2025-11-13T19:58:23.345Z" },
{ url = "https://files.pythonhosted.org/packages/7c/00/207e5de737fdb59b39eb1fac806904fe05681981b46d6a6db9468501062e/ruff-0.14.5-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:410e781f1122d6be4f446981dd479470af86537fb0b8857f27a6e872f65a38e4", size = 13959922, upload-time = "2025-11-13T19:58:26.537Z" },
{ url = "https://files.pythonhosted.org/packages/bc/7e/fa1f5c2776db4be405040293618846a2dece5c70b050874c2d1f10f24776/ruff-0.14.5-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:c01be527ef4c91a6d55e53b337bfe2c0f82af024cc1a33c44792d6844e2331e1", size = 12932501, upload-time = "2025-11-13T19:58:29.822Z" },
{ url = "https://files.pythonhosted.org/packages/67/d8/d86bf784d693a764b59479a6bbdc9515ae42c340a5dc5ab1dabef847bfaa/ruff-0.14.5-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:f66e9bb762e68d66e48550b59c74314168ebb46199886c5c5aa0b0fbcc81b151", size = 12927319, upload-time = "2025-11-13T19:58:32.923Z" },
{ url = "https://files.pythonhosted.org/packages/ac/de/ee0b304d450ae007ce0cb3e455fe24fbcaaedae4ebaad6c23831c6663651/ruff-0.14.5-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d93be8f1fa01022337f1f8f3bcaa7ffee2d0b03f00922c45c2207954f351f465", size = 13206209, upload-time = "2025-11-13T19:58:35.952Z" },
{ url = "https://files.pythonhosted.org/packages/33/aa/193ca7e3a92d74f17d9d5771a765965d2cf42c86e6f0fd95b13969115723/ruff-0.14.5-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:c135d4b681f7401fe0e7312017e41aba9b3160861105726b76cfa14bc25aa367", size = 13953709, upload-time = "2025-11-13T19:58:39.002Z" },
{ url = "https://files.pythonhosted.org/packages/cc/f1/7119e42aa1d3bf036ffc9478885c2e248812b7de9abea4eae89163d2929d/ruff-0.14.5-py3-none-win32.whl", hash = "sha256:c83642e6fccfb6dea8b785eb9f456800dcd6a63f362238af5fc0c83d027dd08b", size = 12925808, upload-time = "2025-11-13T19:58:42.779Z" },
{ url = "https://files.pythonhosted.org/packages/3b/9d/7c0a255d21e0912114784e4a96bf62af0618e2190cae468cd82b13625ad2/ruff-0.14.5-py3-none-win_amd64.whl", hash = "sha256:9d55d7af7166f143c94eae1db3312f9ea8f95a4defef1979ed516dbb38c27621", size = 14331546, upload-time = "2025-11-13T19:58:45.691Z" },
{ url = "https://files.pythonhosted.org/packages/e5/80/69756670caedcf3b9be597a6e12276a6cf6197076eb62aad0c608f8efce0/ruff-0.14.5-py3-none-win_arm64.whl", hash = "sha256:4b700459d4649e2594b31f20a9de33bc7c19976d4746d8d0798ad959621d64a4", size = 13433331, upload-time = "2025-11-13T19:58:48.434Z" },
]
[[package]]
name = "secretstorage"
version = "3.3.3"
@@ -4128,6 +4156,7 @@ dependencies = [
{ name = "httpx" },
{ name = "packaging" },
{ name = "pydantic" },
{ name = "tomli" },
{ name = "tomlkit" },
]
@@ -4144,6 +4173,7 @@ requires-dist = [
{ name = "httpx", specifier = ">=0.28.1" },
{ name = "packaging", specifier = ">=24.1" },
{ name = "pydantic", specifier = ">=2.12.3" },
{ name = "tomli", specifier = ">=2.3.0" },
{ name = "tomlkit", specifier = ">=0.13.3" },
]