Generate business flow diagrams from Python code decorators
Project description
FlowDoc
Generate business flow diagrams from Python code decorators.
Unlike tools that trace technical execution paths, FlowDoc captures business logic flow -- the high-level process steps that describe what your application does from a business perspective. Annotate your code with lightweight decorators, and FlowDoc uses AST analysis to infer the flow graph and render it as a diagram.
✨ Features
- Inference over declaration -- annotate steps, and FlowDoc discovers connections by analyzing your code
- Pure AST analysis -- no code execution, safe to run on untrusted code
- Multiple output formats -- PNG, SVG, PDF, DOT (via Graphviz), and Mermaid markdown
- Flexible patterns -- class-based flows, standalone functions, async/await, and web frameworks (FastAPI, Flask)
- Built-in validation -- detect dead steps, missing entry points, and other flow issues
- CLI included -- generate diagrams and validate flows from the command line
📦 Installation
pip install flowdoc
FlowDoc requires Python 3.10+ and Graphviz installed on your system for PNG/SVG/PDF output.
🚀 Quick Start
Decorate your business logic with @flow and @step:
from flowdoc import flow, step
@flow(name="Order Processing", description="Handle customer orders")
class OrderProcessor:
@step(name="Receive Order")
def receive_order(self, order_data):
return self.validate_payment(order_data)
@step(name="Validate Payment")
def validate_payment(self, order):
if order.get("payment_valid"):
return self.fulfill_order(order)
else:
return self.send_failure_email(order)
@step(name="Fulfill Order")
def fulfill_order(self, order):
return self.send_confirmation(order)
@step(name="Send Confirmation")
def send_confirmation(self, order):
return {"status": "confirmed", "order": order}
@step(name="Send Failure Email")
def send_failure_email(self, order):
return {"status": "failed", "order": order}
Generate the diagram:
flowdoc generate order_processor.py
FlowDoc analyzes the code, detects that validate_payment branches into two paths, and produces a flowchart with decision diamonds, regular steps, and terminal nodes.
💻 Usage
CLI
# Generate a PNG diagram (default)
flowdoc generate mymodule.py
# Choose output format
flowdoc generate mymodule.py --format svg
flowdoc generate mymodule.py --format mermaid
flowdoc generate mymodule.py --format dot
# Validate a flow for issues
flowdoc validate mymodule.py
Programmatic API
from flowdoc import FlowParser, create_generator, FlowValidator
# Parse a source file
parser = FlowParser()
flows = parser.parse_file("mymodule.py")
# Generate a diagram
generator = create_generator("png")
for flow_data in flows:
generator.generate(flow_data, "output.png")
# Validate
validator = FlowValidator()
for flow_data in flows:
messages = validator.validate(flow_data)
for msg in messages:
print(f"[{msg.level}] {msg.message}")
🔧 Supported Patterns
Class-based flows
Use @flow on a class and @step on its methods. FlowDoc detects self.method() calls to build the graph.
Function-based flows
Use @step on standalone functions. FlowDoc detects direct function calls between decorated functions.
from flowdoc import step
@step(name="Process Order")
def process_order(order_data):
validated = validate_order(order_data)
return charge_payment(validated)
@step(name="Validate Order")
def validate_order(order_data):
return order_data
@step(name="Charge Payment")
def charge_payment(order):
return {"status": "charged"}
Async functions
from flowdoc import step
@step(name="Create Order")
async def create_order(order):
validated = await validate_order(order)
return await save_order(validated)
Web framework integration
Works alongside FastAPI, Flask, and other decorator-based frameworks:
from fastapi import FastAPI
from flowdoc import step
app = FastAPI()
@app.post("/orders")
@step(name="Create Order Endpoint")
async def create_order(order: OrderData):
validated = await validate_order(order)
return await save_order(validated)
See examples/fastapi/app.py for a complete CRUD API example with @step decorators on endpoints.
⚙️ How It Works
FlowDoc uses Python's ast module to statically analyze decorated functions. For each @step, it walks the function body looking for:
- Method calls (
self.other_method()) and function calls (other_function()) to other@step-decorated code - Conditional branches (
if/else) to identify decision points - Call count to determine node shapes: multiple outgoing calls produce a diamond (decision), zero calls produce an ellipse (terminal), and single calls produce a box (regular step)
No code is ever executed during analysis.
Limitations
These are intentional design constraints -- FlowDoc focuses on explicit, readable business flows:
- Dynamic decorator arguments: Use literal strings (
@step(name="Process")) rather than variables - Dynamic dispatch:
getattr(self, name)()is not traced -- use explicit method calls - External object calls:
processor.handle()is not followed unless that object's methods are also decorated - Indirect references: Passing functions as arguments is not traced -- use explicit
if/else
❓ Troubleshooting
Graphviz not found
FlowDoc requires the Graphviz system package for PNG/SVG/PDF output. Install it with:
- macOS:
brew install graphviz - Ubuntu/Debian:
sudo apt-get install graphviz - Windows: Download from graphviz.org
Mermaid and DOT formats do not require Graphviz.
No flows found
Ensure your source file contains functions or methods decorated with @step. If using class-based flows, the class must also have the @flow decorator. FlowDoc only analyzes @step and @flow decorators -- it does not detect undecorated functions.
Dynamic decorator arguments
FlowDoc only supports literal string arguments in decorators. This works:
@step(name="Process Order") # literal string
This does not:
step_name = "Process Order"
@step(name=step_name) # variable -- not supported
Use literal strings in all decorator arguments for FlowDoc to detect them.
ImportError when running CLI
If you see ModuleNotFoundError: No module named 'flowdoc' after installation:
# Ensure you're using the correct Python environment
python -m flowdoc --version
# Or reinstall in your active environment
pip install --force-reinstall flowdoc
🛠️ Development
Setup
# Install uv (if needed)
curl -LsSf https://astral.sh/uv/install.sh | sh
# Install dependencies
uv sync
# Install in development mode
uv pip install -e .
Testing
# Run all tests
uv run pytest
# Run with coverage
uv run pytest --cov=flowdoc --cov-report=term-missing
# Run a specific test
uv run pytest tests/test_parser.py::test_class_flow_parsing
Code quality
# Format
uv run ruff format .
# Lint (with auto-fix)
uv run ruff check . --fix
# Type check
uv run ty check flowdoc/
Project Structure
flowdoc/
├── flowdoc/
│ ├── __init__.py # Public API exports
│ ├── decorators.py # @flow and @step decorators
│ ├── parser.py # AST analysis and flow extraction
│ ├── generator.py # Graphviz and Mermaid diagram generators
│ ├── validator.py # Flow validation logic
│ └── cli.py # CLI (Click-based)
├── tests/ # pytest test suite
├── examples/ # Example flows
├── pyproject.toml
└── LICENSE # MIT
🤝 Contributing
Contributions are welcome. To get started:
- Fork the repository and create a feature branch
- Install development dependencies with
uv sync - Make your changes, adding tests for new functionality
- Ensure all checks pass:
uv run pytest,uv run ruff check .,uv run ty check flowdoc/ - Submit a pull request
Please keep decorators minimal, avoid executing user code, and treat validation as advisory (warnings, not errors).
📄 License
MIT -- see LICENSE for details.
Project details
Release history Release notifications | RSS feed
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 flowdoc-0.0.0rc1.tar.gz.
File metadata
- Download URL: flowdoc-0.0.0rc1.tar.gz
- Upload date:
- Size: 276.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3017917a75e9a9b07e8a5148006717ba553d8eb895788b8633d64987a715229c
|
|
| MD5 |
35b681c5bded12ed5da533d338ca112f
|
|
| BLAKE2b-256 |
a373030dd85fdb7db132dd82f4607e51875e87a3442acf998daedd71a5ef160d
|
Provenance
The following attestation bundles were made for flowdoc-0.0.0rc1.tar.gz:
Publisher:
release.yml on jharibo/flowdoc
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
flowdoc-0.0.0rc1.tar.gz -
Subject digest:
3017917a75e9a9b07e8a5148006717ba553d8eb895788b8633d64987a715229c - Sigstore transparency entry: 873636788
- Sigstore integration time:
-
Permalink:
jharibo/flowdoc@448cdcab71077a0fc4755a5efdde80126d79572c -
Branch / Tag:
refs/heads/main - Owner: https://github.com/jharibo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@448cdcab71077a0fc4755a5efdde80126d79572c -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file flowdoc-0.0.0rc1-py3-none-any.whl.
File metadata
- Download URL: flowdoc-0.0.0rc1-py3-none-any.whl
- Upload date:
- Size: 17.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3110f768a0e8f0932a21fb11782cce7a7adef1ec1943c29ad7897a01f8e1ccd6
|
|
| MD5 |
4af0eb6d9e17cb2b4e9bcf6b0e9f54d7
|
|
| BLAKE2b-256 |
631cec2dbac224366b5f0b592704661c87f27a7c7dad5d43fe1a3acff9b6328e
|
Provenance
The following attestation bundles were made for flowdoc-0.0.0rc1-py3-none-any.whl:
Publisher:
release.yml on jharibo/flowdoc
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
flowdoc-0.0.0rc1-py3-none-any.whl -
Subject digest:
3110f768a0e8f0932a21fb11782cce7a7adef1ec1943c29ad7897a01f8e1ccd6 - Sigstore transparency entry: 873636833
- Sigstore integration time:
-
Permalink:
jharibo/flowdoc@448cdcab71077a0fc4755a5efdde80126d79572c -
Branch / Tag:
refs/heads/main - Owner: https://github.com/jharibo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@448cdcab71077a0fc4755a5efdde80126d79572c -
Trigger Event:
workflow_dispatch
-
Statement type: