mirror of
https://github.com/rzmk/learnhouse.git
synced 2025-12-19 04:19:25 +00:00
chore: refactor files & request for db instance
This commit is contained in:
parent
7237a4de49
commit
668d03e172
11 changed files with 76 additions and 72 deletions
30
app.py
30
app.py
|
|
@ -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 ✨"}
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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("");
|
||||||
|
|
@ -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
0
src/core/__init__.py
Normal file
0
src/core/config/__init__.py
Normal file
0
src/core/config/__init__.py
Normal file
0
src/core/config/config.py
Normal file
0
src/core/config/config.py
Normal 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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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})
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue