angreal.integrations.flox
Cross-language development environment and services management powered by Flox.
Overview
Section titled “Overview”Angreal’s Flox integration provides environment activation and services management using Flox, a Nix-based development environment manager. It activates a Flox environment — applying its environment variables to the current process — and manages the declarative background services defined in the environment’s manifest.toml.
Prerequisites
Section titled “Prerequisites”Flox CLI must be installed before using this integration.
Installation:
# macOScurl -fsSL https://flox.dev/install | bash
# Linuxcurl -fsSL https://flox.dev/install | bash
# Verify installationflox --versionCreating a Flox Environment:
cd your-projectflox initflox install python@3.11 nodejs@20Functions
Section titled “Functions”flox_required
Section titled “flox_required”Decorator that wraps a function to run in a Flox environment with optional services.
flox_required(path=None, services=None)Parameters:
path(str | Path, optional): Path to Flox environment. Defaults to current directory.services(List[str], optional): Services to start before execution.
Example:
from angreal.integrations.flox import flox_requiredimport angreal
@angreal.command(name="test")@flox_required(".", services=["postgres"])def run_tests(): """Run tests with Flox environment and Postgres service.""" import subprocess subprocess.run(["pytest", "-v"])
# Without services@angreal.command(name="build")@flox_required(".")def build(): """Build in Flox environment.""" import subprocess subprocess.run(["npm", "run", "build"])The decorator:
- Activates the Flox environment
- Starts specified services (if any)
- Executes the wrapped function
- Stops services and deactivates environment (even on exception)
Classes
Section titled “Classes”Main class for managing Flox environments.
from angreal.integrations.flox import Flox
flox = Flox(path=".")Constructor
Section titled “Constructor”Flox(path=None)Parameters:
path(str | Path, optional): Path to Flox environment. Defaults to current directory.
Properties
Section titled “Properties”exists
Section titled “exists”Check if the Flox environment exists (.flox/ directory present).
@propertydef exists(self) -> boolReturns:
bool: True if.flox/directory exists
has_manifest
Section titled “has_manifest”Check if the environment has a manifest file.
@propertydef has_manifest(self) -> boolReturns:
bool: True if.flox/env/manifest.tomlexists
Get the environment path.
@propertydef path(self) -> PathReturns:
Path: Absolute path to the Flox environment
services
Section titled “services”Get a FloxServices manager for this environment.
@propertydef services(self) -> FloxServicesReturns:
FloxServices: Services manager instance
Instance Methods
Section titled “Instance Methods”activate
Section titled “activate”Activate the Flox environment in the current Python process.
def activate(self) -> NoneModifies os.environ to include Flox environment variables. Changes persist until deactivate() is called.
Raises:
RuntimeError: If the environment does not exist
Example:
flox = Flox(".")flox.activate()# Environment variables now include Flox paths# FLOX_ENV, PATH, etc. are modifiedflox.deactivate()deactivate
Section titled “deactivate”Restore the original environment.
def deactivate(self) -> NoneRestores all environment variables to their state before activation. Safe to call multiple times.
Execute a command within the Flox environment.
def run(command: str, args: List[str] = None) -> tuple[int, str, str]Parameters:
command(str): Command to executeargs(List[str], optional): Command arguments
Returns:
tuple[int, str, str]: (exit_code, stdout, stderr)
Example:
flox = Flox(".")exit_code, stdout, stderr = flox.run("python", ["--version"])print(f"Python version: {stdout}")Context Manager Support
Section titled “Context Manager Support”Flox supports the context manager protocol for automatic activation/deactivation:
with Flox(".") as flox: # Environment is activated exit_code, stdout, _ = flox.run("node", ["--version"]) print(f"Node version: {stdout}")# Environment is automatically deactivatedClass Methods
Section titled “Class Methods”is_available
Section titled “is_available”Check if Flox CLI is installed.
@classmethoddef is_available() -> boolReturns:
bool: True iffloxcommand is available in PATH
Example:
if not Flox.is_available(): print("Please install Flox: curl -fsSL https://flox.dev/install | bash")version
Section titled “version”Get Flox version string.
@classmethoddef version() -> strReturns:
str: Flox version (e.g., “1.2.0”)
Raises:
RuntimeError: If Flox is not installed
FloxServices
Section titled “FloxServices”Manages Flox services for an environment.
from angreal.integrations.flox import FloxServices
services = FloxServices(".")# Or via Flox instanceservices = Flox(".").servicesMethods
Section titled “Methods”Start services and return a handle for later cleanup.
def start(*services: str) -> FloxServiceHandleParameters:
*services: Service names to start. If empty, starts all services.
Returns:
FloxServiceHandle: Handle for managing started services
Example:
services = FloxServices(".")handle = services.start("postgres", "redis")# Services are running...handle.stop()Stop all services in the environment.
def stop() -> Nonestatus
Section titled “status”Get status of all services.
def status() -> List[ServiceInfo]Returns:
List[ServiceInfo]: List of service status objects
Example:
for svc in services.status(): print(f"{svc.name}: {svc.status} (PID: {svc.pid})")Get logs for a service.
def logs(service: str, follow: bool = False, tail: int = None) -> strParameters:
service(str): Service namefollow(bool): Follow log output (default: False)tail(int, optional): Number of lines from end
Returns:
str: Log output
restart
Section titled “restart”Restart services.
def restart(*services: str) -> NoneParameters:
*services: Service names to restart. If empty, restarts all.
FloxServiceHandle
Section titled “FloxServiceHandle”Handle for managing started services across sessions.
Properties
Section titled “Properties”flox_env_path(Path): Path to the Flox environmentservices(List[ServiceInfo]): List of service info objectsstarted_at(str): ISO timestamp when services were started
Methods
Section titled “Methods”Stop the services tracked by this handle.
def stop() -> NoneSave handle to JSON file for later restoration.
def save(path: str = None) -> NoneParameters:
path(str, optional): File path. Defaults to.flox-services.json
Example:
handle = services.start("postgres")handle.save() # Saves to .flox-services.json# Later, in another session...handle = FloxServiceHandle.load()handle.stop()load (classmethod)
Section titled “load (classmethod)”Load handle from JSON file.
@classmethoddef load(path: str = None) -> FloxServiceHandleParameters:
path(str, optional): File path. Defaults to.flox-services.json
Returns:
FloxServiceHandle: Loaded handle
ServiceInfo
Section titled “ServiceInfo”Information about a service.
Attributes
Section titled “Attributes”name(str): Service namestatus(str): Status (e.g., “Running”, “Stopped”)pid(int | None): Process ID if running
Methods
Section titled “Methods”as_tuple
Section titled “as_tuple”Convert to tuple format.
def as_tuple() -> tuple[str, str, int | None]Returns:
tuple: (name, status, pid)
Examples
Section titled “Examples”Full Development Workflow
Section titled “Full Development Workflow”from angreal.integrations.flox import Flox, flox_requiredimport angreal
# Check Flox availability at module loadif not Flox.is_available(): print("Warning: Flox not installed. Some commands may not work.")
@angreal.command(name="setup")def setup(): """Initialize Flox environment.""" import subprocess subprocess.run(["flox", "init"]) subprocess.run(["flox", "install", "python@3.11", "nodejs@20", "postgresql"])
@angreal.command(name="test")@flox_required(".", services=["postgres"])def test(): """Run tests with database.""" import subprocess result = subprocess.run(["pytest", "-v", "tests/"]) return result.returncode
@angreal.command(name="dev")@flox_required(".", services=["postgres", "redis"])def dev(): """Start development server.""" import subprocess subprocess.run(["python", "manage.py", "runserver"])
@angreal.command(name="build")@flox_required(".")def build(): """Build the project.""" flox = Flox(".") exit_code, stdout, stderr = flox.run("npm", ["run", "build"]) if exit_code != 0: print(f"Build failed: {stderr}") return 1 print("Build successful") return 0Service Status Dashboard
Section titled “Service Status Dashboard”from angreal.integrations.flox import Floximport angreal
@angreal.command(name="status")def status(): """Show Flox environment and service status.""" flox = Flox(".")
print(f"Flox version: {Flox.version()}") print(f"Environment exists: {flox.exists}") print(f"Has manifest: {flox.has_manifest}") print(f"Path: {flox.path}") print()
print("Services:") for svc in flox.services.status(): pid_info = f"PID {svc.pid}" if svc.pid else "no PID" print(f" {svc.name}: {svc.status} ({pid_info})")See Also
Section titled “See Also”- Virtual Environment Integration - Python venv integration
- Docker Compose Integration - Docker integration
- Flox Documentation - Official Flox documentation