Launch Your First FastAPI App: Hello World & Beyond

Launch Your First FastAPI App: Hello World & Beyond

What You’ll Learn

In this foundational chapter, you’ll take your very first steps into the world of FastAPI. By the end, you will be able to:

  • Set up a clean Python development environment using virtual environments.
  • Install FastAPI and Uvicorn, the server that runs your FastAPI applications.
  • Create your first “Hello World” FastAPI application.
  • Run your FastAPI application locally and access it from your web browser.
  • Understand the basics of FastAPI path operations and how to define simple GET request endpoints.
  • Return various basic responses, including strings and JSON objects.

Core Concepts

Welcome to building web applications with FastAPI! We’re going to start from scratch, ensuring you have a solid foundation.

Quick Setup: Python, Virtual Environments, and FastAPI

Before writing any code, we need to prepare our workspace.

  1. Python Installation: We’ll assume you have Python 3.8+ installed. If not, please visit python.org to download and install the latest version for your operating system.

  2. Virtual Environments: A virtual environment is a self-contained directory that holds a specific Python installation and any libraries you install for a particular project. This prevents conflicts between different projects that might require different versions of the same library.

    First, create a new directory for your project and navigate into it:

    mkdir my-fastapi-app
    cd my-fastapi-app
    

    Next, create a virtual environment inside your project directory. We’ll name it .venv (a common convention):

    python -m venv .venv
    

    Now, activate your virtual environment. The command varies slightly by operating system:

    • macOS/Linux:
      source .venv/bin/activate
      
    • Windows (Command Prompt):
      .venv\Scripts\activate.bat
      
    • Windows (PowerShell):
      .venv\Scripts\Activate.ps1
      

    You’ll notice (.venv) or similar text appear in your terminal prompt, indicating the virtual environment is active.

  3. Install FastAPI and Uvicorn: With your virtual environment active, you can now install FastAPI and Uvicorn. Uvicorn is an ASGI server (Asynchronous Server Gateway Interface) that FastAPI uses to run your application.

    pip install fastapi uvicorn
    

    This command downloads and installs both packages into your active virtual environment.

Your First ‘Hello World’ Endpoint: Immediate Wins

Now that your environment is set up, let’s write your very first FastAPI application.

  1. Create main.py: Inside your my-fastapi-app directory, create a new file named main.py.

  2. Write the Code: Open main.py and add the following code:

    from fastapi import FastAPI
    
    # Create a FastAPI instance
    app = FastAPI()
    
    # Define a path operation decorator for the root path ("/")
    @app.get("/")
    async def read_root():
        return {"message": "Hello, FastAPI!"}
    

    Let’s break this down:

    • from fastapi import FastAPI: This line imports the FastAPI class, which is the core of your application.
    • app = FastAPI(): This creates an instance of the FastAPI application. This app object will be the main entry point for defining all your API’s paths and operations.
    • @app.get("/"): This is a “decorator.” It tells FastAPI that the function immediately below it (read_root) should handle HTTP GET requests made to the root URL path (/).
    • async def read_root():: This defines an asynchronous Python function. FastAPI (and Uvicorn) are built on asynchronous programming, which allows your application to handle many requests concurrently. For now, just know that async def is the standard for FastAPI path operations.
    • return {"message": "Hello, FastAPI!"}: This line returns a Python dictionary. FastAPI automatically converts Python dictionaries into JSON responses, which is a standard format for web APIs.
  3. Run Your Application: Back in your terminal (with your virtual environment still active), run your application using Uvicorn:

    uvicorn main:app --reload
    
    • uvicorn: The server program.
    • main:app: Tells Uvicorn to look for an app object inside the main.py file.
    • --reload: This is incredibly useful during development. It tells Uvicorn to automatically restart the server whenever you make changes to your code, so you don’t have to manually stop and start it.

    You should see output similar to this:

    INFO:     Will watch for changes in these directories: ['/path/to/my-fastapi-app']
    INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
    INFO:     Started reloader process [12345] using statreload
    INFO:     Started server process [12347]
    INFO:     Waiting for application startup.
    INFO:     Application startup complete.
    

    Open your web browser and navigate to http://127.0.0.1:8000. You should see the JSON response: {"message": "Hello, FastAPI!"}. Congratulations, you’ve launched your first FastAPI app!

Path Operations: GET Requests and Basic Responses

Let’s expand our application to handle more than just the root path. A “path operation” defines how your API handles requests to a specific URL path using a specific HTTP method (like GET, POST, PUT, DELETE).

Add the following code to your main.py file, below the read_root function:

# A new GET path operation at /items/
@app.get("/items/")
async def read_items():
    return {"data": ["item1", "item2", "item3"]}

# A new GET path operation at /status/ that returns a simple string
@app.get("/status/")
async def get_status():
    return "API is up and running!"

Save main.py. Because you’re running Uvicorn with --reload, the server will automatically restart.

Now, try these URLs in your browser:

  • http://127.0.0.1:8000/items/ - You’ll see {"data": ["item1", "item2", "item3"]}.
  • http://127.0.0.1:8000/status/ - You’ll see API is up and running!.

This demonstrates how to define multiple GET endpoints, each returning different types of data (a JSON object from a dictionary, and a plain string).

Hands-On Practice

Let’s get your fingers on the keyboard and build some more!

Exercise 1: Personal Greeting

Modify your existing main.py to add a new GET endpoint that returns a personalized greeting.

  1. Task: Create a new path operation at /greet/.
  2. Code: Define an async def function that returns a dictionary with a message like {"greeting": "Welcome to my FastAPI app!"}.
  3. Expected Outcome: When you visit http://127.0.0.1:8000/greet/ in your browser, you should see the JSON greeting.
  4. Debugging Tip: If you see a 404 Not Found error, double-check the path in your decorator (@app.get("/greet/")) and ensure your function name is unique.

Exercise 2: Simple Math Operation

Create an endpoint that returns the result of a simple math operation.

  1. Task: Create a new path operation at /calculate/.
  2. Code: Define an async def function that calculates 5 * 10 and returns a dictionary like {"result": 50}.
  3. Expected Outcome: Visiting http://127.0.0.1:8000/calculate/ should display {"result": 50}.
  4. Debugging Tip: Ensure your dictionary keys are strings (e.g., "result", not result).

Exercise 3: Returning a List of Objects

Practice returning a more complex JSON structure, such as a list of dictionaries.

  1. Task: Create a new path operation at /users/.
  2. Code: Define an async def function that returns a list of dictionaries, where each dictionary represents a user (e.g., [{"id": 1, "name": "Alice"}, {"id": 2, "name": "Bob"}]).
  3. Expected Outcome: Navigating to http://127.0.0.1:8000/users/ should show a JSON array of user objects.
  4. Debugging Tip: Make sure your list elements are valid Python dictionaries and that all keys and string values are properly quoted.

Real-World Application

The foundational concepts you’ve learned are the building blocks for almost any API.

Project 1: Basic Status API

Imagine you’re building a system where different services need to check if your main application is running.

Task: Create a FastAPI application (you can use your existing main.py) that provides two endpoints:

  1. /health: Returns {"status": "OK", "uptime": "just started"}.
  2. /version: Returns {"api_version": "1.0.0"}.

This simple “health check” and “version info” API is a common pattern in microservices architectures, allowing other systems or monitoring tools to quickly understand the state of your application.

Key Takeaways

In this chapter, you’ve accomplished a lot!

  • You’ve mastered the initial setup, including virtual environments for project isolation and installing FastAPI and Uvicorn.
  • You wrote your first FastAPI application, defining a GET endpoint for the root path.
  • You learned to run your application using Uvicorn with the helpful --reload option for development.
  • You expanded your app to include multiple GET path operations, returning both JSON objects and plain strings.

Before moving on, ensure you’re comfortable creating new project directories, setting up virtual environments, installing packages, writing basic FastAPI endpoints, and running your server. Practice creating a few more simple endpoints that return different messages or data.

Quick Reference

Here’s a quick cheat sheet for the commands and syntax covered in this chapter:

Environment Setup:

  • Create project directory: mkdir my-app && cd my-app
  • Create virtual environment: python -m venv .venv
  • Activate virtual environment (macOS/Linux): source .venv/bin/activate
  • Activate virtual environment (Windows Cmd): .venv\Scripts\activate.bat
  • Install packages: pip install fastapi uvicorn

FastAPI Code Structure (main.py):

from fastapi import FastAPI

app = FastAPI()

@app.get("/") # Decorator for GET requests to the root path
async def read_root():
    return {"message": "Hello!"}

@app.get("/another_path/") # Another GET endpoint
async def another_function():
    return "This is another response."

Running Your Application:

  • Start Uvicorn server: uvicorn main:app --reload
  • Access in browser: http://127.0.0.1:8000 (or http://localhost:8000)

Deactivating Virtual Environment:

  • deactivate