FastAPI Projects: Beginner-Friendly With Code Examples

by Jhon Lennon 55 views
Iklan Headers

Hey there, future Pythonistas! Ready to dive into the world of FastAPI? If you're a beginner, don't sweat it! We're gonna break down some super cool FastAPI projects that are perfect for getting your feet wet. And the best part? We'll provide you with source code examples, so you can follow along and learn by doing. This is your chance to level up your Python skills and build some awesome web applications. Let's get started!

Why FastAPI for Beginners?

So, why choose FastAPI? Well, for starters, it's blazing fast! Seriously, FastAPI is designed for speed, both in terms of development and performance. It's built on top of Python type hints, which not only makes your code easier to read and debug but also helps FastAPI validate data automatically. This means fewer bugs and a smoother development process for you, guys. Plus, FastAPI has great documentation, a supportive community, and it's super easy to learn. Unlike other frameworks, FastAPI emphasizes simplicity and clarity, making it an ideal choice for beginners. You'll be able to build production-ready APIs in no time.

Another awesome thing about FastAPI is its compatibility. It plays nicely with other technologies. You can easily integrate it with databases, message queues, and other services. This flexibility allows you to build complex applications without getting bogged down in complexity. And let's not forget about the automatic API documentation using Swagger UI and ReDoc. This feature is a game-changer because it allows you to visualize and interact with your API endpoints right in your browser. This makes testing and debugging your API a breeze. If you're looking for a modern, efficient, and user-friendly framework for building APIs, FastAPI is the way to go, my friend. This guide will provide you with the best FastAPI projects to start your journey.

Project 1: A Simple Hello World API

Let's kick things off with the classic "Hello, World!" example. This is the simplest FastAPI project you can build, but it's a perfect way to understand the basic structure of a FastAPI application. The goal here is to create a basic API endpoint that returns a simple greeting. This project will introduce you to the core concepts of routing, request handling, and response generation.

First, you'll need to install FastAPI and Uvicorn (an ASGI server) using pip:

pip install fastapi uvicorn

Now, create a file named main.py and add the following code:

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
async def read_root():
    return {"message": "Hello, World!"}

In this code, we import FastAPI and create an app instance. We then define a route (/) using the @app.get decorator. When a GET request is made to the root path, the read_root function is executed, and it returns a JSON response with the message "Hello, World!".

To run this application, open your terminal, navigate to the directory where you saved main.py, and run the following command:

uvicorn main:app --reload

This command starts the Uvicorn server, which will serve your FastAPI application. The --reload option enables automatic code reloading, so you don't have to restart the server every time you make changes to your code. Now, open your web browser and go to http://127.0.0.1:8000/. You should see the "Hello, World!" message in your browser. This is your first FastAPI API, congratulations!

To see the automatically generated API documentation, go to http://127.0.0.1:8000/docs (Swagger UI) or http://127.0.0.1:8000/redoc (ReDoc). These pages will show you the available endpoints and allow you to test them directly from your browser. This is one of the most exciting aspects of using FastAPI.

Project 2: A Basic Todo List API

Next up, let's build a simple Todo List API. This project is a step up from the "Hello, World!" example and introduces you to handling data, creating, reading, updating, and deleting resources (CRUD operations), and using request bodies. This is a very common task in API development, and mastering it is crucial. Our Todo List API will allow you to:

  • Create new todo items.
  • Read all todo items.
  • Read a specific todo item.
  • Update a todo item.
  • Delete a todo item.

First, install any dependencies like the previous project.

pip install fastapi uvicorn

Create a file named main.py with the following code:

from fastapi import FastAPI, HTTPException
from typing import List
from pydantic import BaseModel

app = FastAPI()

class Todo(BaseModel):
    id: int
    title: str
    completed: bool = False

todos = []

@app.get("/todos", response_model=List[Todo])
async def read_todos():
    return todos

@app.post("/todos", response_model=Todo)
async def create_todo(todo: Todo):
    todos.append(todo)
    return todo

@app.get("/todos/{todo_id}", response_model=Todo)
async def read_todo(todo_id: int):
    for todo in todos:
        if todo.id == todo_id:
            return todo
    raise HTTPException(status_code=404, detail="Todo not found")

@app.put("/todos/{todo_id}", response_model=Todo)
async def update_todo(todo_id: int, todo: Todo):
    for i, t in enumerate(todos):
        if t.id == todo_id:
            todos[i] = todo
            return todo
    raise HTTPException(status_code=404, detail="Todo not found")

@app.delete("/todos/{todo_id}")
async def delete_todo(todo_id: int):
    for i, todo in enumerate(todos):
        if todo.id == todo_id:
            del todos[i]
            return {"message": "Todo deleted"}
    raise HTTPException(status_code=404, detail="Todo not found")

In this code:

  • We define a Todo model using Pydantic, which specifies the structure of our todo items (id, title, and completed status).
  • We create a list called todos to store our todo items (in a real-world application, you'd use a database).
  • We define several API endpoints using the @app.get, @app.post, @app.put, and @app.delete decorators for reading, creating, updating, and deleting todo items.
  • We use response models to specify the structure of the responses and use HTTPException to handle errors.

Run the application using uvicorn main:app --reload. You can then test the API using Swagger UI or a tool like Postman. This project gives you a solid foundation for building more complex APIs.

Project 3: A Simple Blog API

Alright, let's ramp things up a bit and build a simple Blog API. This project builds upon the Todo List API by introducing more complex data structures and relationships. It will enable you to create, read, update, and delete blog posts, as well as comments associated with each post. This project will help you understand how to manage data with more intricate relationships and structure your API for a more complex application.

First, you'll need to install any dependencies, like the previous projects.

pip install fastapi uvicorn

Create a file named main.py with the following code:

from fastapi import FastAPI, HTTPException
from typing import List, Optional
from pydantic import BaseModel

app = FastAPI()

class Comment(BaseModel):
    id: int
    content: str

class Post(BaseModel):
    id: int
    title: str
    content: str
    comments: List[Comment] = []

posts = []

@app.post("/posts", response_model=Post)
async def create_post(post: Post):
    posts.append(post)
    return post

@app.get("/posts", response_model=List[Post])
async def read_posts():
    return posts

@app.get("/posts/{post_id}", response_model=Post)
async def read_post(post_id: int):
    for post in posts:
        if post.id == post_id:
            return post
    raise HTTPException(status_code=404, detail="Post not found")

@app.put("/posts/{post_id}", response_model=Post)
async def update_post(post_id: int, updated_post: Post):
    for i, post in enumerate(posts):
        if post.id == post_id:
            posts[i] = updated_post
            return updated_post
    raise HTTPException(status_code=404, detail="Post not found")

@app.delete("/posts/{post_id}")
async def delete_post(post_id: int):
    for i, post in enumerate(posts):
        if post.id == post_id:
            del posts[i]
            return {"message": "Post deleted"}
    raise HTTPException(status_code=404, detail="Post not found")

@app.post("/posts/{post_id}/comments", response_model=Comment)
async def create_comment(post_id: int, comment: Comment):
    for i, post in enumerate(posts):
        if post.id == post_id:
            comment.id = len(post.comments) + 1  # Simple ID generation
            posts[i].comments.append(comment)
            return comment
    raise HTTPException(status_code=404, detail="Post not found")

In this code:

  • We define Comment and Post models using Pydantic, which specify the structure of our blog posts and comments.
  • We include a list of comments within the Post model.
  • We define API endpoints for creating, reading, updating, and deleting posts, as well as creating comments for specific posts.
  • We use a simple in-memory list (posts) to store our data (in a real-world scenario, you would use a database).

Run the application using uvicorn main:app --reload. You can test the API using Swagger UI or a tool like Postman. This project provides a valuable illustration of handling data relationships in an API context.

Project 4: API with Database Integration (Optional)

Let's integrate a database. This is a crucial step for almost any real-world application, as it allows you to persist your data. We'll use SQLite for simplicity, but the principles can be applied to other databases (PostgreSQL, MySQL, etc.). This project will demonstrate how to connect to a database, define data models, and perform CRUD operations. This integration is essential for creating production-ready applications.

First, you'll need to install the necessary packages:

pip install fastapi uvicorn sqlalchemy databases

Next, create a file named main.py with the following code:

from fastapi import FastAPI, HTTPException
from typing import List
from pydantic import BaseModel
from sqlalchemy import create_engine, Column, Integer, String, Boolean
from sqlalchemy.orm import sessionmaker, declarative_base
from databases import Database

DATABASE_URL = "sqlite:///./test.db"

# SQLAlchemy Setup
engine = create_engine(DATABASE_URL)
Base = declarative_base()

# Databases Setup
database = Database(DATABASE_URL)

class Todo(Base):
    __tablename__ = "todos"

    id = Column(Integer, primary_key=True, index=True)
    title = Column(String)
    completed = Column(Boolean, default=False)

Base.metadata.create_all(bind=engine)

app = FastAPI()

@app.on_event("startup")
async def startup():
    await database.connect()

@app.on_event("shutdown")
async def shutdown():
    await database.disconnect()

class TodoCreate(BaseModel):
    title: str

class TodoUpdate(BaseModel):
    title: str
    completed: bool

class TodoResponse(BaseModel):
    id: int
    title: str
    completed: bool

@app.post("/todos", response_model=TodoResponse)
async def create_todo(todo: TodoCreate):
    query = """
        INSERT INTO todos (title, completed) VALUES (:title, :completed)
    """
    values = {"title": todo.title, "completed": False}
    await database.execute(query=query, values=values)
    # Fetch the newly created todo
    query = """
        SELECT id, title, completed FROM todos WHERE title = :title ORDER BY id DESC LIMIT 1
    """
    values = {"title": todo.title}
    todo_created = await database.fetch_one(query=query, values=values)
    return {"id": todo_created["id"], "title": todo_created["title"], "completed": bool(todo_created["completed"])}

@app.get("/todos", response_model=List[TodoResponse])
async def read_todos():
    query = "SELECT id, title, completed FROM todos"
    rows = await database.fetch_all(query=query)
    return [{"id": row["id"], "title": row["title"], "completed": bool(row["completed"])} for row in rows]

@app.get("/todos/{todo_id}", response_model=TodoResponse)
async def read_todo(todo_id: int):
    query = "SELECT id, title, completed FROM todos WHERE id = :todo_id"
    values = {"todo_id": todo_id}
    todo = await database.fetch_one(query=query, values=values)
    if todo is None:
        raise HTTPException(status_code=404, detail="Todo not found")
    return {"id": todo["id"], "title": todo["title"], "completed": bool(todo["completed"])}

@app.put("/todos/{todo_id}", response_model=TodoResponse)
async def update_todo(todo_id: int, todo: TodoUpdate):
    query = """
        UPDATE todos SET title = :title, completed = :completed WHERE id = :todo_id
    """
    values = {"todo_id": todo_id, "title": todo.title, "completed": todo.completed}
    await database.execute(query=query, values=values)

    # Fetch the updated todo
    query = "SELECT id, title, completed FROM todos WHERE id = :todo_id"
    values = {"todo_id": todo_id}
    todo_updated = await database.fetch_one(query=query, values=values)

    if todo_updated is None:
        raise HTTPException(status_code=404, detail="Todo not found")

    return {"id": todo_updated["id"], "title": todo_updated["title"], "completed": bool(todo_updated["completed"])}

@app.delete("/todos/{todo_id}")
async def delete_todo(todo_id: int):
    query = "DELETE FROM todos WHERE id = :todo_id"
    values = {"todo_id": todo_id}
    await database.execute(query=query, values=values)
    return {"message": "Todo deleted"}

In this code:

  • We use SQLAlchemy to define the data model for our Todo items. This will create a table in our SQLite database.
  • We integrate the database using the Databases library. You can perform SQL queries with a modern style.
  • We create a database connection on startup and close it on shutdown. Make sure you don't keep the database connection open for a long time in order not to overload the resource.
  • We use the CRUD operations for interacting with the database. We use SQL commands for our operations, so it can be easy for you to manage the query by just typing, and we fetch the results.

Run the application using uvicorn main:app --reload. Test the API using Swagger UI or a tool like Postman. Now, your data is persisted across sessions!

Conclusion and Next Steps

So there you have it, guys! We've covered some awesome FastAPI projects for beginners, including a "Hello, World!" example, a Todo List API, a Blog API, and an API with database integration. You now have a solid foundation for building FastAPI applications. Keep practicing and experimenting. Here are some next steps you can take:

  • Explore advanced features: Look into features like dependency injection, middleware, and background tasks.
  • Integrate with more databases: Experiment with PostgreSQL, MySQL, or MongoDB.
  • Build more complex projects: Create APIs for user authentication, e-commerce platforms, or social media applications.
  • Contribute to open source: Share your code and help other developers. This will help you learn the best practices and collaborate with the community.
  • Deploy your applications: Learn how to deploy your FastAPI applications to platforms like Heroku, AWS, or Google Cloud.

Building APIs can seem intimidating at first, but with FastAPI and these beginner-friendly projects, you're well on your way to becoming a skilled API developer. Keep coding, keep learning, and have fun! The future is bright. Good luck, and happy coding! We know you can do it!