FastAPI-VO

Utilities to simplify FastAPI view objects


Keywords
fastapi, view, objects, model
License
MIT
Install
pip install FastAPI-VO==0.1.4

Documentation

FastAPI-VO Logo

FastAPI-VO, view objects for FastAPI designed for simplicity.

Test Publish Coverage Package version


Documentation: http://fastapi-vo.r3ck.com.br

Source Code: https://github.com/rennancockles/fastapi-vo


FastAPI-VO is a lightweight library for creating simple FastAPI view objects just by picking or omitting parts of a model. It is designed to be simple, intuitive and easy to use.

It is so simple that doesn't need much explanation. Just check some examples below.

Requirements

A recent and currently supported version of Python (right now, Python supports versions 3.6 and above).

FastAPI-VO only requires FastAPI, but it will be automatically installed when you install FastAPI-VO.

Installation

$ pip install fastapi-vo
---> 100%
Successfully installed fastapi-vo

Example

For an introduction to FastAPI, see the FastAPI documentation.

Here's a quick example. ✨

👀 Full code preview
from typing import List
from fastapi import FastAPI
from pydantic import BaseModel

from fastapi_vo import Omit, Pick


class User(BaseModel):
    username: str
    password: str
    is_active: bool = True
    is_admin: bool = False


Auth = Pick(User, ["username", "password"], classname="Auth")
NoPassword = Omit(User, "password", classname="NoPasswordUser")

app = FastAPI()
johndoe = User(
    username="johndoe",
    password="secret",
    is_admin=False,
    is_active=True,
)
janedoe = User(
    username="janedoe",
    password="janesecret",
    is_admin=True,
    is_active=True,
)


@app.get("/users/", response_model=List[NoPassword])
async def list_users():
    return [johndoe, janedoe]


@app.get("/users/john/", response_model=NoPassword)
async def get_user():
    return johndoe


@app.get("/login/", response_model=NoPassword)
async def login(user: Auth):
    # some authentication logic in here
    return user

Create a Model

Let's create a model called user with:

  • username
  • password
  • is_active
  • is_admin
from pydantic import BaseModel


class User(BaseModel):
    username: str
    password: str
    is_active: bool = True
    is_admin: bool = False


johndoe = User(
    username="johndoe",
    password="secret",
    is_admin=False,
    is_active=True,
)

janedoe = User(
    username="janedoe",
    password="janeSecret",
    is_admin=True,
    is_active=True,
)

Now we create 2 instances of the User model:

from pydantic import BaseModel


class User(BaseModel):
    username: str
    password: str
    is_active: bool = True
    is_admin: bool = False


johndoe = User(
    username="johndoe",
    password="secret",
    is_admin=False,
    is_active=True,
)

janedoe = User(
    username="janedoe",
    password="janeSecret",
    is_admin=True,
    is_active=True,
)

Create a Route

Now we are going to create a FastAPI app with a route to get the user data.

from fastapi import FastAPI
from pydantic import BaseModel


class User(BaseModel):
    username: str
    password: str
    is_active: bool = True
    is_admin: bool = False


johndoe = User(
    username="johndoe",
    password="secret",
    is_admin=False,
    is_active=True,
)

janedoe = User(
    username="janedoe",
    password="janeSecret",
    is_admin=True,
    is_active=True,
)

app = FastAPI()


@app.get("/user/john", response_model=User)
async def get_john():
    return johndoe

This way, FastAPI will return all the user data, including the password, and it is not a good thing to do.

Omitting a field

Now let's use the Omit function to return everything from the user but the password.

from fastapi import FastAPI
from pydantic import BaseModel

from fastapi_vo import Omit


class User(BaseModel):
    username: str
    password: str
    is_active: bool = True
    is_admin: bool = False


johndoe = User(
    username="johndoe",
    password="secret",
    is_admin=False,
    is_active=True,
)

janedoe = User(
    username="janedoe",
    password="janeSecret",
    is_admin=True,
    is_active=True,
)

app = FastAPI()


@app.get("/user/john", response_model=Omit(User, "password"))
async def get_john():
    return johndoe

Multiple variations of the same model

If you want to use multiple variations of the same class, you have to give it a new classname to avoid conflicts. Another approach is to assign it to a variable for reuse.

from typing import List
from fastapi import FastAPI
from pydantic import BaseModel

from fastapi_vo import Omit


class User(BaseModel):
    username: str
    password: str
    is_active: bool = True
    is_admin: bool = False


NoPassword = Omit(User, "password", classname="NoPasswordUser")


johndoe = User(
    username="johndoe",
    password="secret",
    is_admin=False,
    is_active=True,
)

janedoe = User(
    username="janedoe",
    password="janeSecret",
    is_admin=True,
    is_active=True,
)

app = FastAPI()


@app.get("/users", response_model=List[NoPassword])
async def list_users():
    return [johndoe, janedoe]


@app.get("/user/john", response_model=NoPassword)
async def get_john():
    return johndoe

Picking a field

Now let's create a login route with another variation of the user model by picking some fields.

from typing import List
from fastapi import FastAPI
from pydantic import BaseModel

from fastapi_vo import Omit, Pick


class User(BaseModel):
    username: str
    password: str
    is_active: bool = True
    is_admin: bool = False


NoPassword = Omit(User, "password", classname="NoPasswordUser")
Auth = Pick(User, ["username", "password"], classname="Auth")


johndoe = User(
    username="johndoe",
    password="secret",
    is_admin=False,
    is_active=True,
)

janedoe = User(
    username="janedoe",
    password="janeSecret",
    is_admin=True,
    is_active=True,
)

app = FastAPI()


@app.get("/users", response_model=List[NoPassword])
async def list_users():
    return [johndoe, janedoe]


@app.get("/user/john", response_model=NoPassword)
async def get_john():
    return johndoe


@app.get("/login", response_model=NoPassword)
async def login(user: Auth):
    # some authentication logic in here
    return user

License

This project is licensed under the terms of the MIT license.