Python Beginner’s Guide - FastAPI Backend Setup#
What is Python & FastAPI?#
Python#
Python is a high-level, easy-to-read programming language that’s perfect for beginners. It’s used for web development, data analysis, artificial intelligence, and more.
FastAPI#
FastAPI is a modern web framework for building APIs (Application Programming Interfaces) with Python. It’s:
Fast to write and fast to run
Automatically generates API documentation
Has built-in validation and type checking
Our Tech Stack#
FastAPI: Web framework for building the API
SQLModel: Database models and queries (built on SQLAlchemy + Pydantic)
Celery: Background task processing
Redis: In-memory database for caching and task queues
PostgreSQL: Main database for storing data
Docker: Containerization for easy deployment
uv: Modern Python package manager
Prerequisites#
Required Software#
Docker Desktop: Download here
Python 3.12+: Download here
uv Package Manager: Installation guide
Git: Download here
Visual Studio Code: Download here (recommended editor)
VS Code Extensions (Recommended)#
Python extension by Microsoft
Python Debugger
Docker extension
Thunder Client (for API testing)
Setting Up Your Development Environment#
Step 1: Clone the Repository#
# Navigate to your desired directory
cd "C:\Users\shwnd\Desktop\LB_LocalCopy\Coding"
# Clone the project (if not already done)
git clone <your-repository-url> app-capanel-web
cd app-capanel-web
Step 2: Install uv (Python Package Manager)#
# On Windows (PowerShell)
irm https://astral.sh/uv/install.ps1 | iex
# On macOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
Step 3: Set Up the Backend Environment#
# Navigate to the backend directory
cd backend
# Install all Python dependencies
uv sync
# Activate the virtual environment
# On Windows:
.venv\Scripts\activate
# On macOS/Linux:
source .venv/bin/activate
Step 4: Start the Development Environment#
# Go back to the root directory
cd ..
# Start all services with Docker Compose
docker compose up -d
# Watch for changes (recommended during development)
docker compose watch
Step 5: Verify Everything Works#
Open your browser and go to
http://localhost/docsYou should see the FastAPI automatic documentation (Swagger UI)
Try the “Hello World” endpoint to make sure it’s working
Understanding the Project Structure#
backend/
├── app/ # Main application code
│ ├── api/ # API endpoints
│ │ └── routes/ # Individual route files
│ │ ├── census.py # Census data endpoints
│ │ ├── items.py # Items endpoints
│ │ ├── login.py # Authentication endpoints
│ │ └── users.py # User management endpoints
│ ├── core/ # Core configuration
│ │ ├── config.py # App settings
│ │ ├── db.py # Database connection
│ │ └── security.py # Security utilities
│ ├── crud/ # Database operations
│ │ ├── crud_census.py # Census data CRUD
│ │ ├── crud_item.py # Items CRUD
│ │ └── crud_user.py # User CRUD
│ ├── models/ # Database models
│ │ └── models.py # SQLModel definitions
│ ├── tests/ # Unit tests
│ └── main.py # Application entry point
├── alembic/ # Database migrations
├── scripts/ # Utility scripts
└── pyproject.toml # Python dependencies and config
Working with the Census Data API#
Understanding the Census Data Flow#
Database Model (
app/models/models.py):class CensusData(SQLModel, table=True): id: int | None = Field(default=None, primary_key=True) school_name: str total_enr: int # This is what the frontend displays academic_year: str charter: str # ... other fields
CRUD Operations (
app/crud/crud_census.py):def get_total_enrollment(db: Session) -> int: """Calculate total enrollment across all schools""" result = db.exec(select(func.sum(CensusData.total_enr))).first() return result or 0
API Endpoint (
app/api/routes/census.py):@router.get("/censusdata") def get_census_data(db: Session = Depends(get_db)): """Get census data for the dashboard""" total = get_total_enrollment(db) return { "data": {"total_enr": total}, "status": "success" }
The Complete Data Journey#
Database: PostgreSQL stores the census records
CRUD Function: Calculates the total enrollment sum
API Endpoint: Returns the data in JSON format
Frontend: Fetches and displays the data
Step-by-Step Tutorial#
Tutorial 1: Adding a New Field to Census Data#
Let’s add a district_name field to our census data.
Step 1: Update the Database Model#
# In app/models/models.py
class CensusData(SQLModel, table=True):
id: int | None = Field(default=None, primary_key=True)
school_name: str
district_name: str # ← Add this new field
total_enr: int
academic_year: str
charter: str
# ... other existing fields
Step 2: Create a Database Migration#
# Make sure you're in the backend directory and virtual env is active
cd backend
# Create a new migration
docker compose exec backend bash
alembic revision --autogenerate -m "Add district_name to CensusData"
# Apply the migration
alembic upgrade head
Step 3: Update the CRUD Function#
# In app/crud/crud_census.py
def get_census_by_district(db: Session, district_name: str) -> list[CensusData]:
"""Get all census data for a specific district"""
statement = select(CensusData).where(CensusData.district_name == district_name)
return db.exec(statement).all()
Step 4: Add a New API Endpoint#
# In app/api/routes/census.py
@router.get("/censusdata/district/{district_name}")
def get_district_census_data(
district_name: str,
db: Session = Depends(get_db)
):
"""Get census data for a specific district"""
data = get_census_by_district(db, district_name)
if not data:
raise HTTPException(status_code=404, detail="District not found")
return {
"data": [school.model_dump() for school in data],
"status": "success"
}
Tutorial 2: Creating a New API Endpoint from Scratch#
Let’s create an endpoint to get the average enrollment per district.
Step 1: Create the CRUD Function#
# In app/crud/crud_census.py
def get_average_enrollment_by_district(db: Session) -> list[dict]:
"""Calculate average enrollment by district"""
statement = (
select(
CensusData.district_name,
func.avg(CensusData.total_enr).label("avg_enrollment"),
func.count(CensusData.id).label("school_count")
)
.group_by(CensusData.district_name)
.order_by(func.avg(CensusData.total_enr).desc())
)
results = db.exec(statement).all()
return [
{
"district_name": row[0],
"average_enrollment": round(float(row[1]), 2),
"school_count": row[2]
}
for row in results
]
Step 2: Create the API Endpoint#
# In app/api/routes/census.py
@router.get("/censusdata/districts/averages")
def get_district_averages(db: Session = Depends(get_db)):
"""Get average enrollment by district"""
try:
data = get_average_enrollment_by_district(db)
return {
"data": data,
"status": "success",
"count": len(data)
}
except Exception as e:
raise HTTPException(
status_code=500,
detail=f"Error calculating district averages: {str(e)}"
)
Step 3: Test Your New Endpoint#
Start your development server:
docker compose watchGo to
http://localhost/docsFind your new endpoint in the documentation
Click “Try it out” and test it
Common Python Concepts#
1. Type Hints#
# Type hints help catch errors and make code clearer
def calculate_total(numbers: list[int]) -> int:
return sum(numbers)
# Optional types
def get_user_name(user_id: int) -> str | None:
# Returns either a string or None
pass
2. List Comprehensions#
# Instead of:
results = []
for item in data:
if item.is_active:
results.append(item.name)
# You can write:
results = [item.name for item in data if item.is_active]
3. Dictionary Operations#
# Creating dictionaries
user_data = {
"name": "John Doe",
"email": "john@example.com",
"age": 30
}
# Safe access with .get()
email = user_data.get("email", "no-email@example.com") # Provides default
4. Error Handling#
try:
result = risky_operation()
return {"data": result, "status": "success"}
except ValueError as e:
# Handle specific error types
raise HTTPException(status_code=400, detail=f"Invalid data: {e}")
except Exception as e:
# Handle any other errors
raise HTTPException(status_code=500, detail=f"Server error: {e}")
5. Working with Databases#
# SQLModel/SQLAlchemy patterns
from sqlmodel import Session, select
def get_items_by_user(db: Session, user_id: int):
# Create a query
statement = select(Item).where(Item.user_id == user_id)
# Execute and get results
items = db.exec(statement).all()
return items
Debugging and Troubleshooting#
Common Error Messages and Solutions#
1. “ModuleNotFoundError: No module named ‘xxx’”#
Problem: A Python package is not installed.
# Solution: Install the missing package
uv add package-name
# Or sync all dependencies
uv sync
2. “ImportError: attempted relative import with no known parent package”#
Problem: Python can’t find your modules.
# Solution: Make sure you're running from the correct directory
cd backend
python -m app.main # Use module syntax
3. Database Connection Errors#
Problem: Can’t connect to the database.
# Solution: Make sure Docker services are running
docker compose up -d
# Check if database is ready
docker compose logs db
4. “uvicorn command not found”#
Problem: Virtual environment is not activated.
# Solution: Activate the virtual environment
# Windows:
.venv\Scripts\activate
# macOS/Linux:
source .venv/bin/activate
Debugging Tools#
1. Print Debugging#
def my_function(data):
print(f"Input data: {data}") # Debug print
result = process_data(data)
print(f"Processed result: {result}") # Debug print
return result
2. Python Debugger (pdb)#
import pdb
def problematic_function():
some_code()
pdb.set_trace() # Execution will pause here
more_code()
3. FastAPI Error Details#
FastAPI automatically provides detailed error messages. Check:
Browser console for frontend errors
Terminal logs for backend errors
http://localhost/docsfor API documentation
4. Docker Logs#
# View logs for all services
docker compose logs
# View logs for specific service
docker compose logs backend
# Follow logs in real-time
docker compose logs -f backend
Testing Your APIs#
1. Using the Browser#
Go to
http://localhost/docsfor interactive documentationTest endpoints directly in the browser
2. Using curl#
# Test GET endpoint
curl http://localhost/api/v1/censusdata
# Test POST endpoint with JSON data
curl -X POST http://localhost/api/v1/items \
-H "Content-Type: application/json" \
-d '{"title": "Test Item", "description": "Test description"}'
3. Using Python requests#
import requests
# Test your API from Python
response = requests.get("http://localhost/api/v1/censusdata")
print(response.json())
Next Steps#
1. Learn More Python#
Official Python Tutorial: https://docs.python.org/3/tutorial/
Automate the Boring Stuff: https://automatetheboringstuff.com/
Python Crash Course: Great book for beginners
2. FastAPI Deep Dive#
FastAPI Tutorial: https://fastapi.tiangolo.com/tutorial/
SQLModel Tutorial: https://sqlmodel.tiangolo.com/tutorial/
Advanced FastAPI: Dependency injection, middleware, background tasks
3. Database Skills#
SQL Basics: Learn SELECT, INSERT, UPDATE, DELETE
PostgreSQL Documentation: https://www.postgresql.org/docs/
Database Design: Normalization, relationships, indexes
4. Testing#
# Example test for your API
import pytest
from fastapi.testclient import TestClient
from app.main import app
client = TestClient(app)
def test_get_census_data():
response = client.get("/api/v1/censusdata")
assert response.status_code == 200
assert "data" in response.json()
5. Production Deployment#
Learn about Docker containers
Environment variables and configuration
Database migrations
Monitoring and logging
Helpful Commands Reference#
Python/uv Commands#
# Create new virtual environment
uv venv
# Install dependencies
uv sync
# Add new package
uv add package-name
# Remove package
uv remove package-name
# Run Python script
uv run python script.py
# Activate virtual environment
source .venv/bin/activate # macOS/Linux
.venv\Scripts\activate # Windows
Docker Commands#
# Start all services
docker compose up -d
# Watch for changes during development
docker compose watch
# View logs
docker compose logs backend
# Execute command in running container
docker compose exec backend bash
# Stop all services
docker compose down
# Clean up (removes data!)
docker compose down -v
Database Commands#
# Create new migration
alembic revision --autogenerate -m "Description of changes"
# Apply migrations
alembic upgrade head
# View migration history
alembic history
# Rollback one migration
alembic downgrade -1
## Getting Help
Resources#
Project Documentation: Read the README files in each directory
FastAPI Docs: https://fastapi.tiangolo.com/
Python Docs: https://docs.python.org/3/
Stack Overflow: Search for specific error messages
GitHub Issues: Check if others have had similar problems
When Asking for Help#
Include the full error message
Describe what you were trying to do
Share the relevant code
Mention your operating system and Python version
Remember: Everyone starts as a beginner! Take your time, read error messages carefully, and don’t be afraid to experiment. The best way to learn programming is by doing.