Changed users sent data from Form(...) to json. Fixed also some bugs

This commit is contained in:
João Silva
2023-11-01 23:20:30 +00:00
parent 6e1ca5f370
commit 286546bf17
5 changed files with 90 additions and 220 deletions

View File

@@ -1,6 +1,6 @@
import os
import logging
from fastapi import APIRouter, Depends, HTTPException, Form, Response, File, UploadFile, Request
from fastapi import APIRouter, Depends, HTTPException, Response, File, UploadFile, Request
from fastapi.security import OAuth2PasswordBearer
from typing import List, Optional
from sqlalchemy import func, DECIMAL, DateTime, desc

View File

@@ -1,4 +1,4 @@
from fastapi import APIRouter, Depends, HTTPException, Form, Response
from fastapi import APIRouter, Depends, HTTPException
from fastapi.security import OAuth2PasswordBearer
from sqlalchemy.orm import Session
from pydantic import BaseModel
@@ -15,23 +15,6 @@ router = APIRouter()
logger = logging.getLogger("myLogger")
class UserResponse(BaseModel):
id: int
name: str
username: str
email: str
city: Optional[str]
birthdate: Optional[date]
preferred_language: str
gender: int
access_type: int
photo_path: Optional[str]
photo_path_aux: Optional[str]
is_active: int
strava_token: Optional[str]
strava_refresh_token: Optional[str]
strava_token_expires_at: Optional[str]
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
# Define an HTTP GET route to retrieve all users
@@ -252,7 +235,7 @@ async def read_users_userPhotoAuxFromID(user_id: int, token: str = Depends(oauth
photo_path_aux = user.photo_path_aux
else:
# Handle the case where the user was not found or doesn't have a photo path
raise HTTPException(status_code=404, detail="User not found or no photo path available")
raise HTTPException(status_code=404, detail="User not found or no photo path aux available")
except JWTError:
# Handle JWT (JSON Web Token) authentication error
@@ -261,21 +244,24 @@ async def read_users_userPhotoAuxFromID(user_id: int, token: str = Depends(oauth
# Return the user's photo path as a JSON response
return {0: photo_path_aux}
class CreateUserRequest(BaseModel):
name: str
username: str
email: str
password: str
preferred_language: str
city: Optional[str]
birthdate: Optional[str]
gender: int
access_type: int
photo_path: Optional[str]
photo_path_aux: Optional[str]
is_active: int
# Define an HTTP POST route to create a new user
@router.post("/users/create")
async def create_user(
name: str = Form(...),
username: str = Form(...),
email: str = Form(...),
password: str = Form(...),
preferred_language: str = Form(...),
city: Optional[str] = Form(None),
birthdate: Optional[str] = Form(None),
gender: int = Form(...),
access_type: int = Form(...),
photo_path: Optional[str] = Form(None),
photo_path_aux: Optional[str] = Form(None),
is_active: int = Form(...),
user: CreateUserRequest,
token: str = Depends(oauth2_scheme)
):
try:
@@ -287,18 +273,18 @@ async def create_user(
# Create a new User instance using SQLAlchemy's ORM
new_user = User(
name=name,
username=username,
email=email,
password=password,
preferred_language=preferred_language,
city=city,
birthdate=birthdate,
gender=gender,
access_type=access_type,
photo_path=photo_path,
photo_path_aux=photo_path_aux,
is_active=is_active
name=user.name,
username=user.username,
email=user.email,
password=user.password,
preferred_language=user.preferred_language,
city=user.city,
birthdate=user.birthdate,
gender=user.gender,
access_type=user.access_type,
photo_path=user.photo_path,
photo_path_aux=user.photo_path_aux,
is_active=user.is_active
)
with get_db_session() as db_session:
@@ -312,22 +298,25 @@ async def create_user(
print(err)
raise HTTPException(status_code=500, detail="Internal server error")
class EditUserRequest(BaseModel):
name: str
username: str
email: str
preferred_language: str
city: Optional[str]
birthdate: Optional[str]
gender: int
access_type: int
photo_path: Optional[str]
photo_path_aux: Optional[str]
is_active: int
# Define an HTTP PUT route to edit a user's information
@router.put("/users/edit/{user_id}")
@router.put("/users/{user_id}/edit")
async def edit_user(
user_id: int,
name: str = Form(None),
username: str = Form(None),
email: str = Form(None),
preferred_language: str = Form(None),
city: Optional[str] = Form(None),
birthdate: Optional[str] = Form(None),
gender: int = Form(None),
access_type: int = Form(None),
photo_path: Optional[str] = Form(None),
photo_path_aux: Optional[str] = Form(None),
is_active: int = Form(None),
token: str = Depends(oauth2_scheme)
user_attributtes: EditUserRequest,
token: str = Depends(oauth2_scheme) # Add the Request dependency
):
try:
# Validate the user's access token using the oauth2_scheme
@@ -345,28 +334,28 @@ async def edit_user(
raise HTTPException(status_code=404, detail="User not found")
# Update user information if provided in the form data
if name is not None:
user.name = name
if username is not None:
user.username = username
if email is not None:
user.email = email
if preferred_language is not None:
user.preferred_language = preferred_language
if city is not None:
user.city = city
if birthdate is not None:
user.birthdate = birthdate
if gender is not None:
user.gender = gender
if access_type is not None:
user.access_type = access_type
if photo_path is not None:
user.photo_path = photo_path
if photo_path_aux is not None:
user.photo_path_aux = photo_path_aux
if is_active is not None:
user.is_active = is_active
if user_attributtes.name is not None:
user.name = user_attributtes.name
if user_attributtes.username is not None:
user.username = user_attributtes.username
if user_attributtes.email is not None:
user.email = user_attributtes.email
if user_attributtes.preferred_language is not None:
user.preferred_language = user_attributtes.preferred_language
if user_attributtes.city is not None:
user.city = user_attributtes.city
if user_attributtes.birthdate is not None:
user.birthdate = user_attributtes.birthdate
if user_attributtes.gender is not None:
user.gender = user_attributtes.gender
if user_attributtes.access_type is not None:
user.access_type = user_attributtes.access_type
if user_attributtes.photo_path is not None:
user.photo_path = user_attributtes.photo_path
if user_attributtes.photo_path_aux is not None:
user.photo_path_aux = user_attributtes.photo_path_aux
if user_attributtes.is_active is not None:
user.is_active = user_attributtes.is_active
# Commit the changes to the database
db_session.commit()
@@ -382,7 +371,10 @@ async def edit_user(
# Define an HTTP PUT route to delete a user's photo
@router.put("/users/{user_id}/delete-photo")
async def delete_user_photo(user_id: int, token: str = Depends(oauth2_scheme)):
async def delete_user_photo(
user_id: int,
token: str = Depends(oauth2_scheme)
):
try:
# Validate the user's access token using the oauth2_scheme
sessionController.validate_token(token)
@@ -417,7 +409,10 @@ async def delete_user_photo(user_id: int, token: str = Depends(oauth2_scheme)):
# Define an HTTP DELETE route to delete a user
@router.delete("/users/{user_id}/delete")
async def delete_user(user_id: int, response: Response, token: str = Depends(oauth2_scheme)):
async def delete_user(
user_id: int,
token: str = Depends(oauth2_scheme)
):
try:
# Validate the user's access token using the oauth2_scheme
sessionController.validate_token(token)
@@ -431,12 +426,11 @@ async def delete_user(user_id: int, response: Response, token: str = Depends(oau
# Check if the user with the given ID exists
if not user:
raise HTTPException(status_code=404, detail="User not found")
# Check for existing dependencies if needed (e.g., related systems)
count_gear = db_session.query(Gear).filter(gear.user_id == user_id).count()
count_gear = db_session.query(Gear).filter(Gear.user_id == user_id).count()
if count_gear > 0:
raise HTTPException(status_code=409, detail="Cannot delete user due to existing dependencies")
# Delete the user from the database
db_session.delete(user)
db_session.commit()

View File

@@ -1,123 +0,0 @@
import os
import logging
from fastapi import APIRouter, Depends, HTTPException, Form, Response, File, UploadFile, Request
from fastapi.security import OAuth2PasswordBearer
from typing import List, Optional
from sqlalchemy import func, DECIMAL, DateTime
from db.db import get_db_session, Waypoint
from jose import jwt, JWTError
from dotenv import load_dotenv
import mysql.connector.errors
from urllib.parse import unquote
from pydantic import BaseModel
from datetime import datetime
router = APIRouter()
logger = logging.getLogger("myLogger")
# Load the environment variables from config/.env
load_dotenv('config/.env')
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
# @router.post("/waypoints/create")
# async def create_activity(
# activity_id: int = Form(...),
# lat: float = Form(...),
# lon: float = Form(...),
# ele: float = Form(...),
# time: str = Form(...),
# hr: int = Form(...),
# cad: int = Form(...),
# token: str = Depends(oauth2_scheme)
# ):
# from . import sessionController
# try:
# # Validate the user's token
# sessionController.validate_token(token)
# # Convert the 'time' string to a datetime
# time = datetime.strptime(time, "%Y-%m-%dT%H:%M:%SZ")
# # Create a new Activity record
# waypoint = Waypoint(
# activity_id=activity_id,
# latitude=lat,
# longitude=lon,
# elevation=ele,
# time=time,
# heart_rate=hr,
# cadence=cad
# )
# # Store the Activity record in the database
# with get_db_session() as db_session:
# db_session.add(waypoint)
# db_session.commit()
# return {"message": "Waypoint stored successfully"}
# except JWTError:
# raise HTTPException(status_code=401, detail="Unauthorized")
# except Exception as err:
# print(err)
# logger.error(err)
# raise HTTPException(status_code=500, detail="Failed to store activity")
# #return {"message": "Activity stored successfully"}
class WaypointCreate(BaseModel):
lat: float
lon: float
ele: float
time: str
hr: int
cad: int
power: int
@router.post("/waypoints/create/{activity_id}")
async def create_activities(
activity_id: int,
waypoints: List[WaypointCreate],
token: str = Depends(oauth2_scheme)
):
from . import sessionController
try:
# Validate the user's token
sessionController.validate_token(token)
waypoints_to_create = []
for waypoint in waypoints:
# Convert the 'time' string to a datetime
time = datetime.strptime(waypoint.time, "%Y-%m-%dT%H:%M:%SZ")
# Create a dictionary for the Waypoint record
waypoint_data = Waypoint(
activity_id=activity_id,
latitude=waypoint.lat,
longitude=waypoint.lon,
elevation=waypoint.ele,
time=time,
heart_rate=waypoint.hr,
cadence=waypoint.cad,
power=waypoint.power
)
waypoints_to_create.append(waypoint_data)
# Store the Waypoint records in the database using bulk_insert_mappings
with get_db_session() as db_session:
if waypoints_to_create:
# Convert model instances to dictionaries
waypoints_to_create_dict = [waypoint.__dict__ for waypoint in waypoints_to_create]
db_session.bulk_insert_mappings(Waypoint, waypoints_to_create_dict)
db_session.commit()
return {"message": "Waypoints stored successfully"}
except JWTError:
raise HTTPException(status_code=401, detail="Unauthorized")
except Exception as err:
print(err)
logger.error(err)
raise HTTPException(status_code=500, detail="Failed to store waypoints")

View File

@@ -40,7 +40,7 @@ class User(Base):
birthdate = Column(Date, nullable=True, comment='User birthdate (date)')
preferred_language = Column(String(length=5), nullable=False, comment='User preferred language (en, pt, others)')
gender = Column(Integer, nullable=False, comment='User gender (one digit)(1 - male, 2 - female)')
access_type = Column(Integer, nullable=False, comment='User type (one digit)(1 - student, 2 - admin, 3 - teacher, 4 - parent)')
access_type = Column(Integer, nullable=False, comment='User type (one digit)(1 - student, 2 - admin)')
photo_path = Column(String(length=250), nullable=True, comment='User photo path')
photo_path_aux = Column(String(length=250), nullable=True, comment='Auxiliary photo path')
is_active = Column(Integer, nullable=False, comment='Is user active (0 - not active, 1 - active)')
@@ -55,7 +55,7 @@ class User(Base):
# Establish a one-to-many relationship with 'activities'
activities = relationship('Activity', back_populates='user')
# Establish a one-to-many relationship between User and UserSettings
user_settings = relationship("UserSettings", back_populates="user")
# user_settings = relationship("UserSettings", back_populates="user")
# Data model for access_tokens table using SQLAlchemy's ORM
class AccessToken(Base):
@@ -88,19 +88,19 @@ class Gear(Base):
# Establish a one-to-many relationship with 'activities'
activities = relationship('Activity', back_populates='gear')
# Establish a one-to-many relationship between Gear and UserSettings
user_settings = relationship("UserSettings", back_populates="gear")
# user_settings = relationship("UserSettings", back_populates="gear")
class UserSettings(Base):
__tablename__ = 'user_settings'
#class UserSettings(Base):
# __tablename__ = 'user_settings'
id = Column(Integer, primary_key=True, autoincrement=True)
user_id = Column(Integer, nullable=False, doc='User ID that the activity belongs')
activity_type = Column(Integer, nullable=True, doc='Gear type')
gear_id = Column(Integer, nullable=True, doc='Gear ID associated with this activity')
# id = Column(Integer, primary_key=True, autoincrement=True)
# user_id = Column(Integer, ForeignKey('users.id'), nullable=False, doc='User ID that the activity belongs')
# activity_type = Column(Integer, nullable=True, doc='Gear type')
# gear_id = Column(Integer, ForeignKey('gear.id'), nullable=True, doc='Gear ID associated with this activity')
# Define the foreign key relationships
user = relationship("User", back_populates="user_settings")
gear = relationship("Gear", back_populates="user_settings")
# # Define the foreign key relationships
# user = relationship("User", back_populates="user_settings")
# gear = relationship("Gear", back_populates="user_settings")
# Data model for activities table using SQLAlchemy's ORM
class Activity(Base):

View File

@@ -2,7 +2,6 @@ from fastapi import FastAPI
from apscheduler.schedulers.background import BackgroundScheduler
from controllers import sessionController, userController, gearController, activitiesController
import logging
#from db.db import User # Import your SQLAlchemy session management from db.db
app = FastAPI()