FastAPI
FastAPI is a modern, fast (high-performance) Web framework for building APIs with Python, based on standard Python type hints. Key features include:
- Fast: Very high performance, on par with NodeJS and Go (thanks to Starlette and Pydantic)
- Efficient Coding: Increases the speed of feature development by approximately 200% to 300%
- Fewer bugs: Reduces approximately 40% of human (developer) induced errors
- Intelligent: Great editor support with completion everywhere, reducing debugging time
- Simple: Designed to be easy to use and learn, requiring less time reading documentation
- Automatic Documentation: Automatically generates interactive API documentation
This guide describes how to deploy FastAPI applications on CloudBase HTTP cloud functions.
Prerequisites
Before you begin, ensure that you have:
- Installed Python 3.10 or a later version
- Have a Tencent Cloud account and have activated the CloudBase service
- Have a basic knowledge of Python and FastAPI development
Step 1: Create a FastAPI Project
💡 Note: If you already have a FastAPI project, you can skip this step.
Create the project directory
mkdir fastapi-cloudbase
cd fastapi-cloudbase
Create application files
Create the app.py file, which is the entry file of the application:
from fastapi import FastAPI, HTTPException, Query
from pydantic import BaseModel
from typing import List, Optional
import uvicorn
app = FastAPI(
title="FastAPI CloudBase Demo",
description="A FastAPI application running on CloudBase HTTP Functions",
version="1.0.0"
)
# Data Model
class User(BaseModel):
id: int
name: str
email: str
age: Optional[int] = None
class UserCreate(BaseModel):
name: str
email: str
age: Optional[int] = None
# Mock Database
users_db = [
User(id=1, name="Zhang San", email="zhangsan@example.com", age=25),
User(id=2, name="Li Si", email="lisi@example.com", age=30),
User(id=3, name="Wang Wu", email="wangwu@example.com", age=28)
]
@app.get("/")
async def root():
"""Root path handler function"""
return {
"message": "Hello from FastAPI on CloudBase!",
"framework": "FastAPI",
"docs": "/docs",
"redoc": "/redoc"
}
@app.get("/health")
async def health_check():
"""Health Check Endpoint"""
return {
"status": "healthy",
"framework": "FastAPI",
"version": "1.0.0"
}
@app.get("/api/users", response_model=List[User])
async def get_users(
page: int = Query(1, ge=1, description="Page number"),
limit: int = Query(10, ge=1, le=100, description="Items per page")
):
"""Obtain user list (supports pagination)"""
start_index = (page - 1) * limit
end_index = start_index + limit
paginated_users = users_db[start_index:end_index]
return paginated_users
@app.get("/api/users/{user_id}", response_model=User)
async def get_user(user_id: int):
"""Obtain user by ID"""
user = next((user for user in users_db if user.id == user_id), None)
if not user:
raise HTTPException(status_code=404, detail="User not found")
return user
@app.post("/api/users", response_model=User, status_code=201)
async def create_user(user: UserCreate):
"""Create New User"""
# Checking whether the email already exists
if any(u.email == user.email for u in users_db):
raise HTTPException(status_code=400, detail="Email already registered")
# Generate New ID
new_id = max(u.id for u in users_db) + 1 if users_db else 1
# Create New User
new_user = User(id=new_id, **user.dict())
users_db.append(new_user)
return new_user
@app.put("/api/users/{user_id}", response_model=User)
async def update_user(user_id: int, user_update: UserCreate):
"""Update User Information"""
user_index = next((i for i, u in enumerate(users_db) if u.id == user_id), None)
if user_index is None:
raise HTTPException(status_code=404, detail="User not found")
# Check whether the email is already in use by another user
if any(u.email == user_update.email and u.id != user_id for u in users_db):
raise HTTPException(status_code=400, detail="Email already registered")
# Update User
updated_user = User(id=user_id, **user_update.dict())
users_db[user_index] = updated_user
return updated_user
@app.delete("/api/users/{user_id}")
async def delete_user(user_id: int):
"""Delete User"""
user_index = next((i for i, u in enumerate(users_db) if u.id == user_id), None)
if user_index is None:
raise HTTPException(status_code=404, detail="User not found")
deleted_user = users_db.pop(user_index)
return {"message": f"User {deleted_user.name} deleted successfully"}
# Custom Exception Handling
@app.exception_handler(404)
async def not_found_handler(request, exc):
return {"error": "Not Found", "message": "The requested resource was not found"}
@app.exception_handler(500)
async def internal_error_handler(request, exc):
return {"error": "Internal Server Error", "message": "Something went wrong"}
if __name__ == "__main__":
# CloudBase HTTP cloud function requires listening on port 9000
uvicorn.run(app, host="0.0.0.0", port=9000)
Create dependency file
Create the requirements.txt file:
fastapi==0.104.1
uvicorn[standard]==0.24.0
pydantic==1.10.2
💡 Note:
fastapi: FastAPI frameworkuvicorn: ASGI server for running FastAPI applicationspydantic: Data validation and serialization library, use version 1.x to avoid pydantic_core dependency
Step 2: Local Testing
⚠️ Important: CloudBase HTTP cloud functions require the application to listen on port 9000.
Set up the virtual environment
# Create a virtual environment
python -m venv venv
# Activate the virtual environment
# Linux/macOS
source venv/bin/activate
# Windows
# venv\Scripts\activate
Install dependencies
pip install -r requirements.txt
Starting Up the Application
# Method 1: Direct Run
python app.py
# Method 2: Using the uvicorn command
uvicorn app:app --host 0.0.0.0 --port 9000 --reload
Testing API
After the application starts up, you can test it in the following ways:
Access documentation:
- Swagger UI:
http://localhost:9000/docs - ReDoc:
http://localhost:9000/redoc
Test API endpoints:
# Test the Root Path
curl http://localhost:9000/
# Test Health Check
curl http://localhost:9000/health
# Test User List
curl http://localhost:9000/api/users
# Test Pagination
curl "http://localhost:9000/api/users?page=1&limit=2"
# Test Obtaining a Single User
curl http://localhost:9000/api/users/1
# Test Creating a User
curl -X POST http://localhost:9000/api/users \
-H "Content-Type: application/json" \
-d '{"name":"New User","email":"newuser@example.com","age":25}'
# Test Updating a User
curl -X PUT http://localhost:9000/api/users/1 \
-H "Content-Type: application/json" \
-d '{"name":"Updated User","email":"updated@example.com","age":26}'
Step 3: Create the Startup Script
💡 Note:
- When creating the
scf_bootstrapfile on windows, it is recommended to use- When creating the
scf_bootstrapfile using vscode on windows, deploying to an HTTP cloud function may result in an error:scf_bootstrapfile does not exist- This error occurs because the script file contains Windows-style carriage returns (^M), causing Linux to fail to recognize the interpreter path correctly. This is a common issue in WSL
Create the scf_bootstrap file (with no extension):
#!/bin/bash
# Set the Python dependency loading path, which defaults to the third_party directory
export PYTHONPATH="./third_party:$PYTHONPATH"
/var/lang/python310/bin/python3.10 -m uvicorn app:app --host 0.0.0.0 --port 9000
Grant execute permissions to the startup script:
chmod +x scf_bootstrap
💡 Note:
scf_bootstrapis the startup script for CloudBase cloud functions- Use uvicorn to start the FastAPI application
- Ensure the application listens on port 9000
Step 4: Prepare Deployment Files
Before deployment, install dependencies to the third_party directory:
⚠️ Note:
- HTTP cloud functions do not automatically install Python dependencies, so we need to manually download them into the code package
pip install -r requirements.txt -t third_party
Ensure your project directory structure is as follows:
fastapi-cloudbase/
├── third_party/ # Third-party dependencies
├── app.py # Application main file
├── requirements.txt # Dependencies list
└── scf_bootstrap # Startup script
Step 5: Deploy to CloudBase HTTP cloud function
Deploy via the console
- Log in to the CloudBase console
- Select your environment and go to the cloud function page
- Click "New Cloud Function"
- Select "HTTP cloud function"
- Fill in the function name (such as:
fastapi-app) - Select runtime: Python 3.10
- Select submit method: Local folder upload
- Select the project root directory to upload the function code
- Automatic dependency installation: Enable this option
- Click the "Create" button and wait for deployment to complete
Deploy via CLI
For details, see Deploy HTTP cloud function
Package and deploy
If you need to package manually:
# Create deployment package (excluding virtual environment)
zip -r fastapi-app.zip third_party app.py scf_bootstrap
Step 6: Access Your Application
After successful deployment, you can refer to Accessing Cloud Functions via HTTP to set up custom domain access to the
You can access the following endpoints:
- Root path:
/- Welcome message - API Documentation:
/docs- Swagger UI documentation - Alternative documentation:
/redoc- ReDoc documentation - Health Check:
/health- Application Status - User API:
/api/users- RESTful User Interface
Frequently Asked Questions
Q: Why must port 9000 be used?
A: CloudBase HTTP cloud functions require the application to listen on port 9000, which is the standard configuration of the platform.
Q: Can FastAPI's automatic documentation work properly when deployed to cloud functions?
A: Yes, FastAPI's Swagger UI and ReDoc documentation can be accessed and used normally in cloud functions.
Q: How to handle static files?
A: FastAPI can handle static files through the StaticFiles middleware or utilize CDN services.
Q: How to view application logs?
A: On the Cloud Functions page of the CloudBase console, click the function name to go to the details page and view the runtime logs.
Q: Which Python versions are supported?
A: CloudBase supports Python versions 3.6, 3.7, 3.9, and 3.10, with Python 3.10 recommended.
Best Practices
1. Environment Variable Management
import os
from fastapi import FastAPI
# Use environment variables
DEBUG = os.getenv("DEBUG", "False").lower() == "true"
SECRET_KEY = os.getenv("SECRET_KEY", "your-secret-key")
app = FastAPI(debug=DEBUG)
2. Database Integration
# Use SQLAlchemy
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
DATABASE_URL = os.getenv("DATABASE_URL", "sqlite:///./test.db")
engine = create_engine(DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
3. Middleware Configuration
from fastapi.middleware.cors import CORSMiddleware
from fastapi.middleware.gzip import GZipMiddleware
# CORS Configuration
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Gzip Compression
app.add_middleware(GZipMiddleware, minimum_size=1000)
4. Log Configuration
import logging
# Configure logging
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
)
logger = logging.getLogger(__name__)
5. Dependency Injection
from fastapi import Depends
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
@app.get("/api/users")
async def get_users(db: Session = Depends(get_db)):
return db.query(User).all()
Advanced Features
1. Authentication
pip install "python-jose[cryptography]" "passlib[bcrypt]" python-multipart
2. Background Tasks
from fastapi import BackgroundTasks
@app.post("/send-email/")
async def send_email(background_tasks: BackgroundTasks):
background_tasks.add_task(send_email_task, "user@example.com")
return {"message": "Email sent in background"}
3. WebSocket Support
from fastapi import WebSocket
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
while True:
data = await websocket.receive_text()
await websocket.send_text(f"Message: {data}")
Next steps
- Learn more about HTTP cloud function configuration options
- Learn how to connect to CloudBase database