-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #4 from tmeftah/nikhil_raikar
Started addressing and cleaning the backend to make it ready for futher extensions
- Loading branch information
Showing
21 changed files
with
447 additions
and
242 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
name: FastAPI CI | ||
|
||
on: [push, pull_request] | ||
|
||
jobs: | ||
test: | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- name: Checkout code | ||
uses: actions/checkout@v3 | ||
|
||
- name: Set up Python | ||
uses: actions/setup-python@v4 | ||
with: | ||
python-version: '3.10' | ||
cache: 'pip' | ||
|
||
- name: Install dependencies | ||
run: | | ||
cd backend | ||
pip install -r requirements.txt | ||
- name: Start FastAPI app | ||
run: | | ||
cd backend | ||
nohup fastapi dev > /dev/null 2>&1 & | ||
echo $! > uvicorn.pid | ||
sleep 10 | ||
- name: Check FastAPI /health endpoint | ||
run: | | ||
response=$(curl -s http://127.0.0.1:8000/health) | ||
echo "Response: $response" | ||
if [ "$response" == '{"status":"Active"}' ]; then | ||
echo "Health check passed" | ||
else | ||
echo "Health check failed" | ||
exit 1 | ||
fi |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
|
||
from fastapi import APIRouter | ||
|
||
health_router = APIRouter() | ||
|
||
|
||
@health_router.get("/health") | ||
async def check_health(): | ||
return {"status": "Active"} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
from fastapi import APIRouter | ||
from fastapi.responses import StreamingResponse | ||
|
||
from backend.rag_llms_langchain import chain | ||
from backend.embeddings.ingest import get_vectorstore | ||
|
||
import json | ||
import uuid | ||
|
||
|
||
query_router = APIRouter() | ||
|
||
|
||
@query_router.get("/query") | ||
async def query(query: str): | ||
# if current_user.role < 5: | ||
# raise HTTPException(status_code=403, detail="Only admin users can delete other users") | ||
store = get_vectorstore() | ||
docs = store.invoke(query) | ||
|
||
print(20*"*", "docs", 20*"*", "\n", docs) | ||
|
||
async def stream_generator(): | ||
# Use the LangChain model to generate text | ||
print(20*'*', "\n", query) | ||
async for text in chain.astream({"input": query, "context": docs}): | ||
yield json.dumps({"event_id": str(uuid.uuid4()), "data": text}) | ||
|
||
# TODO here we have to add the metadata/source | ||
|
||
return StreamingResponse(stream_generator(), media_type="application/x-ndjson") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
|
||
from fastapi import APIRouter, Depends, HTTPException | ||
from backend.pydantic_models import Token | ||
from backend.oauth import authenticate_user, create_access_token | ||
from backend.config import ACCESS_TOKEN_EXPIRE_MINUTES | ||
from fastapi.security import OAuth2PasswordRequestForm | ||
from datetime import timedelta | ||
|
||
|
||
token_router = APIRouter() | ||
|
||
|
||
@token_router.post("/token", response_model=Token) | ||
async def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends()): | ||
user = authenticate_user(form_data.username, form_data.password) | ||
if not user: | ||
raise HTTPException( | ||
status_code=401, | ||
detail="Incorrect username or password", | ||
headers={"WWW-Authenticate": "Bearer"}, | ||
) | ||
access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES) | ||
access_token = create_access_token( | ||
data={"sub": user.username}, expires_delta=access_token_expires | ||
) | ||
return {"access_token": access_token, "token_type": "bearer"} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
|
||
from fastapi import APIRouter, Depends, HTTPException | ||
from backend.sqlalchemy_models import User | ||
from backend.sessions import session | ||
from backend.oauth import encrypt_password, get_current_user | ||
|
||
|
||
user_router = APIRouter() | ||
|
||
|
||
|
||
@user_router.get("/users/me") | ||
async def read_users_me(current_user: User = Depends(get_current_user)): | ||
return {"username": current_user.username, "role": current_user.role} | ||
|
||
|
||
@user_router.get("/users/") | ||
async def read_users(current_user: User = Depends(get_current_user)): | ||
if current_user.role < 5: | ||
raise HTTPException( | ||
status_code=403, detail="Only admin users can view all users") | ||
return [{"username": user.username, "role": user.role} for user in session.query(User).all()] | ||
|
||
|
||
@user_router.get("/users/{user_id}") | ||
async def read_user(user_id: int, current_user: User = Depends(get_current_user)): | ||
if current_user.id != user_id and current_user.role < 5: | ||
raise HTTPException( | ||
status_code=403, detail="Only admin users can view other users") | ||
user = session.query(User).filter(User.id == user_id).first() | ||
if not user: | ||
raise HTTPException(status_code=404, detail="User not found") | ||
return {"username": user.username, "role": user.role} | ||
|
||
|
||
@user_router.post("/users/") | ||
async def create_user(username: str, password: str, role: int, current_user: User = Depends(get_current_user)): | ||
if current_user.role < 5: | ||
raise HTTPException( | ||
status_code=403, detail="Only admin users can create new users") | ||
user = User(username=username, | ||
password_hash=encrypt_password(password), role=role) | ||
session.add(user) | ||
session.commit() | ||
return {"username": user.username, "role": user.role} | ||
|
||
|
||
@user_router.put("/users/{user_id}") | ||
async def update_user(user_id: int, username: str, password: str, role: int, current_user: User = Depends(get_current_user)): | ||
if current_user.id != user_id and current_user.role < 5: | ||
raise HTTPException( | ||
status_code=403, detail="Only admin users can update other users") | ||
user = session.query(User).filter(User.id == user_id).first() | ||
if not user: | ||
raise HTTPException(status_code=404, detail="User not found") | ||
user.username = username | ||
user.password = password | ||
user.role = role | ||
session.commit() | ||
return {"username": user.username, "role": user.role} | ||
|
||
|
||
@user_router.delete("/users/{user_id}") | ||
async def delete_user(user_id: int, current_user: User = Depends(get_current_user)): | ||
if current_user.id != user_id and current_user.role < 5: | ||
raise HTTPException( | ||
status_code=403, detail="Only admin users can delete other users") | ||
user = session.query(User).filter(User.id == user_id).first() | ||
if not user: | ||
raise HTTPException(status_code=404, detail="User not found") | ||
session.delete(user) | ||
session.commit() | ||
return {"message": "User deleted"} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
SECRET_KEY = "your_secret_key" | ||
ALGORITHM = "HS256" | ||
ACCESS_TOKEN_EXPIRE_MINUTES = 30 | ||
|
||
# No origins are limited for now | ||
# All origins are allowed for now and this | ||
# must be changed | ||
origins = [ | ||
"http://localhost", | ||
"http://127.0.0.1:8000", | ||
] | ||
|
||
|
Empty file.
File renamed without changes.
Oops, something went wrong.