Add database abstraction

This commit is contained in:
François Voron
2019-10-06 08:53:13 +02:00
parent 4e0b0f6f7d
commit 552f313d76
7 changed files with 67 additions and 10 deletions

View File

@ -7,6 +7,7 @@ verify_ssl = true
flake8 = "*" flake8 = "*"
pytest = "*" pytest = "*"
requests = "*" requests = "*"
isort = "*"
[packages] [packages]
fastapi = "*" fastapi = "*"

10
Pipfile.lock generated
View File

@ -1,7 +1,7 @@
{ {
"_meta": { "_meta": {
"hash": { "hash": {
"sha256": "91ae09ea534335646c2472e3a9266d8e870b1316f4a857946ca34925cf4a595c" "sha256": "4879f37c108087df2ecbcee271a3d58de6bfd9d58013d3f9bf0127ef7e7acf92"
}, },
"pipfile-spec": 6, "pipfile-spec": 6,
"requires": { "requires": {
@ -200,6 +200,14 @@
"markers": "python_version < '3.8'", "markers": "python_version < '3.8'",
"version": "==0.23" "version": "==0.23"
}, },
"isort": {
"hashes": [
"sha256:54da7e92468955c4fceacd0c86bd0ec997b0e1ee80d97f67c35a78b719dccab1",
"sha256:6e811fcb295968434526407adb8796944f1988c5b65e8139058f2014cbe100fd"
],
"index": "pypi",
"version": "==4.3.21"
},
"mccabe": { "mccabe": {
"hashes": [ "hashes": [
"sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42",

View File

@ -0,0 +1,19 @@
from typing import List
from ..models import UserDB
class UserDBInterface:
"""
Common interface exposing methods to list, get, create and update users in
the database.
"""
async def list(self) -> List[UserDB]:
raise NotImplementedError()
async def get_by_email(self, email: str) -> UserDB:
raise NotImplementedError()
async def create(self, user: UserDB) -> UserDB:
raise NotImplementedError()

View File

@ -1,7 +1,8 @@
import uuid import uuid
from typing import Optional
from pydantic import BaseModel from pydantic import BaseModel
from pydantic.types import EmailStr from pydantic.types import EmailStr
from typing import Optional
class UserBase(BaseModel): class UserBase(BaseModel):

View File

@ -1,12 +1,20 @@
from fastapi import APIRouter from fastapi import APIRouter
from .db import UserDBInterface
from .models import UserCreate, UserDB from .models import UserCreate, UserDB
from .password import get_password_hash from .password import get_password_hash
router = APIRouter()
class UserRouter:
@router.post('/register') def __new__(cls, userDB: UserDBInterface) -> APIRouter:
async def register(user: UserCreate): router = APIRouter()
hashed_password = get_password_hash(user.password)
return UserDB(**user.dict(), hashed_password=hashed_password) @router.post('/register')
async def register(user: UserCreate):
hashed_password = get_password_hash(user.password)
db_user = UserDB(**user.dict(), hashed_password=hashed_password)
created_user = await userDB.create(db_user)
return created_user
return router

9
setup.cfg Normal file
View File

@ -0,0 +1,9 @@
[flake8]
exclude = docs
max-line-length = 119
[isort]
atomic = true
multi_line_output = 5
known_standard_library = types
known_third_party = pytest,_pytest

View File

@ -1,15 +1,26 @@
import pytest
from starlette import status from starlette import status
from starlette.testclient import TestClient from starlette.testclient import TestClient
import pytest
from fastapi_users.db import UserDBInterface
from fastapi_users.models import UserDB
class MockUserDBInterface(UserDBInterface):
async def create(self, user: UserDB) -> UserDB:
return user
@pytest.fixture @pytest.fixture
def test_app_client() -> TestClient: def test_app_client() -> TestClient:
from fastapi import FastAPI from fastapi import FastAPI
from fastapi_users.router import router from fastapi_users.router import UserRouter
userRouter = UserRouter(MockUserDBInterface())
app = FastAPI() app = FastAPI()
app.include_router(router) app.include_router(userRouter)
return TestClient(app) return TestClient(app)