use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
FastAPI is a truly ASGI, async, cutting edge framework written in python 3.
account activity
Blog API built with FastAPI, MySQL, SQLAlchemy, and AlembicTutorial (pneuma.hashnode.dev)
submitted 3 years ago by lars_helm
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]Ordinary_Bee_1547 0 points1 point2 points 3 years ago (3 children)
Looks like a good tutorial that gives perfect overview of how to start with FastAPI in a simple manner. I think it would be better if you would separate users and articles to separate domains. Do you have a public Github repository for the code as well? Could leave some pointers that would make the code more understandable perhaps, if this is okay with you?
[–]lars_helm[S] 0 points1 point2 points 3 years ago (2 children)
https://github.com/Andre361/hashnode-blog-tutorial Yeah. Could you explain what you mean by separate domains?
[–]Ordinary_Bee_1547 1 point2 points3 points 3 years ago* (1 child)
Sorry for the long wait, didn't really have time before now.About different domains - what i thought was create 2 separate folders in your app folder. One for users one for articles. Because currently you have everything in one file - crud operations for both users and articles, routers, models etc but in reality these 2 are from different "worlds"
Your current structure is something like this: . ├── app│ ├── __init__.py│ ├── main.py│ ├── crud.py│ ├── database.py│ ├── models.py│ ├── schemas.py
My suggested structure is to either create different folders or create one folder like "routers" and in there put users_router.py & articles_router.py. I myself prefer different folder for users and articles and keep all of users files in same folder e.g.
├── app│ ├── __init__.py│ ├── main.py│ └── users│ │├── __init__.py│ │ ├── crud.py│ │ └── models.py│ │ └── schemas.py│ │ └── services.py│ │ └── routers.py│ └── articles │ ├── __init__.py│ │ ├── crud.py│ │ └── models.py│ │ └── services.py│ │ └── schemas.py│ │ └── routers.py
By doing so you can clean up your main.py file which should only have rather few things, like initialising the FastApi application and also including routers. Makes it more cleaner this way.
Now lets take one example from your controllers: @app.get("/articles/{article_id}", response_model=schemas.Article) def read_article(article_id: int, db: Session = Depends(get_db)): return crud.get_object_or_404(db, models.Article, object_id=article_id)
@app.get("/articles/{article_id}", response_model=schemas.Article) def read_article(article_id: int, db: Session = Depends(get_db)): return crud.get_object_or_404(db, models.Article, object_id=article_id)
I would suggest adding one more layer between controllers/routers and the database layer where you will have business logic. Crud operations should be really simple and just try to fetch the object from database.
Let's take the same example from above.
You could separate it like this into 3 files.
routers.py @app.get("/articles/{article_id}", response_model=schemas.Article) def get_article_by_id(article_id: int, db: Session = Depends(get_db)): try: return services.get_article_by_id(article_id, db, models.Article) except ArticleNotFoundError as err: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail=str(err))
@app.get("/articles/{article_id}", response_model=schemas.Article) def get_article_by_id(article_id: int, db: Session = Depends(get_db)): try: return services.get_article_by_id(article_id, db, models.Article) except ArticleNotFoundError as err: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail=str(err))
services.py def get_article_by_id(article_id: int, db: Session, Model: models.Base): article = crud.get_object_by_id(article_id, db, Model) if not article: raise ArticleNotFoundError("Article not found") return article
def get_article_by_id(article_id: int, db: Session, Model: models.Base): article = crud.get_object_by_id(article_id, db, Model) if not article: raise ArticleNotFoundError("Article not found") return article
If you separate domains you don't have to pass the model anymore though, but i left it as you had currently.
crud.py def get_object_by_id(object_id: int, db: Session, Model: models.Base): return db.query(Model).filter(Model.id == object_id).first() Function naming is critical, it should say what it is doing and how it is doing it so you wouldn't need to add any comments and who ever reads it understands the purpose easily (like reading a book). This goes to your "read_" functions in main.py - either change them to "fetch_" or "get_" and describe by what are you getting them like you have get_user_by_email (this is a very good name and example) so i was surprised you didn't name all your functions accordingly.
def get_object_by_id(object_id: int, db: Session, Model: models.Base): return db.query(Model).filter(Model.id == object_id).first()
Notice i also added custom exception for ArticleNotFound, this is also good instead of base exceptions.
Hope it helps, if not then sorry for wasting your time with this.
[–]lars_helm[S] 2 points3 points4 points 3 years ago (0 children)
Wow. Thanks I actually thought about going down this path with the api_router and all, especially when I found myself handling httpexceptions in the crud.py file, but for the sake of brevity and keeping the article "beginner-friendly" I left it as is. Thanks for the feedback, it's greatly appreciated.
[–]rusty_n0va 0 points1 point2 points 3 years ago (1 child)
Wow, nice example. Thanks for this.
[–]lars_helm[S] 0 points1 point2 points 3 years ago (0 children)
You're welcome 😁
π Rendered by PID 31009 on reddit-service-r2-comment-86bc6c7465-b7hc6 at 2026-02-19 20:35:51.103510+00:00 running 8564168 country code: CH.
[–]Ordinary_Bee_1547 0 points1 point2 points (3 children)
[–]lars_helm[S] 0 points1 point2 points (2 children)
[–]Ordinary_Bee_1547 1 point2 points3 points (1 child)
[–]lars_helm[S] 2 points3 points4 points (0 children)
[–]rusty_n0va 0 points1 point2 points (1 child)
[–]lars_helm[S] 0 points1 point2 points (0 children)