Convert YAML workflow files to LangGraph implementations
Project description
YAML to LangGraph Converter
A powerful tool for converting Defy YAML workflow files to LangGraph implementations with comprehensive validation and beautiful CLI output.
Features
- ๐ YAML Schema Validation: Comprehensive validation of workflow structure
- ๐จ Rich CLI Interface: Beautiful command-line interface with Click
- โก Fast Conversion: Efficient parsing and code generation
- ๐งช Comprehensive Testing: Full test suite with pytest
- ๐ฆ Modern Packaging: Standard Python package structure
- ๐ ๏ธ Extensible: Easy to customize and extend
Installation
From Source
git clone https://github.com/example/yaml-to-langgraph.git
cd yaml-to-langgraph
pip install -e .
With Development Dependencies
pip install -e ".[dev]"
With LangChain Dependencies
pip install -e ".[langchain]"
Usage
Command Line Interface
Basic Commands
# Validate YAML workflow file
yaml-to-langgraph validate workflow.yml
# Convert YAML to LangGraph implementation
yaml-to-langgraph convert workflow.yml
# Convert with custom output directory
yaml-to-langgraph convert workflow.yml --output my_workflow
# Convert with verbose output
yaml-to-langgraph convert workflow.yml --verbose
# Skip validation (not recommended)
yaml-to-langgraph convert workflow.yml --skip-validation
# List all nodes in the workflow
yaml-to-langgraph list-nodes workflow.yml
# Dry run to see what would be generated
yaml-to-langgraph dry-run workflow.yml
# Get help for any command
yaml-to-langgraph --help
yaml-to-langgraph convert --help
yaml-to-langgraph validate --help
Validation Examples
# Basic validation
yaml-to-langgraph validate workflow.yml
# Strict validation (treats warnings as errors)
yaml-to-langgraph validate workflow.yml --strict
# Validate with detailed output
yaml-to-langgraph validate workflow.yml --verbose
Conversion Examples
# Simple conversion
yaml-to-langgraph convert sample_workflow.yml
# Convert to specific directory
yaml-to-langgraph convert sample_workflow.yml --output generated_workflow
# Convert with verbose output to see all generated files
yaml-to-langgraph convert sample_workflow.yml --verbose
# Convert multiple workflows
for file in workflows/*.yml; do
yaml-to-langgraph convert "$file" --output "generated_$(basename "$file" .yml)"
done
Python API
Basic Usage
from yaml_to_langgraph import YAMLToLangGraphConverter
from yaml_to_langgraph.schema_validator import validate_yaml_workflow
# Validate a workflow
result = validate_yaml_workflow("workflow.yml")
if result.is_valid:
print("Workflow is valid!")
if result.warnings:
print(f"Warnings: {[w.message for w in result.warnings]}")
else:
print(f"Validation failed: {[e.message for e in result.errors]}")
# Convert YAML workflow to LangGraph
converter = YAMLToLangGraphConverter("workflow.yml", "output_dir")
output_path = converter.convert()
print(f"Generated workflow at: {output_path}")
Advanced Usage
from yaml_to_langgraph import YAMLToLangGraphConverter
from yaml_to_langgraph.yaml_parser import YAMLWorkflowParser
from yaml_to_langgraph.code_generator import LangGraphCodeGenerator
# Parse YAML workflow
parser = YAMLWorkflowParser("workflow.yml")
workflow_data = parser.parse()
# Generate code
generator = LangGraphCodeGenerator(workflow_data)
code_files = generator.generate_code("output_dir")
# Access specific components
print(f"Workflow name: {workflow_data.app.name}")
print(f"Number of nodes: {len(workflow_data.graph.nodes)}")
print(f"Number of edges: {len(workflow_data.graph.edges)}")
# Get LLM nodes
llm_nodes = [node for node in workflow_data.graph.nodes if node.type == "llm"]
print(f"LLM nodes: {[node.id for node in llm_nodes]}")
Error Handling
from yaml_to_langgraph import YAMLToLangGraphConverter
from yaml_to_langgraph.schema_validator import ValidationError
try:
converter = YAMLToLangGraphConverter("invalid_workflow.yml", "output")
output_path = converter.convert()
except ValidationError as e:
print(f"Validation error: {e.message}")
print(f"Path: {e.path}")
except FileNotFoundError:
print("YAML file not found")
except Exception as e:
print(f"Unexpected error: {e}")
Generated Code Structure
When you convert a YAML workflow, the following structure is generated:
generated_workflow/
โโโ prompts/ # Prompt templates for LLM nodes
โ โโโ node1_prompt.py
โ โโโ node2_prompt.py
โ โโโ ...
โโโ nodes/ # Node implementations
โ โโโ workflow_nodes.py
โ โโโ custom_nodes.py
โโโ edges/ # Edge definitions and routing logic
โ โโโ routing.py
โ โโโ conditions.py
โโโ workflow_graph.py # Main graph assembly
โโโ example_usage.py # Usage example
โโโ requirements.txt # Dependencies
โโโ README.md # Generated documentation
Using the Generated Workflow
# After conversion, use the generated workflow
from workflow_graph import create_workflow_graph, run_workflow
from langchain_openai import ChatOpenAI
# Initialize your model
model = ChatOpenAI(model="gpt-4", temperature=0.7)
# Create the workflow graph
graph = create_workflow_graph(model)
# Run the workflow
result = run_workflow(
graph=graph,
input_data={"user_input": "Hello, world!"}
)
print(result)
Real-World Examples
Example 1: Simple Chat Workflow
# simple_chat.yml
app:
name: "simple-chat"
description: "A simple chat workflow"
workflow:
graph:
nodes:
- id: "start"
type: "start"
data:
type: "start"
title: "Start"
- id: "chat"
type: "llm"
data:
type: "llm"
title: "Chat Response"
model:
provider: "openai"
name: "gpt-4"
prompt_template:
- role: "user"
content: "{{user_input}}"
- id: "end"
type: "end"
data:
type: "end"
title: "End"
edges:
- id: "edge1"
source: "start"
target: "chat"
data:
label: "always"
- id: "edge2"
source: "chat"
target: "end"
data:
label: "always"
Convert and use:
yaml-to-langgraph convert simple_chat.yml --output simple_chat_workflow
cd simple_chat_workflow
pip install -r requirements.txt
python example_usage.py
Example 2: Multi-Step Processing Workflow
# processing_workflow.yml
app:
name: "data-processor"
description: "Multi-step data processing workflow"
workflow:
graph:
nodes:
- id: "start"
type: "start"
data:
type: "start"
- id: "analyze"
type: "llm"
data:
type: "llm"
title: "Data Analyzer"
model:
provider: "openai"
name: "gpt-4"
prompt_template:
- role: "system"
content: "Analyze the following data: {{input_data}}"
- id: "process"
type: "llm"
data:
type: "llm"
title: "Data Processor"
model:
provider: "openai"
name: "gpt-4"
prompt_template:
- role: "system"
content: "Process the analyzed data: {{analyze.output}}"
- id: "validate"
type: "llm"
data:
type: "llm"
title: "Data Validator"
model:
provider: "openai"
name: "gpt-4"
prompt_template:
- role: "system"
content: "Validate the processed data: {{process.output}}"
- id: "end"
type: "end"
data:
type: "end"
edges:
- id: "e1"
source: "start"
target: "analyze"
data:
label: "always"
- id: "e2"
source: "analyze"
target: "process"
data:
label: "success"
- id: "e3"
source: "process"
target: "validate"
data:
label: "success"
- id: "e4"
source: "validate"
target: "end"
data:
label: "valid"
Using Make Commands
The project includes a comprehensive Makefile for development:
# Development setup
make dev-setup # Install in development mode
make test # Run all tests
make demo # Convert sample workflow
make validate-demo # Validate sample workflow
# Code quality
make format # Format code
make lint # Run linting
make check # Run all quality checks
# Package management
make build # Build package
make publish-token TOKEN=your-token # Publish to PyPI
make pypi-help # Show PyPI setup instructions
# UV commands
make uv-sync # Sync dependencies
make uv-add PACKAGE=requests # Add new package
make uv-update # Update dependencies
Quick Reference
Common Commands
| Command | Description |
|---|---|
yaml-to-langgraph validate workflow.yml |
Validate YAML workflow |
yaml-to-langgraph convert workflow.yml |
Convert to LangGraph |
yaml-to-langgraph convert workflow.yml --output my_dir |
Convert to specific directory |
yaml-to-langgraph list-nodes workflow.yml |
List all nodes |
yaml-to-langgraph dry-run workflow.yml |
Preview what would be generated |
Make Commands
| Command | Description |
|---|---|
make help |
Show all available commands |
make test |
Run all tests |
make demo |
Convert sample workflow |
make build |
Build package |
make publish-token TOKEN=xxx |
Publish to PyPI |
make pypi-help |
Show PyPI setup help |
YAML Structure
app:
name: "workflow-name"
description: "Workflow description"
workflow:
graph:
nodes:
- id: "node_id"
type: "llm|start|end|code"
data:
type: "llm|start|end|code"
title: "Node Title"
# ... node-specific data
edges:
- id: "edge_id"
source: "source_node"
target: "target_node"
data:
label: "condition"
Generated Files
workflow_graph.py- Main graph implementationprompts/- LLM prompt templatesnodes/- Node implementationsedges/- Routing logicexample_usage.py- Usage examplerequirements.txt- Dependencies
Development
Setup Development Environment
# Clone repository
git clone https://github.com/example/yaml-to-langgraph.git
cd yaml-to-langgraph
# Install in development mode
pip install -e ".[dev]"
# Run tests
pytest tests/ -v
# Run with coverage
pytest tests/ --cov=src/yaml_to_langgraph --cov-report=html
Code Quality
# Format code
black src/ tests/
# Sort imports
isort src/ tests/
# Lint code
ruff check src/ tests/
# Type checking
mypy src/
Project Structure
yaml_to_langgraph/
โโโ src/
โ โโโ yaml_to_langgraph/
โ โโโ __init__.py
โ โโโ cli.py # Command-line interface
โ โโโ converter.py # Main converter logic
โ โโโ schema_validator.py # YAML validation
โ โโโ yaml_parser.py # YAML parsing
โ โโโ code_generator.py # Code generation
โโโ tests/
โ โโโ __init__.py
โ โโโ conftest.py
โ โโโ test_sample_workflow.py
โ โโโ test_cli.py
โ โโโ test_converter.py
โ โโโ test_schema_validation.py
โโโ pyproject.toml
โโโ README.md
Testing
The project includes a comprehensive test suite with 41 tests covering:
- Schema Validation: YAML structure validation
- CLI Functionality: Command-line interface testing
- Core Converter: Conversion logic testing
- Sample Workflow: Real-world workflow testing
# Run all tests
pytest tests/ -v
# Run specific test categories
pytest tests/test_schema_validation.py -v
pytest tests/test_cli.py -v
pytest tests/test_converter.py -v
pytest tests/test_sample_workflow.py -v
Publishing
The package can be published to PyPI using several methods:
Using UV (Recommended)
# Build the package
make build
# Publish with environment variables
export UV_PUBLISH_USERNAME=your-username
export UV_PUBLISH_PASSWORD=your-password
make publish
# Or publish with token
make publish-token TOKEN=your-pypi-token
# Publish to Test PyPI first
make publish-test TOKEN=your-testpypi-token
Using Twine (Fallback)
If you prefer to use your existing ~/.pypirc configuration:
# Build the package
make build
# Publish using twine (reads ~/.pypirc)
make publish-twine
# Publish to Test PyPI using twine
make publish-test-twine
Manual Publishing
# Build
uv build
# Publish with uv
uv publish --token your-token
# Or with twine
python -m twine upload dist/*
Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
License
MIT License - see LICENSE file for details.
Support
- Issues: GitHub Issues
- Documentation: GitHub Wiki
- Discussions: GitHub Discussions
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file yaml_to_langgraph-1.0.1.tar.gz.
File metadata
- Download URL: yaml_to_langgraph-1.0.1.tar.gz
- Upload date:
- Size: 32.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.8.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
11af475db1eb7a1f4be4ce1cd2a83051a77d7f655a0bb10e063cff187609a4ac
|
|
| MD5 |
778626810ee4a65440546d3f3eff4a04
|
|
| BLAKE2b-256 |
8e27259d2cf22313987101ec72848f16e293926d1bccd9cfb0125ef332c9b0d3
|
File details
Details for the file yaml_to_langgraph-1.0.1-py3-none-any.whl.
File metadata
- Download URL: yaml_to_langgraph-1.0.1-py3-none-any.whl
- Upload date:
- Size: 27.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.8.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b61af518c9f28161eebd25c1688268262958d36041df08de13f53f006a62652c
|
|
| MD5 |
0ff393d175617ded908d97f794fa0081
|
|
| BLAKE2b-256 |
f246866f1bbb0544c6f0f255deec6e55e0e67ee9bfd5c79882b4f85ebb714971
|