mirror of
https://github.com/humanlayer/humanlayer.git
synced 2025-08-20 19:01:22 +03:00
HumanLayer FastAPI Example
This example demonstrates how to use AsyncHumanLayer with FastAPI to create an API with human-in-the-loop approval flows.
Overview
The example shows how to:
- Use AsyncHumanLayer with FastAPI endpoints
- Handle human approvals for API operations
- Process both approved and denied responses
- Structure async API endpoints with human-in-the-loop flows
Setup
-
Create a virtual environment and activate it:
python -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate -
Install dependencies:
pip install -r requirements.txt -
Copy
.env.exampleto.envand fill in your API keys:cp .env.example .env # Add your keys to .env: # HUMANLAYER_API_KEY=your_key_here # OPENAI_API_KEY=your_key_here
Code Structure
The main application (app.py) shows how to:
-
Initialize AsyncHumanLayer:
from humanlayer import AsyncHumanLayer hl = AsyncHumanLayer(verbose=True) -
Create functions requiring approval:
@hl.require_approval() async def multiply(a: int, b: int) -> int: return a * b -
Handle approvals in endpoints:
@app.post("/math/multiply") async def math_multiply(a: int, b: int) -> Dict[str, str | int]: result = await multiply(a, b) if isinstance(result, str): # Handle denial message return {"status": "denied", "message": result} return {"status": "success", "result": result} or, with fetch_approval @app.post("/math/multiply") async def math_multiply(a: int, b: int) -> Dict[str, str | int]: approval_result = await hl.fetch_approval( FunctionCallSpec( fn="multiply", kwargs={"a": a, "b": b}, ) ) if not approval_result.approved: return {"status": "denied", "message": result} result = await multiply(a, b) return {"status": "success", "result": result}
Running the Application
Start the server:
python app.py
# Or
uvicorn app:app --reload
Testing Endpoints
Using curl:
# Test multiplication
curl -X POST "http://localhost:8000/math/multiply?a=5&b=3"
# Test division
curl -X POST "http://localhost:8000/math/divide?a=10&b=2"
Or you can ask a question to the human in an asyncio/fastapi compatible way:
curl -X POST "http://localhost:8000/ask-question?question=what+is+the+weather+in+tokyo"
Response Formats
Successful operation:
{
"status": "success",
"result": 15
}
Denied operation:
{
"status": "denied",
"message": "User denied multiply with message: Not allowed"
}
Key Features
- Async operations with human approval
- Error handling for denials and failures
- Type hints and proper response handling
- Health check endpoint with approval flow
- CORS middleware for API access
- Swagger UI at
/docs
Notes
- Operations requiring approval can be handled in two ways:
- Using the
@hl.require_approval()decorator - Using
hl.fetch_approval()to explicitly check approval before execution
- Using the
- When using
fetch_approval(), checkapproval_result.approvedto handle approvals/denials - The health check demonstrates a complete approval flow
- Responses should handle both successful operations and denials