chore: refactor files & request for db instance

This commit is contained in:
swve 2023-01-18 20:07:51 +01:00
parent 7237a4de49
commit 668d03e172
11 changed files with 76 additions and 72 deletions

30
app.py
View file

@ -1,3 +1,4 @@
import logging
from urllib.request import Request from urllib.request import Request
from fastapi import FastAPI from fastapi import FastAPI
from src.main import global_router from src.main import global_router
@ -6,6 +7,7 @@ from fastapi.responses import JSONResponse
from fastapi.staticfiles import StaticFiles from fastapi.staticfiles import StaticFiles
from fastapi_jwt_auth.exceptions import AuthJWTException from fastapi_jwt_auth.exceptions import AuthJWTException
from src.services.mocks.initial import create_initial_data from src.services.mocks.initial import create_initial_data
import pymongo
######################## ########################
# Pre-Alpha Version 0.1.0 # Pre-Alpha Version 0.1.0
@ -24,17 +26,37 @@ app = FastAPI(
app.add_middleware( app.add_middleware(
CORSMiddleware, CORSMiddleware,
allow_origins=["http://localhost:3000"], allow_origins=["http://localhost:3000", "http://localhost:3001"],
allow_methods=["*"], allow_methods=["*"],
allow_credentials=True, allow_credentials=True,
allow_headers=["*"] allow_headers=["*"]
) )
# Static Files
app.mount("/content", StaticFiles(directory="content"), name="content") app.mount("/content", StaticFiles(directory="content"), name="content")
# Exception Handler
# Lifecycle Events
@app.on_event("startup")
def startup_event():
logging.info("Starting LearnHouse...")
# Database Connection
logging.info("Connecting to database...")
try:
app.mongodb_client = pymongo.MongoClient("mongodb://localhost:27017/") # type: ignore
app.db = app.mongodb_client["learnhouse"] # type: ignore
logging.info("Connected to database!")
except Exception as e:
logging.error("Failed to connect to database!")
logging.error(e)
@app.on_event("shutdown")
def shutdown_event():
app.mongodb_client.close() # type: ignore
logging.info("LearnHouse has been shut down.")
# JWT Exception Handler
@app.exception_handler(AuthJWTException) @app.exception_handler(AuthJWTException)
def authjwt_exception_handler(request: Request, exc: AuthJWTException): def authjwt_exception_handler(request: Request, exc: AuthJWTException):
return JSONResponse( return JSONResponse(
@ -42,10 +64,10 @@ def authjwt_exception_handler(request: Request, exc: AuthJWTException):
content={"detail": exc.message} # type: ignore content={"detail": exc.message} # type: ignore
) )
# Global Routes
app.include_router(global_router) app.include_router(global_router)
# General Routes
@app.get("/") @app.get("/")
async def root(): async def root():
return {"Message": "Welcome to LearnHouse ✨"} return {"Message": "Welcome to LearnHouse ✨"}

View file

@ -9,7 +9,7 @@ services:
frontend: frontend:
build: ./front build: ./front
ports: ports:
- "3000:3000" - "3001:3000"
volumes: volumes:
- ./front:/usr/learnhouse/front - ./front:/usr/learnhouse/front
mongo: mongo:

View file

@ -1,7 +1,8 @@
"use client";
import React from "react"; import React from "react";
import Layout from "../../components/UI/Layout"; import Layout from "../../../components/UI/Layout";
import { Title } from "../../components/UI/Elements/Styles/Title"; import { Title } from "../../../components/UI/Elements/Styles/Title";
import { createNewOrganization } from "../../services/orgs"; import { createNewOrganization } from "../../../services/orgs";
const Organizations = () => { const Organizations = () => {
const [name, setName] = React.useState(""); const [name, setName] = React.useState("");

View file

@ -1,6 +1,6 @@
fastapi==0.78.0 fastapi==0.89.1
pydantic>=1.8.0,<2.0.0 pydantic>=1.8.0,<2.0.0
uvicorn>=0.15.0,<0.16.0 uvicorn==0.20.0
pymongo==4.1.1 pymongo==4.1.1
python-multipart python-multipart
python-jose python-jose

0
src/core/__init__.py Normal file
View file

View file

View file

View file

@ -1,4 +1,4 @@
from fastapi import APIRouter, Depends, UploadFile, Form from fastapi import APIRouter, Depends, Request, UploadFile, Form
from src.services.courses.chapters import CourseChapter, CourseChapterMetaData, create_coursechapter, delete_coursechapter, get_coursechapter, get_coursechapters, get_coursechapters_meta, update_coursechapter, update_coursechapters_meta from src.services.courses.chapters import CourseChapter, CourseChapterMetaData, create_coursechapter, delete_coursechapter, get_coursechapter, get_coursechapters, get_coursechapters_meta, update_coursechapter, update_coursechapters_meta
from src.services.users import PublicUser from src.services.users import PublicUser

View file

@ -1,6 +1,7 @@
from fastapi import APIRouter, Depends
from fastapi import APIRouter, Depends, Request
from src.dependencies.auth import get_current_user from src.dependencies.auth import get_current_user
from src.services.orgs import Organization, create_org, delete_org, get_organization, get_organization_by_slug, get_orgs, get_orgs_by_user, update_org from src.services.orgs import Organization, create_org, delete_org, get_organization, get_organization_by_slug, get_orgs_by_user, update_org
from src.services.users import PublicUser, User from src.services.users import PublicUser, User
@ -8,55 +9,49 @@ router = APIRouter()
@router.post("/") @router.post("/")
async def api_create_org(org_object: Organization, current_user: PublicUser = Depends(get_current_user)): async def api_create_org(request: Request, org_object: Organization, current_user: PublicUser = Depends(get_current_user)):
""" """
Create new organization Create new organization
""" """
return await create_org(org_object, current_user) return await create_org(request, org_object, current_user)
@router.get("/{org_id}") @router.get("/{org_id}")
async def api_get_org(org_id: str, current_user: PublicUser = Depends(get_current_user)): async def api_get_org(request: Request, org_id: str, current_user: PublicUser = Depends(get_current_user)):
""" """
Get single Org by ID Get single Org by ID
""" """
return await get_organization(org_id) return await get_organization(request, org_id)
@router.get("/slug/{org_slug}") @router.get("/slug/{org_slug}")
async def api_get_org_by_slug(org_slug: str, current_user: User = Depends(get_current_user)): async def api_get_org_by_slug(request: Request, org_slug: str, current_user: User = Depends(get_current_user)):
""" """
Get single Org by Slug Get single Org by Slug
""" """
return await get_organization_by_slug(org_slug) return await get_organization_by_slug(request, org_slug)
@router.get("/page/{page}/limit/{limit}")
async def api_get_org_by(page: int, limit: int):
"""
Get orgs by page and limit
"""
return await get_orgs(page, limit)
@router.get("/user/page/{page}/limit/{limit}") @router.get("/user/page/{page}/limit/{limit}")
async def api_user_orgs(page: int, limit: int, current_user: PublicUser = Depends(get_current_user)): async def api_user_orgs(request: Request, page: int, limit: int, current_user: PublicUser = Depends(get_current_user)):
""" """
Get orgs by page and limit by user Get orgs by page and limit by user
""" """
return await get_orgs_by_user(current_user.user_id, page, limit) return await get_orgs_by_user(request, current_user.user_id, page, limit)
@router.put("/{org_id}") @router.put("/{org_id}")
async def api_update_org(org_object: Organization, org_id: str, current_user: PublicUser = Depends(get_current_user)): async def api_update_org(request: Request, org_object: Organization, org_id: str, current_user: PublicUser = Depends(get_current_user)):
""" """
Update Org by ID Update Org by ID
""" """
return await update_org(org_object, org_id, current_user) return await update_org(request, org_object, org_id, current_user)
@router.delete("/{org_id}") @router.delete("/{org_id}")
async def api_delete_org(org_id: str, current_user: PublicUser = Depends(get_current_user)): async def api_delete_org(request: Request, org_id: str, current_user: PublicUser = Depends(get_current_user)):
""" """
Delete Org by ID Delete Org by ID
""" """
return await delete_org(org_id, current_user) return await delete_org(request, org_id, current_user)

View file

@ -3,7 +3,7 @@ from typing import List
from uuid import uuid4 from uuid import uuid4
from pydantic import BaseModel from pydantic import BaseModel
from src.services.users import PublicUser, User from src.services.users import PublicUser, User
from src.services.database import create_config_collection, check_database, create_database, learnhouseDB, learnhouseDB from src.services.database import check_database, create_database, learnhouseDB, learnhouseDB
from src.services.security import * from src.services.security import *
from fastapi import FastAPI, HTTPException, status, Request, Response, BackgroundTasks from fastapi import FastAPI, HTTPException, status, Request, Response, BackgroundTasks
from datetime import datetime from datetime import datetime

View file

@ -3,7 +3,7 @@ from typing import List
from uuid import uuid4 from uuid import uuid4
from pydantic import BaseModel from pydantic import BaseModel
from src.services.users import PublicUser, User from src.services.users import PublicUser, User
from src.services.database import create_config_collection, check_database, create_database, learnhouseDB, learnhouseDB from src.services.database import check_database, create_database, learnhouseDB, learnhouseDB
from src.services.security import * from src.services.security import *
from fastapi import FastAPI, HTTPException, status, Request, Response, BackgroundTasks from fastapi import FastAPI, HTTPException, status, Request, Response, BackgroundTasks
from datetime import datetime from datetime import datetime
@ -15,7 +15,7 @@ class Organization(BaseModel):
name: str name: str
description: str description: str
email: str email: str
slug :str slug: str
class OrganizationInDB(Organization): class OrganizationInDB(Organization):
@ -23,6 +23,7 @@ class OrganizationInDB(Organization):
owners: List[str] owners: List[str]
admins: List[str] admins: List[str]
class PublicOrganization(Organization): class PublicOrganization(Organization):
name: str name: str
description: str description: str
@ -34,9 +35,8 @@ class PublicOrganization(Organization):
#### Classes #################################################### #### Classes ####################################################
async def get_organization(org_id: str): async def get_organization(request: Request, org_id: str):
await check_database() orgs = request.app.db["organizations"]
orgs = learnhouseDB["organizations"]
org = orgs.find_one({"org_id": org_id}) org = orgs.find_one({"org_id": org_id})
@ -47,9 +47,9 @@ async def get_organization(org_id: str):
org = PublicOrganization(**org) org = PublicOrganization(**org)
return org return org
async def get_organization_by_slug(org_slug: str):
await check_database() async def get_organization_by_slug(request: Request, org_slug: str):
orgs = learnhouseDB["organizations"] orgs = request.app.db["organizations"]
org = orgs.find_one({"slug": org_slug}) org = orgs.find_one({"slug": org_slug})
@ -61,9 +61,8 @@ async def get_organization_by_slug(org_slug: str):
return org return org
async def create_org(org_object: Organization, current_user: PublicUser): async def create_org(request: Request, org_object: Organization, current_user: PublicUser):
await check_database() orgs = request.app.db["organizations"]
orgs = learnhouseDB["organizations"]
# find if org already exists using name # find if org already exists using name
isOrgAvailable = orgs.find_one({"slug": org_object.slug}) isOrgAvailable = orgs.find_one({"slug": org_object.slug})
@ -88,13 +87,12 @@ async def create_org(org_object: Organization, current_user: PublicUser):
return org.dict() return org.dict()
async def update_org(org_object: Organization, org_id: str, current_user: PublicUser): async def update_org(request: Request, org_object: Organization, org_id: str, current_user: PublicUser):
await check_database()
# verify org rights # verify org rights
await verify_org_rights(org_id, current_user,"update") await verify_org_rights(request, org_id, current_user, "update")
orgs = learnhouseDB["organizations"] orgs = request.app.db["organizations"]
org = orgs.find_one({"org_id": org_id}) org = orgs.find_one({"org_id": org_id})
@ -114,12 +112,12 @@ async def update_org(org_object: Organization, org_id: str, current_user: Public
return Organization(**updated_org.dict()) return Organization(**updated_org.dict())
async def delete_org(org_id: str, current_user: PublicUser): async def delete_org(request: Request, org_id: str, current_user: PublicUser):
await check_database() await check_database()
await verify_org_rights(org_id, current_user,"delete") await verify_org_rights(request, org_id, current_user, "delete")
orgs = learnhouseDB["organizations"] orgs = request.app.db["organizations"]
org = orgs.find_one({"org_id": org_id}) org = orgs.find_one({"org_id": org_id})
@ -136,33 +134,21 @@ async def delete_org(org_id: str, current_user: PublicUser):
status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail="Unavailable database") status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail="Unavailable database")
async def get_orgs(page: int = 1, limit: int = 10): async def get_orgs_by_user(request: Request, user_id: str, page: int = 1, limit: int = 10):
## TODO : Deprecated orgs = request.app.db["organizations"]
await check_database()
orgs = learnhouseDB["organizations"]
# get all orgs from database
all_orgs = orgs.find().sort("name", 1).skip(10 * (page - 1)).limit(limit)
return [json.loads(json.dumps(org, default=str)) for org in all_orgs]
async def get_orgs_by_user(user_id: str, page: int = 1, limit: int = 10):
await check_database()
orgs = learnhouseDB["organizations"]
print(user_id) print(user_id)
# find all orgs where user_id is in owners or admins arrays # find all orgs where user_id is in owners or admins arrays
all_orgs = orgs.find({"$or": [{"owners": user_id}, {"admins": user_id}]}).sort("name", 1).skip(10 * (page - 1)).limit(limit) all_orgs = orgs.find({"$or": [{"owners": user_id}, {"admins": user_id}]}).sort(
"name", 1).skip(10 * (page - 1)).limit(limit)
return [json.loads(json.dumps(org, default=str)) for org in all_orgs] return [json.loads(json.dumps(org, default=str)) for org in all_orgs]
#### Security #################################################### #### Security ####################################################
async def verify_org_rights(org_id: str, current_user: PublicUser, action: str,): async def verify_org_rights(request: Request, org_id: str, current_user: PublicUser, action: str,):
await check_database() orgs = request.app.db["organizations"]
orgs = learnhouseDB["organizations"]
org = orgs.find_one({"org_id": org_id}) org = orgs.find_one({"org_id": org_id})