-
|
Following along the brilliant FastAPI tutorial, however an area doesn't seem to be clear. As an example, why not do: where spam sits in a python file in a "dependency folder"? So the folder structure would look something like: Any extra routes can then call their own dependency files and functions within the dependency folder.. What value does the "route" functionality provide? Links to dependency and APIrouter tutorial: |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
|
Let's break these down because they are fundamentally different concepts. First the APIRouter. The APIRouter just provides a way to breakup the application without having to share a global from fastapi import FastAPI
app = FastAPI()
@app.get('/users')
def list_users():
return
@app.get('/posts')
def list_posts():
returnBut now pretend you want to keep adding routes and you want to separate your user routes and your posts routes. The following 3 modules create an app that is functionally identical to the single file app above. The posts route file The users route file from fastapi import APIRouter
router = APIRouter()
@router.get('/users')
def list_users():
returnThe main app file from fastapi import FastAPI
from . import posts, users
app = FastAPI()
app.include_router(posts.router)
app.include_router(users.router)As you can see this is a lot more verbose for doing exactly the same thing, but it allows you to split things up the way you like when you have a large application. Now for dependencies. Dependencies get their name from dependency injection. When you use a dependency FastAPI is injecting whatever it is that your app depends on into your routes. This is great for testing! For example pretend your application uses a third party API, like the github API. In production you want to use the real thing, in tests you just want to define some static data to return instead. One cool thing about dependencies is that your dependencies can also have dependencies! Combine this with the fact that dependencies are just python functions (or generators) and you can create really powerful behavior! Lets implement a small dependency tree to do what I described above and override the api with a static data for testing. # app.py
import os
from fastapi import FastAPI, Depends
from github_api import GithubAPI
app = FastAPI()
def config():
return {'github_access_token': 'mysupersecrettoken'}
def github_api(config=Depends(config)):
return GithubAPI(token=config['github_access_token'])
@app.get('/users/{user_id}')
def get_user(user_id: str, api=Depends(github_api)):
return api.get_user(user_id)Then in your tests you can override the Example tests.py import pytest
from fastapi.testclient import TestClient
from app import app as webapp, github_api
class MockGithubAPI:
def get_user(user_id):
return {'user': {...}}
@pytest.fixture
def app():
app.dependeny_overrides[github_api] = MockGithubAPI()
yield TestClient(app)
app.dependency_overrides.clear()
def test_get_user(app):
resp = app.get('/users/r-bar')
assert resp.status_code == 200We are overriding the I highly recommend you look around at how the real world app example is structured as a good guideline on how to structure a larger project if you are struggling. I also have found the fullstack template repo to be a handy way to get started. edit: Fixed some of the errors pointed out by @Stontonnot 's comment |
Beta Was this translation helpful? Give feedback.
Let's break these down because they are fundamentally different concepts. First the APIRouter. The APIRouter just provides a way to breakup the application without having to share a global
FastAPIinstance around. In a small app you add routes like this:But now pretend you want to keep adding routes and you want to separate your user routes and your posts routes. The following 3 modules create an app that is functionally identical to the single file app above.
The posts route file
posts.py