Merge pull request #3 from sorrelbri/sj-api-routes

sj api routes
This commit is contained in:
sorrelbri 2019-10-05 22:43:45 -07:00 committed by GitHub
commit 4287766d7f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 250 additions and 60 deletions

View file

@ -3,7 +3,6 @@ from .users.user_endpoint import UserEndpoint
api = Blueprint('api', __name__, url_prefix='/api') api = Blueprint('api', __name__, url_prefix='/api')
@api.route('/home', methods=['GET']) @api.route('/home', methods=['GET'])
def api_home(): def api_home():
response = {"message": "home page"} response = {"message": "home page"}

View file

@ -1,5 +1,7 @@
from models.User import User, user_schema
class UserEndpoint(object): class UserEndpoint(object):
def users(): def users():
response = {"message": "users page"} user = User.query.first()
response = user_schema.dumps(user)
return response return response

57
app.py
View file

@ -1,57 +1,20 @@
import os import os
from database import db, ma
from flask import Flask from flask import Flask
# ! SQLAlchemy > Marshmallow - these must be imported in this order from configuration.config import DevelopmentConfig
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
from flask_migrate import Migrate
from flask_bcrypt import Bcrypt from flask_bcrypt import Bcrypt
from flask_cors import CORS from flask_cors import CORS
app = Flask(__name__) def create_app():
CORS(app) app = Flask(__name__)
CORS(app)
# config database app.config.from_object(DevelopmentConfig)
app_settings = os.getenv( db.init_app(app)
'APP_SETTINGS', ma.init_app(app)
'config.DevelopmentConfig' return app
)
app.config.from_object(app_settings) bcrypt = Bcrypt(create_app())
# init bcrypt
bcrypt = Bcrypt(app)
# init database
db = SQLAlchemy(app)
# init marshmallow
ma = Marshmallow(app)
# init all db models
import models
migrate = Migrate(app, db)
# dev server
DEBUG = True
PORT = 8000
# Routes
@app.route('/')
def hello_world():
return 'Hello World'
# Blue prints
from api.api import api
app.register_blueprint(api)
if __name__ == '__main__':
app.run(debug=DEBUG, port=PORT)

0
auth/__init__.py Normal file
View file

49
auth/auth.py Normal file
View file

@ -0,0 +1,49 @@
from flask import Blueprint, request, jsonify, session
from database import db
from models.User import User
auth = Blueprint('auth', __name__, url_prefix='/auth')
@auth.route('/signup', methods=['POST'])
def auth_signup():
data = request.get_json()
user = User.query.filter_by(email=data.get('email')).first()
if not user:
try:
print('getting here 1')
user = User(
email = data['email'],
password = data['password'],
)
print('getting here 2')
db.session.add(user)
print('wtf')
db.session.commit()
print('user')
auth_token = user.encode_auth_token(user.id)
print('getting here 4')
response = {
'status': 'success',
'message': 'Succesfully registered.',
'auth_token': auth_token.decode()
}
return jsonify(response), 201
except Exception as e:
print(e.__dict__)
response = {
'status': 'fail',
'message': 'There was an error. Please try again.'
}
return jsonify(response), 401
else:
response = {
'status': 'fail',
'message': 'User already exists. Please login.'
}
return jsonify(response), 202
@auth.route('/login', methods=['POST'])
def auth_login():
response = {"message": "login post"}
return jsonify(response)

View file

View file

@ -14,6 +14,7 @@ class DevelopmentConfig(BaseConfig):
DEBUG = True DEBUG = True
BCRYPT_LOG_ROUNDS = 4 BCRYPT_LOG_ROUNDS = 4
SQLALCHEMY_DATABASE_URI = DATABASE SQLALCHEMY_DATABASE_URI = DATABASE
PORT = 8000
class TestingConfig(BaseConfig): class TestingConfig(BaseConfig):

View file

@ -0,0 +1,7 @@
if __name__ == '__main__':
from ..models.User import User
from ..models.GameRoom import GameRoom
from ..models.TimeSettings import TimeSettings
from ..models.Game import Game
from ..models.Move import Move
from ..models.Message import Message

10
database.py Normal file
View file

@ -0,0 +1,10 @@
# ! SQLAlchemy > Marshmallow - these must be imported in this order
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
# init database
db = SQLAlchemy()
# init marshmallow
ma = Marshmallow()

View file

@ -4,11 +4,20 @@ import unittest
from flask_script import Manager from flask_script import Manager
from flask_migrate import Migrate, MigrateCommand from flask_migrate import Migrate, MigrateCommand
from app import app, db from database import db
from app import create_app
app = create_app()
migrate = Migrate(app, db) migrate = Migrate(app, db)
manager = Manager(app) manager = Manager(app)
from models.Game import Game
from models.GameRoom import GameRoom
from models.Message import Message
from models.Move import Move
from models.TimeSettings import TimeSettings
from models.User import User
# migrations # migrations
manager.add_command('db', MigrateCommand) manager.add_command('db', MigrateCommand)

View file

@ -0,0 +1,28 @@
"""empty message
Revision ID: 50aab465cf44
Revises: bfa4b406e22f
Create Date: 2019-10-05 22:37:07.643522
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '50aab465cf44'
down_revision = 'bfa4b406e22f'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('users', sa.Column('password', sa.String(length=255), nullable=False))
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('users', 'password')
# ### end Alembic commands ###

View file

@ -39,7 +39,7 @@ def upgrade():
op.create_table('users', op.create_table('users',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False), sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('email', sa.String(length=255), nullable=False), sa.Column('email', sa.String(length=255), nullable=False),
sa.Column('password', sa.DateTime(), nullable=False), sa.Column('password', sa.Integer(length=255), nullable=False),
sa.Column('registered_on', sa.DateTime(), nullable=False), sa.Column('registered_on', sa.DateTime(), nullable=False),
sa.Column('admin', sa.Boolean(), nullable=False), sa.Column('admin', sa.Boolean(), nullable=False),
sa.Column('rank', sa.Enum('D7', 'D6', 'D5', 'D4', 'D3', 'D2', 'D1', 'K1', 'K2', 'K3', 'K4', 'K5', 'K6', 'K7', 'K8', 'K9', 'K10', 'K11', 'K12', 'K13', 'K14', 'K15', 'K16', 'K17', 'K18', 'K19', 'K20', 'K21', 'K22', 'K23', 'K24', 'K25', 'K26', 'K27', 'K28', 'K29', 'K30', name='ranks'), nullable=True), sa.Column('rank', sa.Enum('D7', 'D6', 'D5', 'D4', 'D3', 'D2', 'D1', 'K1', 'K2', 'K3', 'K4', 'K5', 'K6', 'K7', 'K8', 'K9', 'K10', 'K11', 'K12', 'K13', 'K14', 'K15', 'K16', 'K17', 'K18', 'K19', 'K20', 'K21', 'K22', 'K23', 'K24', 'K25', 'K26', 'K27', 'K28', 'K29', 'K30', name='ranks'), nullable=True),

View file

@ -0,0 +1,28 @@
"""empty message
Revision ID: bdc3cd5d7499
Revises: 16c70b11242e
Create Date: 2019-10-05 22:34:04.358841
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'bdc3cd5d7499'
down_revision = '16c70b11242e'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('moves', sa.Column('is_pass', sa.Boolean(), nullable=False))
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('moves', 'is_pass')
# ### end Alembic commands ###

View file

@ -0,0 +1,28 @@
"""empty message
Revision ID: bfa4b406e22f
Revises: bdc3cd5d7499
Create Date: 2019-10-05 22:36:45.420054
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql
# revision identifiers, used by Alembic.
revision = 'bfa4b406e22f'
down_revision = 'bdc3cd5d7499'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('users', 'password')
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('users', sa.Column('password', postgresql.TIMESTAMP(), autoincrement=False, nullable=False))
# ### end Alembic commands ###

View file

@ -1,6 +0,0 @@
from models.User import User
from models.GameRoom import GameRoom
from models.TimeSettings import TimeSettings
from models.Game import Game
from models.Move import Move
from models.Message import Message

View file

@ -1,6 +1,9 @@
from app import db, ma, bcrypt from database import db, ma
from app import bcrypt
from configuration import config
import datetime import datetime
import enum import enum
import jwt
class Ranks(enum.Enum): # with minimal Elo rating class Ranks(enum.Enum): # with minimal Elo rating
D7 = "Seven Dan" # Elo 2700+ D7 = "Seven Dan" # Elo 2700+
@ -47,7 +50,7 @@ class User(db.Model):
id = db.Column(db.Integer, primary_key=True, autoincrement=True) id = db.Column(db.Integer, primary_key=True, autoincrement=True)
email = db.Column(db.String(255), unique=True, nullable=False) email = db.Column(db.String(255), unique=True, nullable=False)
password = db.Column(db.DateTime, nullable=False) password = db.Column(db.String(255), nullable=False)
registered_on = db.Column(db.DateTime, nullable=False) registered_on = db.Column(db.DateTime, nullable=False)
admin = db.Column(db.Boolean, nullable=False, default=False) admin = db.Column(db.Boolean, nullable=False, default=False)
rank = db.Column(db.Enum(Ranks)) rank = db.Column(db.Enum(Ranks))
@ -55,9 +58,60 @@ class User(db.Model):
rank_certainty = db.Column(db.Boolean, nullable=False, default=False) rank_certainty = db.Column(db.Boolean, nullable=False, default=False)
def __init__(self, email, password, admin=False,): def __init__(self, email, password, admin=False,):
print('user init')
self.email = email self.email = email
print('user email init')
self.password = bcrypt.generate_password_hash( self.password = bcrypt.generate_password_hash(
password, app.config.get('BCRYPT_LOG_ROUNDS') password, 13
).decode() ).decode()
print('user password init')
self.registered_on = datetime.datetime.now() self.registered_on = datetime.datetime.now()
self.admin = admin self.admin = admin
def encode_auth_token(self, user_id):
"""
Generates the Auth Token
:return: string
"""
try:
payload = {
'exp': datetime.datetime.utcnow() + datetime.timedelta(days=0, seconds=5),
'iat': datetime.datetime.utcnow(),
'sub': user_id
}
return jwt.encode(
payload,
app.config.get('SECRET_KEY'),
algorithm='HS256'
)
except Exception as e:
return e
@staticmethod
def decode_auth_token(auth_token):
"""
Decodes the auth token
:param auth_token:
:return: integer|string
"""
try:
payload = jwt.decode(auth_token, app.config.get('SECRET_KEY'))
return payload['sub']
except jwt.ExpiredSignatureError:
return 'Signature expired. Please log in again.'
except jwt.InvalidTokenError:
return 'Invalid token. Please log in again.'
class UserSchema(ma.ModelSchema):
class Meta:
fields = (
'id',
'name',
'registered_on',
'rank',
'rank_certainty',
'elo'
)
user_schema = UserSchema()
users_schema = UserSchema(many=True)

View file

@ -23,6 +23,7 @@ mccabe==0.6.1
numpy==1.17.2 numpy==1.17.2
psycopg2==2.8.3 psycopg2==2.8.3
pycparser==2.19 pycparser==2.19
PyJWT==1.7.1
pylint==2.4.2 pylint==2.4.2
python-dateutil==2.8.0 python-dateutil==2.8.0
python-editor==1.0.4 python-editor==1.0.4

17
server.py Normal file
View file

@ -0,0 +1,17 @@
from app import create_app, db
# Blueprints
from api.api import api
from auth.auth import auth
import configuration.models_mount
from flask_migrate import Migrate
if __name__ == '__main__':
app = create_app()
app.register_blueprint(api)
app.register_blueprint(auth)
migrate = Migrate(app, db)
app.run(port=8000, debug=True)