Deploy a Python App using OpenFaaS: Serverless Functions Made Simple
Learn how to deploy serverless Python functions using OpenFaaS. Build, deploy, and scale your functions with Docker containers and focus on code, not infrastructure.
Deploy a Python App using OpenFaaS: Serverless Functions Made Simple
OpenFaaS (Functions as a Service) provides a powerful framework for building serverless functions on top of containers. With OpenFaaS, developers can focus on writing code rather than managing servers and deployments.
What is OpenFaaS?
OpenFaaS transforms any container into a serverless function. Key benefits include:
- Pay-per-execution: Only pay for actual computation time
- Auto-scaling: Functions scale based on demand
- Language agnostic: Support for multiple programming languages
- Docker-based: Runs on Docker Swarm or Kubernetes
Note: If you haven't installed OpenFaaS yet, follow the installation guide before proceeding.
Building Your First Python Function
Let's create a simple Python function that calculates the sum of numbers.
Step 1: Project Setup
Create a new directory for your project:
mkdir myapp && cd myapp
Download the official templates:
faas-cli template pull
Step 2: Create Function Scaffold
Use the FaaS CLI to create a new Python function:
faas-cli new --lang python3 elements-sum --prefix="<your-docker-username>"
This creates the following structure:
./elements-sum.yml # Function configuration
./elements-sum/
├── handler.py # Your function code
└── requirements.txt # Python dependencies
Step 3: Implement the Function Logic
The default handler.py contains a simple echo function:
def handle(req):
"""handle a request to the function
Args:
req (str): request body
"""
return req
Let's modify it to calculate the sum of comma-separated numbers:
def handle(req):
"""Calculate sum of comma-separated numbers
Args:
req (str): comma-separated numbers (e.g., "10,20,30")
Returns:
str: sum of the numbers
"""
try:
# Parse comma-separated values
numbers = [int(x.strip()) for x in req.split(",")]
# Calculate sum
total = sum(numbers)
return str(total)
except ValueError:
return "Error: Please provide valid comma-separated numbers"
except Exception as e:
return f"Error: {str(e)}"
Step 4: Add Dependencies (Optional)
If your function requires additional Python packages, add them to requirements.txt:
# Add any required packages here
# requests==2.28.1
# numpy==1.21.0
Deployment
Build, Push, and Deploy
Deploy your function with a single command:
faas-cli up -f elements-sum.yml
This command:
- Builds the Docker image
- Pushes it to Docker Hub
- Deploys the function to OpenFaaS
Tip: If you encounter authentication errors, login to Docker Hub first:
docker login
Verify Deployment
Once deployed, your function will be available at the OpenFaaS UI: http://127.0.0.1:8080/ui/
Testing Your Function
Using the Web UI
- Navigate to the OpenFaaS UI
- Select your
elements-sumfunction - Enter test input:
10,20,30,40,50 - Click Invoke
- Expected output:
150
Using the CLI
Test your function from the command line:
echo "10,20,30,40,50" | faas-cli invoke elements-sum
Using cURL
Make HTTP requests directly:
curl -X POST http://127.0.0.1:8080/function/elements-sum \
-H "Content-Type: text/plain" \
-d "10,20,30,40,50"
Advanced Function Features
Environment Variables
Add environment variables to your function configuration:
# elements-sum.yml
version: 1.0
provider:
name: openfaas
gateway: http://127.0.0.1:8080
functions:
elements-sum:
lang: python3
handler: ./elements-sum
image: <your-username>/elements-sum:latest
environment:
DEBUG: "true"
MAX_NUMBERS: "100"
Function Annotations
Configure resource limits and scaling:
functions:
elements-sum:
# ... other config
annotations:
com.openfaas.scale.min: "1"
com.openfaas.scale.max: "10"
com.openfaas.scale.factor: "20"
limits:
memory: "128Mi"
cpu: "100m"
requests:
memory: "64Mi"
cpu: "50m"
Best Practices
1. Error Handling
Always implement proper error handling:
def handle(req):
try:
# Your function logic
result = process_request(req)
return result
except ValidationError as e:
return f"Validation Error: {str(e)}"
except Exception as e:
# Log error for debugging
print(f"Unexpected error: {str(e)}")
return "Internal Server Error"
2. Input Validation
Validate input data before processing:
import json
def handle(req):
try:
# Parse JSON input
data = json.loads(req)
# Validate required fields
if 'numbers' not in data:
return json.dumps({"error": "Missing 'numbers' field"})
# Process valid input
numbers = data['numbers']
result = sum(numbers)
return json.dumps({"sum": result})
except json.JSONDecodeError:
return json.dumps({"error": "Invalid JSON format"})
3. Performance Optimization
- Keep functions lightweight and focused
- Minimize cold start times
- Use connection pooling for databases
- Cache frequently used data
Monitoring and Logging
Function Metrics
OpenFaaS provides built-in metrics for:
- Invocation count
- Response time
- Error rate
- Replica count
Custom Logging
Add structured logging to your functions:
import json
import sys
from datetime import datetime
def log(level, message, **kwargs):
log_entry = {
"timestamp": datetime.utcnow().isoformat(),
"level": level,
"message": message,
**kwargs
}
print(json.dumps(log_entry), file=sys.stderr)
def handle(req):
log("INFO", "Function invoked", input_length=len(req))
try:
result = process_request(req)
log("INFO", "Function completed successfully")
return result
except Exception as e:
log("ERROR", "Function failed", error=str(e))
raise
Conclusion
OpenFaaS provides an excellent platform for deploying serverless Python functions. With its Docker-based approach, you get:
- Flexibility: Use any Python libraries
- Portability: Run anywhere Docker runs
- Scalability: Auto-scale based on demand
- Simplicity: Focus on code, not infrastructure
Start building your serverless functions today and experience the power of FaaS architecture!
Next Steps
- Explore more OpenFaaS templates
- Integrate with databases and external APIs
- Set up CI/CD pipelines for function deployment
- Monitor function performance in production