Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions server/controller/transcript.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import http

from fastapi import APIRouter
from botocore.exceptions import ClientError

from src.utils.settings import AWS_BUCKET_NAME
from src.schemas.base import GenericResponseModel
from src.schemas.transcription import (
TranscribeAudioRequestSchema,
PollTranscriptionRequestSchema
)
from src.services.transcription import TranscriptionService

transcription_router = APIRouter(
prefix="/v1/transcription",
tags=[TranscriptionRouterTags.transcribe]
)

# Define the path operation decorator
@transcription_router.post(
"/create",
status_code=http.HTTPStatus.CREATED,
response_model=GenericResponseModel
)

# Define an async function to create the transcribed audio with help from Service layer
async def transcribe_audio(req: TranscribeAudioRequestSchema):
transcribe_client = AWSTranscribeClient().get_client()

service = TranscriptionService()

filename, file_format = req.s3_filename.split(".")
job_name = req.job_name
language_code = req.language_code

file_uri = service.generate_file_uri(
bucket_name=AWS_BUCKET_NAME,
filename=filename,
extension=file_format
)

try:
response = await service.transcribe_file(
transcribe_client=transcribe_client,
job_name=job_name,
file_uri=file_uri,
file_format=file_format,
language_code=language_code
)

return GenericResponseModel(
status_code=http.HTTPStatus.CREATED,
message="Successfully created audio transcription",
error="",
data=response,
)
except TimeoutError:
return GenericResponseModel(
...
)
except ClientError:
return GenericResponseModel(
...
)
64 changes: 64 additions & 0 deletions server/controller/user.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import http
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session
from pydantic import BaseModel, EmailStr

from database import get_db
from models.user import User as UserModel
from services.user_service import UserService
from schemas.user import UserCreate, UserResponse, TokenResponse
from schemas.generic import GenericResponseModel

user_router = APIRouter(
prefix="/v1/users",
tags=["users"]
)

@user_router.post(
"/register",
status_code=http.HTTPStatus.CREATED,
response_model=GenericResponseModel
)
async def register_user(user: UserCreate, db: Session = Depends(get_db)):
service = UserService(db)
try:
new_user = service.create_user(user)
return GenericResponseModel(
status_code=http.HTTPStatus.CREATED,
message="User successfully registered",
error="",
data={"user": new_user}
)
except Exception as e:
raise HTTPException(status_code=400, detail=str(e))

@user_router.post(
"/login",
status_code=http.HTTPStatus.OK,
response_model=GenericResponseModel
)
async def login_user(email: EmailStr, password: str, db: Session = Depends(get_db)):
service = UserService(db)
try:
token = service.authenticate_user(email, password)
return GenericResponseModel(
status_code=http.HTTPStatus.OK,
message="User successfully logged in",
error="",
data={"token": token}
)
except Exception as e:
raise HTTPException(status_code=400, detail=str(e))

@user_router.get(
"/me",
status_code=http.HTTPStatus.OK,
response_model=GenericResponseModel
)
async def get_user_details(current_user: UserModel = Depends(UserService.get_current_user)):
return GenericResponseModel(
status_code=http.HTTPStatus.OK,
message="User details retrieved successfully",
error="",
data={"user": current_user}
)
47 changes: 47 additions & 0 deletions server/database.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import os
from dotenv import load_dotenv
import psycopg2
from psycopg2 import pool

load_dotenv()

# SEE QUICKSTART PYTHON COSMOSDB POSTGRESQL
# https://learn.microsoft.com/en-us/azure/cosmos-db/postgresql/quickstart-app-stacks-python
# https://devblogs.microsoft.com/cosmosdb/azure-cosmos-db-python-and-fastapi/

# NOTE: fill in these variables in .env
host = os.getenv('COSMOS_HOST')
dbname = "citus"
user = "citus"
password = os.getenv('COSMOS_DB_PASSWORD')
sslmode = "require"

# Build a connection string from the variables
conn_string = "host={0} user={1} dbname={2} password={3} sslmode={4}".format(host, user, dbname, password, sslmode)

# Create a connection pool
try:
postgreSQL_pool = psycopg2.pool.SimpleConnectionPool(1, 20, conn_string)
print("Connection pool created successfully")
except psycopg2.Error as e:
print(f"Error creating connection pool: {e}")
exit(1)

def get_db_connection():
conn = postgreSQL_pool.getconn()
try:
yield conn
finally:
postgreSQL_pool.putconn(conn)

# # # Use getconn() to get a connection from the connection pool
# conn = postgreSQL_pool.getconn()

# cursor = conn.cursor()



# # Clean up
# conn.commit()
# cursor.close()
# conn.close()
119 changes: 119 additions & 0 deletions server/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
from sqlalchemy import Column, Integer, String, DateTime, ForeignKey, Boolean, Float, Text
from sqlalchemy.sql.functions import current_timestamp
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True, autoincrement=True)
username = Column(String(32), unique=True, nullable=False)
email = Column(String(256), unique=True, nullable=False)
passwordHash = Column(String(256), nullable=False)
updated_at = Column(DateTime, default=current_timestamp(), onupdate=current_timestamp())
created_at = Column(DateTime, default=current_timestamp())
verified = Column(Boolean, default=False)

class Team(Base):
__tablename__ = 'teams'
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(32), unique=True, nullable=False)
updated_at = Column(DateTime, default=current_timestamp(), onupdate=current_timestamp())
created_at = Column(DateTime, default=current_timestamp())

class TeamStat(Base):
__tablename__ = 'teamStats'
id = Column(Integer, primary_key=True, autoincrement=True)
teamId = Column(Integer, ForeignKey('teams.id'), nullable=False)
boxscoreId = Column(Integer, ForeignKey('boxscores.id'), nullable=False)
createdAt = Column(DateTime, default=current_timestamp())
startAt = Column(DateTime, nullable=False)
endAt = Column(DateTime, nullable=False)
points = Column(Integer, nullable=False)
rebounds = Column(Integer, nullable=False)
assists = Column(Integer, nullable=False)
steal = Column(Integer, nullable=False)
block = Column(Integer, nullable=False)
turnover = Column(Integer, nullable=False)
fgPercent = Column(Float, nullable=False)
fgAttempt = Column(Integer, nullable=False)
fgMade = Column(Integer, nullable=False)
fouls = Column(Integer, nullable=False)

class Boxscore(Base):
__tablename__ = 'boxscores'
id = Column(Integer, primary_key=True, autoincrement=True)
userId = Column(Integer, ForeignKey('users.id'), nullable=False)
homeTeamId = Column(Integer, ForeignKey('teams.id'), nullable=False)
awayTeamId = Column(Integer, ForeignKey('teams.id'), nullable=False)
textFileId = Column(Integer, ForeignKey('textFiles.id'), nullable=False)
score = Column(String, nullable=False)
homeScore = Column(Integer, nullable=False)
awayScore = Column(Integer, nullable=False)
startAt = Column(DateTime, nullable=False)
endAt = Column(DateTime, nullable=False)
updatedAt = Column(DateTime, default=current_timestamp(), onupdate=current_timestamp())
createdAt = Column(DateTime, default=current_timestamp())

class Player(Base):
__tablename__ = 'players'
id = Column(Integer, primary_key=True, autoincrement=True)
userId = Column(Integer, ForeignKey('users.id'), nullable=False)
teamId = Column(Integer, ForeignKey('teams.id'), nullable=False)
updatedAt = Column(DateTime, default=current_timestamp(), onupdate=current_timestamp())
createdAt = Column(DateTime, default=current_timestamp())
matches = Column(String, nullable=True)

class PlayerStat(Base):
__tablename__ = 'playerStats'
id = Column(Integer, primary_key=True, autoincrement=True)
playerId = Column(Integer, ForeignKey('players.id'), nullable=False)
boxscoreId = Column(Integer, ForeignKey('boxscores.id'), nullable=False)
points = Column(Integer, nullable=False)
rebounds = Column(Integer, nullable=False)
assists = Column(Integer, nullable=False)
steal = Column(Integer, nullable=False)
block = Column(Integer, nullable=False)
turnover = Column(Integer, nullable=False)
fgPercent = Column(Float, nullable=False)
fgAttempt = Column(Integer, nullable=False)
fgMade = Column(Integer, nullable=False)
fouls = Column(Integer, nullable=False)

class Token(Base):
__tablename__ = 'tokens'
id = Column(Integer, primary_key=True, autoincrement=True)
userId = Column(Integer, ForeignKey('users.id'), nullable=False)
token = Column(String(256), unique=True, nullable=False)
expiresAt = Column(DateTime, nullable=False)
used = Column(Boolean, default=False)

class PasswordResetToken(Base):
__tablename__ = 'passwordResetTokens'
id = Column(Integer, primary_key=True, autoincrement=True)
userId = Column(Integer, ForeignKey('users.id'), nullable=False)
token = Column(String(256), unique=True, nullable=False)
expiresAt = Column(DateTime, nullable=False)

class AccountVerificationToken(Base):
__tablename__ = 'accountVerificationTokens'
id = Column(Integer, primary_key=True, autoincrement=True)
userId = Column(Integer, ForeignKey('users.id'), nullable=False)
token = Column(String(256), unique=True, nullable=False)
expiresAt = Column(DateTime, nullable=False)

class AudioFile(Base):
__tablename__ = 'audioFiles'
id = Column(Integer, primary_key=True, autoincrement=True)
userId = Column(Integer, ForeignKey('users.id'), nullable=False)
filePath = Column(String, nullable=False)
createdAt = Column(DateTime, default=current_timestamp())

class TextFile(Base):
__tablename__ = 'textFiles'
id = Column(Integer, primary_key=True, autoincrement=True)
userId = Column(Integer, ForeignKey('users.id'), nullable=False)
audioId = Column(Integer, ForeignKey('audioFiles.id'), nullable=False)
contents = Column(Text, nullable=False)
createdAt = Column(DateTime, default=current_timestamp())
filepath = Column(String, nullable=False)
11 changes: 11 additions & 0 deletions server/models/account_verification_token.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from sqlalchemy import Column, Integer, String, DateTime, ForeignKey, Boolean, Float, Text
from sqlalchemy.sql.functions import current_timestamp
from sqlalchemy.ext.declarative import declarative_base

class AccountVerificationToken(Base):
__tablename__ = 'accountVerificationTokens'
id = Column(Integer, primary_key=True, autoincrement=True)
userId = Column(Integer, ForeignKey('users.id'), nullable=False)
token = Column(String(256), unique=True, nullable=False)
expiresAt = Column(DateTime, nullable=False)
createdAt = Column(DateTime, default=current_timestamp())
10 changes: 10 additions & 0 deletions server/models/audio_file.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from sqlalchemy import Column, Integer, String, DateTime, ForeignKey, Boolean, Float, Text
from sqlalchemy.sql.functions import current_timestamp
from sqlalchemy.ext.declarative import declarative_base

class AudioFile(Base):
__tablename__ = 'audioFiles'
id = Column(Integer, primary_key=True, autoincrement=True)
userId = Column(Integer, ForeignKey('users.id'), nullable=False)
filePath = Column(String, nullable=False)
createdAt = Column(DateTime, default=current_timestamp())
18 changes: 18 additions & 0 deletions server/models/box_score.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from sqlalchemy import Column, Integer, String, DateTime, ForeignKey, Boolean, Float, Text
from sqlalchemy.sql.functions import current_timestamp
from sqlalchemy.ext.declarative import declarative_base

class Boxscore(Base):
__tablename__ = 'boxscores'
id = Column(Integer, primary_key=True, autoincrement=True)
userId = Column(Integer, ForeignKey('users.id'), nullable=False)
homeTeamId = Column(Integer, ForeignKey('teams.id'), nullable=False)
awayTeamId = Column(Integer, ForeignKey('teams.id'), nullable=False)
textFileId = Column(Integer, ForeignKey('textFiles.id'), nullable=False)
score = Column(String, nullable=False)
homeScore = Column(Integer, nullable=False)
awayScore = Column(Integer, nullable=False)
startAt = Column(DateTime, nullable=False)
endAt = Column(DateTime, nullable=False)
updatedAt = Column(DateTime, default=current_timestamp(), onupdate=current_timestamp())
createdAt = Column(DateTime, default=current_timestamp())
10 changes: 10 additions & 0 deletions server/models/password_reset_token.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from sqlalchemy import Column, Integer, String, DateTime, ForeignKey, Boolean, Float, Text
from sqlalchemy.sql.functions import current_timestamp
from sqlalchemy.ext.declarative import declarative_base

class PasswordResetToken(Base):
__tablename__ = 'passwordResetTokens'
id = Column(Integer, primary_key=True, autoincrement=True)
userId = Column(Integer, ForeignKey('users.id'), nullable=False)
token = Column(String(256), unique=True, nullable=False)
expiresAt = Column(DateTime, nullable=False)
12 changes: 12 additions & 0 deletions server/models/player.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from sqlalchemy import Column, Integer, String, DateTime, ForeignKey, Boolean, Float, Text
from sqlalchemy.sql.functions import current_timestamp
from sqlalchemy.ext.declarative import declarative_base

class Player(Base):
__tablename__ = 'players'
id = Column(Integer, primary_key=True, autoincrement=True)
userId = Column(Integer, ForeignKey('users.id'), nullable=False)
teamId = Column(Integer, ForeignKey('teams.id'), nullable=False)
updatedAt = Column(DateTime, default=current_timestamp(), onupdate=current_timestamp())
createdAt = Column(DateTime, default=current_timestamp())
matches = Column(String, nullable=True)
19 changes: 19 additions & 0 deletions server/models/player_stat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from sqlalchemy import Column, Integer, String, DateTime, ForeignKey, Boolean, Float, Text
from sqlalchemy.sql.functions import current_timestamp
from sqlalchemy.ext.declarative import declarative_base

class PlayerStat(Base):
__tablename__ = 'playerStats'
id = Column(Integer, primary_key=True, autoincrement=True)
playerId = Column(Integer, ForeignKey('players.id'), nullable=False)
boxscoreId = Column(Integer, ForeignKey('boxscores.id'), nullable=False)
points = Column(Integer, nullable=False)
rebounds = Column(Integer, nullable=False)
assists = Column(Integer, nullable=False)
steal = Column(Integer, nullable=False)
block = Column(Integer, nullable=False)
turnover = Column(Integer, nullable=False)
fgPercent = Column(Float, nullable=False)
fgAttempt = Column(Integer, nullable=False)
fgMade = Column(Integer, nullable=False)
fouls = Column(Integer, nullable=False)
Loading