Category: Uncategorized

  • Python Anvil Full-Stack Web Development

    Python Anvil is reshaping the way developers build full‑stack web applications by letting you write both the front‑end and back‑end entirely in Python. Whether you’re a solo freelancer, a startup founder, or an enterprise team looking to accelerate delivery, Anvil’s drag‑and‑drop UI builder combined with a powerful Python runtime offers a low‑code, serverless experience without sacrificing flexibility. In this guide we’ll explore what makes Anvil unique, walk through a complete project workflow, and share best practices to help you create production‑ready web apps that rank well in search engines.

    Why Choose Anvil for Full‑Stack Development?

    All‑Python Stack

    • Front‑end: Design UI components with a visual editor or write custom HTML/CSS/JS, all while using Python for event handling.
    • Back‑end: Deploy server‑side code on Anvil’s managed cloud, write database queries in Python, and expose REST or GraphQL endpoints.
    • Data layer: Built‑in Data Tables act as a NoSQL database, and you can connect external services (PostgreSQL, MySQL, Firebase) via Python libraries.

    Rapid Prototyping + Production Readiness

    • Instant preview of UI changes without rebuilding or redeploying.
    • One‑click deployment to a secure, HTTPS‑enabled domain.
    • Scalable hosting on Anvil Cloud or your own Docker container.

    SEO‑Friendly Architecture

    Search engines love clean, semantic HTML and fast load times. Anvil lets you:

    • Inject custom <meta> tags, Open Graph data, and structured data (JSON‑LD) directly from Python.
    • Serve pre‑rendered pages using Server Modules for better crawlability.
    • Optimize assets with built‑in minification and CDN delivery.

    Getting Started: Setting Up Your First Anvil App

    Step 1 – Create an Account and New App

    1. Visit anvil.works and sign up for a free account.
    2. Click “New App”, choose a blank template or a pre‑built starter (e.g., “To‑Do List”).
    3. Name your app (e.g., my_first_anvil_app) and click “Create”.

    Step 2 – Design the UI with the Drag‑and‑Drop Builder

    In the visual editor you can add rows, columns, buttons, text boxes, and data tables. For SEO, give each component a descriptive id and class attribute so you can target them with CSS and add meaningful headings.

    Step 3 – Write Front‑End Logic in Python

    Each form has a corresponding Python file. Here’s a simple example that adds a new item to a list when a button is clicked:

    def add_button_click(self, **event_args):
        new_item = self.text_box.text
        if new_item:
            self.repeating_panel.items.append(new_item)
            self.text_box.text = ""
            self.refresh_data_bindings()
    

    Step 4 – Add a Server Module for Back‑End Operations

    Server modules run on Anvil’s cloud and can access external libraries. Below is a module that stores a user’s profile in the built‑in Data Table:

    @anvil.server.callable
    def save_user_profile(name, email):
        users = app_tables.users
        users.add_row(name=name, email=email, created=anvil.now())
        return "Profile saved"
    

    Step 5 – Connect Front‑End to Server Functions

    Use anvil.server.call to invoke back‑end code asynchronously, which improves page load speed and SEO metrics like Time to Interactive (TTI).

    def submit_profile_click(self, **event_args):
        name = self.name_input.text
        email = self.email_input.text
        result = anvil.server.call('save_user_profile', name, email)
        self.status_label.text = result
    

    Advanced Full‑Stack Features

    Custom HTTP Endpoints

    Anvil lets you expose Python functions as RESTful endpoints, perfect for integrating with mobile apps or third‑party services.

    @anvil.server.http_endpoint("/api/v1/items", methods=["GET"])
    def get_items():
        return [row['name'] for row in app_tables.items.search()]
    

    Integrating External APIs

    Because you have full Python access, you can use requests, httpx, or any async library. Example: fetching weather data from OpenWeatherMap.

    @anvil.server.callable
    def get_weather(city):
        import requests
        api_key = anvil.secrets.get_secret('OPENWEATHER_API_KEY')
        url = f"https://api.openweathermap.org/data/2.5/weather?q={city}&appid={api_key}"
        resp = requests.get(url).json()
        return {
            "temp": resp["main"]["temp"],
            "description": resp["weather"][0]["description"]
        }
    

    Database Migration and Scaling

    • Start with Anvil Data Tables for rapid prototyping.
    • When you need relational features, connect to an external PostgreSQL database via psycopg2 or SQLAlchemy in a Server Module.
    • Use Anvil’s Background Tasks to run long‑running jobs without blocking UI interactions.

    SEO Best Practices for Anvil Apps

    1. Semantic HTML and Proper Heading Structure

    Even though the UI is built visually, you can edit the generated HTML in the “Custom HTML” panel. Ensure you use <h2>, <h3>, and <p> tags appropriately, and avoid generic <div> wrappers for main content.

    2. Meta Tags and Open Graph

    @anvil.server.http_endpoint("/", methods=["GET"])
    def index():
        return anvil.server.render_template(
            "index.html",
            title="Python Anvil Full‑Stack Web Development",
            description="Learn how to build SEO‑friendly, production‑ready web apps using Python Anvil.",
            og_image="https://example.com/og-image.png"
        )
    

    3. Structured Data (JSON‑LD)

    Embedding structured data helps search engines understand your content. Add the following to the page’s <head>:

    <script type="application/ld+json">
    {
      "@context": "https://schema.org",
      "@type": "Article",
      "headline": "Python Anvil Full‑Stack Web Development",
      "author": {"@type": "Person", "name": "Your Name"},
      "datePublished": "2026-10-14",
      "image": "https://example.com/cover.jpg"
    }
    </script>
    

    4. Performance Optimizations

    • Enable Lazy Loading for images using the loading="lazy" attribute.
    • Compress static assets with GZIP or Brotli (handled automatically by Anvil’s CDN).
    • Minimize JavaScript by using Anvil’s built‑in components instead of custom scripts when possible.

    5. Accessibility (A11y) and Mobile‑First Design

    Google’s Core Web Vitals consider accessibility signals. Use proper aria- attributes, ensure contrast ratios meet WCAG 2.1 AA, and test your app with Lighthouse.

    Real‑World Use Cases

    Internal Dashboards

    Companies replace bulky Excel sheets with Anvil dashboards that pull data from ERP systems, offering real‑time charts via Plotly or Altair.

    Customer‑Facing Portals

    Build login‑protected portals for users to manage subscriptions, view invoices, and submit support tickets—all in a single Python codebase.

    Educational Platforms

    Instructors create interactive coding labs where students write Python directly in the browser, while the back‑end evaluates submissions on Anvil’s servers.

    Deploying and Maintaining Your Anvil Application

    One‑Click Production Deploy

    After testing, click “Publish” → “Deploy”. You can bind a custom domain (e.g., app.yourdomain.com) and enable automatic SSL certificates.

    Version Control with Anvil’s Git Integration

    • Export your app as a .zip or connect to a GitHub repository.
    • Use git push to sync changes, then deploy from the CI pipeline for continuous delivery.

    Monitoring and Logging

    Anvil’s console logs are searchable, and you can forward logs to external services like Sentry or Datadog for advanced monitoring.

    Tips & Tricks from the Anvil Community

    • Reuse Components: Create custom “Form Templates” for common UI patterns (cards, modals, navigation bars) and import them across projects.
    • Leverage Packages: Install third‑party Python packages directly from the “Packages” tab—great for adding p
  • Python Gradio Machine Learning Web Interface

    Creating a user‑friendly web interface for a machine‑learning model used to be a daunting task that required knowledge of front‑end frameworks, HTTP servers, and often a hefty amount of boilerplate code. Python Gradio changes the game by letting data scientists and developers spin up a polished, interactive UI with just a few lines of Python. In this guide we’ll explore how Gradio works, why it’s a top choice for building a machine learning web interface, and walk through a complete example—from local development to production deployment. Whether you’re showcasing a simple image classifier or launching a multi‑modal chatbot, Gradio provides the tools you need to turn code into a shareable web app in minutes.

    What Is Gradio and How Does It Fit Into the Python ML Stack?

    Gradio is an open‑source Python library that automatically generates web UIs for functions, models, or pipelines. It sits on top of Flask (or FastAPI under the hood) and abstracts away the HTTP layer, letting you focus on the core ML logic. Key characteristics include:

    • Zero‑code front‑end: No HTML, CSS, or JavaScript is required to get a functional UI.
    • Live preview: The interface updates instantly as you modify the underlying Python function.
    • Shareable links: Gradio can generate a public URL (via share=True) that can be accessed from any browser.
    • Integration with Hugging Face Spaces: Deploy directly to the cloud with a single click.

    Because it’s pure Python, Gradio integrates seamlessly with popular ML libraries such as TensorFlow, PyTorch, Scikit‑learn, and Hugging Face Transformers.

    Why Choose Gradio for a Machine Learning Web Interface?

    Speed and Simplicity

    Traditional web development often involves setting up routes, handling file uploads, and writing JavaScript callbacks. Gradio reduces that overhead to a single gr.Interface call. For rapid prototyping, this speed is invaluable.

    Rich Input & Output Components

    Gradio ships with over 30 built‑in components, including:

    • Image, audio, and video uploaders
    • Text boxes, sliders, and dropdowns
    • Dataframe viewers and markdown renderers

    These components are automatically rendered as HTML widgets, allowing you to test any data modality without extra code.

    Collaboration‑Ready

    With the share=True flag, Gradio creates a temporary HTTPS tunnel (powered by ngrok) and provides a public link. This makes it easy to gather feedback from teammates, stakeholders, or the wider community.

    Production‑Ready Options

    When you’re ready to go beyond a temporary tunnel, Gradio supports:

    1. Docker containerization for reproducible environments.
    2. Deployment to Hugging Face Spaces (free for public projects).
    3. Embedding as a component inside larger Flask or FastAPI apps.

    Installing and Setting Up Gradio

    Gradio can be installed via pip or conda. It’s recommended to use a virtual environment to keep dependencies isolated.

    # Using pip
    python -m venv venv
    source venv/bin/activate  # Windows: venv\Scripts\activate
    pip install gradio
    
    # Optional: install extra ML libraries
    pip install torch torchvision torchaudio  # for PyTorch models
    pip install transformers                 # for Hugging Face models
    

    After installation, verify the setup with a quick sanity check:

    python -c "import gradio as gr; print('Gradio version:', gr.__version__)"
    

    Building Your First Gradio Interface

    Let’s walk through a minimal example: a sentiment‑analysis model built with Hugging Face Transformers. The code below demonstrates the entire pipeline—from loading the model to launching the UI.

    import gradio as gr
    from transformers import pipeline
    
    # Load a pre‑trained sentiment analysis pipeline
    sentiment = pipeline("sentiment-analysis")
    
    def classify_text(text):
        """Return the sentiment label and confidence."""
        result = sentiment(text)[0]
        label = result["label"]
        score = round(result["score"], 3)
        return f"{label} ({score})"
    
    # Define Gradio interface
    iface = gr.Interface(
        fn=classify_text,
        inputs=gr.Textbox(lines=2, placeholder="Enter a sentence..."),
        outputs=gr.Label(num_top_classes=2),
        title="Simple Sentiment Analyzer",
        description="Enter any English sentence and get a sentiment prediction.",
        examples=[["I love using Gradio!"], ["This is terrible."]],
        theme="default"
    )
    
    # Launch with a shareable link
    if __name__ == "__main__":
        iface.launch(share=True)
    

    When you run this script, Gradio automatically creates a local web server, renders a clean UI, and provides a public URL you can share instantly.

    Advanced Features: Customizing the UI and Adding Logic

    Custom CSS and Theming

    Gradio allows you to inject custom CSS to match your brand or project style.

    custom_css = """
    body { background-color: #f8f9fa; }
    h1, h2 { color: #2c3e50; }
    """
    
    iface = gr.Interface(
        fn=classify_text,
        inputs=gr.Textbox(),
        outputs=gr.Label(),
        css=custom_css,
        theme="default"
    )
    

    Chaining Multiple Functions

    Complex applications often need a series of steps—pre‑processing, inference, post‑processing. Gradio’s Blocks API lets you chain components together.

    with gr.Blocks() as demo:
        gr.Markdown("# Multi‑Stage Image Classifier")
        with gr.Row():
            img_input = gr.Image(label="Upload an image")
            label_output = gr.Label(num_top_classes=3, label="Prediction")
        
        def preprocess(image):
            # Resize, normalize, etc.
            return processed_image
        
        def infer(processed_image):
            # Run model inference
            return model(processed_image)
        
        # Connect the pipeline
        processed = img_input.change(preprocess, inputs=img_input, outputs="temp")
        processed.then(infer, inputs="temp", outputs=label_output)
    
    demo.launch()
    

    Authentication and Rate Limiting

    For private demos, you can protect your Gradio app with a simple username/password pair.

    iface = gr.Interface(
        fn=classify_text,
        inputs=gr.Textbox(),
        outputs=gr.Label(),
        auth=("admin", "secret123")  # (username, password)
    )
    

    Deploying a Gradio App to Production

    Option 1: Hugging Face Spaces

    Spaces provide a free, managed environment for public Gradio apps. To deploy:

    1. Create a new Space on huggingface.co/spaces and select “Gradio”.
    2. Push your code and requirements.txt to the repository.
    3. The platform builds a Docker image automatically and serves your UI at https://<your‑space>.huggingface.co.

    Option 2: Docker & Cloud Providers

    If you need more control (private endpoints, custom domains, GPU support), containerize the app:

    # Dockerfile
    FROM python:3.11-slim
    WORKDIR /app
    COPY requirements.txt .
    RUN pip install --no-cache-dir -r requirements.txt
    COPY . .
    EXPOSE 7860
    CMD ["python", "app.py"]
    

    Build and push the image, then run it on services like AWS ECS, Google Cloud Run, or Azure Container Apps. Remember to set the environment variable GRADIO_SERVER_PORT=7860 if you need a custom port.

    Option 3: Embedding in Existing Flask/FastAPI Apps

    Gradio can be mounted as a sub‑application, allowing you to combine it with other APIs.

    from flask import Flask
    import gradio as gr
    
    app = Flask(__name__)
    
    # Define Gradio interface (as before)
    iface = gr.Interface(fn=classify_text, inputs=..., outputs=...)
    gradio_app = iface.launch(prevent_thread_lock=True, inline=True)
    
    # Mount Gradio at /demo
    app.mount("/demo", gradio_app)
    
    if __name__ == "__main__":
        app.run(port=5000)
    

    SEO Tips for a Gradio‑Powered Web Interface

    Even though Gradio generates HTML on the fly, you can still optimize for search engines:

    • Meta tags: Add <meta name="description" content="..."/> in the head of your HTML template if you embed Gradio in a larger page.
    • Descriptive titles: Use the title parameter in gr.Interface to set a clear, keyword‑rich page title.
    • Alt text for images: When
  • Python Streamlit Rapid Dashboard Tutorial

    Looking to turn raw data into a stunning, interactive web app in minutes? Python Streamlit makes it possible to build rapid dashboards without wrestling with HTML, CSS, or JavaScript. In this step‑by‑step tutorial you’ll learn how to set up a clean development environment, craft a fully functional dashboard, and deploy it with a single click. Whether you’re a data scientist, analyst, or developer, the techniques below will accelerate your workflow and boost your project’s visibility on search engines.

    What Is Streamlit and Why It’s Perfect for Rapid Dashboards

    Streamlit is an open‑source Python library that transforms scripts into shareable web apps. Its declarative API, built‑in caching, and seamless integration with popular data‑science packages (like pandas, numpy, plotly, and matplotlib) let you focus on logic rather than UI plumbing. Here’s why it’s a favorite for rapid dashboard development:

    • Zero‑HTML requirement – Write pure Python and Streamlit handles the front‑end.
    • Live reloading – Changes appear instantly, shortening the feedback loop.
    • Built‑in widgets – Sliders, select boxes, file uploaders, and more are ready to use.
    • One‑line deployment – Push to Streamlit Community Cloud or any cloud platform with minimal configuration.

    Setting Up Your Python Environment

    1. Install Streamlit

    First, create an isolated virtual environment to keep dependencies tidy. Open a terminal and run:

    python -m venv streamlit-env
    source streamlit-env/bin/activate  # macOS/Linux
    # .\streamlit-env\Scripts\activate   # Windows
    pip install --upgrade pip
    pip install streamlit pandas plotly
    

    2. Create a New Project Folder

    Organize your files for easy maintenance:

    • app.py – Main Streamlit script.
    • data/ – Store CSV or JSON files.
    • requirements.txt – Pin exact package versions.

    Generate requirements.txt after installing packages:

    pip freeze > requirements.txt

    Building Your First Dashboard Step‑by‑Step

    Import Libraries and Load Data

    Start app.py with the essential imports and a data load function. Using st.cache_data ensures the dataset is read only once, speeding up interactions.

    import streamlit as st
    import pandas as pd
    import plotly.express as px
    
    @st.cache_data
    def load_data(path):
        return pd.read_csv(path)
    
    df = load_data('data/iris.csv')
    

    Design the Layout with Columns and Sidebar

    Streamlit lets you split the page into columns, rows, and sidebars with just a few commands. Below is a common pattern for a clean dashboard:

    # Page title
    st.title('Iris Species Explorer')
    
    # Sidebar for filters
    st.sidebar.header('Filter Options')
    species = st.sidebar.multiselect(
        'Select species',
        options=df['species'].unique(),
        default=df['species'].unique()
    )
    
    # Main layout: two columns
    col1, col2 = st.columns(2)
    

    Add Interactive Widgets

    Widgets capture user input and automatically trigger a rerun of the script. Here’s a numeric slider that controls the size of plotted markers:

    marker_size = st.sidebar.slider('Marker size', 5, 20, 10)
    
    filtered_df = df[df['species'].isin(species)]
    

    Visualize Data with Charts

    Combine plotly.express with Streamlit’s st.plotly_chart to deliver responsive, zoomable visuals. The example below creates a scatter matrix that updates based on the sidebar filters.

    fig = px.scatter_matrix(
        filtered_df,
        dimensions=['sepal_length', 'sepal_width', 'petal_length', 'petal_width'],
        color='species',
        title='Iris Feature Relationships',
        height=600
    )
    fig.update_traces(marker=dict(size=marker_size))
    
    col1.plotly_chart(fig, use_container_width=True)
    

    In the second column you might want to show a summary table:

    col2.subheader('Statistical Summary')
    col2.dataframe(filtered_df.describe())
    

    Deploying the Dashboard to the Cloud

    Using Streamlit Community Cloud

    Streamlit Community Cloud (formerly Streamlit Sharing) offers a frictionless deployment pipeline:

    1. Push your project to a public GitHub repository.
    2. Log in to share.streamlit.io with your GitHub account.
    3. Click “New app”, select the repo, branch, and app.py as the entry point.
    4. Press “Deploy”. Streamlit automatically installs dependencies from requirements.txt and serves your app at a unique URL.

    Custom Domain and Continuous Deployment

    If you own a domain, you can map it to your Streamlit Cloud app using a CNAME record. For advanced CI/CD, connect the repo to GitHub Actions:

    name: Deploy Streamlit App
    on:
      push:
        branches: [ main ]
    jobs:
      build-deploy:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v3
          - name: Deploy to Streamlit Cloud
            uses: streamlit/streamlit-action@v1
            with:
              api_key: ${{ secrets.STREAMLIT_API_KEY }}
    

    This workflow redeploys your dashboard every time you push changes to the main branch, ensuring the live version stays up‑to‑date.

    Best Practices and Tips for Faster Development

    • Leverage caching wisely – Use st.cache_data for data loads and st.cache_resource for heavy model objects.
    • Modularize code – Split large scripts into reusable functions or separate modules (e.g., visuals.py, utils.py).
    • Keep UI responsive – Limit the number of heavy plots per rerun; consider st.spinner to show progress.
    • Write SEO‑friendly titles and meta tags – When embedding the app in a website, add <meta name="description" content="Python Streamlit rapid dashboard tutorial"> to improve search visibility.
    • Test locally before pushing – Run streamlit run app.py and use the “Rerun” button to catch errors early.

    Conclusion

    With just a few lines of Python, you can transform static datasets into interactive, shareable dashboards that look professional and load instantly. This tutorial covered everything from environment setup, core Streamlit components, and dynamic visualizations, to cloud deployment and best‑practice tips. By following the steps outlined above, you’ll be able to deliver data‑driven insights faster, keep stakeholders engaged, and boost your site’s SEO with keyword‑rich content. Ready to build your next rapid dashboard? Fire up streamlit run app.py and watch your ideas come to life in real time.

  • Python Fastapi Graphql Integration Tutorial

    FastAPI has quickly become a favorite among Python developers for building high‑performance APIs, thanks to its async capabilities, automatic documentation, and developer‑friendly design. But what if you need the flexibility of GraphQL alongside FastAPI’s speed? In this tutorial, we’ll walk through a step‑by‑step integration of GraphQL into a FastAPI project, covering everything from setting up the environment to defining schemas, resolvers, and testing your endpoint. By the end, you’ll have a production‑ready FastAPI app that serves GraphQL queries and mutations, ready to boost your API’s efficiency and developer experience.

    Why Combine FastAPI with GraphQL?

    Before diving into code, let’s explore the key benefits of pairing FastAPI with GraphQL:

    • Selective Data Retrieval: Clients request exactly the fields they need, reducing over‑fetching and under‑fetching.
    • Single Endpoint: One flexible endpoint replaces multiple REST routes, simplifying versioning and maintenance.
    • Strong Type System: GraphQL’s schema definition provides clear contracts, while FastAPI’s Pydantic models ensure data validation.
    • Async‑First Performance: FastAPI’s async support pairs perfectly with GraphQL resolvers that may call async database drivers.

    Prerequisites

    Make sure you have the following before starting:

    1. Python 3.9+ installed.
    2. Basic knowledge of FastAPI and GraphQL concepts.
    3. A virtual environment (venv or Conda) to keep dependencies isolated.

    Step 1: Set Up the Project Structure

    First, create a clean directory layout. This structure keeps your code organized and scales well as the project grows.

    fastapi-graphql-demo/
    ├─ app/
    │  ├─ __init__.py
    │  ├─ main.py
    │  ├─ schema.py
    │  └─ models.py
    ├─ requirements.txt
    └─ README.md
    

    Step 2: Install Required Packages

    We’ll use fastapi, uvicorn for the ASGI server, strawberry-graphql as a modern GraphQL library, and pydantic for data validation.

    python -m venv venv
    source venv/bin/activate   # Windows: venv\Scripts\activate
    pip install fastapi uvicorn strawberry-graphql[fastapi] pydantic
    pip freeze > requirements.txt
    

    Step 3: Define Pydantic Models

    In app/models.py, create the data models that will back your GraphQL types. Using Pydantic ensures automatic validation and serialization.

    from pydantic import BaseModel
    from typing import List, Optional
    
    class Book(BaseModel):
        id: int
        title: str
        author: str
        pages: Optional[int] = None
    
    class Author(BaseModel):
        id: int
        name: str
        books: List[Book] = []
    

    Step 4: Build the GraphQL Schema with Strawberry

    Strawberry lets you define GraphQL types using Python dataclasses, which feels natural for FastAPI developers.

    import strawberry
    from typing import List
    from .models import Book as BookModel, Author as AuthorModel
    
    @strawberry.type
    class Book:
        id: int
        title: str
        author: str
        pages: int | None = None
    
    @strawberry.type
    class Author:
        id: int
        name: str
        books: List[Book]
    
    # In‑memory data store for demo purposes
    books_db = [
        BookModel(id=1, title="FastAPI in Action", author="John Doe", pages=320),
        BookModel(id=2, title="GraphQL Essentials", author="Jane Smith", pages=210),
    ]
    
    authors_db = [
        AuthorModel(id=1, name="John Doe", books=[books_db[0]]),
        AuthorModel(id=2, name="Jane Smith", books=[books_db[1]]),
    ]
    
    @strawberry.type
    class Query:
        @strawberry.field
        def books(self) -> List[Book]:
            return [Book(**b.dict()) for b in books_db]
    
        @strawberry.field
        def authors(self) -> List[Author]:
            return [Author(id=a.id, name=a.name, books=[Book(**b.dict()) for b in a.books]) for a in authors_db]
    
    @strawberry.type
    class Mutation:
        @strawberry.mutation
        def add_book(self, title: str, author: str, pages: int | None = None) -> Book:
            new_id = max(b.id for b in books_db) + 1
            new_book = BookModel(id=new_id, title=title, author=author, pages=pages)
            books_db.append(new_book)
            # Update author relationship
            for a in authors_db:
                if a.name == author:
                    a.books.append(new_book)
                    break
            else:
                authors_db.append(AuthorModel(id=len(authors_db)+1, name=author, books=[new_book]))
            return Book(**new_book.dict())
    
    schema = strawberry.Schema(query=Query, mutation=Mutation)
    

    Step 5: Wire GraphQL into FastAPI

    FastAPI’s APIRouter makes it trivial to mount the Strawberry GraphQL view.

    # app/main.py
    import strawberry
    from fastapi import FastAPI
    from strawberry.fastapi import GraphQLRouter
    from .schema import schema
    
    app = FastAPI(
        title="FastAPI + GraphQL Demo",
        description="A simple tutorial showing how to integrate GraphQL with FastAPI using Strawberry.",
        version="1.0.0",
    )
    
    graphql_app = GraphQLRouter(schema, graphiql=True)  # Enable GraphiQL UI for testing
    app.include_router(graphql_app, prefix="/graphql")
    
    # Optional: Add a health‑check endpoint
    @app.get("/health")
    async def health_check():
        return {"status": "ok"}
    

    Step 6: Run the Application

    Start the server with uvicorn. The GraphQL playground will be available at http://localhost:8000/graphql.

    uvicorn app.main:app --reload
    

    Testing a Query

    Open the GraphiQL UI and run:

    query {
      books {
        id
        title
        author
        pages
      }
    }
    

    You should see a JSON response containing the two sample books.

    Testing a Mutation

    Add a new book using the following mutation:

    mutation {
      addBook(title: "Async Python", author: "Alice", pages: 400) {
        id
        title
        author
        pages
      }
    }
    

    The new entry will be persisted in the in‑memory list, and subsequent queries will return it.

    Step 7: Adding Database Integration (Optional)

    For production use, replace the in‑memory lists with an async ORM such as SQLModel or SQLAlchemy 2.0. Below is a quick outline using SQLModel:

    # Install extra dependency
    pip install sqlmodel[async]
    
    # models.py (extended)
    from sqlmodel import SQLModel, Field, Relationship
    from typing import List, Optional
    
    class Book(SQLModel, table=True):
        id: Optional[int] = Field(default=None, primary_key=True)
        title: str
        author: str
        pages: Optional[int] = None
        author_id: Optional[int] = Field(default=None, foreign_key="author.id")
    
    class Author(SQLModel, table=True):
        id: Optional[int] = Field(default=None, primary_key=True)
        name: str
        books: List[Book] = Relationship(back_populates="author")
    

    In your resolvers, use await session.exec(...) to fetch data asynchronously. The rest of the GraphQL schema remains unchanged, demonstrating how Strawberry cleanly separates schema definition from data fetching logic.

    Best Practices for FastAPI‑GraphQL Projects

    • Schema First Design: Draft your GraphQL schema before writing resolvers; this ensures a clear contract.
    • Use Data Loaders: Prevent the N+1 query problem by batching database calls with strawberry.dataloader or external libraries.
    • Enable CORS: If your frontend runs on a different domain, add fastapi.middleware.cors.CORSMiddleware to allow cross‑origin requests.
    • Secure the Endpoint: Protect the GraphQL route with OAuth2, API keys, or JWT authentication using FastAPI’s dependency injection system.
    • Version Your API: Although GraphQL encourages a single evolving endpoint, you can still version the underlying FastAPI app (e.g., /v1/graphql) for major breaking changes.

    Deploying to Production

    When you’re ready to go live, consider the following deployment checklist:

    1. Use an ASGI server like uvicorn or hypercorn behind a reverse proxy (NGINX or Traefik).
    2. Enable HTTP/2 and TLS for secure, high‑throughput connections.
    3. Configure logging and monitoring (e.g., structlog, Prometheus, Grafana).
    4. Set up automated tests for both GraphQL queries and FastAPI routes using pytest and httpx.
    5. Scale horizontally with containers (Docker) or serverless platforms that support ASGI.

    Conclusion

    Integrating GraphQL with FastAPI gives you the best of both worlds: the speed and

  • Python Fastapi Dockerized Production Setup

    Building a fast, reliable, and scalable API with Python’s FastAPI is only half the battle – getting it to run smoothly in production is where the real challenge lies. By containerizing your FastAPI service with Docker, you lock in a consistent runtime, simplify deployment, and lay the groundwork for modern DevOps practices such as CI/CD, auto‑scaling, and zero‑downtime updates. In this guide we’ll walk through a complete, production‑grade Dockerized setup, from the Dockerfile to Nginx reverse‑proxy, security hardening, performance tuning, and monitoring, so you can ship your API with confidence.

    Why Dockerize FastAPI for Production?

    • Environment consistency: The same image runs on a developer’s laptop, a staging server, and a cloud VM, eliminating “it works on my machine” bugs.
    • Isolation: Each service runs in its own container, preventing dependency clashes and making resource limits easy to enforce.
    • Scalability: Containers can be replicated instantly with orchestration tools like Kubernetes or Docker Swarm.
    • Rapid rollbacks: Deploy a new image, and if something goes wrong, revert to the previous tag in seconds.
    • DevOps friendliness: Docker integrates seamlessly with CI pipelines, enabling automated builds, tests, and deployments.

    Core Components of a Production‑Ready Setup

    FastAPI Application

    The heart of the system is a clean FastAPI project structure. Keep the business logic separate from the API layer, and use pydantic models for validation.

    # app/main.py
    from fastapi import FastAPI
    from .routers import items
    
    app = FastAPI(title="My Production API", version="1.0.0")
    app.include_router(items.router)
    

    Uvicorn + Gunicorn Workers

    While uvicorn is perfect for development, pairing it with gunicorn in production gives you robust process management and multiple worker processes.

    # gunicorn_conf.py
    workers = 4
    worker_class = "uvicorn.workers.UvicornWorker"
    bind = "0.0.0.0:8000"
    

    Dockerfile Essentials

    A minimal, multi‑stage Dockerfile reduces image size and speeds up builds. Use the official python:3.12-slim base, install only runtime dependencies, and copy the compiled wheels.

    # Dockerfile
    FROM python:3.12-slim AS builder
    WORKDIR /app
    RUN pip install --upgrade pip
    COPY pyproject.toml poetry.lock ./
    RUN pip install poetry && poetry config virtualenvs.create false && poetry install --no-dev
    
    FROM python:3.12-slim
    WORKDIR /app
    COPY --from=builder /usr/local/lib/python3.12/site-packages /usr/local/lib/python3.12/site-packages
    COPY . .
    EXPOSE 8000
    CMD ["gunicorn", "-c", "gunicorn_conf.py", "app.main:app"]
    

    Docker Compose for Multi‑Container Orchestration

    In a typical production stack you’ll need a database, a cache, and a reverse proxy. Docker Compose lets you spin up the whole stack locally for testing before moving to Kubernetes.

    # docker-compose.yml
    version: "3.9"
    services:
      api:
        build: .
        container_name: fastapi_app
        restart: unless-stopped
        env_file: .env
        depends_on:
          - db
          - redis
        ports:
          - "8000:8000"
        networks:
          - backend
    
      nginx:
        image: nginx:alpine
        container_name: nginx_proxy
        restart: unless-stopped
        ports:
          - "80:80"
          - "443:443"
        volumes:
          - ./nginx/conf.d:/etc/nginx/conf.d:ro
          - ./certs:/etc/nginx/certs:ro
        depends_on:
          - api
        networks:
          - backend
    
      db:
        image: postgres:16-alpine
        container_name: postgres_db
        restart: unless-stopped
        environment:
          POSTGRES_USER: ${POSTGRES_USER}
          POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
          POSTGRES_DB: ${POSTGRES_DB}
        volumes:
          - pg_data:/var/lib/postgresql/data
        networks:
          - backend
    
      redis:
        image: redis:7-alpine
        container_name: redis_cache
        restart: unless-stopped
        networks:
          - backend
    
    networks:
      backend:
    
    volumes:
      pg_data:
    

    Reverse Proxy with Nginx

    Nginx terminates TLS, handles HTTP/2, and forwards traffic to the FastAPI container. Keep the configuration simple and secure.

    # nginx/conf.d/api.conf
    server {
        listen 80;
        server_name api.example.com;
        return 301 https://$host$request_uri;
    }
    
    server {
        listen 443 ssl http2;
        server_name api.example.com;
    
        ssl_certificate /etc/nginx/certs/fullchain.pem;
        ssl_certificate_key /etc/nginx/certs/privkey.pem;
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers HIGH:!aNULL:!MD5;
    
        location / {
            proxy_pass http://api:8000;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    }
    

    Step‑by‑Step Guide to Deploy a Dockerized FastAPI Service

    1. Set up the project skeleton. Create app/, tests/, Dockerfile, and pyproject.toml. Use poetry or pipenv for dependency management.
    2. Write a minimal FastAPI endpoint. Verify it works locally with uvicorn app.main:app --reload.
    3. Add a production server. Install gunicorn and create gunicorn_conf.py as shown above.
    4. Build the Docker image. Run docker build -t myfastapi:latest . and test with docker run -p 8000:8000 myfastapi.
    5. Configure Nginx. Place the api.conf file in nginx/conf.d/ and generate TLS certificates (Let’s Encrypt or self‑signed for testing).
    6. Define Docker Compose. Add the API, Nginx, PostgreSQL, and Redis services as illustrated. Use a .env file for secrets.
    7. Run the stack locally. docker compose up --build -d. Verify https://localhost returns the FastAPI swagger UI.
    8. Push the image to a registry. Tag it (docker tag myfastapi registry.example.com/myfastapi:1.0.0) and push (docker push).
    9. Deploy to production. On your server, pull the image, copy the docker-compose.yml and nginx config, and start with docker compose up -d.
    10. Set up health checks. Add HEALTHCHECK CMD curl -f http://localhost:8000/health || exit 1 in the Dockerfile or Docker Compose to let orchestration tools detect failures.

    Security Best Practices

    • Run as non‑root. Add a dedicated user in the Dockerfile and use USER appuser before CMD.
    • Least‑privilege network. Keep the database and Redis on an internal Docker network, never expose them to the public internet.
    • Environment variables. Store secrets in a .env file or a secret manager (AWS Secrets Manager, HashiCorp Vault) and never commit them to Git.
  • Python Fastapi Jwt Oauth2 Authentication

    FastAPI has quickly become the go‑to framework for building high‑performance APIs in Python, and one of the most common questions newcomers ask is how to secure those APIs with JWT and OAuth2. In this guide we’ll walk through everything you need to know to implement robust JWT‑based OAuth2 authentication in a FastAPI project—step by step, with clear code examples, best‑practice tips, and SEO‑friendly explanations that will help your article rank for keywords like “Python FastAPI JWT OAuth2 authentication”. Whether you’re building a microservice, a mobile backend, or a full‑stack web app, mastering this authentication flow will keep your endpoints safe and your users happy.

    Why Choose JWT and OAuth2 with FastAPI?

    Before diving into code, it’s worth understanding the benefits that make JSON Web Tokens (JWT) and the OAuth2 protocol a natural fit for FastAPI:

    • Statelessness: JWTs carry all the necessary claims, so you don’t need server‑side session storage.
    • Scalability: Because tokens are self‑contained, horizontal scaling across multiple instances is straightforward.
    • Performance: FastAPI’s async nature pairs well with lightweight token verification, keeping response times low.
    • Industry Standard: OAuth2 is the de‑facto protocol for delegated access, and many third‑party services (Google, GitHub, etc.) already speak it.

    Core Concepts You Need to Know

    1. Access Token vs. Refresh Token

    An access token is a short‑lived JWT that grants the bearer permission to call protected endpoints. A refresh token is a longer‑lived credential used to obtain new access tokens without re‑authenticating the user.

    2. OAuth2 Grant Types

    FastAPI primarily supports the password grant (resource owner password credentials) for internal APIs and the authorization_code flow for third‑party integrations. In this tutorial we’ll focus on the password grant because it’s the simplest to demonstrate.

    3. Security Scopes

    FastAPI lets you define scopes (e.g., read:items, write:items) that are embedded in the JWT payload. Endpoints can then enforce scope checks automatically.

    Setting Up the Project

    First, create a fresh virtual environment and install the required packages:

    python -m venv venv
    source venv/bin/activate  # On Windows use `venv\Scripts\activate`
    pip install fastapi uvicorn python-multipart python-jose[cryptography] passlib[bcrypt]
    

    We’ll use python-jose for JWT encoding/decoding and passlib for password hashing.

    Creating the User Model and Password Utilities

    In a real application you’d store users in a database, but for clarity we’ll keep an in‑memory dictionary.

    from passlib.context import CryptContext
    
    pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
    
    def verify_password(plain_password: str, hashed_password: str) -> bool:
        return pwd_context.verify(plain_password, hashed_password)
    
    def get_password_hash(password: str) -> str:
        return pwd_context.hash(password)
    
    # Mock user DB
    fake_users_db = {
        "alice": {
            "username": "alice",
            "full_name": "Alice Wonderland",
            "email": "alice@example.com",
            "hashed_password": get_password_hash("secret123"),
            "disabled": False,
            "scopes": ["read:items", "write:items"]
        }
    }
    

    Configuring JWT Settings

    Define the secret key, algorithm, and token expiration times. Keep the secret out of source control in production (e.g., use environment variables).

    import os
    from datetime import datetime, timedelta
    
    SECRET_KEY = os.getenv("SECRET_KEY", "supersecretkeychange_me")
    ALGORITHM = "HS256"
    ACCESS_TOKEN_EXPIRE_MINUTES = 30
    REFRESH_TOKEN_EXPIRE_DAYS = 7
    

    Generating Access and Refresh Tokens

    The following helper creates both token types. Notice how we embed scopes and sub (subject) claims.

    from jose import JWTError, jwt
    
    def create_access_token(data: dict, expires_delta: timedelta | None = None):
        to_encode = data.copy()
        expire = datetime.utcnow() + (expires_delta or timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES))
        to_encode.update({"exp": expire, "type": "access"})
        return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
    
    def create_refresh_token(data: dict, expires_delta: timedelta | None = None):
        to_encode = data.copy()
        expire = datetime.utcnow() + (expires_delta or timedelta(days=REFRESH_TOKEN_EXPIRE_DAYS))
        to_encode.update({"exp": expire, "type": "refresh"})
        return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
    

    OAuth2PasswordBearer Dependency

    FastAPI provides OAuth2PasswordBearer to extract the token from the Authorization: Bearer header. We’ll also create a function to decode and validate the JWT.

    from fastapi import Depends, FastAPI, HTTPException, status
    from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
    
    oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
    
    def decode_token(token: str):
        try:
            payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
            token_type = payload.get("type")
            if token_type != "access":
                raise HTTPException(
                    status_code=status.HTTP_401_UNAUTHORIZED,
                    detail="Invalid token type",
                )
            username: str = payload.get("sub")
            if username is None:
                raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token")
            token_scopes = payload.get("scopes", [])
            return {"username": username, "scopes": token_scopes}
        except JWTError:
            raise HTTPException(
                status_code=status.HTTP_401_UNAUTHORIZED,
                detail="Could not validate credentials",
            )
    

    Creating the Login Endpoint

    The /token route authenticates the user, issues both tokens, and returns them in a JSON response.

    app = FastAPI()
    
    @app.post("/token", response_model=dict)
    async def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends()):
        user_dict = fake_users_db.get(form_data.username)
        if not user_dict:
            raise HTTPException(status_code=400, detail="Incorrect username or password")
        if not verify_password(form_data.password, user_dict["hashed_password"]):
            raise HTTPException(status_code=400, detail="Incorrect username or password")
        
        user_data = {
            "sub": user_dict["username"],
            "scopes": user_dict["scopes"]
        }
        access_token = create_access_token(user_data)
        refresh_token = create_refresh_token(user_data)
        return {
            "access_token": access_token,
            "refresh_token": refresh_token,
            "token_type": "bearer"
        }
    

    Protecting Routes with Scopes

    Now we can protect any endpoint by requiring a valid JWT and optionally checking for specific scopes.

    from fastapi.security import SecurityScopes
    
    def get_current_user(security_scopes: SecurityScopes, token: str = Depends(oauth2_scheme)):
        token_data = decode_token(token)
        user = fake_users_db.get(token_data["username"])
        if user is None or user["disabled"]:
            raise HTTPException(status_code=400, detail="Inactive user")
        
        # Scope validation
        for required_scope in security_scopes.scopes:
            if required_scope not in token_data["scopes"]:
                raise HTTPException(
                    status_code=403,
                    detail=f"Not enough permissions. Required scope: {required_scope}"
                )
        return user
    
    @app.get("/items/", response_model=list)
    async def read_items(current_user: dict = Depends(get_current_user)):
        return [{"item_id": "foo", "owner": current_user["username"]}]
    

    Refreshing an Expired Access Token

    When the access token expires, the client can request a new one using the refresh token. This endpoint validates the refresh token’s type and issues a fresh access token.

    @app.post("/refresh", response_model=dict)
    async def refresh_access_token(refresh_token: str):
        try:
            payload = jwt.decode(refresh_token, SECRET_KEY, algorithms=[ALGORITHM])
            if payload.get("type") != "refresh":
                raise HTTPException(status_code=401, detail="Invalid refresh token")
            username = payload.get("sub")
            user = fake_users_db.get(username)
            if not user:
                raise HTTPException(status_code=401, detail="User not found")
            new_access_token = create_access_token({"sub": username, "scopes": user["scopes"]})
            return {"access_token": new_access_token, "token_type": "bearer"}
        except JWTError:
            raise HTTPException(status_code=401, detail="Could not validate refresh token")
    

    Best Practices for Production‑Ready Security

    • Use HTTPS: Never transmit tokens over plain HTTP.
    • Rotate Secrets: Change SECRET_KEY regularly and store it securely (e.g., AWS Secrets Manager).
    • Short‑Lived Access Tokens: Keep the access token lifespan under 15 minutes to limit exposure.
    • Secure Cookie Storage: If you’re serving a browser client, consider
  • Python Fastapi Api Rate Limiting Tutorial

    If you’re building a high‑traffic REST service with FastAPI, you’ll quickly discover that protecting your endpoints from abuse is just as important as delivering blazing‑fast responses. Rate limiting—the practice of restricting how many requests a client can make within a given time window—keeps your API reliable, prevents denial‑of‑service attacks, and ensures fair usage for all consumers. In this tutorial we’ll walk through everything you need to know to add robust, production‑ready rate limiting to a FastAPI application, from the basics of why it matters to hands‑on code using the popular slowapi library and a custom middleware solution.

    What Is Rate Limiting and Why It Matters

    Rate limiting is a defensive technique that controls the number of requests a client (identified by IP address, API key, or user token) can send to an endpoint over a defined period. Here are the primary reasons every API should enforce it:

    • Protect resources: Prevent a single client from overwhelming your database, cache, or third‑party services.
    • Improve user experience: By throttling abusive traffic, legitimate users experience more consistent latency.
    • Guard against attacks: Simple brute‑force attacks, credential stuffing, and DDoS attempts become harder to execute.
    • Enforce business rules: Offer tiered plans (free vs. premium) with different request quotas.

    FastAPI Overview: A Quick Recap

    FastAPI is a modern, async‑first web framework built on top of Starlette and Pydantic. Its key strengths for API development include:

    • Automatic OpenAPI documentation.
    • Dependency injection that makes adding cross‑cutting concerns (like authentication or rate limiting) straightforward.
    • Native support for asynchronous endpoints, which pairs nicely with high‑performance rate‑limiting backends such as Redis.

    Because FastAPI is built on Starlette, any Starlette Middleware or ExceptionHandler can be reused directly, giving us flexibility when choosing a rate‑limiting strategy.

    Choosing a Rate Limiting Strategy

    Before diving into code, decide which strategy aligns with your use case. The most common patterns are:

    1. Fixed window: Allow N requests per fixed interval (e.g., 100 requests per minute). Simple but can cause bursts at the window boundary.
    2. Sliding window log: Record timestamps of each request and count those within the last interval. Accurate but memory‑intensive.
    3. Token bucket / Leaky bucket: Tokens are added at a steady rate; each request consumes a token. Handles bursts gracefully.

    For most web APIs, a fixed window with Redis backing offers a good balance of simplicity and performance. The slowapi library implements this pattern out of the box.

    Implementing Rate Limiting with slowapi

    SlowAPI is a thin wrapper around the popular limits library, providing ready‑made FastAPI decorators and middleware. Follow these steps to get it up and running.

    Step 1: Install Dependencies

    pip install fastapi[all] slowapi redis
    

    Step 2: Configure Redis Backend

    Redis stores the request counters. You can run it locally with Docker:

    docker run -d -p 6379:6379 redis:7
    

    Step 3: Create the FastAPI App with SlowAPI Middleware

    from fastapi import FastAPI, Request, HTTPException
    from slowapi import Limiter, _rate_limit_exceeded_handler
    from slowapi.util import get_remote_address
    from slowapi.errors import RateLimitExceeded
    
    # Initialise the limiter – 100 requests per minute per IP
    limiter = Limiter(key_func=get_remote_address, default_limits=["100/minute"])
    app = FastAPI()
    
    # Register the global exception handler for rate‑limit errors
    app.state.limiter = limiter
    app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)
    

    Step 4: Protect Endpoints with Decorators

    You can apply a global limit (as above) or fine‑tune per‑route limits using the @limiter.limit decorator.

    @app.get("/items")
    @limiter.limit("10/minute")
    async def list_items():
        return {"msg": "This endpoint is limited to 10 requests per minute per IP."}
    
    @app.post("/orders")
    @limiter.limit("5/minute")
    async def create_order(order: dict):
        # Business logic here
        return {"status": "order created"}
    

    Step 5: Testing the Limits

    Run the app with uvicorn main:app --reload and use curl or a tool like hey to fire requests. After exceeding the limit you’ll receive a 429 Too Many Requests response with a helpful Retry-After header.

    Custom Middleware Approach (When You Need Full Control)

    While slowapi covers most scenarios, some projects require custom logic—such as rate limiting based on API keys, user roles, or dynamic quotas stored in a database. Below is a lightweight middleware example that demonstrates how to implement a token‑bucket algorithm with Redis.

    Middleware Code

    import time
    import aioredis
    from fastapi import FastAPI, Request, Response
    from starlette.middleware.base import BaseHTTPMiddleware
    
    class TokenBucketMiddleware(BaseHTTPMiddleware):
        def __init__(self, app, redis_url: str, capacity: int = 100, refill_rate: float = 1.0):
            super().__init__(app)
            self.capacity = capacity          # Max tokens per bucket
            self.refill_rate = refill_rate    # Tokens added per second
            self.redis = aioredis.from_url(redis_url, decode_responses=True)
    
        async def dispatch(self, request: Request, call_next):
            identifier = request.client.host   # Could be API key or user ID instead
            bucket_key = f"rate_limit:{identifier}"
    
            # 1. Fetch current token count and last refill timestamp
            data = await self.redis.hmget(bucket_key, "tokens", "timestamp")
            tokens = float(data[0]) if data[0] else self.capacity
            last_ts = float(data[1]) if data[1] else time.time()
    
            # 2. Refill tokens based on elapsed time
            now = time.time()
            elapsed = now - last_ts
            tokens = min(self.capacity, tokens + elapsed * self.refill_rate)
    
            # 3. Check if a token is available
            if tokens < 1:
                # Not enough tokens – reject request
                retry_after = int((1 - tokens) / self.refill_rate) + 1
                return Response(
                    content='{"detail":"Rate limit exceeded"}',
                    status_code=429,
                    media_type="application/json",
                    headers={"Retry-After": str(retry_after)},
                )
    
            # 4. Consume a token and persist new state
            tokens -= 1
            await self.redis.hmset_dict(bucket_key, {"tokens": tokens, "timestamp": now})
            # Optional: set TTL to automatically clean stale keys
            await self.redis.expire(bucket_key, int(self.capacity / self.refill_rate * 2))
    
            # 5. Continue processing the request
            response = await call_next(request)
            return response
    
    app = FastAPI()
    app.add_middleware(
        TokenBucketMiddleware,
        redis_url="redis://localhost:6379",
        capacity=200,          # 200 requests per 200 seconds ≈ 1 rps
        refill_rate=1.0        # 1 token added each second
    )
    
    @app.get("/ping")
    async def ping():
        return {"msg": "pong"}
    

    Why Use Custom Middleware?

    • Dynamic quotas: Pull per‑user limits from a database and adjust capacity on the fly.
    • Multi‑tenant SaaS: Enforce different limits for free vs. paid plans without adding extra decorators.
    • Fine‑grained logging: Record each limit breach for analytics or billing.

    Testing Your Rate Limiting Logic

    Automated tests ensure that limits behave as expected under load. Below is a simple pytest example using httpx and the FastAPI test client.

    import pytest
    from fastapi.testclient import TestClient
    from main import app   # assuming your FastAPI instance is in main.py
    
    client = TestClient(app)
    
    def test_fixed_limit():
        # The endpoint is limited to 5 requests per minute
        for i in range(5):
            resp = client.get("/orders")
            assert resp.status_code == 200
    
        # Sixth request should be blocked
        resp = client.get("/orders")
        assert resp.status_code == 429
        assert "Retry-After" in resp.headers
    

    Run the test suite with pytest -q. For more realistic load testing, tools like hey or Locust can simulate thousands of concurrent users.

    Best Practices for Production

  • Python Fastapi Websockets Real-Time App

    Imagine a web application that updates instantly, without the user ever needing to click “Refresh”. Whether it’s a live chat, a collaborative dashboard, or a real‑time notification system, Python FastAPI WebSockets make this possible with minimal boilerplate and blazing‑fast performance. In this guide we’ll walk through everything you need to build a production‑ready real‑time app using FastAPI’s native WebSocket support, from environment setup to deployment, while keeping SEO best practices in mind.

    What Are WebSockets and Why Do They Matter?

    WebSockets are a full‑duplex communication protocol that establishes a persistent connection between a client’s browser and a server. Unlike traditional HTTP requests, which follow a request/response cycle, WebSockets enable the server to push data to the client at any time, dramatically reducing latency and bandwidth usage.

    • Bidirectional: Both client and server can send messages independently.
    • Low overhead: After the initial handshake, only the payload is transmitted.
    • Real‑time: Ideal for chat apps, live feeds, gaming, IoT dashboards, and more.

    Why FastAPI Is the Perfect Choice for Real‑Time Apps

    FastAPI has quickly become the go‑to framework for modern Python web development, and its WebSocket support is a key reason why developers choose it for real‑time solutions.

    Key Advantages

    • Asynchronous by design: Powered by asyncio, FastAPI can handle thousands of concurrent connections without blocking.
    • Automatic data validation: Pydantic models ensure that incoming messages conform to your schema.
    • OpenAPI documentation: Even WebSocket endpoints appear in the interactive Swagger UI, improving developer experience.
    • Fast performance: Benchmarks show FastAPI + Uvicorn often outperform traditional frameworks like Flask or Django for async workloads.

    Setting Up Your Development Environment

    Before diving into code, make sure your workstation is ready. The following steps assume you have Python 3.9+ installed.

    # 1. Create a virtual environment
    python -m venv venv
    source venv/bin/activate   # On Windows use `venv\Scripts\activate`
    
    # 2. Install FastAPI and Uvicorn (the ASGI server)
    pip install fastapi uvicorn[standard]
    
    # 3. (Optional) Install a WebSocket client for testing
    pip install websockets
    

    With the environment ready, you can start building your first real‑time endpoint.

    Building a Simple Real‑Time Chat Application

    Let’s create a minimal chat server that broadcasts messages to all connected clients. The example demonstrates core concepts such as connection management, message broadcasting, and graceful disconnect handling.

    Project Structure

    my_chat_app/
    ├── main.py          # FastAPI application
    └── requirements.txt # Dependencies
    

    main.py – Core Logic

    from fastapi import FastAPI, WebSocket, WebSocketDisconnect
    from typing import List
    
    app = FastAPI()
    
    class ConnectionManager:
        """Manage active WebSocket connections."""
        def __init__(self):
            self.active_connections: List[WebSocket] = []
    
        async def connect(self, websocket: WebSocket):
            await websocket.accept()
            self.active_connections.append(websocket)
    
        def disconnect(self, websocket: WebSocket):
            self.active_connections.remove(websocket)
    
        async def broadcast(self, message: str):
            for connection in self.active_connections:
                await connection.send_text(message)
    
    manager = ConnectionManager()
    
    @app.websocket("/ws/chat")
    async def chat_endpoint(websocket: WebSocket):
        await manager.connect(websocket)
        try:
            while True:
                data = await websocket.receive_text()
                await manager.broadcast(f"User says: {data}")
        except WebSocketDisconnect:
            manager.disconnect(websocket)
            await manager.broadcast("A user has left the chat")
    

    Key takeaways from the code above:

    • Each new client connects to /ws/chat and is added to active_connections.
    • Incoming text messages are broadcast to every connected client.
    • When a client disconnects, the server removes it from the list and notifies remaining users.

    Running the Server

    uvicorn main:app --reload
    

    The --reload flag enables hot‑reloading during development. Navigate to http://localhost:8000/docs to see the auto‑generated OpenAPI UI; while WebSocket endpoints aren’t directly testable there, the documentation still helps developers understand the API surface.

    Connecting from the Browser

    Below is a minimal HTML page that opens a WebSocket connection to the FastAPI server and displays messages in real time.

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>FastAPI WebSocket Chat</title>
        <style>
            body {font-family: Arial, sans-serif; margin: 2rem;}
            #messages {border: 1px solid #ccc; padding: 1rem; height: 300px; overflow-y: scroll;}
        </style>
    </head>
    <body>
        <h2>FastAPI Real‑Time Chat</h2>
        <div id="messages"></div>
        <input id="input" type="text" placeholder="Type a message..." autofocus />
        <script>
            const ws = new WebSocket("ws://localhost:8000/ws/chat");
            const messages = document.getElementById("messages");
            const input = document.getElementById("input");
    
            ws.onmessage = (event) => {
                const msg = document.createElement("div");
                msg.textContent = event.data;
                messages.appendChild(msg);
                messages.scrollTop = messages.scrollHeight;
            };
    
            input.addEventListener("keypress", (e) => {
                if (e.key === "Enter" && input.value) {
                    ws.send(input.value);
                    input.value = "";
                }
            });
        </script>
    </body>
    </html>
    

    Open this file in a browser, open a second tab, and start typing. Both windows will instantly reflect each other’s messages—pure real‑time interaction powered by FastAPI WebSockets.

    Scaling Beyond a Simple Chat: Managing Multiple Rooms

    Real‑world applications often need to isolate conversations into “rooms” or “channels”. Below is a concise pattern for handling rooms using a dictionary of ConnectionManager instances.

    from collections import defaultdict
    
    room_managers = defaultdict(ConnectionManager)
    
    @app.websocket("/ws/{room_name}")
    async def room_endpoint(websocket: WebSocket, room_name: str):
        manager = room_managers[room_name]
        await manager.connect(websocket)
        try:
            while True:
                data = await websocket.receive_text()
                await manager.broadcast(f"[{room_name}] {data}")
        except WebSocketDisconnect:
            manager.disconnect(websocket)
            await manager.broadcast(f"A user left {room_name}")
    

    This approach automatically creates a new manager for each unique room_name, keeping room logic clean and scalable.

    Security Best Practices for FastAPI WebSockets

    WebSockets inherit the same security concerns as any other web endpoint. Follow these guidelines to keep your real‑time app safe.

    Authentication Strategies

    • Token‑based authentication: Send a JWT as a query parameter or in the Sec-WebSocket-Protocol header, then validate it in the endpoint.
    • Cookie‑based session: Leverage existing FastAPI session middleware and read cookies during the handshake.
    • OAuth2 scopes: Restrict access to specific rooms or actions based on user roles.

    Example: JWT Validation

    from fastapi import Depends, HTTPException, status
    from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
    import jwt
    
    security = HTTPBearer()
    
    async def get_current_user(credentials: HTTPAuthorizationCredentials = Depends(security)):
        try:
            payload = jwt.decode(credentials.credentials, "YOUR_SECRET_KEY", algorithms=["HS256"])
            return payload["sub"]
        except jwt.PyJWTError:
            raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Invalid token")
    
    @app.websocket("/ws/secure")
    async def secure_endpoint(websocket: WebSocket, user: str = Depends(get_current_user)):
        await manager.connect(websocket)
        # ... same logic as before ...
    

    By integrating FastAPI’s dependency injection, you keep authentication logic reusable and testable.

    Deploying FastAPI WebSocket Apps to Production

    When you move from local development to production, a few extra steps ensure reliability, scalability, and observability.

    Choose an ASGI‑compatible Server

    • Uvicorn: Ideal for small‑to‑medium deployments.
    • Gunicorn + Uvicorn workers: Combines Gunicorn’s process management with Uvicorn’s async capabilities.
    • Hypercorn
  • Python Fastapi Dependency Injection Guide

    FastAPI has quickly become the go‑to framework for building high‑performance APIs with Python, and one of its secret weapons is the built‑in dependency injection (DI) system. Whether you’re a seasoned backend engineer or just starting out, mastering FastAPI’s DI will make your code cleaner, more reusable, and easier to test. In this guide we’ll walk through the core concepts, practical patterns, and advanced tricks you need to create robust, production‑ready APIs with FastAPI’s dependency injection.

    What Is Dependency Injection in FastAPI?

    At its core, dependency injection is a design pattern that decouples the creation of an object from its usage. In FastAPI, a dependency is simply a callable (function, class, or async function) that returns a value. The framework calls this callable, resolves any of its own dependencies, and injects the resulting value into your path operation functions.

    Key benefits include:

    • Reusability: Write a single function that can be shared across many endpoints.
    • Testability: Swap real implementations with mocks or stubs in unit tests.
    • Separation of concerns: Keep business logic separate from request handling, authentication, or database connections.

    Basic Dependency Syntax

    Simple Function Dependency

    Start with the most straightforward example – a function that returns a static value.

    from fastapi import FastAPI, Depends
    
    app = FastAPI()
    
    def common_parameters(q: str = None, skip: int = 0, limit: int = 100):
        return {"q": q, "skip": skip, "limit": limit}
    
    @app.get("/items/")
    async def read_items(params: dict = Depends(common_parameters)):
        return params
    

    Here common_parameters is declared as a dependency using Depends(). FastAPI automatically extracts the query parameters q, skip, and limit and passes the resulting dictionary to read_items.

    Class‑Based Dependency

    When you need stateful objects (e.g., a database session), a class can be used as a dependency.

    from fastapi import Depends
    
    class DBSession:
        def __init__(self):
            self.connection = create_connection()  # pseudo‑function
    
        def __enter__(self):
            return self.connection
    
        def __exit__(self, exc_type, exc_val, exc_tb):
            self.connection.close()
    
    def get_db():
        with DBSession() as db:
            yield db
    

    The get_db function yields a database connection that is automatically closed after the request finishes.

    Advanced Dependency Features

    Dependency Overrides for Testing

    FastAPI allows you to replace a dependency with a mock during tests, making isolated unit testing painless.

    from fastapi.testclient import TestClient
    
    def fake_get_db():
        class FakeDB:
            def fetch(self):
                return {"id": 1, "name": "Test Item"}
        yield FakeDB()
    
    app.dependency_overrides[get_db] = fake_get_db
    
    client = TestClient(app)
    response = client.get("/items/1")
    assert response.json() == {"id": 1, "name": "Test Item"}
    

    Using Depends Inside Other Dependencies

    Dependencies can be nested, creating a powerful chain of reusable components.

    def get_current_user(token: str = Depends(oauth2_scheme)):
        user = decode_token(token)
        if not user:
            raise HTTPException(status_code=401, detail="Invalid token")
        return user
    
    def get_user_profile(user: User = Depends(get_current_user)):
        return fetch_profile(user.id)
    
    @app.get("/profile")
    async def profile(profile: dict = Depends(get_user_profile)):
        return profile
    

    Background Tasks as Dependencies

    Sometimes you need to trigger a background job after a request finishes. FastAPI’s BackgroundTasks can be injected just like any other dependency.

    from fastapi import BackgroundTasks
    
    def send_email(email: str):
        # simulate email sending
        ...
    
    def email_dependency(background_tasks: BackgroundTasks):
        background_tasks.add_task(send_email, "user@example.com")
        return background_tasks
    
    @app.post("/signup")
    async def signup(background_tasks: BackgroundTasks = Depends(email_dependency)):
        return {"message": "User created, email will be sent shortly"}
    

    Practical Patterns for Real‑World APIs

    1. Centralized Database Session Management

    Use a single get_db dependency across the entire project. Combine it with SQLAlchemy’s sessionmaker for thread‑safe sessions.

    from sqlalchemy.orm import sessionmaker
    from sqlalchemy import create_engine
    
    SQLALCHEMY_DATABASE_URL = "postgresql://user:pass@localhost/db"
    engine = create_engine(SQLALCHEMY_DATABASE_URL)
    SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
    
    def get_db():
        db = SessionLocal()
        try:
            yield db
        finally:
            db.close()
    

    2. Role‑Based Access Control (RBAC)

    Define a dependency that checks the user’s role before allowing access to an endpoint.

    def require_role(role: str):
        def role_checker(user: User = Depends(get_current_user)):
            if role not in user.roles:
                raise HTTPException(status_code=403, detail="Insufficient permissions")
            return user
        return role_checker
    
    @app.delete("/admin/users/{user_id}")
    async def delete_user(user_id: int, admin: User = Depends(require_role("admin"))):
        # deletion logic
        return {"status": "deleted"}
    

    3. Caching Layer as a Dependency

    Wrap a Redis client in a dependency to share the same connection across many routes.

    import aioredis
    
    redis = aioredis.from_url("redis://localhost")
    
    async def get_cache():
        return redis
    
    @app.get("/cached-data")
    async def cached_data(cache = Depends(get_cache)):
        value = await cache.get("some_key")
        return {"cached_value": value}
    

    Common Pitfalls and How to Avoid Them

    • Yield vs. Return: Use yield when you need cleanup logic (e.g., closing DB connections). A plain return will not trigger finally blocks.
    • Mutable Default Arguments: Never use mutable objects as default values in dependency functions; they persist across requests.
    • Blocking I/O: If your dependency performs blocking I/O (file reads, network calls), declare it as async and use await to keep the server responsive.
    • Dependency Order: FastAPI resolves dependencies depth‑first. Ensure that lower‑level dependencies (e.g., DB) do not depend on higher‑level ones (e.g., request data) to avoid circular imports.

    SEO Tips for FastAPI Documentation

    When publishing your API docs or blog posts, follow these quick SEO best practices to improve visibility:

    1. Include the primary keyword “Python FastAPI dependency injection” in the title, first paragraph, and at least one subheading.
    2. Use related terms such as “DI”, “FastAPI dependencies”, “dependency overrides”, and “testing FastAPI” naturally throughout the content.
    3. Add descriptive alt text to any images (e.g., “FastAPI DI flow diagram”).
    4. Structure the article with clear <h2> and <h3> tags, as search engines prioritize hierarchical headings.
    5. Provide a concise meta description (under 160 characters) summarizing the guide.

    Full Example: A Minimal CRUD API with DI

    Below is a compact yet complete FastAPI application that demonstrates most of the concepts covered.

    from fastapi import FastAPI, Depends, HTTPException, status
    from pydantic import BaseModel
    from typing import List
    
    app = FastAPI()
    
    # ----- Models -----
    class Item(BaseModel):
        id: int
        name: str
        description: str | None = None
    
    # In‑memory “database”
    fake_db: List[Item] = []
    
    # ----- Dependencies -----
    def get_item(item_id: int):
        for item in fake_db:
            if item.id == item_id:
                return item
        raise HTTPException(status_code=404, detail="Item not found")
    
    def verify_token(token: str = Depends(oauth2_scheme)):
        user = decode_token(token)
        if not user:
            raise HTTPException(status_code=401, detail="Invalid token")
        return user
    
    # ----- Routes -----
    @app.post("/items/", response_model=Item, status_code=status.HTTP_201_CREATED)
    async def create_item(item: Item, user = Depends(verify_token)):
        fake_db.append(item)
        return item
    
    @app.get("/items/", response_model=List[Item])
    async def list_items():
        return fake_db
    
    @app.get("/items/{item_id}", response_model=Item)
    async def read_item(item: Item = Depends(get_item)):
        return item
    
    @app.put("/items/{item_id}", response_model=Item)
    async def update_item(updated: Item, item: Item = Depends(get_item)):
        item.name = updated.name
        item.description = updated.description
        return item
    
    @app.delete("/items/{item_id}", status_code=status.HTTP_204_NO_CONTENT)
    async def delete_item(item: Item = Depends(get_item)):
        fake_db.remove(item)
    

    This snippet showcases:

    • Path parameter injection (item_id).
    • Reusing get_item across GET, PUT, and DELETE.
    • Security dependency (verify_token) applied only where needed.
    • Clean separation of models, dependencies, and route logic.

    Conclusion

    FastAPI’s dependency injection system is more than a convenience—it’s a powerful architectural tool that can dramatically improve the

  • Python Fastapi Async Crud Operations Tutorial

    Welcome to the ultimate Python FastAPI async CRUD operations tutorial! In this guide you’ll learn how to build a high‑performance REST API that handles Create, Read, Update, and Delete (CRUD) actions using FastAPI’s native async support. Whether you’re a seasoned Python developer or just starting out, this step‑by‑step walkthrough will equip you with everything you need to design, code, and test a production‑ready async API in under an hour.

    Why Choose FastAPI for Async CRUD?

    FastAPI has quickly become the go‑to framework for modern web services because it combines speed, developer friendliness, and automatic OpenAPI documentation. Its async capabilities let you handle thousands of concurrent requests without blocking the event loop, making it perfect for I/O‑bound tasks like database interactions.

    • Performance: Comparable to Node.js and Go, thanks to Starlette and Pydantic.
    • Type safety: Python type hints are validated at runtime, reducing bugs.
    • Built‑in docs: Swagger UI and ReDoc appear automatically.
    • Scalability: Async functions let you scale horizontally with minimal code changes.

    Prerequisites and Environment Setup

    1. Install Python 3.9+ and create a virtual environment

    python3 -m venv venv
    source venv/bin/activate  # On Windows use `venv\Scripts\activate`
    

    2. Install FastAPI, Uvicorn, and an async‑compatible ORM

    For this tutorial we’ll use SQLModel, which blends Pydantic and SQLAlchemy and works natively with async engines.

    pip install fastapi uvicorn[standard] sqlmodel aiosqlite
    

    3. Project structure

    • app/main.py – FastAPI application entry point.
    • app/models.py – Database models.
    • app/crud.py – Async CRUD helper functions.
    • app/router.py – API routes.

    Defining the Data Model with SQLModel

    SQLModel lets you declare tables using Pydantic‑style classes. Below is a simple Item model representing a product in an inventory.

    # app/models.py
    from typing import Optional
    from sqlmodel import SQLModel, Field
    
    class Item(SQLModel, table=True):
        id: Optional[int] = Field(default=None, primary_key=True)
        name: str = Field(index=True, max_length=100)
        description: Optional[str] = Field(default=None, max_length=255)
        price: float
        in_stock: bool = Field(default=True)
    

    Creating an Async Database Engine

    FastAPI works best with an async engine. We’ll use SQLite for simplicity, but the same pattern applies to PostgreSQL, MySQL, or any async‑compatible DB.

    # app/database.py
    from sqlmodel import create_engine, SQLModel
    from sqlalchemy.ext.asyncio import AsyncEngine, create_async_engine
    
    DATABASE_URL = "sqlite+aiosqlite:///./test.db"
    
    engine: AsyncEngine = create_async_engine(DATABASE_URL, echo=True)
    
    async def init_db():
        async with engine.begin() as conn:
            await conn.run_sync(SQLModel.metadata.create_all)
    

    Building Async CRUD Functions

    Keeping business logic separate from route definitions makes the code easier to test and maintain. Each function below uses async with to acquire a database session without blocking the event loop.

    Create an item

    # app/crud.py
    from sqlmodel.ext.asyncio.session import AsyncSession
    from sqlmodel import select
    from .models import Item
    
    async def create_item(session: AsyncSession, item: Item) -> Item:
        session.add(item)
        await session.commit()
        await session.refresh(item)
        return item
    

    Read (list & single)

    async def get_item(session: AsyncSession, item_id: int) -> Item | None:
        result = await session.get(Item, item_id)
        return result
    
    async def list_items(session: AsyncSession, skip: int = 0, limit: int = 100) -> list[Item]:
        statement = select(Item).offset(skip).limit(limit)
        results = await session.exec(statement)
        return results.all()
    

    Update an item

    async def update_item(session: AsyncSession, item_id: int, data: dict) -> Item | None:
        db_item = await session.get(Item, item_id)
        if not db_item:
            return None
        for key, value in data.items():
            setattr(db_item, key, value)
        session.add(db_item)
        await session.commit()
        await session.refresh(db_item)
        return db_item
    

    Delete an item

    async def delete_item(session: AsyncSession, item_id: int) -> bool:
        db_item = await session.get(Item, item_id)
        if not db_item:
            return False
        await session.delete(db_item)
        await session.commit()
        return True
    

    Exposing the CRUD Operations via FastAPI Routes

    Now we tie everything together in a router that FastAPI will serve. Notice the use of Depends to inject an async session into each endpoint.

    # app/router.py
    from fastapi import APIRouter, Depends, HTTPException, status
    from sqlmodel.ext.asyncio.session import AsyncSession
    from .database import engine
    from .models import Item
    from .crud import create_item, get_item, list_items, update_item, delete_item
    
    router = APIRouter(prefix="/items", tags=["items"])
    
    async def get_session() -> AsyncSession:
        async with AsyncSession(engine) as session:
            yield session
    
    @router.post("/", response_model=Item, status_code=status.HTTP_201_CREATED)
    async def api_create_item(item: Item, session: AsyncSession = Depends(get_session)):
        return await create_item(session, item)
    
    @router.get("/", response_model=list[Item])
    async def api_list_items(skip: int = 0, limit: int = 100,
                             session: AsyncSession = Depends(get_session)):
        return await list_items(session, skip, limit)
    
    @router.get("/{item_id}", response_model=Item)
    async def api_get_item(item_id: int, session: AsyncSession = Depends(get_session)):
        db_item = await get_item(session, item_id)
        if not db_item:
            raise HTTPException(status_code=404, detail="Item not found")
        return db_item
    
    @router.put("/{item_id}", response_model=Item)
    async def api_update_item(item_id: int, item: Item,
                              session: AsyncSession = Depends(get_session)):
        updated = await update_item(session, item_id, item.dict(exclude_unset=True))
        if not updated:
            raise HTTPException(status_code=404, detail="Item not found")
        return updated
    
    @router.delete("/{item_id}", status_code=status.HTTP_204_NO_CONTENT)
    async def api_delete_item(item_id: int, session: AsyncSession = Depends(get_session)):
        success = await delete_item(session, item_id)
        if not success:
            raise HTTPException(status_code=404, detail="Item not found")
        return None
    

    Launching the Application

    Finally, create the FastAPI app, include the router, and start the server with Uvicorn.

    # app/main.py
    import uvicorn
    from fastapi import FastAPI
    from .router import router
    from .database import init_db
    
    app = FastAPI(
        title="Async CRUD API with FastAPI",
        description="A minimal example demonstrating async CRUD operations using FastAPI and SQLModel.",
        version="1.0.0",
    )
    
    app.include_router(router)
    
    @app.on_event("startup")
    async def on_startup():
        await init_db()
    
    if __name__ == "__main__":
        uvicorn.run("app.main:app", host="0.0.0.0", port=8000, reload=True)
    

    Testing Your Async Endpoints

    With the server running (uvicorn app.main:app --reload), you can quickly verify each route using curl or httpie. Below are example commands:

    1. Create a new item:
      http POST http://localhost:8000/items/ name="Widget" price:=19.99 description="A useful widget"
    2. List all items:
      http GET http://localhost:8000/items/
    3. Retrieve a single item (replace 1 with the actual ID):
      http GET http://localhost:8000/items/1
    4. Update an item:
      <