A lightweight, intelligent worker system for creating, compiling, running, and managing Python-based processes.
Procyl simplifies the management of isolated Python workers with automatic dependency detection, environment management, and parallel execution support.
- π§ Automatic Dependency Detection - Scans code for external packages (not stdlib)
- π― Smart Environment Management - One-time environment setup via
procyl.prepare() - π Multiple Execution Modes - Python source, PyInstaller, or Nuitka compilation
- β‘ Parallel Execution - Run workers multiple times simultaneously
- π Rich Metadata - Access worker info via
.dataproperty - π‘οΈ Verification - Built-in worker integrity checks
- π¦ Minimal Footprint - Lightweight, disk-efficient design
- π Version Control - Support for specific package versions and requirements files
pip install procylFor compilation support:
pip install procyl[compile]Workers are Python functions executed in isolated processes:
import procyl
# Create a simple worker
worker = procyl.create(
"greet",
'''
import sys
print(f"Hello, {sys.argv[1]}!")
'''
)Install all dependencies used by workers:
# Automatic - scans all workers
procyl.prepare()
# With specific versions
procyl.prepare(constraints={
"requests": "==2.32.3",
"numpy": ">=2.3,<3"
})
# From requirements file
procyl.prepare(requirements="requirements.txt")print(worker.data.hash) # Code hash
print(worker.data.compiler) # Compiler used
print(worker.data.compiled) # Compilation status
print(worker.data.dependencies) # External dependencies
print(worker.data.python_version) # Python version
print(worker.data.platform) # Platform info
print(worker.data.path) # Artifact path
print(worker.data.size) # Artifact size
print(worker.data.running) # Is running?result = worker.verify()
print(result)
# {
# 'name': 'greet',
# 'valid': True,
# 'issues': [],
# 'dependencies': ['requests', 'numpy']
# }# Single execution
output = procyl.run("greet", args=["Alice"])
# Multiple parallel executions
results = worker.run(count=8, args=["Bob"])
for output in results:
print(output)Create a new worker.
worker = procyl.create(
name: str, # Worker name
code: str, # Python code
icon: Optional[str] = None, # Icon path
args: Optional[List[str]] = None, # Default arguments
compiler: str = "auto", # python/pyinstaller/nuitka/auto
output_dir: Optional[str] = None, # Output directory
timeout_seconds: Optional[int] = None,
auto_delete_after: Optional[int] = None,
compile_args: Optional[List[str]] = None,
)Returns: Worker object
Prepare the Python environment with dependencies.
success = procyl.prepare(
constraints: Optional[Dict[str, str]] = None,
requirements: Optional[str] = None,
)Parameters:
constraints: Dict of package version constraintsrequirements: Path to requirements.txt file
Returns: bool - Success status
Access worker metadata (read-only).
Properties:
hash- SHA256 hash of code (16 chars)compiler- Compiler usedcompiled- Whether compiledcreated_at- Creation timestamplast_build- Last build timestampdependencies- Set of external package namespython_version- Python versionplatform- Platform stringpath- Path to artifactsize- Artifact size in bytespid- Process ID (if running)running- Whether currently running
Verify worker integrity.
result = worker.verify()
# Returns dict with:
# - 'name': worker name
# - 'valid': boolean
# - 'issues': list of issues
# - 'compiled': (optional)
# - 'artifact_size': (optional)
# - 'dependencies': (optional)Execute worker once or multiple times in parallel.
results = worker.run(
count: int = 1, # Number of parallel executions
args: Optional[List[str]] = None, # Arguments (overrides default)
)Returns: List[str] - List of outputs
Execute a worker by name.
output = procyl.run(
name: str,
args: Optional[List[str]] = None,
)Get worker status.
status = procyl.status(name: str)Delete a worker.
result = procyl.delete(name: str)Compile a worker ahead of time.
result = procyl.precompile(
name: str,
output_dir: Optional[str] = None,
compiler: Optional[str] = None,
thread: bool = False,
).procyl/ # Created by prepare()
βββ env/ # Python venv
β βββ bin/ # Python executables
β βββ lib/ # Installed packages
β βββ ...
βββ .metadata/ # Worker metadata
βββ metadata.json # Environment info
Procyl automatically scans code for external dependencies using AST analysis:
worker = procyl.create("demo", '''
import requests
import numpy as np
import sys # stdlib - ignored
import os # stdlib - ignored
print("Hello")
''')
print(worker.data.dependencies)
# Output: {'requests', 'numpy'}worker = procyl.create("compute", "print(sum(range(1000)))")
results = worker.run(count=8)
print(f"Computed {len(results)} times in parallel")procyl.prepare(constraints={
"tensorflow": "==2.13.0",
"numpy": "<2.0"
})worker = procyl.create("app", code)
procyl.precompile("app", compiler="pyinstaller", output_dir="./dist")See examples/demo.py for a comprehensive example:
python examples/demo.pyRun tests:
pytest tests/test_core_v1.py -vRun verification:
python verify.py- CHANGELOG_v1.md - What's new in v1.0.0
- MIGRATION_v1.md - Migration guide from v0.1.1
- README_v1.md - Full API documentation
MIT
yolezz
Procyl v1.0.0 - Intelligent Python Worker Management