From 69792075cb539e9b9f236f27d1b79047f91a7f6c Mon Sep 17 00:00:00 2001 From: coolneng Date: Wed, 15 Apr 2020 00:29:59 +0200 Subject: [PATCH] Add user registration, with JSON validation --- src/Pipfile | 2 + src/Pipfile.lock | 44 ++++++++++++------ src/app/__init__.py | 2 + src/app/routes.py | 8 ++-- src/database/crud.py | 30 ++++++++++++ src/database/models.py | 102 +++++++---------------------------------- src/database/schema.py | 92 +++++++++++++++++++++++++++++++++++++ 7 files changed, 177 insertions(+), 103 deletions(-) create mode 100644 src/database/crud.py create mode 100644 src/database/schema.py diff --git a/src/Pipfile b/src/Pipfile index fb832c8..70abf3b 100644 --- a/src/Pipfile +++ b/src/Pipfile @@ -12,6 +12,8 @@ pymysql = "*" flask-praetorian = "*" flask-sqlalchemy = "*" flask-migrate = "*" +flask-marshmallow = "*" +marshmallow = "*" [requires] python_version = "3.8" diff --git a/src/Pipfile.lock b/src/Pipfile.lock index 6288644..72c6323 100644 --- a/src/Pipfile.lock +++ b/src/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "4328be3ab2dfc7cdc0c6dfc8ff03702be800ff524133228b149ca368e1d29bfe" + "sha256": "f45ecdf6d0ebe7b78d400e7fc1df90d2dbabf6e9f1c146e4768f215652c06008" }, "pipfile-spec": 6, "requires": { @@ -30,10 +30,10 @@ }, "certifi": { "hashes": [ - "sha256:017c25db2a153ce562900032d5bc68e9f191e44e9a0f762f373977de9df1fbb3", - "sha256:25b64c7da4cd7479594d035c08c2d809eb4aab3a26e5a990ea98cc450c320f1f" + "sha256:1d987a998c75633c40847cc966fcf5904906c920a7f17ef374f5aa4282abd304", + "sha256:51fcb31174be6e6664c5f69e3e1691a2d72a1a12e90f872cbdb1567eb47b6519" ], - "version": "==2019.11.28" + "version": "==2020.4.5.1" }, "chardet": { "hashes": [ @@ -51,11 +51,11 @@ }, "flask": { "hashes": [ - "sha256:13f9f196f330c7c2c5d7a5cf91af894110ca0215ac051b5844701f2bfd934d52", - "sha256:45eb5a6fd193d6cf7e0cf5d8a5b31f83d5faae0293695626f539a823e93b13f6" + "sha256:4efa1ae2d7c9865af48986de8aeb8504bf32c7f3d6fdc9353d34b21f4b127060", + "sha256:8a4fdd8936eba2512e9c85df320a37e694c93945b33ef33c89946a340a238557" ], "index": "pypi", - "version": "==1.1.1" + "version": "==1.1.2" }, "flask-buzz": { "hashes": [ @@ -70,6 +70,14 @@ ], "version": "==0.9.1" }, + "flask-marshmallow": { + "hashes": [ + "sha256:01520ef1851ccb64d4ffb33196cddff895cc1302ae1585bff1abf58684a8111a", + "sha256:28b969193958d9602ab5d6add6d280e0e360c8e373d3492c2f73b024ecd36374" + ], + "index": "pypi", + "version": "==0.11.0" + }, "flask-migrate": { "hashes": [ "sha256:4dc4a5cce8cbbb06b8dc963fd86cf8136bd7d875aabe2d840302ea739b243732", @@ -160,6 +168,14 @@ ], "version": "==1.1.1" }, + "marshmallow": { + "hashes": [ + "sha256:90854221bbb1498d003a0c3cc9d8390259137551917961c8b5258c64026b2f85", + "sha256:ac2e13b30165501b7d41fc0371b8df35944f5849769d136f20e2c5f6cdc6e665" + ], + "index": "pypi", + "version": "==3.5.1" + }, "passlib": { "hashes": [ "sha256:68c35c98a7968850e17f1b6892720764cc7eed0ef2b7cb3116a89a28e43fe177", @@ -258,16 +274,16 @@ }, "sqlalchemy": { "hashes": [ - "sha256:c4cca4aed606297afbe90d4306b49ad3a4cd36feb3f87e4bfd655c57fd9ef445" + "sha256:7224e126c00b8178dfd227bc337ba5e754b197a3867d33b9f30dc0208f773d70" ], - "version": "==1.3.15" + "version": "==1.3.16" }, "twilio": { "hashes": [ - "sha256:284040aa4cd504d67e95cde17db38d4d11454ac8bd43cab94f66694241b962af" + "sha256:39b949c671f1b29259c85569de58e6a4c8b04e13aba08d2d20ddba9d7c304573" ], "index": "pypi", - "version": "==6.37.0" + "version": "==6.38.0" }, "urllib3": { "hashes": [ @@ -278,10 +294,10 @@ }, "werkzeug": { "hashes": [ - "sha256:169ba8a33788476292d04186ab33b01d6add475033dfc07215e6d219cc077096", - "sha256:6dc65cf9091cf750012f56f2cad759fa9e879f511b5ff8685e456b4e3bf90d16" + "sha256:2de2a5db0baeae7b2d2664949077c2ac63fbd16d98da0ff71837f7d1dea3fd43", + "sha256:6c80b1e5ad3665290ea39320b91e1be1e0d5f60652b964a3070216de83d2e47c" ], - "version": "==1.0.0" + "version": "==1.0.1" } }, "develop": {} diff --git a/src/app/__init__.py b/src/app/__init__.py index 59127e7..0f8819b 100644 --- a/src/app/__init__.py +++ b/src/app/__init__.py @@ -2,10 +2,12 @@ from flask import Flask from config import Config from flask_sqlalchemy import SQLAlchemy from flask_migrate import Migrate +from flask_marshmallow import Marshmallow app = Flask(__name__) app.config.from_object(Config) db = SQLAlchemy(app) migrate = Migrate(app, db) +ma = Marshmallow(app) from app import routes, models diff --git a/src/app/routes.py b/src/app/routes.py index 0ab9232..bff5ac1 100644 --- a/src/app/routes.py +++ b/src/app/routes.py @@ -1,12 +1,12 @@ from flask import request, jsonify -from database import register_user +from database.crud import insert_data from external.twilio import send_otp from app import app -@app.route("/users", methods=["POST"]) +@app.route("/register", methods=["POST"]) def create_user(): data = request.get_json() - register_user(data) - send_otp(data["mobile"]) + insert_data(schema="Users", data=data) + send_otp(receiver=data["mobile"]) return jsonify("User created, pending OTP verification") diff --git a/src/database/crud.py b/src/database/crud.py new file mode 100644 index 0000000..9d7b86a --- /dev/null +++ b/src/database/crud.py @@ -0,0 +1,30 @@ +from app import db +from database.models import * +from database.schema import * +from marshmallow import ValidationError + + +def insert_data(schema, data): + instance = validate_data(schema=schema, data=data) + db.session.add(instance) + db.session.commit() + + +def delete_data(id): + db.session.delete(data) + db.session.commit() + + +def update_otp(user_id, otp): + db.session.query(table="Users").filter_by(id=user_id).update(dict(otp=otp)) + db.session.commit() + + +def validate_data(schema, data): + validation_schema = schema + "Schema()" + instance = validation_schema + try: + output = instance.load(data).data + return output + except ValidationError as err: + print(err.messages) diff --git a/src/database/models.py b/src/database/models.py index 9d069bd..ebf2e2c 100644 --- a/src/database/models.py +++ b/src/database/models.py @@ -26,7 +26,6 @@ class Users(db.Model): def __init__( self, - id, social_id, type, full_name, @@ -46,9 +45,7 @@ class Users(db.Model): admin_status, device_id, device_type, - created, ): - self.id = id self.social_id = social_id self.type = type self.full_name = full_name @@ -68,7 +65,6 @@ class Users(db.Model): self.admin_status = admin_status self.device_id = device_id self.device_type = device_type - self.created = created class Cities(db.Model): @@ -116,7 +112,6 @@ class Games(db.Model): def __init__( self, - id, name, image, date_time, @@ -133,10 +128,7 @@ class Games(db.Model): no_of_already_player, payment_mode, card_id, - created, - updated, ): - self.id = id self.name = name self.image = image self.date_time = date_time @@ -151,8 +143,6 @@ class Games(db.Model): self.no_of_already_player = no_of_already_player self.payment_mode = payment_mode self.card_id = card_id - self.created = created - self.updated = updated class Payments(db.Model): @@ -173,7 +163,6 @@ class Payments(db.Model): def __init__( self, - id, user_id, game_id, amount, @@ -185,10 +174,7 @@ class Payments(db.Model): description, pay_mode, status, - created, - modified, ): - self.id = id self.user_id = user_id self.game_id = game_id self.amount = amount @@ -200,11 +186,9 @@ class Payments(db.Model): self.description = description self.pay_mode = pay_mode self.status = status - self.created = created - self.modified = modified -class Player_Availabilities: +class PlayerAvailabilities: id = db.Column(db.Integer, primary_key=True, autoincrement=True) game_id = db.Column(db.Integer) player_id = db.Column(db.Integer) @@ -213,17 +197,14 @@ class Player_Availabilities: modified = db.Column(db.DateTime, nullable=False, onupdate=db.func.now()) def __init__( - self, id, game_id, player_id, status, created, modified, + self, game_id, player_id, status, ): - self.id = id self.game_id = game_id self.player_id = player_id self.status = status - self.created = created - self.modified = modified -class Player_Cancel_Games: +class PlayerCancelGames: id = db.Column(db.Integer, primary_key=True, autoincrement=True) player_id = db.Column(db.Integer) game_id = db.Column(db.Integer) @@ -231,16 +212,13 @@ class Player_Cancel_Games: modified = db.Column(db.DateTime, nullable=False, onupdate=db.func.now()) def __init__( - self, id, player_id, game_id, created, modified, + self, player_id, game_id, ): - self.id = id self.player_id = player_id self.game_id = game_id - self.created = created - self.modified = modified -class Purchase_Games: +class PurchaseGames: id = db.Column(db.Integer, primary_key=True, autoincrement=True) game_id = db.Column(db.Integer) user_id = db.Column(db.Integer) @@ -249,14 +227,11 @@ class Purchase_Games: modified = db.Column(db.DateTime, nullable=False, onupdate=db.func.now()) def __init__( - self, id, game_id, user_id, pay_mode, created, modified, + self, game_id, user_id, pay_mode, ): - self.id = id self.game_id = game_id self.user_id = user_id self.pay_mode = pay_mode - self.created = created - self.modified = modified class Sports: @@ -268,14 +243,11 @@ class Sports: modified = db.Column(db.DateTime, nullable=False, onupdate=db.func.now()) def __init__( - self, id, name, spanish_name, status, created, modified, + self, name, spanish_name, status, ): - self.id = id self.name = name self.spanish_name = spanish_name self.status = status - self.created = created - self.modified = modified class Teams: @@ -288,18 +260,15 @@ class Teams: modified = db.Column(db.DateTime, nullable=False, onupdate=db.func.now()) def __init__( - self, id, game_id, user_id, team_id, status, created, modified, + self, game_id, user_id, team_id, status, ): - self.id = id self.game_id = game_id self.user_id = user_id self.team_id = team_id self.status = status - self.created = created - self.modified = modified -class User_Ratings: +class UserRatings: id = db.Column(db.Integer, primary_key=True, autoincrement=True) game_id = db.Column(db.Integer) user_id = db.Column(db.Integer) @@ -309,20 +278,15 @@ class User_Ratings: modified = db.Column(db.DateTime, nullable=False, onupdate=db.func.now()) user_type = db.Column(db.Integer) - def __init__( - self, id, game_id, user_id, player_id, rating, created, modified, user_type - ): - self.id = id + 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.created = created - self.modified = modified self.user_type = user_type -class Venue_Images: +class VenueImages: id = db.Column(db.Integer, primary_key=True, autoincrement=True) venue_id = db.Column(db.Integer) user_id = db.Column(db.Integer) @@ -331,14 +295,11 @@ class Venue_Images: modified = db.Column(db.DateTime, nullable=False, onupdate=db.func.now()) def __init__( - self, id, venue_id, user_id, image, created, modified, + self, venue_id, user_id, image, ): - self.id = id self.venue_id = venue_id self.user_id = user_id self.image = image - self.created = created - self.modified = modified class Venues: @@ -353,29 +314,17 @@ class Venues: modified = db.Column(db.DateTime, nullable=False, onupdate=db.func.now()) def __init__( - self, - id, - user_id, - address, - latitude, - longitude, - name, - sports_id, - created, - modified, + self, user_id, address, latitude, longitude, name, sports_id, ): - self.id = id self.user_id = user_id self.address = address self.latitude = latitude self.longitude = longitude self.name = name self.sports_id = sports_id - self.created = created - self.modified = modified -class View_News: +class ViewNews: id = db.Column(db.Integer, primary_key=True, autoincrement=True) news_id = db.Column(db.Integer) user_id = db.Column(db.Integer) @@ -383,16 +332,13 @@ class View_News: modified = db.Column(db.DateTime, nullable=False, onupdate=db.func.now()) def __init__( - self, id, news_id, user_id, created, modified, + self, news_id, user_id, ): - self.id = id self.news_id = news_id self.user_id = user_id - self.created = created - self.modified = modified -class Web_Bookings: +class WebBookings: id = db.Column(db.Integer, primary_key=True, autoincrement=True) name = db.Column(db.String(255)) email = db.Column(db.String(255)) @@ -404,20 +350,8 @@ class Web_Bookings: updated = db.Column(db.DateTime, nullable=False, onupdate=db.func.now()) def __init__( - self, - id, - user_id, - address, - name, - email, - contact, - message, - game, - city, - created, - updated, + self, user_id, address, name, email, contact, message, game, city, ): - self.id = id self.user_id = user_id self.address = address self.name = name @@ -426,5 +360,3 @@ class Web_Bookings: self.message = message self.game = game self.city = city - self.created = created - self.updated = updated diff --git a/src/database/schema.py b/src/database/schema.py new file mode 100644 index 0000000..94d904e --- /dev/null +++ b/src/database/schema.py @@ -0,0 +1,92 @@ +from app import ma +from database.models import * +from marshmallow.validate import Length, Range + + +class UsersSchema(ma.Schema): + full_name = ma.fields.Str(required=True, validate=Length(max=255)) + email = ma.fields.Email(required=True, validate=Length(max=255)) + password = ma.fields.Str(validate=Length(max=255)) + gender = ma.fields.Integer(required=True, validate=Range(min=1, max=2)) + mobile = ma.fields.Str(required=True, validate=Length(max=13)) + user_image = ma.fields.Str(validate=Length(max=255)) + user_type = ma.fields.Integer(required=True, validate=Range(min=1, max=2)) + lang_type = ma.fields.Integer(required=True, validate=Range(min=1, max=2)) + device_type = ma.fields.Integer(required=True, validate=Range(min=1, max=2)) + device_id = ma.fields.Str(required=True) + + class Meta: + model = Users + include_fk = True + + +class CitiesSchema(ma.Schema): + class Meta: + model = Cities + include_fk = True + + +class GamesSchema(ma.Schema): + class Meta: + model = Games + include_fk = True + + +class PlayerAvailabilitiesSchema(ma.Schema): + class Meta: + model = PlayerAvailabilities + include_fk = True + + +class PlayerCancelGamesSchema(ma.Schema): + class Meta: + model = PlayerCancelGames + include_fk = True + + +class PurchaseGamesSchema(ma.Schema): + class Meta: + model = PurchaseGames + include_fk = True + + +class SportsSchema(ma.Schema): + class Meta: + model = Sports + include_fk = True + + +class TeamsSchema(ma.Schema): + class Meta: + model = Teams + include_fk = True + + +class UserRatingsSchema(ma.Schema): + class Meta: + model = UserRatings + include_fk = True + + +class VenueImagesSchema(ma.Schema): + class Meta: + model = VenueImages + include_fk = True + + +class VenuesSchema(ma.Schema): + class Meta: + model = Venues + include_fk = True + + +class ViewNewsSchema(ma.Schema): + class Meta: + model = ViewNews + include_fk = True + + +class WebBookingsSchema(ma.Schema): + class Meta: + model = WebBookings + include_fk = True