In my exploration of Python application development, I discovered FastAPI, a web framework for Python. With so many frameworks available, choosing the right one depends on project requirements. Here are some reasons why FastAPI might be a great fit for your next project
- High performance: It boasts performance comparable to Node.js and Go frameworks.
- Easy to learn: FastAPI uses clear syntax and leverages Python’s type hints for data validation and automatic documentation.
- Automatic Documentation: API endpoints are automatically documented based on your code, saving development time.
In words of FastAPI developers, FastAPI stands on the shoulders of giants:
Installation and Setup
pip install fastapi
pip install "uvicorn[standard]"
Building a basic app with FastAPI
Create a file main.py
and use the following code
from fastapi import FastAPI
app = FastAPI()
@app.get("/health")
def health_check() -> dict:
return {"message": "Hello World!"}
@app.get("/books/{book_id}")
def get_(book_id: int) -> dict:
return {"book_id": book_id}
Run the app
uvicorn main:app --reload
Now the application must have started to run in your local environment. To access the app, goto http://127.0.0.1:8000/docs
You will be seeing an automatic swagger docs created and you can run the api
Now, we can update the code to add some CRUD operations. A Pydantic BaseModel
is a class that defines how your data looks like and the validation requirements it needs to pass in order to be valid. You can also add validation to the model
from pydantic import BaseModel, Field
class Book(BaseModel):
id: int
name: str = Field(title="The description of the item", min_length=10, max_length=50
)
price: float = Field(gt=0, description="The price must be greater than zero")
from fastapi import FastAPI
from pydantic import BaseModel, Field
app = FastAPI()
class Book(BaseModel):
id: int
name: str = Field(title="The description of the item", min_length=10, max_length=50
)
price: float = Field(gt=0, description="The price must be greater than zero")
books = []
@app.get("/health")
def health_check():
return {"message": "Hello World!"}
@app.post("/books")
def create_book(book: Book):
books.append(book)
return {"result": "Book added successfully", "error": ""}
@app.get("/books/{book_id}")
def get_book(book_id: int):
for book in books:
if book.id == book_id:
return {"result": book, "error": ""}
return {"result": "", "error": "Book not found."}
@app.put("/books/{book_id}")
def update_book(book_id: int, book_to_update: Book):
for idx, book in enumerate(books):
if book.id == book_id:
books[idx] = book_to_update
return {"result": book_to_update, "error": ""}
return {"result": "", "error": "Book not found."}
@app.delete("/books/{book_id}")
def delete_book(book_id: int):
for idx, book in enumerate(books):
if book.id == book_id:
del books[idx]
return {"message": "Book deleted successfully", "error": ""}
return {"message": "", "error": "Delete failed. Book not found."}
Conclusion
This CRUD example demonstrates how API calls can be made with clear data validation and informative responses. While this serves as a springboard for your FastAPI journey, there’s a vast world of functionalities waiting to be explored. You can implement more intricate data validations, integrate with databases for persistence, and leverage features like security and asynchronous programming to build robust and scalable APIs. Remember, this blog serves as a launchpad; the true power of FastAPI awaits your exploration!