With your development environment ready, it’s time to write some code! This chapter focuses on creating a minimal FastAPI application, understanding its basic components, and establishing a sensible project structure.
Purpose of this Chapter
By the end of this chapter, you will be able to:
- Write a simple “Hello, World!” FastAPI application.
- Run the FastAPI application using Uvicorn.
- Understand basic FastAPI routing.
- Create a foundational project directory structure.
Concepts Explained: FastAPI Basics
FastAPI is a modern, fast (high-performance) web framework for building APIs with Python 3.8+ based on standard Python type hints. It offers:
- Automatic documentation: Generates interactive API documentation (Swagger UI and ReDoc) from your code.
- Data validation and serialization: Uses Pydantic for robust data handling.
- Performance: Built on Starlette (for web parts) and Pydantic (for data parts), making it extremely fast.
An “endpoint” or “route” in FastAPI is a specific URL that your application listens to. When a client sends a request to that URL, FastAPI executes a Python function associated with that route.
Step-by-Step Tasks
1. Create main.py
Inside your realtime-chat-app directory, create a new file named main.py. This will be the entry point for our FastAPI application.
# realtime-chat-app/main.py
from fastapi import FastAPI
# Create a FastAPI instance
app = FastAPI()
# Define a root endpoint
@app.get("/")
async def read_root():
return {"message": "Welcome to the Real-time Chat API!"}
# Define another endpoint to test
@app.get("/health")
async def health_check():
return {"status": "ok"}
Code Explanation:
from fastapi import FastAPI: Imports theFastAPIclass.app = FastAPI(): Creates an instance of theFastAPIapplication.@app.get("/"): This is a “decorator” that registers theread_rootfunction to handle HTTP GET requests to the/path.async def read_root():: Defines an asynchronous function. FastAPI leverages Python’sasync/awaitfor efficient handling of I/O operations, which is crucial for real-time applications.return {"message": "..."}: The function returns a Python dictionary, which FastAPI automatically converts into a JSON response.
2. Run the Application with Uvicorn
Open your terminal, navigate to your realtime-chat-app directory, and activate your virtual environment.
pipenv shell
Now, run your FastAPI application using Uvicorn:
uvicorn main:app --reload
Command Explanation:
uvicorn: The command to run the Uvicorn server.main:app: Tells Uvicorn to look for an application object namedappinside themain.pyfile.--reload: This flag enables auto-reloading. Uvicorn will monitor your code for changes and restart the server automatically, which is very useful during development.
You should see output similar to this:
INFO: Will watch for changes in these directories: ['/path/to/your/realtime-chat-app']
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [12345] using WatchFiles
INFO: Started server process [12347]
INFO: Waiting for application startup.
INFO: Application startup complete.
3. Test Your Endpoints
Open your web browser or a tool like Postman/Insomnia and visit:
http://127.0.0.1:8000/- You should see:
{"message": "Welcome to the Real-time Chat API!"}
- You should see:
http://127.0.0.1:8000/health- You should see:
{"status": "ok"}
- You should see:
http://127.0.0.1:8000/docs- You’ll find the automatically generated interactive API documentation (Swagger UI).
http://127.0.0.1:8000/redoc- You’ll find the alternative API documentation (ReDoc).
This confirms that your FastAPI application is running and accessible.
4. Establish Initial Project Structure
As our application grows, a clear project structure becomes essential. Let’s create a few subdirectories to organize our code.
Stop the Uvicorn server (Ctrl+C) and create the following structure within your realtime-chat-app directory:
realtime-chat-app/
├── app/
│ ├── __init__.py
│ └── main.py # Our FastAPI app will be here
├── .env # For environment variables (later)
├── Pipfile
├── Pipfile.lock
├── README.md
Now, move your main.py file into the app/ directory:
mv main.py app/
touch app/__init__.py # Create an empty __init__.py to make 'app' a Python package
Your main.py content remains the same. The __init__.py file is empty but tells Python that the app directory should be treated as a Python package.
5. Update Uvicorn Command
Since main.py is now inside the app directory, you need to update the Uvicorn command to reflect this:
uvicorn app.main:app --reload
Test it again in your browser to ensure it’s still working.
Tips/Challenges/Errors
- “uvicorn: command not found”: Ensure you’ve activated your virtual environment (
pipenv shell) or installed Uvicorn globally (not recommended for projects). - “ModuleNotFoundError: No module named ‘app.main’”: Double-check that
main.pyis inside theappdirectory and that you created an emptyapp/__init__.pyfile. Also, verify youruvicorncommand points toapp.main:app. - Port already in use: If you see
OSError: [Errno 98] Address already in use, it means another process is using port 8000. You can either find and kill that process or run Uvicorn on a different port:uvicorn app.main:app --reload --port 8001.
Summary/Key Takeaways
You’ve successfully created and run your first FastAPI application, establishing the foundation of our project. A clear project structure will aid maintainability as we add more features. The next step is to introduce WebSockets to enable real-time communication.