Browse Source

Merge pull request #1 from Madiwka4/Madi

Madi
main
Madiwka 1 year ago
committed by GitHub
parent
commit
5a63267ea4
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 255 additions and 240 deletions
  1. +1
    -1
      README.md
  2. +0
    -1
      app/alembic/README
  3. +0
    -83
      app/alembic/env.py
  4. +0
    -26
      app/alembic/script.py.mako
  5. +0
    -60
      app/alembic/versions/9a0214838ac8_create_user_and_vehicle_tables.py
  6. +49
    -14
      app/apis/v1/route_auth.py
  7. +12
    -3
      app/apis/v1/route_user.py
  8. +62
    -10
      app/apis/v1/route_vehicle.py
  9. +3
    -1
      app/core/auth.py
  10. +23
    -1
      app/core/config.py
  11. +3
    -3
      app/db/base.py
  12. +14
    -0
      app/db/base_class.py
  13. +0
    -0
      app/db/models/assignment.py
  14. +4
    -2
      app/db/models/user.py
  15. +4
    -3
      app/db/models/vehicle.py
  16. +7
    -0
      app/db/repository/user.py
  17. +47
    -22
      app/db/repository/vehicle.py
  18. +6
    -2
      app/main.py
  19. +5
    -0
      app/schemas/token.py
  20. +4
    -2
      app/schemas/user.py
  21. +11
    -6
      app/schemas/vehicle.py

+ 1
- 1
README.md View File

@@ -14,7 +14,7 @@
## How to launch
First, make sure that python is installed. Create a virtual environment (if you want to)
```
python -m venv venv
python/python3 -m venv venv
source /venv/bin/activate
```
(not necessary)


+ 0
- 1
app/alembic/README View File

@@ -1 +0,0 @@
Generic single-database configuration.

+ 0
- 83
app/alembic/env.py View File

@@ -1,83 +0,0 @@
from logging.config import fileConfig

from sqlalchemy import engine_from_config
from sqlalchemy import pool

from alembic import context

from core.config import settings
from db.base import Base


# this is the Alembic Config object, which provides
# access to the values within the .ini file in use.
config = context.config


config.set_main_option("sqlalchemy.url", settings.DATABASE_URL)

# Interpret the config file for Python logging.
# This line sets up loggers basically.
if config.config_file_name is not None:
fileConfig(config.config_file_name)

# add your model's MetaData object here
# for 'autogenerate' support
# from myapp import mymodel
# target_metadata = mymodel.Base.metadata
target_metadata = Base.metadata

# other values from the config, defined by the needs of env.py,
# can be acquired:
# my_important_option = config.get_main_option("my_important_option")
# ... etc.


def run_migrations_offline() -> None:
"""Run migrations in 'offline' mode.

This configures the context with just a URL
and not an Engine, though an Engine is acceptable
here as well. By skipping the Engine creation
we don't even need a DBAPI to be available.

Calls to context.execute() here emit the given string to the
script output.

"""
url = config.get_main_option("sqlalchemy.url")
context.configure(
url=url,
target_metadata=target_metadata,
literal_binds=True,
dialect_opts={"paramstyle": "named"},
)

with context.begin_transaction():
context.run_migrations()


def run_migrations_online() -> None:
"""Run migrations in 'online' mode.

In this scenario we need to create an Engine
and associate a connection with the context.

"""
connectable = engine_from_config(
config.get_section(config.config_ini_section, {}),
prefix="sqlalchemy.",
poolclass=pool.NullPool,
)

with connectable.connect() as connection:
context.configure(connection=connection, target_metadata=target_metadata)

with context.begin_transaction():
context.run_migrations()


if context.is_offline_mode():
run_migrations_offline()
else:
run_migrations_online()

+ 0
- 26
app/alembic/script.py.mako View File

@@ -1,26 +0,0 @@
"""${message}

Revision ID: ${up_revision}
Revises: ${down_revision | comma,n}
Create Date: ${create_date}

"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa
${imports if imports else ""}

# revision identifiers, used by Alembic.
revision: str = ${repr(up_revision)}
down_revision: Union[str, None] = ${repr(down_revision)}
branch_labels: Union[str, Sequence[str], None] = ${repr(branch_labels)}
depends_on: Union[str, Sequence[str], None] = ${repr(depends_on)}


def upgrade() -> None:
${upgrades if upgrades else "pass"}


def downgrade() -> None:
${downgrades if downgrades else "pass"}

+ 0
- 60
app/alembic/versions/9a0214838ac8_create_user_and_vehicle_tables.py View File

@@ -1,60 +0,0 @@
"""create User and Vehicle tables

Revision ID: 9a0214838ac8
Revises:
Create Date: 2023-09-01 13:31:01.324861

"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision: str = '9a0214838ac8'
down_revision: Union[str, None] = None
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('users',
sa.Column('Id', sa.Integer(), nullable=False),
sa.Column('Name', sa.String(), nullable=False),
sa.Column('MiddleName', sa.String(), nullable=True),
sa.Column('LastName', sa.String(), nullable=False),
sa.Column('BirthDate', sa.DateTime(), nullable=False),
sa.Column('ContactNumber', sa.String(), nullable=False),
sa.Column('Email', sa.String(), nullable=False),
sa.Column('Role', sa.String(), nullable=False),
sa.Column('DrivingLicenseNumber', sa.String(), nullable=True),
sa.Column('HashedPassword', sa.String(), nullable=False),
sa.PrimaryKeyConstraint('Id')
)
op.create_index(op.f('ix_users_Id'), 'users', ['Id'], unique=False)
op.create_table('vehicles',
sa.Column('Id', sa.Integer(), nullable=False),
sa.Column('Model', sa.String(), nullable=False),
sa.Column('Year', sa.Integer(), nullable=False),
sa.Column('LicensePlate', sa.String(), nullable=False),
sa.Column('Type', sa.String(), nullable=False),
sa.Column('AssignedDriverIds', sa.ARRAY(sa.Integer()), nullable=True),
sa.Column('CurrentLocation', sa.ARRAY(sa.String()), nullable=True),
sa.Column('Fuel', sa.Integer(), nullable=False),
sa.Column('Mileage', sa.Integer(), nullable=False),
sa.Column('MaintenanceNotes', sa.ARRAY(sa.String()), nullable=True),
sa.PrimaryKeyConstraint('Id')
)
op.create_index(op.f('ix_vehicles_Id'), 'vehicles', ['Id'], unique=False)
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_index(op.f('ix_vehicles_Id'), table_name='vehicles')
op.drop_table('vehicles')
op.drop_index(op.f('ix_users_Id'), table_name='users')
op.drop_table('users')
# ### end Alembic commands ###

+ 49
- 14
app/apis/v1/route_auth.py View File

@@ -1,3 +1,4 @@
from datetime import datetime
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from fastapi import Depends, APIRouter
from sqlalchemy.orm import Session
@@ -7,20 +8,23 @@ from db.session import get_db
from core.hashing import Hasher
from core.config import settings
from jose import JWTError, jwt
from schemas.token import Token
from schemas.token import Token, TokenPayload
from db.repository.user import get_user_by_email, get_user_by_phone
from core.auth import create_access_token


router = APIRouter()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/token")
oauth2_scheme = OAuth2PasswordBearer(
tokenUrl="/token",
)


def authenticate_user(login: str, password: str, db: Session):
print("Trying to auth...")
user = None
if ("@" in login):
if "@" in login:
user = get_user_by_email(email=login, db=db)
elif ("+" in login):
elif "+" in login:
user = get_user_by_phone(phone=login, db=db)
else:
return False
@@ -31,30 +35,61 @@ def authenticate_user(login: str, password: str, db: Session):
return user


def get_current_user(token: Annotated[str, Depends(oauth2_scheme)], db: Annotated[Session, Depends(get_db)]):
def get_current_user(
token: Annotated[str, Depends(oauth2_scheme)],
db: Annotated[Session, Depends(get_db)],
):
print("Getting current user...")
try:
payload = jwt.decode(token, settings.SECRET_KEY, algorithms=[settings.ALGORITHM])
payload = jwt.decode(
token, settings.SECRET_KEY, algorithms=[settings.ALGORITHM]
)
token_data = TokenPayload(**payload)

if datetime.fromtimestamp(token_data.exp) < datetime.now():
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Session expired. Please login again.",
)
username: str = payload.get("sub")
if username is None:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Could not validate credentials")
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Could not validate credentials",
)
except JWTError:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Could not validate credentials")
if ("@" in username):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Could not validate credentials",
)
if "@" in username:
user = get_user_by_email(email=username, db=db)
elif ("+" in username):
elif "+" in username:
user = get_user_by_phone(phone=username, db=db)
else:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Could not validate credentials")
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Could not validate credentials",
)
return user


@router.post("/token", response_model=Token)
def access_token(form_data: OAuth2PasswordRequestForm = Depends(), db: Session = Depends(get_db)):
def access_token(
form_data: OAuth2PasswordRequestForm = Depends(), db: Session = Depends(get_db)
):
print("Getting token...")
user = authenticate_user(form_data.username, form_data.password, db)
print(user)
if not user:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid username or password")
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid username or password",
)
access_token = create_access_token(data={"sub": user.Email})
return {"access_token": access_token, "token_type": "bearer"}
print("TOKENS ARE: ")
print(access_token)
return {
"access_token": access_token,
"token_type": "bearer",
}

+ 12
- 3
app/apis/v1/route_user.py View File

@@ -14,9 +14,15 @@ router = APIRouter()


@router.post("/", response_model=ShowUser, status_code=status.HTTP_201_CREATED)
def create_user(user: UserCreate, db: Session = Depends(get_db), current_user: User = Depends(get_current_user)):
if current_user.Role != "Admin":
def create_user(
user: UserCreate,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
):
if (current_user.Role != "Admin"):
raise HTTPException(status_code=403, detail="You are not authorized to perform this action")
# if current_user.Role != "Admin":
# raise HTTPException(status_code=403, detail="You are not authorized to perform this action")
user = create_new_user(user=user, db=db)
return user

@@ -31,7 +37,10 @@ def get_all_users(db: Session = Depends(get_db), role: str = None):


@router.get("/me", response_model=ShowUser, status_code=status.HTTP_200_OK)
def get_user_me(current_user: Annotated[User, Depends(get_current_user)], db: Annotated[Session, Depends(get_db)]):
def get_user_me(
current_user: Annotated[User, Depends(get_current_user)],
db: Annotated[Session, Depends(get_db)],
):
print("Getting current user...")
return current_user



+ 62
- 10
app/apis/v1/route_vehicle.py View File

@@ -3,7 +3,7 @@ from sqlalchemy.orm import Session
from fastapi import Depends
from typing import List
from db.session import get_db
from schemas.vehicle import OutputVehicle, CreateVehicle, UpdateVehicle
from schemas.vehicle import OutputVehicle, CreateVehicle, UpdateVehicle, VehicleLocation
from db.repository.vehicle import (
create_new_vehicle,
assign_vehicle_driver,
@@ -11,6 +11,7 @@ from db.repository.vehicle import (
get_vehicle_by_id,
replace_vehicle_data,
delete_vehicle_data,
update_vehicle_geoloc,
)
from db.models.user import User
from apis.v1.route_auth import get_current_user
@@ -19,9 +20,16 @@ router = APIRouter()


@router.post("/", response_model=OutputVehicle, status_code=status.HTTP_201_CREATED)
async def create_vehicle(vehicle: CreateVehicle, db: Session = Depends(get_db), current_user: User = Depends(get_current_user)):
async def create_vehicle(
vehicle: CreateVehicle,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
):
print(current_user.Role)
if current_user.Role != "Admin":
raise HTTPException(status_code=403, detail="You are not authorized to perform this action")
raise HTTPException(
status_code=403, detail="You are not authorized to perform this action"
)
vehicle = create_new_vehicle(vehicle=vehicle, db=db)
return vehicle

@@ -52,9 +60,16 @@ async def create_vehicle(vehicle: CreateVehicle, db: Session = Depends(get_db),
response_model=OutputVehicle,
status_code=status.HTTP_200_OK,
)
async def assign_driver(vehicle_id: int, driver_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_user)):
async def assign_driver(
vehicle_id: int,
driver_id: int,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
):
if current_user.Role != "Admin":
raise HTTPException(status_code=403, detail="You are not authorized to perform this action")
raise HTTPException(
status_code=403, detail="You are not authorized to perform this action"
)
vehicle = assign_vehicle_driver(vehicle_id=vehicle_id, driver_id=driver_id, db=db)
if vehicle == "nodriver":
raise HTTPException(
@@ -67,7 +82,7 @@ async def assign_driver(vehicle_id: int, driver_id: int, db: Session = Depends(g
if vehicle == "alreadyassigned":
raise HTTPException(
status_code=400,
detail=f"Driver with id {driver_id} is already assigned to vehicle with id {vehicle_id}",
detail=f"A driver is already assigned to vehicle with id {vehicle_id}",
)
return vehicle

@@ -92,23 +107,60 @@ async def get_vehicle(vehicle_id: int, db: Session = Depends(get_db)):
"/{vehicle_id}", response_model=OutputVehicle, status_code=status.HTTP_200_OK
)
def update_vehicle(
vehicle_id: int, vehicle: UpdateVehicle, db: Session = Depends(get_db), current_user: User = Depends(get_current_user)
vehicle_id: int,
vehicle: UpdateVehicle,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
):
if current_user.Role != "Admin":
raise HTTPException(status_code=403, detail="You are not authorized to perform this action")
raise HTTPException(
status_code=403, detail="You are not authorized to perform this action"
)
vehicleRes = replace_vehicle_data(id=vehicle_id, vehicle=vehicle, db=db)
if vehicleRes == "vehicleNotFound":
raise HTTPException(status_code=404, detail="Vehicle not found")
elif vehicleRes == "badreq":
raise HTTPException(status_code=502, detail="Bad request")
elif vehicleRes == "driverNotFound":
raise HTTPException(status_code=404, detail="Driver not found")
return vehicleRes


@router.delete("/{vehicle_id}", status_code=status.HTTP_200_OK)
def delete_vehicle(vehicle_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_user)):
def delete_vehicle(
vehicle_id: int,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
):
if current_user.Role != "Admin":
raise HTTPException(status_code=403, detail="You are not authorized to perform this action")
raise HTTPException(
status_code=403, detail="You are not authorized to perform this action"
)
result = delete_vehicle_data(id=vehicle_id, db=db)
if result == "vehicleNotFound":
raise HTTPException(status_code=404, detail="Vehicle not found")
return {"msg": "Vehicle deleted successfully"}


@router.post("/{vehicle_id}/location", status_code=status.HTTP_200_OK)
def update_vehicle_location(
vehicle_id: int,
location: VehicleLocation,
current_user: User = Depends(get_current_user),
db: Session = Depends(get_db),
):
print(current_user)
print(current_user.Name)
if current_user.Role != "Driver":
raise HTTPException(
status_code=403, detail="You are not authorized to perform this action"
)
if current_user.AssignedVehicle != vehicle_id:
raise HTTPException(
status_code=403, detail="You are not the correct car driver"
)
print("FUNNY")
vehicle = update_vehicle_geoloc(vehicle_id=vehicle_id, location=location, db=db)
if vehicle == "vehiclenotfound":
raise HTTPException(status_code=404, detail="Vehicle not found")
return vehicle

+ 3
- 1
app/core/auth.py View File

@@ -12,5 +12,7 @@ def create_access_token(data: dict, expires_delta: Optional[timedelta] = None):
else:
expire = datetime.utcnow() + timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE)
to_encode.update({"exp": expire})
encoded_jwt = jwt.encode(to_encode, settings.SECRET_KEY, algorithm=settings.ALGORITHM)
encoded_jwt = jwt.encode(
to_encode, settings.SECRET_KEY, algorithm=settings.ALGORITHM
)
return encoded_jwt

+ 23
- 1
app/core/config.py View File

@@ -7,9 +7,31 @@ class Settings:
POSTGRES_PORT: str = "5432"
POSTGRES_DB: str = "VMSData"
DATABASE_URL = f"postgresql://{POSTGRES_USER}:{POSTGRES_PASSWORD}@{POSTGRES_SERVER}:{POSTGRES_PORT}/{POSTGRES_DB}"
ACCESS_TOKEN_EXPIRE: int = 30
ACCESS_TOKEN_EXPIRE: int = 60 * 24 * 7 # 7 days
SECRET_KEY: str = "tH357aC6oA7ofCaN3yTffYkRh"
ALGORITHM: str = "HS256"


settings = Settings()


def createAdminAcc():
from db.session import SessionLocal
from db.repository.user import create_new_user
from schemas.user import UserCreate
from db.models.user import User

db = SessionLocal()
user = UserCreate(
Email="madi.turgunov@nu.edu.kz",
Password="1234567",
Name="Madi",
LastName="Turgunov",
ContactNumber="+77071234567",
Role="Admin",
BirthDate="2000-01-01T00:00:00+06:00",
)
if db.query(User).filter(User.Email == user.Email).first():
return False
create_new_user(user=user, db=db)
return True

+ 3
- 3
app/db/base.py View File

@@ -1,4 +1,4 @@
# Base class for all sqlalchemy models
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
from db.base_class import Base
from db.models.user import User
from db.models.vehicle import Vehicle

+ 14
- 0
app/db/base_class.py View File

@@ -0,0 +1,14 @@
from typing import Any

from sqlalchemy.ext.declarative import as_declarative, declared_attr


@as_declarative()
class Base:
id: Any
__name__: str

# Generate __tablename__ automatically
@declared_attr
def __tablename__(cls) -> str:
return cls.__name__.lower()

+ 0
- 0
app/db/models/assignment.py View File


+ 4
- 2
app/db/models/user.py View File

@@ -1,10 +1,10 @@
# PostgreSQL table model for users
from sqlalchemy import Column, Integer, String, DateTime
from sqlalchemy import Column, Integer, String, DateTime, ForeignKey
from sqlalchemy.orm import relationship
from db.base import Base


class User(Base):
__tablename__ = "users"
Id = Column(Integer, primary_key=True, index=True)
Name = Column(String, nullable=False)
MiddleName = Column(String, nullable=True)
@@ -14,4 +14,6 @@ class User(Base):
Email = Column(String, nullable=False)
Role = Column(String, nullable=False)
DrivingLicenseNumber = Column(String, nullable=True)
AssignedVehicle = Column(Integer, ForeignKey("vehicle.Id"), nullable=True)
vehicle = relationship("Vehicle", back_populates="driver")
HashedPassword = Column(String, nullable=False)

+ 4
- 3
app/db/models/vehicle.py View File

@@ -5,18 +5,19 @@ from sqlalchemy import (
String,
ARRAY,
)
from sqlalchemy.orm import relationship
from db.base import Base


class Vehicle(Base):
__tablename__ = "vehicles"
Id = Column(Integer, primary_key=True, index=True)
Model = Column(String, nullable=False)
Year = Column(Integer, nullable=False)
LicensePlate = Column(String, nullable=False)
Type = Column(String, nullable=False)
AssignedDriverIds = Column(ARRAY(Integer), nullable=True)
CurrentLocation = Column(ARRAY(String), nullable=True)
Fuel = Column(Integer, nullable=False)
Mileage = Column(Integer, nullable=False)
Status = Column(String, nullable=False)
Capacity = Column(Integer, nullable=False)
MaintenanceNotes = Column(ARRAY(String), nullable=True)
driver = relationship("User", back_populates="vehicle")

+ 7
- 0
app/db/repository/user.py View File

@@ -47,6 +47,13 @@ def verify_driver_exists(driver_id: int, db: Session):
return True


def get_car_driver(vehicle_id: int, db: Session):
driver = db.query(User).filter(User.AssignedVehicle == vehicle_id).first()
if not driver:
return False
return driver


def list_users(db: Session, role: str = "Any"):
users = db.query(User).filter((User.Role == role) | (role == "Any")).all()
return users

+ 47
- 22
app/db/repository/vehicle.py View File

@@ -1,51 +1,72 @@
from sqlalchemy.orm import Session
from schemas.vehicle import CreateVehicle, UpdateVehicle
from schemas.vehicle import CreateVehicle, UpdateVehicle, VehicleLocation
from db.models.vehicle import Vehicle
from db.repository.user import verify_driver_exists
from db.base import User
from db.repository.user import get_car_driver


def create_new_vehicle(vehicle: CreateVehicle, db: Session):
vehicle_object = Vehicle(
**vehicle.model_dump(),
Fuel=0,
AssignedDriverIds=[],
Status="Inactive",
CurrentLocation=[],
MaintenanceNotes=[]
)
db.add(vehicle_object)
db.commit()
db.refresh(vehicle_object)
return vehicle
return vehicle_object


def update_vehicle_geoloc(vehicle_id: int, location: VehicleLocation, db: Session):
vehicle_db = db.query(Vehicle).filter(Vehicle.Id == vehicle_id)
vehicle_object = vehicle_db.first()
if not vehicle_object:
return "vehiclenotfound"
print("Location: " + str(location.CurrentLocation))
vehicle_object.CurrentLocation = location.CurrentLocation
db.add(vehicle_object)
db.commit()
db.refresh(vehicle_object)
return vehicle_object


def assign_vehicle_driver(vehicle_id: int, driver_id: int, db: Session):
vehicledb = db.query(Vehicle).filter(Vehicle.Id == vehicle_id)
vehicle = vehicledb.first()
driver = (
db.query(User).filter((User.Id == driver_id) & (User.Role == "Driver")).first()
)
print(driver)
vehicle = db.query(Vehicle).filter(Vehicle.Id == vehicle_id).first()
if not vehicle:
return "novehicle"
if driver_id in vehicle.AssignedDriverIds:
return "alreadyassigned"
if verify_driver_exists(driver_id=driver_id, db=db):
print(vehicle.AssignedDriverIds)
vehicledb.update(
{"AssignedDriverIds": vehicle.AssignedDriverIds + [driver_id]}
)
print(vehicle.AssignedDriverIds)
db.add(vehicle)
db.commit()
db.refresh(vehicle)
return vehicle
# return a 404 error if the driver does not exist
return "nodriver"
if not driver:
return "nodriver"
driver.AssignedVehicle = vehicle_id
db.add(driver)
db.commit()
return vehicle


def list_vehicles(db: Session):
vehicles = db.query(Vehicle).all()
# assign AssignedDriver to all vehicles based on their drivers
for vehicle in vehicles:
driver = get_car_driver(vehicle.Id, db)
if driver:
vehicle.AssignedDriver = driver.Id
else:
vehicle.AssignedDriver = None
return vehicles


def get_vehicle_by_id(vehicle_id: int, db: Session):
vehicle = db.query(Vehicle).filter(Vehicle.Id == vehicle_id).first()
driver = get_car_driver(vehicle.Id, db)
if driver:
vehicle.AssignedDriver = driver.Id
else:
vehicle.AssignedDriver = None
return vehicle


@@ -54,18 +75,22 @@ def replace_vehicle_data(id: int, vehicle: UpdateVehicle, db: Session):
vehicle_object = vehicle_db.first()
if not vehicle_object:
return "vehiclenotfound"
vehicle_object.AssignedDriverIds = vehicle.AssignedDriverIds
vehicle_object.CurrentLocation = vehicle.CurrentLocation
vehicle_object.Fuel = vehicle.Fuel
vehicle_object.LicensePlate = vehicle.LicensePlate
vehicle_object.MaintenanceNotes = vehicle.MaintenanceNotes
vehicle_object.Mileage = vehicle.Mileage
vehicle_object.Model = vehicle.Model
vehicle_object.Type = vehicle.Type
vehicle_object.Status = vehicle.Status
res = assign_vehicle_driver(id, vehicle.AssignedDriver, db)
if res == "nodriver":
return "driverNotFound"
vehicle_object.Capacity = vehicle.Capacity
vehicle_object.Year = vehicle.Year
print(vehicle_object)
db.add(vehicle_object)
db.commit()
vehicle_object.AssignedDriver = vehicle.AssignedDriver
return vehicle_object




+ 6
- 2
app/main.py View File

@@ -1,5 +1,5 @@
from fastapi import FastAPI
from core.config import settings
from core.config import settings, createAdminAcc
from db.session import engine
from db.base import Base
from apis.base import api_router
@@ -10,8 +10,12 @@ def include_routes(app): # include all routes from our api/v1/


def startup(): # start the project, and create the tables
app = FastAPI(title=settings.PROJECT_NAME, version=settings.PROJECT_VERSION)
app = FastAPI(
title=settings.PROJECT_NAME,
version=settings.PROJECT_VERSION,
)
Base.metadata.create_all(bind=engine)
createAdminAcc()
include_routes(app)
return app



+ 5
- 0
app/schemas/token.py View File

@@ -4,3 +4,8 @@ from pydantic import BaseModel
class Token(BaseModel):
access_token: str
token_type: str


class TokenPayload(BaseModel):
sub: str = None
exp: int = None

+ 4
- 2
app/schemas/user.py View File

@@ -8,7 +8,7 @@ class UserCreate(BaseModel):
Email: EmailStr
Password: str = Field(..., min_length=7, max_length=20)
Name: str = Field(..., min_length=3, max_length=50)
MiddleName: str = Field(None, min_length=3, max_length=50)
MiddleName: str = Field(None)
LastName: str = Field(..., min_length=3, max_length=50)
ContactNumber: str = Field(..., min_length=12, max_length=12)
BirthDate: datetime = Field(...)
@@ -19,12 +19,14 @@ class UserCreate(BaseModel):
class ShowUser(BaseModel):
Id: int
Name: str
MiddleName: str
MiddleName: str | None
LastName: str
ContactNumber: str
BirthDate: datetime
Email: EmailStr
Role: str
AssignedVehicle: int | None

class Config:
orm_mode = True
validate_assignment = True

+ 11
- 6
app/schemas/vehicle.py View File

@@ -3,12 +3,11 @@ from pydantic import BaseModel


class CreateVehicle(BaseModel):
Id: int
Model: str
Year: int
LicensePlate: str
Type: str
Mileage: int
Capacity: int


class OutputVehicle(BaseModel):
@@ -16,21 +15,27 @@ class OutputVehicle(BaseModel):
Model: str
Year: int
LicensePlate: str
Type: str
Mileage: int
CurrentLocation: Optional[list[str]] = None
Fuel: Optional[int] = 0
MaintenanceNotes: Optional[list[str]] = None
AssignedDriverIds: Optional[list[int]] = None
AssignedDriver: Optional[int] = None
Capacity: int
Status: str


class UpdateVehicle(BaseModel):
Model: str
Year: int
LicensePlate: str
Type: str
Capacity: int
Mileage: int
Status: str
CurrentLocation: Optional[list[str]] = None
Fuel: Optional[int] = 0
MaintenanceNotes: Optional[list[str]] = None
AssignedDriverIds: Optional[list[int]] = None
AssignedDriver: Optional[int] = None


class VehicleLocation(BaseModel):
CurrentLocation: list[str]

Loading…
Cancel
Save