How to Use uv with Integration Dependencies¶
uv is a fast Python package manager that simplifies running OAA Runner integrations with custom dependencies. This guide explains how to manage integration requirements using uv, so your integration’s requirements.txt dependencies are automatically installed and available at runtime.
TL;DR¶
If your integration has a requirements.txt file (e.g., custom Python modules that need external libraries):
cd /path/to/integration
uv tool run --with-requirements=requirements.txt --from oaa-runner \
oaa app run --config-file=config.yaml --save-json
That’s it. uv installs dependencies and runs the integration without needing a virtual environment.
When You Need This¶
Your integration needs requirements.txt if:
✅ Your custom modules import external libraries (e.g.,
import pandas,import requests)✅ You have a
modules/folder with custom fetch functions✅ Your hooks use third-party libraries
Example requirements.txt:
requests==2.31.0
pandas==2.1.0
pyyaml==6.0
If your integration only uses standard library + oaa-runner, you don’t need requirements.txt.
Setup: Create requirements.txt¶
If you don’t have a requirements.txt yet:
cd /path/to/integration
# Create empty file
touch requirements.txt
# Add your dependencies (one per line)
cat >> requirements.txt << EOF
requests==2.31.0
pandas==2.1.0
EOF
Or use uv to generate it from your environment:
# If you're developing locally
uv pip freeze > requirements.txt
Run Integration with Dependencies¶
Basic: Run with requirements.txt¶
uv tool run --with-requirements=requirements.txt --from oaa-runner \
oaa app run --config-file=config.yaml --save-json
What happens:
uv downloads oaa-runner from PyPI
uv installs dependencies from
requirements.txtinto a temporary environmentoaa app runs with all dependencies available
Temporary environment is cleaned up after
Dry-run with Dependencies¶
Test without pushing to Veza:
uv tool run --with-requirements=requirements.txt --from oaa-runner \
oaa app run --config-file=config.yaml --dry-run=True --save-json
No-push with Dependencies¶
Test against real API without pushing to Veza:
uv tool run --with-requirements=requirements.txt --from oaa-runner \
oaa app run --config-file=config.yaml --no-push=True --save-json
Multiple Requirements Files¶
If you have separate dev and prod requirements:
# Combine both files
uv tool run --with-requirements=requirements.txt \
--with-requirements=requirements-dev.txt \
--from oaa-runner \
oaa app run --config-file=config.yaml --save-json
Common Patterns¶
Environment Variables in setup¶
Before running, set your API credentials:
export API_KEY=your_key_here
export VEZA_URL=https://tenant.vezacloud.com
export VEZA_API_KEY=your_veza_key
uv tool run --with-requirements=requirements.txt --from oaa-runner \
oaa app run --config-file=config.yaml --save-json
Or load from .env:
# Create .env if not present
cat > .env << EOF
API_KEY=your_key_here
VEZA_URL=https://tenant.vezacloud.com
VEZA_API_KEY=your_veza_key
EOF
# Load and run
source .env
uv tool run --with-requirements=requirements.txt --from oaa-runner \
oaa app run --config-file=config.yaml --save-json
Pinning Versions in requirements.txt¶
For reproducibility, always pin exact versions:
# Good — reproducible
requests==2.31.0
pandas==2.1.0
pyyaml==6.0.1
# Avoid — may break later
requests
pandas
pyyaml
Checking What’s Installed¶
See what dependencies uv will install:
cat requirements.txt
Or test without running the integration:
uv tool run --with-requirements=requirements.txt python3 -c \
"import requests; print(requests.__version__)"
Troubleshooting¶
Error: “No such file or directory: requirements.txt”¶
Problem: requirements.txt doesn’t exist or is in wrong location.
Fix:
# Check file exists
ls requirements.txt
# Check you're in correct directory
pwd
ls -la | grep requirements.txt
Error: “Could not find a package with name X”¶
Problem: Package name is misspelled or doesn’t exist on PyPI.
Fix:
# Check spelling in requirements.txt
cat requirements.txt
# Verify package exists on PyPI
python3 -c "import requests; print(requests.__version__)"
# Update requirements.txt with correct name
Error: “Version X of package Y not found”¶
Problem: Pinned version doesn’t exist on PyPI.
Fix:
# Find available versions
uv pip search package_name
# Update requirements.txt with available version
cat requirements.txt | grep package_name
Error: “Module X not found” at runtime¶
Problem: Custom module imports library not in requirements.txt.
Fix:
# Check what modules import
grep -r "^import\|^from" modules/
# Add missing imports to requirements.txt
cat >> requirements.txt << EOF
missing_package==1.0.0
EOF
# Re-run with updated requirements.txt
Memory Issues with Large Integrations¶
If integration fails due to memory, uv can optimize dependency installation:
# Reduce downloaded dependencies
uv pip install --no-cache-dir -q -r requirements.txt
# Then run
uv tool run --with-requirements=requirements.txt --from oaa-runner \
oaa app run --config-file=config.yaml --save-json
Advanced: Custom Python Version¶
If integration requires specific Python version:
# Use Python 3.9
uv tool run --python 3.9 --with-requirements=requirements.txt \
--from oaa-runner \
oaa app run --config-file=config.yaml --save-json
Best Practices¶
✅ Do¶
Pin exact versions —
requests==2.31.0notrequestsKeep requirements.txt minimal — only add what you need
Test locally first — run with
--dry-run=Truebefore pushingDocument dependencies — add comments explaining why each package is needed
Example with comments:
# API client library
requests==2.31.0
# Data transformation
pandas==2.1.0
# Configuration parsing
pyyaml==6.0
❌ Don’t¶
Pin oaa-runner — uv handles that via
--from oaa-runnerMix local + PyPI — keep requirements.txt PyPI-only
Use setup.py — stick with requirements.txt for integrations
Forget to update — bump versions periodically for security
Integration Lifecycle¶
Phase 1: Development¶
# Create integration
uv tool run --from oaa-runner oaa app gen_oaa --folder-location . my_app
# Test with dependencies
uv tool run --with-requirements=my_app/requirements.txt --from oaa-runner \
oaa app run --config-file=my_app/config.yaml --dry-run=True --save-json
Phase 2: Testing¶
# Run against real API (no push)
uv tool run --with-requirements=requirements.txt --from oaa-runner \
oaa app run --config-file=config.yaml --no-push=True --save-json
# Inspect output
jq '.' output.json | head -50
Phase 3: Production¶
# Push to Veza
source .env
uv tool run --with-requirements=requirements.txt --from oaa-runner \
oaa app run --config-file=config.yaml --save-json