Skip to content

Commit e75ec45

Browse files
init
0 parents  commit e75ec45

File tree

94 files changed

+63729
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

94 files changed

+63729
-0
lines changed

.github/workflows/test.yml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
name: Test
2+
3+
on:
4+
push:
5+
pull_request:
6+
7+
jobs:
8+
test:
9+
runs-on: ubuntu-latest
10+
strategy:
11+
matrix:
12+
python-version: ["3.10", "3.11", "3.12", "3.13"]
13+
14+
steps:
15+
- uses: actions/checkout@v4
16+
17+
- name: Set up Python ${{ matrix.python-version }}
18+
uses: actions/setup-python@v5
19+
with:
20+
python-version: ${{ matrix.python-version }}
21+
22+
- name: Install PDM
23+
run: |
24+
pip install pdm
25+
26+
- name: Install dependencies
27+
run: |
28+
cd runner
29+
pdm install
30+
31+
- name: Run tests
32+
run: |
33+
cd runner
34+
pdm run test
35+
36+
- name: Run linting
37+
run: |
38+
cd runner
39+
pdm run lint
40+
continue-on-error: true

README.md

Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
This repository contains projects related to the creation, verification and execution of Arazzo Workfows.
2+
3+
# Arazzo Runner [Beta]
4+
5+
The Arazzo Runner is a workflow execution engine that processes and executes API workflows defined in the Arazzo format and individual API calls defined in OpenAPI specifications.
6+
7+
## Usage
8+
9+
### Execute a Workflow
10+
```python
11+
from arazzo_runner import ArazzoRunner
12+
13+
runner = ArazzoRunner.from_arazzo_path("../../workflows/discord.com/workflows.arazzo.json")
14+
15+
result = runner.execute_workflow("workflowId", {"param1": "value1"})
16+
```
17+
18+
### Display Authentication Options
19+
```python
20+
from arazzo_runner import ArazzoRunner
21+
22+
runner = ArazzoRunner.from_arazzo_path("../../workflows/discord.com/workflows.arazzo.json")
23+
24+
print(runner.get_env_mappings())
25+
```
26+
27+
### Execute a Single OpenAPI Operation
28+
```python
29+
from arazzo_runner import ArazzoRunner
30+
# Execute a single OpenAPI operation with an operationId
31+
result = runner.execute_operation("operationId", {"param1": "value1"})
32+
33+
# Execute a single OpenAPI operation by path
34+
result = runner.execute_operation("GET /users/@me/guilds", {"param1": "value1"})
35+
```
36+
37+
### Create a Runner with a Custom Base Path
38+
```python
39+
# Create a runner instance with a custom base path for resolving OpenAPI file paths
40+
runner_with_base_path = ArazzoRunner.from_arazzo_path(
41+
"./my/arazzo.yaml",
42+
base_path="./my/source/description/base"
43+
)
44+
```
45+
46+
## Authentication
47+
48+
Credentials are resolved from environment variables defined by the Arazzo Runner based on the Arazzo or OpenAPI file. You can see the authentication options by using `runner.get_env_mappings` or the `show-env-mappings` command line tool defined below.
49+
50+
The Arazzo Runner supports various authentication methods defined in OpenAPI specifications:
51+
52+
- **API Key**: Header, Query, or Cookie API keys
53+
- **OAuth2**: Some OAuth2 Flows (Client Credentials, Password)
54+
- **HTTP**: Basic and Bearer Authentication
55+
56+
### Auth Methods Not Yet Supported
57+
- **OAuth2**: Authorization Code, Implicit
58+
- **OpenID**: OpenID Connect
59+
- **Custom**: Custom Authentication Schemes
60+
61+
## Command Line Usage
62+
63+
Usage:
64+
```sh
65+
uvx arazzo-runner <command> [command-specific arguments] [global options]
66+
```
67+
68+
**Commands:**
69+
70+
1. **`show-env-mappings`**: Show environment variable mappings for authentication based on an Arazzo or OpenAPI file.
71+
```sh
72+
uvx arazzo-runner show-env-mappings [arazzo_path | --openapi-path PATH]
73+
```
74+
- `arazzo_path`: Path to the Arazzo YAML file (use this OR --openapi-path).
75+
- `--openapi-path PATH`: Path to the OpenAPI spec file (use this OR arazzo_path).
76+
*One of the path arguments is required.*
77+
78+
2. **`execute-workflow`**: Execute a workflow defined in an Arazzo file.
79+
```sh
80+
uvx arazzo-runner execute-workflow <arazzo_path> --workflow-id <workflow_id> [--inputs <json_string>]
81+
```
82+
- `arazzo_path`: *Required*. Path to the Arazzo YAML file containing the workflow.
83+
- `--workflow-id WORKFLOW_ID`: *Required*. ID of the workflow to execute.
84+
- `--inputs INPUTS`: Optional JSON string of workflow inputs (default: `{}`).
85+
86+
3. **`execute-operation`**: Execute a single API operation directly from an OpenAPI specification (or an Arazzo file for context).
87+
```sh
88+
uvx arazzo-runner execute-operation [--arazzo-path PATH | --openapi-path PATH] [--operation-id ID | --operation-path PATH_METHOD] [--inputs <json_string>]
89+
```
90+
- `--arazzo-path PATH`: Path to an Arazzo file (provides context, use this OR --openapi-path).
91+
- `--openapi-path PATH`: Path to the OpenAPI spec file (use this OR --arazzo-path).
92+
*One of the path arguments is required.*
93+
- `--operation-id ID`: The `operationId` from the OpenAPI spec (use this OR --operation-path).
94+
- `--operation-path PATH_METHOD`: The HTTP method and path (e.g., 'GET /users/{id}') from the OpenAPI spec (use this OR --operation-id).
95+
*One of the operation identifiers is required.*
96+
- `--inputs INPUTS`: Optional JSON string of operation inputs (parameters, request body) (default: `{}`).
97+
98+
4. **`list-workflows`**: List all available workflows defined in an Arazzo file.
99+
```sh
100+
uvx arazzo-runner list-workflows <arazzo_path>
101+
```
102+
- `arazzo_path`: *Required*. Path to the Arazzo YAML file.
103+
104+
5. **`describe-workflow`**: Show details of a specific workflow, including its summary, inputs, steps, and outputs.
105+
```sh
106+
uvx arazzo-runner describe-workflow <arazzo_path> --workflow-id <workflow_id>
107+
```
108+
- `arazzo_path`: *Required*. Path to the Arazzo YAML file containing the workflow.
109+
- `--workflow-id WORKFLOW_ID`: *Required*. ID of the workflow to describe.
110+
111+
6. **`generate-example`**: Generate an example CLI command to execute a specified workflow, including placeholder inputs.
112+
```sh
113+
uvx arazzo-runner generate-example <arazzo_path> --workflow-id <workflow_id>
114+
```
115+
- `arazzo_path`: *Required*. Path to the Arazzo YAML file containing the workflow.
116+
- `--workflow-id WORKFLOW_ID`: *Required*. ID of the workflow to generate an example for.
117+
118+
119+
**Global Options:**
120+
- `--log-level {DEBUG,INFO,WARNING,ERROR,CRITICAL}`: Set the logging level (default: INFO).
121+
122+
123+
**Examples:**
124+
125+
```sh
126+
# Show environment variable mappings using an Arazzo file
127+
uvx arazzo-runner show-env-mappings ./tests/fixtures/discord/discord.arazzo.yaml
128+
129+
# Show environment variable mappings using an OpenAPI file
130+
uvx arazzo-runner show-env-mappings --openapi-path ./tests/fixtures/discord/discord.openapi.json
131+
132+
# Execute a workflow
133+
uvx arazzo-runner execute-workflow ./tests/fixtures/discord/discord.arazzo.yaml --workflow-id getUserInfoAndSendMessage --inputs '{\"recipient_id\": \"1234567890\", \"message_content\": \"Hello!\"}'
134+
135+
# Execute a specific operation using its operationId and an OpenAPI file
136+
uvx arazzo-runner execute-operation --openapi-path ./tests/fixtures/discord/discord.openapi.json --operation-id list_my_guilds --inputs '{}'
137+
138+
# Execute a specific operation using its path/method and an Arazzo file (for context)
139+
uvx arazzo-runner execute-operation --arazzo-path ./tests/fixtures/discord/discord.arazzo.yaml --operation-path 'GET /users/@me/guilds' --inputs '{}' --log-level DEBUG
140+
141+
# List all available workflows
142+
uvx arazzo-runner list-workflows ./tests/fixtures/discord/discord.arazzo.yaml
143+
144+
# Describe a specific workflow
145+
uvx arazzo-runner describe-workflow ./tests/fixtures/discord/discord.arazzo.yaml --workflow-id getUserInfoAndSendMessage
146+
147+
# Generate an example CLI command to execute a workflow
148+
uvx arazzo-runner generate-example ./tests/fixtures/discord/discord.arazzo.yaml --workflow-id getUserInfoAndSendMessage
149+
```
150+
151+
**Help:**
152+
```sh
153+
# General help
154+
uvx arazzo-runner --help
155+
156+
# Help for a specific command (e.g., execute-operation)
157+
uvx arazzo-runner execute-operation --help
158+
```
159+
160+
## Server URL Configuration
161+
162+
Arazzo Runner supports dynamic server URLs as defined in the `servers` object of an OpenAPI specification. This allows you to define API server URLs with templated variables (e.g., `https://{instance_id}.api.example.com/v1` or `https://api.example.com/{region}/users`).
163+
164+
### Variable Resolution
165+
166+
When an operation requires a server URL with variables, Arazzo Runner resolves these variables in the following order of precedence:
167+
168+
1. **Runtime Parameters**: Values passed explicitly when executing an operation or workflow (e.g., via the `--server-variables` CLI argument or the `runtime_params` parameter in `execute_operation`/`execute_workflow` methods). These parameters should be provided as a dictionary where keys match the expected environment variable names for the server variables (see below).
169+
2. **Environment Variables**: If not provided as a runtime parameter, Arazzo Runner attempts to find an environment variable.
170+
3. **Default Values**: If not found in runtime parameters or environment variables, the `default` value specified for the variable in the OpenAPI document's `servers` object is used.
171+
172+
If a variable in the URL template cannot be resolved through any of these means, and it does not have a default value, an error will occur.
173+
174+
### Environment Variable Naming
175+
176+
The environment variables for server URLs follow these naming conventions:
177+
178+
- If the OpenAPI specification's `info.title` is available and an `API_TITLE_PREFIX` can be derived from it (typically the first word of the title, uppercased and sanitized, e.g., `PETSTORE` from "Petstore API"), the format is:
179+
`[API_TITLE_PREFIX_]RUNNER_SERVER_<VAR_NAME_UPPERCASE>`
180+
Example: `PETSTORE_RUNNER_SERVER_REGION=us-east-1`
181+
182+
- If an `API_TITLE_PREFIX` cannot be derived (e.g., `info.title` is missing or empty), the format is:
183+
`RUNNER_SERVER_<VAR_NAME_UPPERCASE>`
184+
Example: `RUNNER_SERVER_INSTANCE_ID=my-instance-123`
185+
186+
The `<VAR_NAME_UPPERCASE>` corresponds to the variable name defined in the `servers` object's `variables` map (e.g., `region` or `instance_id`), converted to uppercase.
187+
188+
You can use the `show-env-mappings` CLI command to see the expected environment variable names for server URLs, alongside authentication variables, for a given OpenAPI specification.
189+
190+
### Example
191+
192+
Consider an OpenAPI specification with:
193+
- `info.title: "My Custom API"`
194+
- A server definition:
195+
```yaml
196+
servers:
197+
- url: "https://{instance}.api.example.com/{version}"
198+
variables:
199+
instance:
200+
default: "prod"
201+
description: "The API instance name."
202+
version:
203+
default: "v1"
204+
description: "API version."
205+
```
206+
207+
To set the `instance` to "dev" and `version` to "v2" via environment variables, you would set:
208+
```sh
209+
export MYCUSTOM_RUNNER_SERVER_INSTANCE=dev
210+
export MYCUSTOM_RUNNER_SERVER_VERSION=v2
211+
```
212+
(Assuming "MYCUSTOM" is derived from "My Custom API").
213+
214+
Alternatively, to provide these at runtime via the CLI when executing an operation:
215+
```sh
216+
uvx arazzo-runner execute-operation --openapi-path path/to/spec.yaml --operation-id someOperation \
217+
--server-variables '{"MYCUSTOM_RUNNER_SERVER_INSTANCE": "staging", "MYCUSTOM_RUNNER_SERVER_VERSION": "v2beta"}'
218+
```
219+
220+
221+
## Overview
222+
223+
Arazzo Runner orchestrates API workflows by:
224+
225+
- Loading and validating Arazzo workflow documents
226+
- Executing workflow steps sequentially or conditionally
227+
- Evaluating runtime expressions and success criteria
228+
- Extracting and transforming data between steps
229+
- Handling flow control (continue, goto, retry, end)
230+
- Supporting nested workflow execution
231+
- Providing event callbacks for workflow lifecycle events
232+
- Managing authentication requirements across different APIs
233+
234+
235+
## Testing
236+
237+
The Arazzo Runner includes a comprehensive testing framework for workflow validation:
238+
239+
- Automated test fixtures for different workflow scenarios
240+
- Mock HTTP responses based on OpenAPI specs
241+
- Custom mock responses for specific endpoints
242+
- Validation of workflow outputs and API call counts
243+
244+
For details on testing, see [Arazzo Runner Testing Framework](https://github.com/jentic/arazzo-engine/blob/main/runner/tests/README.md)
245+
246+
## Arazzo Format
247+
248+
The Arazzo specification is our workflow definition format that orchestrates API calls using OpenAPI specifications.
249+
250+
- Schema: [arazzo-schema.yaml](https://github.com/jentic/arazzo-engine/blob/main/runner/arazzo_spec/arazzo-schema.yaml)
251+
- Documentation: [arazzo-spec.md](https://github.com/jentic/arazzo-engine/blob/main/runner/arazzo_spec/arazzo-spec.md)

init-plan.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
Create the repository jentic/arazzo-engine.
2+
Copy oak-runner code to jentic/arazzo-engine/runner.
3+
Rename the class. OAKRunner → ArazzoRunner.
4+
Rename package oak_runner → arazzo_engine_runner.
5+
Update Jentic SDK code to match package and class names.
6+
Update hosted executor code to match package and class names.
7+
8+
oak-runner is currently in ~/oak/tools/oak-runner. We'll need to delete it after

runner/.gitignore

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Python
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
*.so
6+
.Python
7+
env/
8+
build/
9+
develop-eggs/
10+
dist/
11+
downloads/
12+
eggs/
13+
.eggs/
14+
lib/
15+
lib64/
16+
parts/
17+
sdist/
18+
var/
19+
*.egg-info/
20+
.installed.cfg
21+
*.egg
22+
.env
23+
.venv/
24+
.ruff_cache/
25+
26+
# PDM
27+
.pdm-python
28+
.pdm-build/
29+
__pypackages__/
30+
pdm.lock
31+
32+
# Logs
33+
logs/
34+
*.log
35+
36+
# Testing
37+
.coverage
38+
htmlcov/
39+
.pytest_cache/
40+
.mypy_cache/
41+
42+
# IDE
43+
.idea/
44+
.vscode/
45+
*.swp
46+
*.swo
47+
48+
# OS
49+
.DS_Store
50+
Thumbs.db
51+
52+
# Debug output
53+
debug_output/
54+
test_output/
55+
.test_output/

runner/arazzo_runner/__init__.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
"""
2+
Arazzo Runner
3+
4+
A library for executing Arazzo workflows step-by-step and OpenAPI operations.
5+
"""
6+
7+
from .runner import ArazzoRunner
8+
from .models import StepStatus, ExecutionState, ActionType, WorkflowExecutionStatus, WorkflowExecutionResult
9+
10+
__all__ = ["ArazzoRunner", "StepStatus", "ExecutionState", "ActionType", "WorkflowExecutionStatus", "WorkflowExecutionResult"]

0 commit comments

Comments
 (0)