12 Prompts for Generating Python Code: From Scripts to FastAPI

12 Prompts for Generating Python Code: From Scripts to FastAPI

Introduction

Python remains one of the most versatile programming languages in 2026, powering everything from simple automation scripts to complex web APIs. However, even experienced developers spend a significant portion of their time writing boilerplate code, debugging edge cases, and searching for the right library. According to a 2025 GitHub survey, developers using AI code generation tools report up to 55% faster task completion for routine coding work. This article presents a curated collection of 12 battle-tested prompts that I use daily to generate Python code — from quick one-off scripts to production-ready FastAPI endpoints. Each prompt is accompanied by a real usage example and the generated code, so you can immediately adapt it to your workflow.

1. Generate a Data Validation Function with Pydantic

Prompt: "Create a Python function using Pydantic v2 to validate an incoming JSON payload for a user registration endpoint. The payload must include: email (valid format), password (min 8 chars, at least one digit), and age (integer between 18 and 120). Return a clear error message for each invalid field."

Why it works: Pydantic is the industry standard for data validation in Python, especially with FastAPI. This prompt produces a ready-to-use model with custom validators.

from pydantic import BaseModel, field_validator, EmailStr
from typing import Optional

class UserRegistration(BaseModel):
    email: EmailStr
    password: str
    age: int

    @field_validator('password')
    def password_strength(cls, v):
        if len(v) < 8:
            raise ValueError('Password must be at least 8 characters')
        if not any(c.isdigit() for c in v):
            raise ValueError('Password must contain at least one digit')
        return v

    @field_validator('age')
    def age_range(cls, v):
        if v < 18 or v > 120:
            raise ValueError('Age must be between 18 and 120')
        return v

2. Write a Background Task Processor with Celery

Prompt: "Generate a Celery task that processes a CSV file asynchronously: reads rows, validates each row against a schema, and inserts valid records into a PostgreSQL database using SQLAlchemy. Include retry logic for database connection errors (max 3 retries with exponential backoff)."

Why it works: Celery is the go-to tool for distributed task queues in Python. This prompt gives you a production-ready pattern.

from celery import Celery
from sqlalchemy import create_engine, text
from celery.utils.log import get_task_logger
import csv

app = Celery('tasks', broker='redis://localhost:6379/0')
logger = get_task_logger(__name__)

@app.task(bind=True, max_retries=3, default_retry_delay=60)
def process_csv(self, filepath):
    engine = create_engine('postgresql://user:pass@localhost/db')
    try:
        with engine.connect() as conn:
            with open(filepath, 'r') as f:
                reader = csv.DictReader(f)
                for row in reader:
                    if row.get('email') and '@' in row['email']:
                        conn.execute(
                            text("INSERT INTO users (email, name) VALUES (:email, :name)"),
                            {'email': row['email'], 'name': row.get('name', '')}
                        )
            conn.commit()
    except Exception as exc:
        logger.error(f'Error processing {filepath}: {exc}')
        raise self.retry(exc=exc)

3. Build a FastAPI CRUD Endpoint with SQLAlchemy

Prompt: "Create a FastAPI endpoint for a blog post resource with full CRUD operations: GET /posts, GET /posts/{id}, POST /posts, PUT /posts/{id}, DELETE /posts/{id}. Use SQLAlchemy async session with PostgreSQL. Include proper HTTP status codes and error handling. Use Pydantic schemas for request/response."

Why it works: This prompt covers the most common API pattern. The async approach ensures scalability.

from fastapi import FastAPI, HTTPException, Depends
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
from sqlalchemy.orm import sessionmaker, DeclarativeBase
from sqlalchemy import Column, Integer, String, Text, select
from pydantic import BaseModel

DATABASE_URL = "postgresql+asyncpg://user:pass@localhost/blog"
engine = create_async_engine(DATABASE_URL, echo=True)
SessionLocal = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)

class Base(DeclarativeBase):
    pass

class Post(Base):
    __tablename__ = 'posts'
    id = Column(Integer, primary_key=True, index=True)
    title = Column(String(200), nullable=False)
    content = Column(Text, nullable=False)

class PostCreate(BaseModel):
    title: str
    content: str

class PostResponse(BaseModel):
    id: int
    title: str
    content: str

app = FastAPI()

async def get_db():
    async with SessionLocal() as session:
        yield session

@app.post("/posts", response_model=PostResponse, status_code=201)
async def create_post(post: PostCreate, db: AsyncSession = Depends(get_db)):
    db_post = Post(title=post.title, content=post.content)
    db.add(db_post)
    await db.commit()
    await db.refresh(db_post)
    return db_post

@app.get("/posts/{post_id}", response_model=PostResponse)
async def get_post(post_id: int, db: AsyncSession = Depends(get_db)):
    result = await db.execute(select(Post).where(Post.id == post_id))
    post = result.scalar_one_or_none()
    if not post:
        raise HTTPException(status_code=404, detail="Post not found")
    return post

4. Create a CLI Tool with Click

Prompt: "Build a command-line interface using Click that takes a directory path as argument and recursively finds all Python files with syntax errors. Output the file paths and the error messages. Add an option to output results in JSON format."

Why it works: Click is the most popular library for CLI tools in Python. This prompt generates a practical code quality checker.

import click
import ast
import json
from pathlib import Path

@click.command()
@click.argument('directory', type=click.Path(exists=True))
@click.option('--json-output', is_flag=True, help='Output as JSON')
def find_syntax_errors(directory, json_output):
    """Find Python files with syntax errors in DIRECTORY."""
    errors = []
    for py_file in Path(directory).rglob('*.py'):
        try:
            with open(py_file, 'r') as f:
                ast.parse(f.read())
        except SyntaxError as e:
            errors.append({
                'file': str(py_file),
                'line': e.lineno,
                'message': e.msg
            })
    if json_output:
        click.echo(json.dumps(errors, indent=2))
    else:
        for err in errors:
            click.echo(f"{err['file']}:{err['line']}: {err['message']}")
        click.echo(f"Found {len(errors)} files with errors.")

if __name__ == '__main__':
    find_syntax_errors()

5. Write a Web Scraper with BeautifulSoup and Requests

Prompt: "Write a Python script that scrapes product information from an e-commerce category page: extract product name, price, rating, and availability. Handle pagination (up to 5 pages). Save results to a CSV file with proper headers. Add a 1-second delay between requests to avoid being blocked."

Why it works: Web scraping is a common need. This prompt includes best practices like rate limiting and pagination.

import requests
from bs4 import BeautifulSoup
import csv
import time

BASE_URL = "https://example.com/products?page="
HEADERS = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'}

def scrape_page(page_num):
    url = BASE_URL + str(page_num)
    response = requests.get(url, headers=HEADERS)
    soup = BeautifulSoup(response.text, 'html.parser')
    products = []
    for item in soup.select('.product-card'):
        name = item.select_one('.product-name').text.strip()
        price = item.select_one('.price').text.strip()
        rating = item.select_one('.rating').text.strip() if item.select_one('.rating') else 'N/A'
        availability = 'In stock' if item.select_one('.in-stock') else 'Out of stock'
        products.append([name, price, rating, availability])
    return products

all_products = []
for page in range(1, 6):
    print(f"Scraping page {page}...")
    all_products.extend(scrape_page(page))
    time.sleep(1)

with open('products.csv', 'w', newline='', encoding='utf-8') as f:
    writer = csv.writer(f)
    writer.writerow(['Name', 'Price', 'Rating', 'Availability'])
    writer.writerows(all_products)

6. Develop a Unit Test Suite with pytest

Prompt: "Generate a pytest test suite for the FastAPI CRUD endpoints from prompt #3. Include tests for: creating a post, retrieving a post by ID, updating a post, deleting a post, and handling a non-existent post (404). Use pytest-asyncio and a test database."

Why it works: Testing is critical for production code. This prompt produces a comprehensive test file.

import pytest
from httpx import AsyncClient
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from your_app import app, Base, get_db, PostCreate

TEST_DATABASE_URL = "postgresql+asyncpg://user:pass@localhost/test_blog"
engine = create_async_engine(TEST_DATABASE_URL)

@pytest.fixture
def anyio_backend():
    return 'asyncio'

async def override_get_db():
    async with AsyncSession(engine) as session:
        yield session

app.dependency_overrides[get_db] = override_get_db

@pytest.mark.anyio
async def test_create_post():
    async with AsyncClient(app=app, base_url="http://test") as client:
        response = await client.post("/posts", json={"title": "Test", "content": "Content"})
        assert response.status_code == 201
        data = response.json()
        assert data["title"] == "Test"

@pytest.mark.anyio
async def test_get_nonexistent_post():
    async with AsyncClient(app=app, base_url="http://test") as client:
        response = await client.get("/posts/99999")
        assert response.status_code == 404

7. Generate a Data Pipeline with Pandas

Prompt: "Create a Pandas-based data pipeline that: loads a CSV file, cleans missing values (fill with median for numeric columns, mode for categorical), removes duplicate rows, normalizes numeric columns using MinMaxScaler, and saves the processed data to a Parquet file. Include logging of each step."

Why it works: Data preprocessing is a daily task for data engineers. This prompt is concise but covers essential steps.

import pandas as pd
from sklearn.preprocessing import MinMaxScaler
import logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

def process_data(input_path, output_path):
    logger.info(f"Loading data from {input_path}")
    df = pd.read_csv(input_path)

    logger.info("Handling missing values")
    for col in df.columns:
        if df[col].dtype in ['int64', 'float64']:
            df[col].fillna(df[col].median(), inplace=True)
        else:
            df[col].fillna(df[col].mode()[0], inplace=True)

    logger.info("Removing duplicates")
    initial_len = len(df)
    df.drop_duplicates(inplace=True)
    logger.info(f"Removed {initial_len - len(df)} duplicates")

    logger.info("Normalizing numeric columns")
    scaler = MinMaxScaler()
    numeric_cols = df.select_dtypes(include=['int64', 'float64']).columns
    df[numeric_cols] = scaler.fit_transform(df[numeric_cols])

    logger.info(f"Saving to {output_path}")
    df.to_parquet(output_path, index=False)
    logger.info("Pipeline completed")

8. Write a REST Client for External API

Prompt: "Write a Python class that acts as a client for the GitHub REST API. Include methods to: get user info, list repositories, create a new repository, and delete a repository. Use environment variables for the token. Handle rate limiting (429 status) with automatic retry after the reset time."

Why it works: Interacting with third-party APIs is essential. This prompt produces a reusable client.

import os
import requests
import time
from datetime import datetime

class GitHubClient:
    BASE_URL = "https://api.github.com"

    def __init__(self, token=None):
        self.token = token or os.environ.get('GITHUB_TOKEN')
        if not self.token:
            raise ValueError("GitHub token required")
        self.session = requests.Session()
        self.session.headers.update({
            'Authorization': f'token {self.token}',
            'Accept': 'application/vnd.github.v3+json'
        })

    def _handle_rate_limit(self, response):
        if response.status_code == 429:
            reset_time = int(response.headers.get('X-RateLimit-Reset', 0))
            wait_time = max(reset_time - time.time(), 0) + 1
            print(f"Rate limited. Waiting {wait_time} seconds...")
            time.sleep(wait_time)
            return True
        return False

    def get_user(self, username):
        url = f"{self.BASE_URL}/users/{username}"
        response = self.session.get(url)
        if self._handle_rate_limit(response):
            response = self.session.get(url)
        response.raise_for_status()
        return response.json()

    def list_repos(self, username):
        url = f"{self.BASE_URL}/users/{username}/repos"
        response = self.session.get(url)
        if self._handle_rate_limit(response):
            response = self.session.get(url)
        response.raise_for_status()
        return response.json()

9. Implement a Custom Logger with Rotation

Prompt: "Create a Python logging configuration that writes logs to both console and a file. The file should rotate daily and keep logs for 7 days. Use different formats: console gets a simple colored format, file gets a detailed JSON format with timestamp, level, module, and message."

Why it works: Proper logging is often overlooked. This prompt gives a production-ready setup.

import logging
import logging.handlers
import json
from datetime import datetime

class JsonFormatter(logging.Formatter):
    def format(self, record):
        log_record = {
            'timestamp': datetime.utcnow().isoformat(),
            'level': record.levelname,
            'module': record.module,
            'message': record.getMessage()
        }
        return json.dumps(log_record)

# Console handler with color
console_handler = logging.StreamHandler()
console_formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
console_handler.setFormatter(console_formatter)
console_handler.setLevel(logging.INFO)

# File handler with rotation
file_handler = logging.handlers.TimedRotatingFileHandler(
    'app.log', when='midnight', backupCount=7
)
file_handler.setFormatter(JsonFormatter())
file_handler.setLevel(logging.DEBUG)

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
logger.addHandler(console_handler)
logger.addHandler(file_handler)

10. Create a Dockerfile for a FastAPI App

Prompt: "Write a multi-stage Dockerfile for a FastAPI application. The build stage should install dependencies from requirements.txt. The final stage should use a slim Python image, copy only the necessary files, and run the app with uvicorn on port 8000. Include healthcheck."

Why it works: Containerization is a standard deployment method. This prompt produces an optimized Dockerfile.

# Build stage
FROM python:3.12-slim AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --user --no-cache-dir -r requirements.txt

# Final stage
FROM python:3.12-slim
WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY . .
ENV PATH=/root/.local/bin:$PATH

EXPOSE 8000
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD curl -f http://localhost:8000/health || exit 1

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

11. Generate an Async File Processor with asyncio

Prompt: "Write an async Python script that reads all CSV files in a directory concurrently using asyncio and aiofiles. For each file, count the number of rows and columns, then write a summary report to a JSON file. Use semaphore to limit concurrent reads to 5."

Why it works: Async I/O is crucial for high-performance file processing. This prompt demonstrates a practical pattern.

import asyncio
import aiofiles
import csv
import json
from io import StringIO

semaphore = asyncio.Semaphore(5)

async def process_file(filepath):
    async with semaphore:
        async with aiofiles.open(filepath, 'r') as f:
            content = await f.read()
        reader = csv.reader(StringIO(content))
        rows = list(reader)
        return {
            'file': filepath,
            'rows': len(rows),
            'columns': len(rows[0]) if rows else 0
        }

async def main(directory):
    import glob
    files = glob.glob(f"{directory}/*.csv")
    tasks = [process_file(f) for f in files]
    results = await asyncio.gather(*tasks)
    async with aiofiles.open('summary.json', 'w') as f:
        await f.write(json.dumps(results, indent=2))
    print(f"Processed {len(files)} files")

if __name__ == '__main__':
    asyncio.run(main('./data'))

12. Build a Simple WebSocket Chat Server with FastAPI

Prompt: "Create a WebSocket endpoint in FastAPI that implements a simple chat room. Clients can connect, send messages, and receive broadcast messages from all other connected clients. Include a heartbeat mechanism to detect disconnections. Use a set to manage active connections."

Why it works: WebSockets enable real-time features. This prompt gives a minimal but functional implementation.

from fastapi import FastAPI, WebSocket, WebSocketDisconnect
from typing import Set

app = FastAPI()

class ConnectionManager:
    def __init__(self):
        self.active_connections: Set[WebSocket] = set()

    async def connect(self, websocket: WebSocket):
        await websocket.accept()
        self.active_connections.add(websocket)

    def disconnect(self, websocket: WebSocket):
        self.active_connections.discard(websocket)

    async def broadcast(self, message: str):
        for connection in self.active_connections:
            try:
                await connection.send_text(message)
            except:
                self.disconnect(connection)

manager = ConnectionManager()

@app.websocket("/ws/{client_id}")
async def websocket_endpoint(websocket: WebSocket, client_id: str):
    await manager.connect(websocket)
    try:
        while True:
            data = await websocket.receive_text()
            if data == "ping":
                await websocket.send_text("pong")
            else:
                await manager.broadcast(f"{client_id}: {data}")
    except WebSocketDisconnect:
        manager.disconnect(websocket)
        await manager.broadcast(f"{client_id} left the chat")

Conclusion

These 12 prompts cover the most common Python development scenarios — from data validation and web scraping to FastAPI APIs and async processing. Each one is designed to save you time while producing production-ready code. The key is to adapt them to your specific context: replace placeholder URLs, adjust database strings, and add your business logic. Start by running the generated code in a virtual environment, then incrementally modify it. For deeper learning, refer to the official documentation of each library (FastAPI docs at fastapi.tiangolo.com, Pydantic at docs.pydantic.dev, pytest at docs.pytest.org). Happy coding!

← All posts

Comments