backend changes
This commit is contained in:
parent
e5a5e141a9
commit
0d34959e08
|
@ -0,0 +1,31 @@
|
|||
aiosqlite==0.17.0
|
||||
alembic==1.6.5
|
||||
asgiref==3.4.1
|
||||
bcrypt==3.2.0
|
||||
cffi==1.14.6
|
||||
click==8.0.1
|
||||
databases==0.4.3
|
||||
Deprecated==1.2.12
|
||||
dnspython==2.1.0
|
||||
email-validator==1.1.3
|
||||
fastapi==0.68.0
|
||||
fastapi-users==6.1.2
|
||||
h11==0.12.0
|
||||
idna==3.2
|
||||
makefun==1.11.3
|
||||
Mako==1.1.4
|
||||
MarkupSafe==2.0.1
|
||||
ormar==0.10.16
|
||||
passlib==1.7.4
|
||||
pycparser==2.20
|
||||
pydantic==1.8.2
|
||||
PyJWT==2.1.0
|
||||
python-dateutil==2.8.2
|
||||
python-editor==1.0.4
|
||||
python-multipart==0.0.5
|
||||
six==1.16.0
|
||||
SQLAlchemy==1.3.23
|
||||
starlette==0.14.2
|
||||
typing-extensions==3.7.4.3
|
||||
uvicorn==0.15.0
|
||||
wrapt==1.12.1
|
|
@ -1,19 +1,20 @@
|
|||
from .db import database, engine, Base, DbSession
|
||||
from .users import add_user_routers, User
|
||||
from fastapi import FastAPI
|
||||
from users import add_user_routers, User
|
||||
from db import database, engine, Base, DbSession
|
||||
from .routes import create_api_router
|
||||
from starlette.requests import Request
|
||||
from routes import router as api_router
|
||||
import models
|
||||
|
||||
|
||||
def get_app() -> FastAPI:
|
||||
def get_app(database) -> FastAPI:
|
||||
application = FastAPI(title="swimtracker", debug=True, version="0.1")
|
||||
application.include_router(api_router)
|
||||
add_user_routers(application)
|
||||
fastapi_users = add_user_routers(application, database)
|
||||
current_user = fastapi_users.current_user(active=True, verified=True)
|
||||
current_superuser = fastapi_users.current_user(active=True, superuser=True, verified=True)
|
||||
application.include_router(create_api_router(current_user))
|
||||
return application
|
||||
|
||||
|
||||
app = get_app()
|
||||
app = get_app(database)
|
||||
|
||||
|
||||
@app.middleware("http")
|
|
@ -1,7 +1,6 @@
|
|||
import databases
|
||||
import sqlalchemy
|
||||
from starlette import requests
|
||||
from config import DATABASE_URL
|
||||
from .config import DATABASE_URL
|
||||
from sqlalchemy.ext.declarative import DeclarativeMeta, declarative_base
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from starlette.requests import Request
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
from db import Base
|
||||
from .db import Base
|
||||
from sqlalchemy import Column, Integer, Index, LargeBinary, ForeignKey, and_, or_
|
||||
from typing import Tuple
|
||||
|
||||
|
||||
class Session(Base):
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
import base64
|
||||
from . import models
|
||||
from . import schemas
|
||||
from .db import get_db
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from typing import List
|
||||
import schemas
|
||||
from users import User, UserDB, UserTable, current_user
|
||||
from db import get_db
|
||||
import models
|
||||
from sqlalchemy.orm import Session as DbSession, lazyload
|
||||
from sqlalchemy.orm.exc import NoResultFound
|
||||
from sqlalchemy.exc import IntegrityError
|
||||
from fastapi import status
|
||||
from sqlalchemy.sql import select
|
||||
from sqlalchemy.exc import IntegrityError
|
||||
from sqlalchemy.orm import Session as DbSession
|
||||
from sqlalchemy.orm.exc import NoResultFound
|
||||
from typing import List
|
||||
from .users import User, UserTable
|
||||
import base64
|
||||
|
||||
|
||||
def create_api_router(current_user):
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
|
@ -86,7 +87,7 @@ def list_friends_info(db: DbSession = Depends(get_db), user: User = Depends(curr
|
|||
return schemas.FriendsInfo(incoming_requests=user_obj.friend_requests_in,
|
||||
outgoing_requests=user_obj.friend_requests_out)
|
||||
|
||||
|
||||
return router
|
||||
# todo: remove friend requests
|
||||
# todo: remove friendship
|
||||
# todo: search user by email
|
||||
|
|
|
@ -20,9 +20,6 @@ class UserInfo(BaseModel):
|
|||
id: UUID4
|
||||
email: EmailStr
|
||||
|
||||
class Config:
|
||||
orm_mode = True
|
||||
|
||||
|
||||
class Session(SessionBase):
|
||||
user: UUID4
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
from fastapi_users import FastAPIUsers, models
|
||||
from fastapi_users.db import SQLAlchemyBaseUserTable, SQLAlchemyUserDatabase
|
||||
from fastapi_users.authentication import JWTAuthentication
|
||||
from config import JWT_SECRET
|
||||
from .config import JWT_SECRET
|
||||
from .db import Base
|
||||
from fastapi import Request
|
||||
from db import database, Base
|
||||
from fastapi_users import FastAPIUsers, models
|
||||
from fastapi_users.authentication import JWTAuthentication
|
||||
from fastapi_users.db import SQLAlchemyBaseUserTable, SQLAlchemyUserDatabase
|
||||
from sqlalchemy.orm import relationship, backref
|
||||
from sqlalchemy import Integer, Column
|
||||
from fastapi_users.models import BaseUser
|
||||
|
||||
|
||||
class User(models.BaseUser):
|
||||
|
@ -40,6 +38,7 @@ class UserTable(Base, SQLAlchemyBaseUserTable):
|
|||
secondaryjoin=("UserTable.id == Friendship.friend_id"))
|
||||
|
||||
|
||||
def add_user_routers(app, database):
|
||||
user_db = SQLAlchemyUserDatabase(UserDB, database, UserTable.__table__)
|
||||
jwt_authentication = JWTAuthentication(secret=JWT_SECRET,
|
||||
lifetime_seconds=60 * 60 * 8,
|
||||
|
@ -53,23 +52,16 @@ fastapi_users = FastAPIUsers(
|
|||
UserUpdate,
|
||||
UserDB,
|
||||
)
|
||||
current_user = fastapi_users.current_user(active=True, verified=True)
|
||||
current_superuser = fastapi_users.current_user(active=True, superuser=True, verified=True)
|
||||
|
||||
|
||||
def on_after_register(user: UserDB, request: Request):
|
||||
print(f"User {user.id} has registered.")
|
||||
|
||||
|
||||
def on_after_forgot_password(user: UserDB, token: str, request: Request):
|
||||
print(f"User {user.id} has forgot their password. Reset token: {token}")
|
||||
|
||||
|
||||
def after_verification_request(user: UserDB, token: str, request: Request):
|
||||
print(f"Verification requested for user {user.id}. Verification token: {token}")
|
||||
|
||||
|
||||
def add_user_routers(app):
|
||||
app.include_router(fastapi_users.get_auth_router(jwt_authentication),
|
||||
prefix="/auth/jwt",
|
||||
tags=["auth"])
|
||||
|
@ -90,3 +82,4 @@ def add_user_routers(app):
|
|||
tags=["auth"],
|
||||
)
|
||||
app.include_router(fastapi_users.get_users_router(), prefix="/users", tags=["users"])
|
||||
return fastapi_users
|
|
@ -2,8 +2,9 @@ import os
|
|||
from typing import Any, Generator
|
||||
|
||||
import pytest
|
||||
import databases
|
||||
from src.db import Base, get_db
|
||||
from src.main import app as _app
|
||||
from src import get_app
|
||||
from fastapi import FastAPI
|
||||
from fastapi.testclient import TestClient
|
||||
from sqlalchemy import create_engine
|
||||
|
@ -14,9 +15,7 @@ from sqlalchemy.orm import sessionmaker
|
|||
# database engines
|
||||
SQLALCHEMY_DATABASE_URL = os.getenv('TEST_DATABASE_URL', "sqlite://")
|
||||
|
||||
engine = create_engine(
|
||||
SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}
|
||||
)
|
||||
engine = create_engine(SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False})
|
||||
|
||||
Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
||||
|
||||
|
@ -26,7 +25,9 @@ def app() -> Generator[FastAPI, Any, None]:
|
|||
"""
|
||||
Create a fresh database on each test case.
|
||||
"""
|
||||
print(list(Base.metadata.tables.keys()))
|
||||
Base.metadata.create_all(engine) # Create the tables.
|
||||
_app = get_app(databases.Database(SQLALCHEMY_DATABASE_URL))
|
||||
yield _app
|
||||
Base.metadata.drop_all(engine)
|
||||
|
||||
|
@ -61,7 +62,6 @@ def client(app: FastAPI, db_session: Session) -> Generator[TestClient, Any, None
|
|||
Create a new FastAPI TestClient that uses the `db_session` fixture to override
|
||||
the `get_db` dependency that is injected into routes.
|
||||
"""
|
||||
|
||||
def _get_test_db():
|
||||
try:
|
||||
yield db_session
|
||||
|
|
|
@ -1,11 +1,24 @@
|
|||
from backend.src.db import DbSession
|
||||
from src.db import DbSession
|
||||
from src.schemas import Session
|
||||
from fastapi import FastAPI
|
||||
from src.db import DbSession
|
||||
from fastapi.testclient import TestClient
|
||||
from src.users import UserCreate, User
|
||||
from fastapi.encoders import jsonable_encoder
|
||||
|
||||
#----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
def test_session_create(app: FastAPI, db_session: DbSession, client: TestClient):
|
||||
pass
|
||||
# Tests to write
|
||||
# - User Flow: register, verify, login
|
||||
# - create, list, delete session
|
||||
# - friendship: query user by mail, create friend request, accept
|
||||
def test_register_user(app: FastAPI, db_session: DbSession, client: TestClient):
|
||||
req_data = jsonable_encoder(UserCreate(email="test@abc.com", password="password"))
|
||||
response = client.post("/auth/register", json=req_data)
|
||||
print(response.json())
|
||||
resp_user = User(**response.json())
|
||||
assert response.status_code == 201
|
||||
assert resp_user.is_active
|
||||
assert not resp_user.is_superuser
|
||||
assert not resp_user.is_verified
|
||||
|
|
Loading…
Reference in New Issue