Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to save data in Mongo? #151

Closed
oskar-gmerek opened this issue Jul 22, 2020 · 3 comments
Closed

How to save data in Mongo? #151

oskar-gmerek opened this issue Jul 22, 2020 · 3 comments

Comments

@oskar-gmerek
Copy link

oskar-gmerek commented Jul 22, 2020

  • FastAPI Contrib version: 0.2.7
  • FastAPI version: 0.59.0
  • Python version: 3.7.7
  • Operating System: MacOS

Description

Hello. I was looking for tools with what will be possible to play FastAPI with MongoDB in nice, simple way, because I never before using NoSQL. I found FastAPI_Contrib, my attention takes especially two of features:

  1. ModelSerializers: serialize (pydantic) incoming request, connect data with DB model and save

  2. MongoDB integration: Use models as if it was Django (based on pydantic models)

I was trying all day to understand the documentation how to use FastAPI_Contrib, unfortunately documentation is so hard for entry-level users. What I want to achieve at this time is nothing more than just:

  1. Create Model
  2. Create Serializer
  3. Send the request with data from for example Postman
  4. Save that data in MongoDB

Just a first step of CRUD...

What I Did

I was trying take it in very different ways, but for this issue I will present the most simply way based on documentation...

Project Structure:
project/
- project/
-- sample/
--- __init__.py
--- serializers.py
- __init__.py
- main.py

project/main.py:

import os

from fastapi_contrib.db.utils import setup_mongodb, create_indexes
import motor.motor_asyncio
from fastapi import FastAPI
from dotenv import load_dotenv

from project.serializers import sample_router

load_dotenv(verbose=True)
DATABASE_URL =os.getenv("DB_URL")

SECRET = os.getenv("SECRET")

CONTRIB_APPS = os.getenv("CONTRIB_APPS")
CONTRIB_APPS_FOLDER_NAME = os.getenv("CONTRIB_APPS_FOLDER_NAME")

client = motor.motor_asyncio.AsyncIOMotorClient(
    DATABASE_URL, uuidRepresentation="standard"
)
db = client["sample"]

app = FastAPI()

@app.on_event("startup")
async def startup():
    setup_mongodb(db)
    await create_indexes()
    print('Is it connected to DB?')

app.include_router(sample_router)

project/sample/serializers.py

from fastapi import APIRouter
from fastapi_contrib.db.models import MongoDBModel
from fastapi_contrib.serializers import openapi
from fastapi_contrib.serializers.common import Serializer

# from yourapp.models import SomeModel

sample_router = APIRouter()


class SomeModel(MongoDBModel):
    field1: str

    class Meta:
        collection = "test"


@openapi.patch
class SomeSerializer(Serializer):
    read_only1: str = "const"
    write_only2: int
    not_visible: str = "42"

    class Meta:
        model = SomeModel
        exclude = {"not_visible"}
        write_only_fields = {"write_only2"}
        read_only_fields = {"read_only1"}


@sample_router.post("/test/", response_model=SomeSerializer.response_model)
async def root(serializer: SomeSerializer):
    model_instance = await serializer.save()
    return model_instance.dict()

When I send data as POST to /test/ from postman

{
  "write_only2": 2,
  "field1": "string"
}

or by curl

curl -X POST "http://127.0.0.1:8000/test/" -H  "accept: application/json" -H  "Content-Type: application/json" -d "{\"id\":0,\"field1\":\"string\",\"write_only2\":0}"

Then I got errors:
Screenshot 1

if I will remove:

    class Meta:
        collection = "test"

as it in an example in documentation then I got other error:
Screenshot 2

I will be grateful if someone will explain to me using simple examples how to properly combine models, serializers, and perform CRUD operations on them reflected in MongoDB.

By the way.
I think is it good idea to rewrite documentation to be more affordable to not so advenced users. And add to them a tutorial, awesome will be to see there real world examples. I think, good documentation can make this package a very popular.

Regards,
Oskar

@ilias-ant
Copy link

I also had a similar problem, resulting in AttributeError: 'NoneType' object has no attribute 'split' - it will be awesome if we can get some guidance on this.

@smeggingsmegger
Copy link

Hey all, I forked, dove-in, and figured it out. You need an ENV variable called CONTRIB_FASTAPI_APP and it needs to be whatever your fastapi main app is in dot notation as a string.

i.e. Mine is 'main.app'

os.environ['CONTRIB_FASTAPI_APP'] = 'main.app' to test.

@levchik
Copy link
Contributor

levchik commented Sep 4, 2020

Yeah guys, sorry that this is not in the docs. Hopefully I will have time soon to update descriptions on how everything works in various topics. And @smeggingsmegger thanks for the help here!

@levchik levchik closed this as completed Sep 4, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants