Difference between revisions of "FastAPI"
Adelo Vieira (talk | contribs) (→Course 1) |
Adelo Vieira (talk | contribs) (→Course 1) |
||
Line 20: | Line 20: | ||
<br /> | <br /> | ||
− | ===Creating a FastAPI application | + | ===Project 1=== |
+ | |||
+ | '''Creating a FastAPI application:''' | ||
+ | |||
<code>project_1/books.py</code> | <code>project_1/books.py</code> | ||
<syntaxhighlight lang="python3"> | <syntaxhighlight lang="python3"> | ||
Line 101: | Line 104: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
+ | |||
+ | We can run our first app: | ||
+ | <syntaxhighlight lang="bash"> | ||
+ | uvicorn books:app --reload | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | http://127.0.0.1:8000/books | ||
+ | |||
+ | |||
+ | FastAPI has an integrated Swagger: http://127.0.0.1:8000/docs | ||
Revision as of 13:54, 9 June 2023
FastAPI official documentation: https://fastapi.tiangolo.com
Contents
Course 1
FastAPI - The Complete Course 2023 (Beginner + Advanced): https://www.udemy.com/course/fastapi-the-complete-course/
Source code: https://github.com/codingwithroby/FastAPI-The-Complete-Course
Project 1
Creating a FastAPI application:
project_1/books.py
from fastapi import Body, FastAPI
app = FastAPI()
BOOKS = [
{'title': 'Title One', 'author': 'Author One', 'category': 'science'},
{'title': 'Title Two', 'author': 'Author Two', 'category': 'science'},
{'title': 'Title Three', 'author': 'Author Three', 'category': 'history'},
{'title': 'Title Four', 'author': 'Author Four', 'category': 'math'},
{'title': 'Title Five', 'author': 'Author Five', 'category': 'math'},
{'title': 'Title Six', 'author': 'Author Two', 'category': 'math'}
]
@app.get("/books")
async def read_all_books():
return BOOKS
@app.get("/books/{book_title}")
async def read_book(book_title: str):
for book in BOOKS:
if book.get('title').casefold() == book_title.casefold():
return book
@app.get("/books/")
async def read_category_by_query(category: str):
books_to_return = []
for book in BOOKS:
if book.get('category').casefold() == category.casefold():
books_to_return.append(book)
return books_to_return
# Get all books from a specific author using path or query parameters
@app.get("/books/byauthor/")
async def read_books_by_author_path(author: str):
books_to_return = []
for book in BOOKS:
if book.get('author').casefold() == author.casefold():
books_to_return.append(book)
return books_to_return
@app.get("/books/{book_author}/")
async def read_author_category_by_query(book_author: str, category: str):
books_to_return = []
for book in BOOKS:
if book.get('author').casefold() == book_author.casefold() and \
book.get('category').casefold() == category.casefold():
books_to_return.append(book)
return books_to_return
@app.post("/books/create_book")
async def create_book(new_book=Body()):
BOOKS.append(new_book)
@app.put("/books/update_book")
async def update_book(updated_book=Body()):
for i in range(len(BOOKS)):
if BOOKS[i].get('title').casefold() == updated_book.get('title').casefold():
BOOKS[i] = updated_book
@app.delete("/books/delete_book/{book_title}")
async def delete_book(book_title: str):
for i in range(len(BOOKS)):
if BOOKS[i].get('title').casefold() == book_title.casefold():
BOOKS.pop(i)
break
We can run our first app:
uvicorn books:app --reload
FastAPI has an integrated Swagger: http://127.0.0.1:8000/docs
Course 2
Build a Modern API with FastAPI and Python: https://www.udemy.com/course/build-a-movie-tracking-api-with-fastapi-and-python/
During this course we will build a Movie Tracking API with Fast API and Python for tracking movies.
- Section 2: Environment Setup
- We will install Pycharm, Docker and Docker-compose and Insomnia. If you already have an environment you can skip this section.
- Note: If you're an university student you can apply for a free licence of Pycharm Professional here: https://www.jetbrains.com/community/education/#students
- Section 3: Docker Basic
- We will learn some basic docker commands that will help us in improving our workflow.
- Section 4: MongoDB Basics
- We will learn very basic MongoDB commands and we'll execute them inside the docker container and in Pycharm Professional.
- Section 5: Web API Project Structure
- In this section we'll learn how to structure the project and we will write some basic endpoints with FastAPI just to make you more familiar with writing endpoints.
- Section 6: Storage Layer
- We talk about CRUD and we'll apply the repository pattern to develop and In-Memory repository and a MongoDB repository in order to use them within our application. We will also test the implementations.
- Section 7: Movie Tracker API
- We will write the actual API for tracking movies using the previous developed components. We'll implement the application's settings module and we'll add pagination to some of the routes. In the end we will write unit tests.
- Section 8: Middleware
- We'll talk about Fast API middleware and how to write your own custom middleware.
- Section 9: Authentication
- We'll talk about implementing Basic Authentication and validating JWT tokens.
- Section 10: Deployment
- We'll containerize the application and we will deploy it on a local microk8s kubernetes cluster. In the end we'll visualise some metrics with Grafana. Having metrics is a good way to observe your applications performance and behaviour and troubleshoot it.
- Resources for this lecture at https://www.udemy.com/course/build-a-movie-tracking-api-with-fastapi-and-python/learn/lecture/35148314?start=1#overview
Environment setup
- python3, python3-pip, docker, docker Compose.
- IDE: The instructor is using Pycharm Professional, which is paid but we can install Pycharm community. On Ubuntu:
sudo snap install pycharm-community --classic
- Database: MongoDB in a Docker container
- DB IDE:
- I thinks the instructor is also using PyCharm.
- I'll be using the MongoDB for VS Code extension:
- For testing the API we are going to use Insomnia, which is a powerful REST client that allows developers to interact with and test RESTful APIs. It provides a user-friendly interface for making HTTP requests, inspecting responses, and debugging API interactions. The tool is often used for tasks such as sending requests, setting headers, managing authentication, and viewing API documentation.
- To install it on Ubuntu:
sudo snap install insomnia
Creating our Mongo Docker comtainer using docker-compose
docker-compose.yaml
version: '3.1'
services:
mongo:
image: mongo:5.0.14
restart: always
ports:
- "27017:27017"
docker-compose up -d
MongoDB basics
We can start our MongoDB shell by:
docker exec -it fastapi-rest-api-movie-tracker-mongo-1 mongosh
Or we can use our favory DB IDE to manage our MongoDB. I'm using MongoDB for VS Code extension.
Let's see some MongoDB basics:
playground-1.mongodb.js
show('databases') // show databases can be used from mongosh
use('movies') // use movies can be used from mongosh. If the movies collection doesn't exits it will create it
db.movies.insertOne({'title':'My Movie', 'year':2022, watched:false})
db.movies.insertMany([
{
'title': 'The Shawshank Redemption',
'year': 1994,
'watched': false
},
{
'title': 'The Dark Knkght',
'year': 2008,
'watched': false
},
{
'title': 'Puld Fiction',
'year': 1994,
'watched': false
},
{
'title': 'Fight Club',
'year': 1999,
'watched': false
},
{
'title': 'The Lord of the Rings: The Two Towers',
'year': 2002,
'watched': false
},
])
db.movies.findOne()
// Find all the movies
db.movies.find()
// Filtering by title
db.movies.find({'title': 'Fight Club'})
// Find a movie that has been produced before 2000
db.movies.find({'year': {'$lt': 2000}})
// Filter by id
db.movies.find({'_id':ObjectId('647b582d74a86f2cb913d881')})
// Find all movies but skip the first one and limit the result to only 2 movies
db.movies.find().skip(1).limit(2)
// Sorting
db.movies.find().sort({'year':-1}) // 1: ascending; -1: descending
// Select only some attributes
db.movies.find({}, {'title':1, 'year':1})
db.movies.find({}, {'title':0})
// Delete a document
db.movies.deleteOne({'_id': ObjectId('647b55cdc98722c8abe8ee94')})
db.movies.find()
// Updating
db.movies.updateOne({'_id': ObjectId('647b582d74a86f2cb913d87e')}, {$set: {'watched': true}})
db.movies.updateOne({'_id': ObjectId('647b582d74a86f2cb913d87e')}, {$inc: {'year': -3}})
db.movies.find()