FastAPI – Routers and File Structure #6

Posted by


FastAPI provides a powerful mechanism for organizing your code through the use of routers and file structures. By using routers, you can divide your API into separate logical components and handle requests more efficiently. In this tutorial, we will explore how to use routers and how to organize your code using a file structure in FastAPI.

Creating a Router
To create a router in FastAPI, you can use the APIRouter class provided by FastAPI. This class allows you to define the routes, dependencies, and operations for a specific logical component of your API. Here’s how you can create a router in FastAPI:

from fastapi import APIRouter

router = APIRouter()

Defining Routes
Once you have created a router, you can define routes inside the router using the router.get(), router.post(), router.put(), router.delete(), and other methods provided by the router object. Here’s an example of how you can define a simple GET route inside a router:

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

Mounting a Router
To mount a router to your FastAPI application, you can use the include_router() method provided by your FastAPI app instance. Here’s how you can mount a router to your FastAPI application:

from fastapi import FastAPI

app = FastAPI()

app.include_router(router, prefix="/items", tags=["items"])

In the above code snippet, we are mounting the router to our FastAPI application with a prefix of "/items". This means that all routes defined inside the router will be prefixed with "/items". The tags parameter allows you to group routes in the automatic documentation generated by FastAPI.

File Structure
When building a larger FastAPI application, it’s essential to organize your code effectively using a file structure. A typical file structure for a FastAPI application might look like this:

app/
    └── main.py
    └── routers/
        └── __init__.py
        └── items.py

In this file structure, the main.py file is the entry point of the FastAPI application. The routers directory contains different router modules, with each module representing a logical component of the API. The init.py file inside the routers directory is used to initialize the router modules, while the items.py file contains the router for handling item-related routes.

In your main.py file, you can import and mount routers to your FastAPI application as follows:

from fastapi import FastAPI
from app.routers import items

app = FastAPI()

app.include_router(items.router, prefix="/items", tags=["items"])

By organizing your code using a file structure and routers, you can keep your FastAPI application modular, maintainable, and scalable. Routers help you divide your API into logical components, while a file structure helps you manage your codebase effectively. This tutorial has provided an overview of how to use routers and a file structure in FastAPI and highlighted their benefits in building robust APIs.

0 0 votes
Article Rating
47 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
@artemshumeiko
1 month ago

💡 Попробуй онлайн-тренажёр для подготовки к техническому собеседованию: https://clck.ru/3B5gwP 💡

Забирай роадмап изучения самого востребованного фреймворка на Python – FastAPI здесь: https://t.me/ArtemShumeikoBot

@БехрузАбдуллоев-р4с
1 month ago

🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥

@mmmm45454
1 month ago

почему ты изменил файлы не показывая на видео? в прошлом видео у тебя другая структура файлов, и тут ты сразу изменил не показывая как, и что изменил

@orthodox-chanel
1 month ago

почему-то алхимия выдала кортежи а не json/dict как на видео, помогла типизация
class OperationModel(BaseModel):
id: int
quantity: str
figi: str
instrument_type: str
date: datetime.datetime
type: str

@router.get('/{operation_type}', response_model=List[OperationModel])
async def get_specific_operation(operation_type:str , session: AsyncSession = Depends(get_async_session)):
query = select(operation).where(operation.c.type == operation_type)
result = await session.execute(query)
res = result.all()
return res

@kaluginpeter
1 month ago

36:55 хах, неоднозначно получилось)

@Vegas_Silver
1 month ago

Про букву Z было смешно ))) Классный урок, спасибо !

@vladratnikov5705
1 month ago

36:55🤣 в этот момент они могут только появиться

@shalaginovdanila5421
1 month ago

28:47 Артëм, ты откуда взял данные для этой таблицы? Дай ссылку.

@D1NgLo_0
1 month ago

Прикольно, всю структуру проекта поменять и не показать по подробнее…

@mustafinmp
1 month ago

Сейчас в sqlalchemy что-то изменили, и теперь нельзя получить список словарей (объектов), написав result.all() (возвращается объект типа Sequence[Row[_TP]]). По этой теме даже появился вопрос на Стаковерфлоу, посвященный именно этому моменту именно из этого видео. Вместо result.all() теперь работает что-то вроде [dict(r._mapping) for r in result]. Надеюсь, с более сложной структурой это также будет работать.
P.s. увидел в комментариях более элегантное решение через result.mappings().all()

@Denzi33
1 month ago

Легенда…

@Павел-ю5и
1 month ago

Артем спасибо за такие классные видео. Ты большой молодец.)

@voronovmaksim88
1 month ago

Спасибо за видео.

@Яков-ч6ц
1 month ago

Добрый день, кто знает, как сделать валидацию существования внешнего ключа в БД через Pydantic? Чтоб если передаем Id внешнего ключа, которого нет в бд, не возвращала 500 ошибку.

@awesomeex5821
1 month ago

урок про файловую структуру – "я изменил файловую структуру без вас потому что с вами было бы долго"

@andrewbright7487
1 month ago

Ну плохой комментарий, так плохой комментарий😂, а так классная серия видосов, спасибо большое)

@Edvardmoskovka
1 month ago

Добрый вечер Я вместо класс принял параметры от формы html, при попытке записать их в бд в запросе происходить ошибка, пробовал через словарь – ошибка, можете помочь, интересно, как вместо класса получать данные с формы. спасибо
@router.post("/submit-form")
async def submit_form(request: Request, session: AsyncSession = Depends(get_async_session)):
form = await request.form()
id = randint(10**4 , 10**5-1)
stmt = insert(towar).values(id=id,name=form.get('username'),
opus=form.get('texte'), price=form.get('price'),
count=form.get('tcount'), kategoriy=form.get('kategoriy') )
await session.execute(stmt)
await session.commit()
return {"status": "success"}

@ПавелСотников-ж2ю
1 month ago

Добрый день. Подскажите почему на видео не было ошибки при получения get запроса(return result.all())? 29 минута. У меня была ошибка ValueError: [TypeError('cannot convert dictionary update sequence element #0 to a sequence'), TypeError('vars() argument must have dict attribute')]. Когда исправил на return result.mappings().all() ошибка пропала.

@gayratsaidakhmedov5451
1 month ago

Спасибо
из своего опыта скажу – db инициализацию (создание таблиц, триггеров, функций, …) стоит выносить в отдельную папку
будет меньше забот при масштабировании проекта

@ПавелСотников-ж2ю
1 month ago

Интересно на платном курсе тоже такие подставы есть, где лектор что-то делает сам, а ты потом должен догадаться что да как?