From 12d44056547e94d4319f48fe69351ca57f98507e Mon Sep 17 00:00:00 2001 From: coolneng Date: Fri, 5 Jun 2020 01:09:55 +0200 Subject: [PATCH] Migrate to FastAPI with a focus on async code --- app/__init__.py | 14 +- app/models.py | 355 ----------------------------------------- app/routes.py | 43 ++--- app/schema.py | 101 ------------ app/schemas.py | 28 ++++ app/twilio.py | 14 +- config.py | 7 - database/__init__.py | 12 ++ database/crud.py | 95 +++++------ database/models.py | 356 ++++++++++++++++++++++++++++++++++++++++++ shell.nix | 16 +- tests/conftest.py | 10 -- tests/queries_test.py | 2 +- 13 files changed, 486 insertions(+), 567 deletions(-) delete mode 100644 app/models.py delete mode 100644 app/schema.py create mode 100644 app/schemas.py delete mode 100644 config.py create mode 100644 database/models.py delete mode 100644 tests/conftest.py diff --git a/app/__init__.py b/app/__init__.py index 87481be..354ce4c 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1,13 +1,5 @@ -from flask import Flask -from config import Config -from flask_sqlalchemy import SQLAlchemy -from flask_migrate import Migrate -from flask_marshmallow import Marshmallow +from fastapi import FastAPI -app = Flask(__name__) -app.config.from_object(Config) -db = SQLAlchemy(app) -migrate = Migrate(app, db) -ma = Marshmallow(app) +app = FastAPI() -from app import routes, models, schema +from app import routes, schema diff --git a/app/models.py b/app/models.py deleted file mode 100644 index 4bee864..0000000 --- a/app/models.py +++ /dev/null @@ -1,355 +0,0 @@ -from app import db -from sqlalchemy import text - - -class Users(db.Model): - id = db.Column(db.Integer, primary_key=True, autoincrement=True) - social_id = db.Column(db.Text) - type = db.Column(db.Integer) - full_name = db.Column(db.String(255), index=True, unique=True) - email = db.Column(db.String(255), index=True, unique=True) - password = db.Column(db.String(255)) - gender = db.Column(db.Integer) - mobile = db.Column(db.String(255)) - user_image = db.Column(db.String(255)) - city_id = db.Column(db.Integer) - user_type = db.Column(db.Integer) - otp = db.Column(db.String(255)) - otp_valid_time = db.Column(db.Date) - access_key = db.Column(db.Text) - lang_type = db.Column(db.Integer) - badge = db.Column(db.Integer) - status = db.Column(db.Integer, server_default=text("0")) - admin_status = db.Column(db.Integer, server_default=text("0")) - device_id = db.Column(db.Text) - device_type = db.Column(db.Integer) - created = db.Column(db.TIMESTAMP, nullable=False, server_default=db.func.now()) - - def __init__( - self, - full_name, - email, - password, - gender, - mobile, - city_id, - user_type, - lang_type, - badge, - device_id, - device_type, - social_id="", - access_key="", - user_image=None, - type=0, - ): - self.social_id = social_id - self.type = type - self.full_name = full_name - self.email = email - self.password = password - self.gender = gender - self.mobile = mobile - self.user_image = user_image - self.city_id = city_id - self.user_type = user_type - self.access_key = access_key - self.lang_type = lang_type - self.badge = badge - self.device_id = device_id - self.device_type = device_type - - -class Cities(db.Model): - id = db.Column(db.Integer, primary_key=True, autoincrement=True) - name = db.Column(db.String(255)) - image = db.Column(db.String(255)) - status = db.Column(db.Enum("1", "0")) - created = db.Column(db.DateTime, nullable=False, server_default=db.func.now()) - modified = db.Column(db.DateTime, nullable=False, onupdate=db.func.now()) - - def __init__(self, name, image, status, created, modified): - self.name = name - self.image = image - self.status = status - self.created = created - self.modified = modified - - -class Games(db.Model): - id = db.Column(db.Integer, primary_key=True, autoincrement=True) - name = db.Column(db.String(255)) - image = db.Column(db.String(255)) - date_time = db.Column(db.DateTime) - price = db.Column(db.String(100)) - description = db.Column(db.Text) - user_id = db.Column(db.Integer) - gender = db.Column(db.Enum("1", "2", "3")) - city_id = db.Column(db.Integer) - venue_id = db.Column(db.Integer) - sports_id = db.Column(db.Integer) - no_of_player = db.Column(db.Integer) - min_player = db.Column(db.Integer) - already_player = db.Column(db.Integer) - no_of_already_player = db.Column(db.Integer) - payment_mode = db.Column(db.Integer) - card_id = db.Column(db.Integer) - status = db.Column(db.Integer, server_default=text("1")) - game_status = db.Column(db.Integer, server_default=text("0")) - cancel_status = db.Column(db.Integer) - cancel_date = db.Column(db.DateTime) - noti_status = db.Column(db.Integer, server_default=text("0")) - conduct_status = db.Column(db.Integer, server_default=text("1")) - created = db.Column(db.DateTime, nullable=False, server_default=db.func.now()) - modified = db.Column(db.DateTime, nullable=False, onupdate=db.func.now()) - - def __init__( - self, - name, - image, - date_time, - price, - description, - user_id, - gender, - city_id, - venue_id, - sports_id, - no_of_player, - min_player, - already_player, - no_of_already_player, - payment_mode, - card_id, - ): - self.name = name - self.image = image - self.date_time = date_time - self.price = price - self.description = description - self.user_id = user_id - self.gender = gender - self.city_id = city_id - self.venue_id = venue_id - self.sports_id = sports_id - self.no_of_player = no_of_player - self.no_of_already_player = no_of_already_player - self.payment_mode = payment_mode - self.card_id = card_id - - -class Payments(db.Model): - id = db.Column(db.Integer, primary_key=True, autoincrement=True) - user_id = db.Column(db.Integer) - game_id = db.Column(db.Integer) - amount = db.Column(db.Integer) - token = db.Column(db.String(100)) - charge_id = db.Column(db.String(200)) - transfer_id = db.Column(db.String(200)) - transaction_id = db.Column(db.String(200)) - account_no = db.Column(db.String(200)) - description = db.Column(db.Text) - pay_mode = db.Column(db.Integer) - status = db.Column(db.Integer) - created = db.Column(db.DateTime, nullable=False, server_default=db.func.now()) - modified = db.Column(db.DateTime, nullable=False, onupdate=db.func.now()) - - def __init__( - self, - user_id, - game_id, - amount, - token, - charge_id, - transfer_id, - transaction_id, - account_no, - description, - pay_mode, - status, - ): - self.user_id = user_id - self.game_id = game_id - self.amount = amount - self.token = token - self.charge_id = charge_id - self.transfer_id = transfer_id - self.transaction_id = transaction_id - self.account_no = account_no - self.description = description - self.pay_mode = pay_mode - self.status = status - - -class PlayerAvailabilities(db.Model): - id = db.Column(db.Integer, primary_key=True, autoincrement=True) - game_id = db.Column(db.Integer) - player_id = db.Column(db.Integer) - status = db.Column(db.Integer) - created = db.Column(db.DateTime, nullable=False, server_default=db.func.now()) - modified = db.Column(db.DateTime, nullable=False, onupdate=db.func.now()) - - def __init__( - self, game_id, player_id, status, - ): - self.game_id = game_id - self.player_id = player_id - self.status = status - - -class PlayerCancelGames(db.Model): - id = db.Column(db.Integer, primary_key=True, autoincrement=True) - player_id = db.Column(db.Integer) - game_id = db.Column(db.Integer) - created = db.Column(db.DateTime, nullable=False, server_default=db.func.now()) - modified = db.Column(db.DateTime, nullable=False, onupdate=db.func.now()) - - def __init__( - self, player_id, game_id, - ): - self.player_id = player_id - self.game_id = game_id - - -class PurchaseGames(db.Model): - id = db.Column(db.Integer, primary_key=True, autoincrement=True) - game_id = db.Column(db.Integer) - user_id = db.Column(db.Integer) - pay_mode = db.Column(db.Integer) - created = db.Column(db.DateTime, nullable=False, server_default=db.func.now()) - modified = db.Column(db.DateTime, nullable=False, onupdate=db.func.now()) - - def __init__( - self, game_id, user_id, pay_mode, - ): - self.game_id = game_id - self.user_id = user_id - self.pay_mode = pay_mode - - -class Sports(db.Model): - id = db.Column(db.Integer, primary_key=True, autoincrement=True) - name = db.Column(db.String(255)) - spanish_name = db.Column(db.String(100)) - status = db.Column(db.Integer) - created = db.Column(db.DateTime, nullable=False, server_default=db.func.now()) - modified = db.Column(db.DateTime, nullable=False, onupdate=db.func.now()) - - def __init__( - self, name, spanish_name, status, - ): - self.name = name - self.spanish_name = spanish_name - self.status = status - - -class Teams(db.Model): - id = db.Column(db.Integer, primary_key=True, autoincrement=True) - user_id = db.Column(db.Integer) - team_id = db.Column(db.Enum("1", "2")) - game_id = db.Column(db.Integer) - status = db.Column(db.Integer) - created = db.Column(db.DateTime, nullable=False, server_default=db.func.now()) - modified = db.Column(db.DateTime, nullable=False, onupdate=db.func.now()) - - def __init__( - self, game_id, user_id, team_id, status, - ): - self.game_id = game_id - self.user_id = user_id - self.team_id = team_id - self.status = status - - -class UserRatings(db.Model): - id = db.Column(db.Integer, primary_key=True, autoincrement=True) - game_id = db.Column(db.Integer) - user_id = db.Column(db.Integer) - player_id = db.Column(db.Integer) - rating = db.Column(db.String(100)) - created = db.Column(db.DateTime, nullable=False, server_default=db.func.now()) - modified = db.Column(db.DateTime, nullable=False, onupdate=db.func.now()) - user_type = db.Column(db.Integer) - - def __init__(self, game_id, user_id, player_id, rating, user_type): - self.game_id = game_id - self.user_id = user_id - self.player_id = player_id - self.rating = rating - self.user_type = user_type - - -class VenueImages(db.Model): - id = db.Column(db.Integer, primary_key=True, autoincrement=True) - venue_id = db.Column(db.Integer) - user_id = db.Column(db.Integer) - image = db.Column(db.String(255)) - created = db.Column(db.DateTime, nullable=False, server_default=db.func.now()) - updated = db.Column(db.DateTime, nullable=False, onupdate=db.func.now()) - - def __init__( - self, venue_id, user_id, image, - ): - self.venue_id = venue_id - self.user_id = user_id - self.image = image - - -class Venues(db.Model): - id = db.Column(db.Integer, primary_key=True, autoincrement=True) - user_id = db.Column(db.Integer) - address = db.Column(db.Text) - latitude = db.Column(db.String(100)) - longitude = db.Column(db.String(100)) - name = db.Column(db.String(100)) - sports_id = db.Column(db.Integer) - created = db.Column(db.DateTime, nullable=False, server_default=db.func.now()) - modified = db.Column(db.DateTime, nullable=False, onupdate=db.func.now()) - - def __init__( - self, user_id, address, latitude, longitude, name, sports_id, - ): - self.user_id = user_id - self.address = address - self.latitude = latitude - self.longitude = longitude - self.name = name - self.sports_id = sports_id - - -class ViewNews(db.Model): - id = db.Column(db.Integer, primary_key=True, autoincrement=True) - news_id = db.Column(db.Integer) - user_id = db.Column(db.Integer) - created = db.Column(db.DateTime, nullable=False, server_default=db.func.now()) - updated = db.Column(db.DateTime, nullable=False, onupdate=db.func.now()) - - def __init__( - self, news_id, user_id, - ): - self.news_id = news_id - self.user_id = user_id - - -class WebBookings(db.Model): - id = db.Column(db.Integer, primary_key=True, autoincrement=True) - name = db.Column(db.String(255)) - email = db.Column(db.String(255)) - contact = db.Column(db.String(100)) - message = db.Column(db.Text) - game = db.Column(db.String(255)) - city = db.Column(db.String(100)) - created = db.Column(db.DateTime, nullable=False, server_default=db.func.now()) - updated = db.Column(db.DateTime, nullable=False, onupdate=db.func.now()) - - def __init__( - self, user_id, address, name, email, contact, message, game, city, - ): - self.user_id = user_id - self.address = address - self.name = name - self.email = email - self.contact = contact - self.message = message - self.game = game - self.city = city diff --git a/app/routes.py b/app/routes.py index 069e8f9..3ab0e23 100644 --- a/app/routes.py +++ b/app/routes.py @@ -1,28 +1,29 @@ -from flask import request, jsonify, make_response -from database.crud import insert_data, verify_otp, verify_login -from app.twilio import send_otp +from fastapi import Response, status + from app import app +from app.schemas import * +from app.twilio import send_otp +from database.crud import insert_data, verify_login, verify_otp -@app.route("/register", methods=["POST"]) -def create_user(): - data = request.get_json() - insert_data(schema="Users", data=data) - send_otp(receiver=data["mobile"]) - return make_response(jsonify("User created, pending OTP verification")) +@app.post("/register", status_code=status.HTTP_200_OK) +async def create_user(request: RegisterSchema): + insert_data(schema="Users", data=request) + send_otp(receiver=request.mobile) + return {"message": "User created, pending OTP verification"} -@app.route("/login", methods=["POST"]) -def log_in(): - data = request.get_json - if verify_login(data=data): - return make_response(jsonify("Successful login")) - return make_response(jsonify("The email/password combination is not correct")) +# FIXME Use OAuth2 for verification +@app.post("/login", status_code=status.HTTP_200_OK) +async def log_in(request: LoginSchema, response: Response): + return {"message": "Logged in successfully"} + # response.status_code = status.HTTP_400_BAD_REQUEST + # return {"message": "The email/password combination is not correct"} -@app.route("/otpVerification", methods=["POST"]) -def validate_otp(): - data = request.get_json() - if verify_otp(mobile=data["mobile"], otp=data["otp"]): - return make_response(jsonify("The OTP has been verified successfully")) - return make_response(jsonify("The OTP is not correct")) +@app.post("/otpVerification", status_code=status.HTTP_200_OK) +async def validate_otp(request: OTPSchema, response: Response): + if verify_otp(data=request): + return {"message": "The OTP has been verified successfully"} + response.status_code = status.HTTP_400_BAD_REQUEST + return {"message": "The OTP is not correct"} diff --git a/app/schema.py b/app/schema.py deleted file mode 100644 index 098b305..0000000 --- a/app/schema.py +++ /dev/null @@ -1,101 +0,0 @@ -from app import ma -from app.models import * -from marshmallow import fields -from marshmallow.validate import Length, Range - - -class UsersSchema(ma.Schema): - full_name = fields.Str(required=True, validate=Length(max=255)) - email = fields.Email(required=True, validate=Length(max=255)) - password = fields.Str(validate=Length(max=255)) - gender = fields.Integer(required=True, validate=Range(min=1, max=3)) - mobile = fields.Str(required=True, validate=Length(max=13)) - user_image = fields.Str(validate=Length(max=255)) - user_type = fields.Integer(required=True, validate=Range(min=1, max=2)) - lang_type = fields.Integer(required=True, validate=Range(min=1, max=2)) - device_type = fields.Integer(validate=Range(min=1, max=2)) - device_id = fields.Str(required=True) - - -class CitiesSchema(ma.SQLAlchemyAutoSchema): - class Meta: - model = Cities - load_instance = True - include_relationships = True - - -class GamesSchema(ma.SQLAlchemyAutoSchema): - class Meta: - model = Games - load_instance = True - include_relationships = True - - -class PlayerAvailabilitiesSchema(ma.SQLAlchemyAutoSchema): - class Meta: - model = PlayerAvailabilities - load_instance = True - include_relationships = True - - -class PlayerCancelGamesSchema(ma.SQLAlchemyAutoSchema): - class Meta: - model = PlayerCancelGames - load_instance = True - include_relationships = True - - -class PurchaseGamesSchema(ma.SQLAlchemyAutoSchema): - class Meta: - model = PurchaseGames - load_instance = True - include_relationships = True - - -class SportsSchema(ma.SQLAlchemyAutoSchema): - class Meta: - model = Sports - load_instance = True - include_relationships = True - - -class TeamsSchema(ma.SQLAlchemyAutoSchema): - class Meta: - model = Teams - load_instance = True - include_relationships = True - - -class UserRatingsSchema(ma.SQLAlchemyAutoSchema): - class Meta: - model = UserRatings - load_instance = True - include_relationships = True - - -class VenueImagesSchema(ma.SQLAlchemyAutoSchema): - class Meta: - model = VenueImages - load_instance = True - include_relationships = True - - -class VenuesSchema(ma.SQLAlchemyAutoSchema): - class Meta: - model = Venues - load_instance = True - include_relationships = True - - -class ViewNewsSchema(ma.SQLAlchemyAutoSchema): - class Meta: - model = ViewNews - load_instance = True - include_relationships = True - - -class WebBookingsSchema(ma.SQLAlchemyAutoSchema): - class Meta: - model = WebBookings - load_instance = True - include_relationships = True diff --git a/app/schemas.py b/app/schemas.py new file mode 100644 index 0000000..8be3413 --- /dev/null +++ b/app/schemas.py @@ -0,0 +1,28 @@ +from pydantic import BaseModel, EmailStr +from fastapi import Query + + +class RegisterSchema(BaseModel): + full_name: str + email: EmailStr + password: str + gender: int = Query(le=1, ge=3) + mobile: str = Query(min_length=8, max_length=13) + user_image: str = None + user_type: int = Query(le=1, ge=2) + lang_type: int = Query(le=1, ge=2) + device_type: int = Query(le=1, ge=2) + device_id: str + + +class LoginSchema(BaseModel): + email: EmailStr + password: str + user_type: int = Query(le=1, ge=2) + lang_type: int = Query(le=1, ge=2) + device_id: str + + +class OTPSchema(BaseModel): + mobile: str = Query(min_length=8, max_length=13) + otp: int = Query(le=6, ge=6) diff --git a/app/twilio.py b/app/twilio.py index fac4ee7..02d26c7 100644 --- a/app/twilio.py +++ b/app/twilio.py @@ -1,25 +1,25 @@ from twilio.rest import Client from secrets import randbits -from constants import account_id, token, sms_sender +from constants import ACCOUNT_ID, TOKEN, SMS_SENDER from database.crud import save_otp -def connect_api(): - account_sid = account_id - auth_token = token +async def connect_api(): + account_sid = ACCOUNT_ID + auth_token = TOKEN client = Client(account_sid, auth_token) return client -def generate_code(): +async def generate_code(): bits = 16 code = randbits(bits) return code -def send_otp(receiver): +async def send_otp(receiver): client = connect_api() code = generate_code() message = "Your OTP code is {0}".format(code) - client.messages.create(to=receiver, from_=sms_sender, body=message) + client.messages.create(to=receiver, from_=SMS_SENDER, body=message) save_otp(receiver, code) diff --git a/config.py b/config.py deleted file mode 100644 index cca6efd..0000000 --- a/config.py +++ /dev/null @@ -1,7 +0,0 @@ -from constants import connection_uri, secret_key - - -class Config(object): - SQLALCHEMY_DATABASE_URI = connection_uri - SQLALCHEMY_TRACK_MODIFICATIONS = False - SECRET_KEY = secret_key diff --git a/database/__init__.py b/database/__init__.py index e69de29..f6f5b6c 100644 --- a/database/__init__.py +++ b/database/__init__.py @@ -0,0 +1,12 @@ +from constants import CONNECTION_URI +from sqlalchemy import MetaData, create_engine +from sqlalchemy.ext.declarative import declarative_base +from databases import Database + +metadata = MetaData() +engine = create_engine(CONNECTION_URI) +metadata.create_all(engine) +Base = declarative_base() +database = Database(CONNECTION_URI) + +from database import models diff --git a/database/crud.py b/database/crud.py index ded980b..aa473f2 100644 --- a/database/crud.py +++ b/database/crud.py @@ -1,73 +1,74 @@ from datetime import datetime -from app import db -from app.models import * -from app.schema import * -from marshmallow import ValidationError -from pydoc import locate + +from app import app +from app.schemas import * +from database import database from werkzeug.security import check_password_hash +from pydoc import locate -def validate_schema(schema, data): - schema_name = schema + "Schema" - validation_schema = locate("app.schema." + schema_name) - instance = validation_schema() - instance.load(data) +@app.on_event("startup") +async def startup(): + await database.connect() -def validate_json(schema, data): - validate_schema(schema=schema, data=data) - model = locate("app.models." + schema) +@app.on_event("shutdown") +async def shutdown(): + await database.disconnect() + + +async def instantiate_model(schema, data): + model = locate("database.models." + schema) instance = model(**data) return instance -def insert_data(schema, data): - instance = validate_json(schema, data) - db.session.add(instance) - db.session.commit() +async def insert_data(schema, data): + instance = instantiate_model(schema, data) + query = instance.insert() + await database.execute(query=query, values=data) -def delete_data(data): - db.session.delete(data) - db.session.commit() +# FIXME instance.id has to be replaced with the table's UID +async def delete_data(schema, data): + instance = instantiate_model(schema, data) + query = instance.delete().where(instance.id == data.id) + await database.execute(query=query) -def save_otp(mobile, otp): - db.session.query(table="Users").filter_by(mobile=mobile).update(dict(otp=otp)) - db.session.commit() +async def fetch_user(data): + instance = instantiate_model(schema="Users", data=data) + query = instance.select().where(instance.email == data.email) + return await database.fetch_one(query=query) -def fetch_stored_otp(mobile): - user = db.session.query(table="Users").filter_by(mobile=mobile) - otp = user.otp - return otp +async def fetch_otp(data: OTPSchema): + instance = instantiate_model(schema="Users", data=data) + query = instance.select().where(instance.mobile == data.mobile) + return await database.fetch_one(query=query) -def activate_account(mobile): +async def save_otp(data: OTPSchema): + instance = instantiate_model(schema="Users", data=data) + query = instance.update().where(instance.mobile == data.mobile).values(otp=data.otp) + await database.execute(query=query) + + +async def activate_account(data: OTPSchema): timestamp = datetime.now() - db.session.query(table="Users").filter_by(mobile=mobile).update( - dict(otp_valid_time=timestamp) + instance = instantiate_model(schema="Users", data=data) + query = ( + instance.update() + .where(instance.mobile == data.mobile) + .values(mobile=instance.data, otp_valid_time=timestamp, status=1) ) - db.session.query(table="Users").filter_by(mobile=mobile).update(dict(status=1)) + await database.execute(query=query) -def verify_otp(mobile, otp): - stored_otp = fetch_stored_otp(mobile=mobile) +async def verify_otp(data: OTPSchema): + user = fetch_otp(data=data) + stored.otp = user.otp if stored_otp == otp: activate_account(mobile=mobile) return True return False - - -def fetch_user(data): - user = db.session.query(table="Users").filter_by(email=data["email"]) - email = user.email - password = user.password - return email, password - - -def verify_login(data): - user, password = fetch_user(data) - if user == data["email"] and check_password_hash(password, data["password"]): - return True - return False diff --git a/database/models.py b/database/models.py new file mode 100644 index 0000000..a0cebb1 --- /dev/null +++ b/database/models.py @@ -0,0 +1,356 @@ +from app import Base +from sqlalchemy import Column, Integer, String, DateTime, Text, Enum +from sqlalchemy.sql import func + + +class Users(Base): + id = Column(Integer, primary_key=True, autoincrement=True) + social_id = Column(Text) + type = Column(Integer) + full_name = Column(String(255), index=True, unique=True) + email = Column(String(255), index=True, unique=True) + password = Column(String(255)) + gender = Column(Integer) + mobile = Column(String(255)) + user_image = Column(String(255)) + city_id = Column(Integer) + user_type = Column(Integer) + otp = Column(String(255)) + otp_valid_time = Column(DateTime) + access_key = Column(Text) + lang_type = Column(Integer) + badge = Column(Integer) + status = Column(Integer, server_default=Text("0")) + admin_status = Column(Integer, server_default=Text("0")) + device_id = Column(Text) + device_type = Column(Integer) + created = Column(DateTime, nullable=False, server_default=func.now()) + + def __init__( + self, + full_name, + email, + password, + gender, + mobile, + city_id, + user_type, + lang_type, + badge, + device_id, + device_type, + social_id="", + access_key="", + user_image=None, + type=0, + ): + self.social_id = social_id + self.type = type + self.full_name = full_name + self.email = email + self.password = password + self.gender = gender + self.mobile = mobile + self.user_image = user_image + self.city_id = city_id + self.user_type = user_type + self.access_key = access_key + self.lang_type = lang_type + self.badge = badge + self.device_id = device_id + self.device_type = device_type + + +class Cities(Base): + id = Column(Integer, primary_key=True, autoincrement=True) + name = Column(String(255)) + image = Column(String(255)) + status = Column(Enum("1", "0")) + created = Column(DateTime, nullable=False, server_default=func.now()) + modified = Column(DateTime, nullable=False, onupdate=func.now()) + + def __init__(self, name, image, status, created, modified): + self.name = name + self.image = image + self.status = status + self.created = created + self.modified = modified + + +class Games(Base): + id = Column(Integer, primary_key=True, autoincrement=True) + name = Column(String(255)) + image = Column(String(255)) + date_time = Column(DateTime) + price = Column(String(100)) + description = Column(Text) + user_id = Column(Integer) + gender = Column(Enum("1", "2", "3")) + city_id = Column(Integer) + venue_id = Column(Integer) + sports_id = Column(Integer) + no_of_player = Column(Integer) + min_player = Column(Integer) + already_player = Column(Integer) + no_of_already_player = Column(Integer) + payment_mode = Column(Integer) + card_id = Column(Integer) + status = Column(Integer, server_default=Text("1")) + game_status = Column(Integer, server_default=Text("0")) + cancel_status = Column(Integer) + cancel_date = Column(DateTime) + noti_status = Column(Integer, server_default=Text("0")) + conduct_status = Column(Integer, server_default=Text("1")) + created = Column(DateTime, nullable=False, server_default=func.now()) + modified = Column(DateTime, nullable=False, onupdate=func.now()) + + def __init__( + self, + name, + image, + date_time, + price, + description, + user_id, + gender, + city_id, + venue_id, + sports_id, + no_of_player, + min_player, + already_player, + no_of_already_player, + payment_mode, + card_id, + ): + self.name = name + self.image = image + self.date_time = date_time + self.price = price + self.description = description + self.user_id = user_id + self.gender = gender + self.city_id = city_id + self.venue_id = venue_id + self.sports_id = sports_id + self.no_of_player = no_of_player + self.no_of_already_player = no_of_already_player + self.payment_mode = payment_mode + self.card_id = card_id + + +class Payments(Base): + id = Column(Integer, primary_key=True, autoincrement=True) + user_id = Column(Integer) + game_id = Column(Integer) + amount = Column(Integer) + token = Column(String(100)) + charge_id = Column(String(200)) + transfer_id = Column(String(200)) + transaction_id = Column(String(200)) + account_no = Column(String(200)) + description = Column(Text) + pay_mode = Column(Integer) + status = Column(Integer) + created = Column(DateTime, nullable=False, server_default=func.now()) + modified = Column(DateTime, nullable=False, onupdate=func.now()) + + def __init__( + self, + user_id, + game_id, + amount, + token, + charge_id, + transfer_id, + transaction_id, + account_no, + description, + pay_mode, + status, + ): + self.user_id = user_id + self.game_id = game_id + self.amount = amount + self.token = token + self.charge_id = charge_id + self.transfer_id = transfer_id + self.transaction_id = transaction_id + self.account_no = account_no + self.description = description + self.pay_mode = pay_mode + self.status = status + + +class PlayerAvailabilities(Base): + id = Column(Integer, primary_key=True, autoincrement=True) + game_id = Column(Integer) + player_id = Column(Integer) + status = Column(Integer) + created = Column(DateTime, nullable=False, server_default=func.now()) + modified = Column(DateTime, nullable=False, onupdate=func.now()) + + def __init__( + self, game_id, player_id, status, + ): + self.game_id = game_id + self.player_id = player_id + self.status = status + + +class PlayerCancelGames(Base): + id = Column(Integer, primary_key=True, autoincrement=True) + player_id = Column(Integer) + game_id = Column(Integer) + created = Column(DateTime, nullable=False, server_default=func.now()) + modified = Column(DateTime, nullable=False, onupdate=func.now()) + + def __init__( + self, player_id, game_id, + ): + self.player_id = player_id + self.game_id = game_id + + +class PurchaseGames(Base): + id = Column(Integer, primary_key=True, autoincrement=True) + game_id = Column(Integer) + user_id = Column(Integer) + pay_mode = Column(Integer) + created = Column(DateTime, nullable=False, server_default=func.now()) + modified = Column(DateTime, nullable=False, onupdate=func.now()) + + def __init__( + self, game_id, user_id, pay_mode, + ): + self.game_id = game_id + self.user_id = user_id + self.pay_mode = pay_mode + + +class Sports(Base): + id = Column(Integer, primary_key=True, autoincrement=True) + name = Column(String(255)) + spanish_name = Column(String(100)) + status = Column(Integer) + created = Column(DateTime, nullable=False, server_default=func.now()) + modified = Column(DateTime, nullable=False, onupdate=func.now()) + + def __init__( + self, name, spanish_name, status, + ): + self.name = name + self.spanish_name = spanish_name + self.status = status + + +class Teams(Base): + id = Column(Integer, primary_key=True, autoincrement=True) + user_id = Column(Integer) + team_id = Column(Enum("1", "2")) + game_id = Column(Integer) + status = Column(Integer) + created = Column(DateTime, nullable=False, server_default=func.now()) + modified = Column(DateTime, nullable=False, onupdate=func.now()) + + def __init__( + self, game_id, user_id, team_id, status, + ): + self.game_id = game_id + self.user_id = user_id + self.team_id = team_id + self.status = status + + +class UserRatings(Base): + id = Column(Integer, primary_key=True, autoincrement=True) + game_id = Column(Integer) + user_id = Column(Integer) + player_id = Column(Integer) + rating = Column(String(100)) + created = Column(DateTime, nullable=False, server_default=func.now()) + modified = Column(DateTime, nullable=False, onupdate=func.now()) + user_type = Column(Integer) + + def __init__(self, game_id, user_id, player_id, rating, user_type): + self.game_id = game_id + self.user_id = user_id + self.player_id = player_id + self.rating = rating + self.user_type = user_type + + +class VenueImages(Base): + id = Column(Integer, primary_key=True, autoincrement=True) + venue_id = Column(Integer) + user_id = Column(Integer) + image = Column(String(255)) + created = Column(DateTime, nullable=False, server_default=func.now()) + updated = Column(DateTime, nullable=False, onupdate=func.now()) + + def __init__( + self, venue_id, user_id, image, + ): + self.venue_id = venue_id + self.user_id = user_id + self.image = image + + +class Venues(Base): + id = Column(Integer, primary_key=True, autoincrement=True) + user_id = Column(Integer) + address = Column(Text) + latitude = Column(String(100)) + longitude = Column(String(100)) + name = Column(String(100)) + sports_id = Column(Integer) + created = Column(DateTime, nullable=False, server_default=func.now()) + modified = Column(DateTime, nullable=False, onupdate=func.now()) + + def __init__( + self, user_id, address, latitude, longitude, name, sports_id, + ): + self.user_id = user_id + self.address = address + self.latitude = latitude + self.longitude = longitude + self.name = name + self.sports_id = sports_id + + +class ViewNews(Base): + id = Column(Integer, primary_key=True, autoincrement=True) + news_id = Column(Integer) + user_id = Column(Integer) + created = Column(DateTime, nullable=False, server_default=func.now()) + updated = Column(DateTime, nullable=False, onupdate=func.now()) + + def __init__( + self, news_id, user_id, + ): + self.news_id = news_id + self.user_id = user_id + + +class WebBookings(Base): + id = Column(Integer, primary_key=True, autoincrement=True) + name = Column(String(255)) + email = Column(String(255)) + contact = Column(String(100)) + message = Column(Text) + game = Column(String(255)) + city = Column(String(100)) + created = Column(DateTime, nullable=False, server_default=func.now()) + updated = Column(DateTime, nullable=False, onupdate=func.now()) + + def __init__( + self, user_id, address, name, email, contact, message, game, city, + ): + self.user_id = user_id + self.address = address + self.name = name + self.email = email + self.contact = contact + self.message = message + self.game = game + self.city = city diff --git a/shell.nix b/shell.nix index 57e2cff..a9e35d0 100644 --- a/shell.nix +++ b/shell.nix @@ -5,15 +5,16 @@ with pkgs.python37Packages; pkgs.mkShell { buildInputs = [ # Dependencies - flask - flask_sqlalchemy - flask_migrate - flask_marshmallow + fastapi + uvicorn + pydantic + email_validator + sqlalchemy pymysql - marshmallow - marshmallow-sqlalchemy + databases + aiomysql + alembic pytest - pytest-flask twilio # Development tools black @@ -22,5 +23,6 @@ pkgs.mkShell { python-language-server pyls-black pyls-isort + pyls-mypy ]; } diff --git a/tests/conftest.py b/tests/conftest.py deleted file mode 100644 index 476b067..0000000 --- a/tests/conftest.py +++ /dev/null @@ -1,10 +0,0 @@ -from app import app as test_app -from pytest import fixture -from secrets import token_bytes - - -@fixture -def app(): - test_app.config["TESTING"] = True - test_app.config["WTF_CSRF_ENABLED"] = False - return test_app diff --git a/tests/queries_test.py b/tests/queries_test.py index 291568e..7b9505f 100644 --- a/tests/queries_test.py +++ b/tests/queries_test.py @@ -1,4 +1,4 @@ -from app.models import * +from database.models import * from datetime import datetime