DEV Community

loading...
Cover image for Microservice in Python using FastAPI

Microservice in Python using FastAPI

Paurakh Sharma Humagain on March 19, 2020

Creating Microservices with Python Introduction to Microservices Benefits of Microservice Drawbacks of Microservice Why Microservi...
pic
Editor guide
Collapse
cimmanuel profile image
Immanuel Kolapo

Hello @paurakhsharma , I tried using these steps to create another project but when I try inserting in the database, I get asyncpg.exceptions.DataError: invalid input for query argument $1: 213127865166 (value out of int32 range). What could be wrong? Kindly assist!
You can see this stack overflow for more https://stackoverflow.com/questions/63404139/asyncpg-exceptions-dataerror-invalid-input-for-query-argument-1-217027642536

Collapse
paurakhsharma profile image
Paurakh Sharma Humagain Author

I see you have already accepted the answer in StackOverflow, good luck :)

Collapse
tadashii1417 profile image
tadashii1417

Thanks a lot for your article, really appreciate that !

But I have a little problem, when I clone the code and run "docker-compose up -d", it return
"502 Bad Gateway"

Do you know how to fix this ? I quite new to docker and nginx :v

Thanks in advance !

Collapse
uwevanopfern profile image
UweVanOpfern

I was facing the issue, fixed by solving this BUG, because in docker-compose.yml we used DATABASE_URI under movie-service, change it in movie-service\app\api\db.py as well, replace everywhere you have DATABASE_URL to DATABASE_URI

Collapse
nyancodeid profile image
Ryan Aunur Rassyid

same here

[SOLVED]
Check your docker-compose logs to see what problem came from.

docker-compose logs

Collapse
sobolevn profile image
Nikita Sobolev

Thanks a lot for your introduction with FastAPI.

Consider using wemake-python-styleguide for your next FastAPI project.

It is the strictest Python linter out there. It will help you to find possible errors in your code early, show you possible refactoring opportunities, and enforce consistency across the project's codebase.

Check it out:

GitHub logo wemake-services / wemake-python-styleguide

The strictest and most opinionated python linter ever!

wemake-python-styleguide

wemake.services Supporters Build Status codecov Python Version wemake-python-styleguide


Welcome to the strictest and most opinionated python linter ever.

wemake-python-styleguide logo

wemake-python-styleguide is actually a flake8 plugin with some other plugins as dependencies.

Quickstart

pip install wemake-python-styleguide

You will also need to create a setup.cfg file with the configuration.

We highly recommend to also use:

  • flakehell for easy integration into a legacy codebase
  • nitpick for sharing and validating configuration across multiple projects

Running

flake8 your_module.py

This app is still just good old flake8 And it won't change your existing workflow.

invocation results

See "Usage" section in the docs for examples and integrations.

We also support GitHub Actions as first class-citizens Try it out!

What we are about

The ultimate goal of this project is to make all people write exactly the same python code.

flake8 pylint black mypy wemake-python-styleguide
Formats code?
Finds style issues? 🤔 🤔
Finds bugs? 🤔
Collapse
paurakhsharma profile image
Paurakh Sharma Humagain Author

Sure, I will definitely have a look at it.
Thanks for sharing 🙂

Collapse
bagonzalo profile image
Curated

Major bugs:
(1) you need to initialize first de dabases in the "docker-compose.yml". Otherwise the services try to conect (in my case) to them without being initialize.
(2) change DATABASE_URL for DATABASE_URI here:
"""

~/python-microservices/movie-service/app/api/db.py

import os

from sqlalchemy import (Column, DateTime, Integer, MetaData, String, Table,
create_engine, ARRAY)

from databases import Database

DATABASE_URL = os.getenv('DATABASE_URL')
"""

Collapse
uwevanopfern profile image
UweVanOpfern

Helped me, a lot, thanks

Collapse
bagonzalo profile image
Curated

And thanks indeed for the post.

Collapse
demianbrecht profile image
Demian Brecht

This is a great, great post that touches many things. FastAPI has been on my back burner for quite some time to try out so thanks for sharing!

A question about async database queries though: Last time I looked, depending on where your database is (same network boundary as your app), you can actually incur a performance penalty by using the event loop. Do you know if that's still the case? I'm imagining a lot of work has gone into that since I last looked so maybe it's not as noticeable. That said, you'd still be freeing up the worker with the async call, so depending on your application needs, taking that performance hit may still be best.

Collapse
paurakhsharma profile image
Paurakh Sharma Humagain Author

I am glad that you liked it.
I am not so sure about it either.

Collapse
turningpro profile image
turningpro

Excellent article. Looking forward to read more of your posts.

Collapse
turningpro profile image
turningpro

If you can do a variation with mongodb would be much appreciated.
Not much content out there on that stack.

Collapse
paurakhsharma profile image
Paurakh Sharma Humagain Author

Thank you for following the article. I am glad it helped you.

Thank you for the suggestion, I will try to come up with the article for using FastAPI with Momgodb

Thread Thread
wborbajr profile image
Waldir Borba Jr 

I earned another fan. Yes, please make an article FastAPI + Mongo... pls, pls plssssss

Collapse
plaoo profile image
Paolo Monni

Beautiful article, following what you made I created a personal "library" project. I would like to ask you if you can add the way to do the tests on the various endpoints, because following the fastapi documentation I find myself having problems with the db

Collapse
coolguy1210 profile image
Aravinth Ponnusamy

Hey Paurakh, first of all, thanks for the post very helpful. I am trying to understand a few things here any guidance would be appreciated. I am a novice so, pls excuse if my questions are lame,

Q1 - I tried the example that you have given were there were only 4 fields name, plot, genres, casts
everything is fine. Now if I need to make this work for let's say mongo, I need to add 2 more fields id and year, how would you go about doing that?

fake_movie_db = [
{
'name': 'Star Wars: Episode IX - The Rise of Skywalker',
'plot': 'The surviving members of the resistance face the First Order once again.',
'genres': ['Action', 'Adventure', 'Fantasy'],
'casts': ['Daisy Ridley', 'Adam Driver']
}
]

Q2 - when I tried the same with our existing code, POST request was successful but when do a get it was not showing any of the new fields. there should be an error in this scenario?

Thanks
Aravinth

Collapse
paurakhsharma profile image
Paurakh Sharma Humagain Author

No, this is not a lame question. Thank you for asking the question.

To achieve this you have to add id and year to your Movie model.

e.g

class Movie(BaseModel):
    name: str
    plot: str
    genres: List[str]
    casts: List[str]
    id: str
    year: str

I hope that answers your question. Please let me know how that goes.

Collapse
olegasdo profile image
olegasdo

Thank you.

Very nice article

Collapse
paurakhsharma profile image
Collapse
5no0p profile image
Mohammed Almustafa

Dosen't work for me

this is my docker-compose.yml:

version: '3.7'

services:
movie_service:
build: ./movie-service
command: uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
volumes:
- ./movie-service/:/app/
ports:
- 8001:8000
environment:
- DATABASE_URI=postgresql://postgres:"password"@movie_db/movie_db_dev
- CAST_SERVICE_HOST_URL=cast_service:8000/api/v1/casts/

movie_db:
image: postgres:10.14
volumes:
- postgres_data_movie:/var/lib/postgresql/data/
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD="password"
- POSTGRES_DB=movie_db_dev

cast_service:
build: ./cast-service
command: uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
volumes:
- ./cast-service/:/app/
ports:
- 8002:8000
environment:
- DATABASE_URI=postgresql://postgres:"password"@cast_db/cast_db_dev

cast_db:
image: postgres:10.14
volumes:
- postgres_data_cast:/var/lib/postgresql/data/
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD="password"
- POSTGRES_DB=cast_db_dev

nginx:
image: nginx:latest
ports:
- "8080:8080"
volumes:
- ./nginx_config.conf:/etc/nginx/conf.d/default.conf
depends_on:
- cast_service
- movie_service

volumes:
postgres_data_movie:
postgres_data_cast:

hint: "password" is my postgresql password

My nginx runing:
prnt.sc/v0qi2v

My docker:
prnt.sc/v0qind

Collapse
spansky profile image
Leon

An excellent article. Thanks a lot.

Collapse
paurakhsharma profile image
Paurakh Sharma Humagain Author

Thank you so much, I am glad that you liked it 😊

Collapse
mpavlov profile image
Marat Pavlov

Thanks!
1q: why did you use venv instead pipenv? I saw your previous articles and you use pipenv there

Collapse
paurakhsharma profile image
Paurakh Sharma Humagain Author

I think people are more familiar with venv instead fo pipenv so I choose venv.. But you can use pipenv instead, if you like it 🙂

Collapse
minchulkim87 profile image
Min

Wow. Thank you so much! I was looking for something like this.

Collapse
paurakhsharma profile image
Paurakh Sharma Humagain Author

Awesome 😊
Let me know what you would like to see next.

Collapse
osema profile image
osema

wooow thank u very much bro great tuto
one thing is missing i need it fastapi oauth2

Collapse
paurakhsharma profile image
Paurakh Sharma Humagain Author

I am glad that you like the post. I will try to come up with an article covering it.

Collapse
lioncoding profile image
Kodjo Laurent Egbakou

Very nice article !
Please, can you add Travis or GitHub actions to the project and deploy it on heroku ?
Maybe update the article too. It will be nice !

Collapse
paurakhsharma profile image
Paurakh Sharma Humagain Author

Thanks for the suggestion. I will try to come up with another article regarding deployment.

Collapse
uwevanopfern profile image
UweVanOpfern

Really very very useful article, thanks @paurakhsharma , we need another one for deploying as well

Collapse
pvssrikanth profile image
pvssrikanth

Hi ,
can i get the complete code url for this article.

I am in mid way but running few errors.

please send the complete code url

thanks

Collapse
tomarnaez profile image
TomArnaez

Thanks for this. I wanted to ask what's the easiest way to define a relationship a many-to-many when using encode/database?