Merge pull request #24 from WebEngineering2/api

Updated API
- Updated database model
- Update telegram user id in database
- Updated documentation
This commit is contained in:
Florian Kaiser 2022-03-27 18:02:46 +02:00 committed by GitHub
commit e8b9107f65
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 489 additions and 308 deletions

View File

@ -3,7 +3,7 @@ import os
from apiflask import APIBlueprint, abort
from db import db
from helper_functions import get_user_id_from_username, get_username_or_abort_401, make_response
from helper_functions import make_response, get_email_or_abort_401
from auth import auth
from schema import KeywordResponseSchema, KeywordSchema, DeleteSuccessfulSchema
from models import Keyword
@ -18,17 +18,17 @@ __location__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file
@keyword_blueprint.auth_required(auth)
@keyword_blueprint.doc(summary="Add new keyword", description="Adds new keyword for current user")
def add_keyword(data):
username = get_username_or_abort_401()
email = get_email_or_abort_401()
check_if_keyword_data_exists(data)
key = data['keyword']
check_keyword = db.session.query(Keyword).filter_by(keyword=key, user_id=get_user_id_from_username(username)).first()
check_keyword = db.session.query(Keyword).filter_by(keyword=key, email=email).first()
if check_keyword is None:
# Keyword doesn't exist yet for this user
new_keyword = Keyword(
user_id=get_user_id_from_username(username),
email=email,
keyword=key
)
db.session.add(new_keyword)
@ -45,16 +45,21 @@ def add_keyword(data):
@keyword_blueprint.auth_required(auth)
@keyword_blueprint.doc(summary="Removes existing keyword", description="Removes existing keyword for current user")
def remove_keyword(data):
username = get_username_or_abort_401()
email = get_email_or_abort_401()
check_if_keyword_data_exists(data)
key = data['keyword']
db.session.query(Keyword).filter_by(keyword=key, user_id=get_user_id_from_username(username)).delete()
db.session.commit()
check_keyword = db.session.query(Keyword).filter_by(keyword=key, email=email).first()
return make_response({}, 200, "Successfully removed keyword")
if check_keyword is None:
return make_response({}, 500, "Keyword doesn't exist for this user")
else:
db.session.query(Keyword).filter_by(keyword=key, email=email).delete()
db.session.commit()
return make_response({}, 200, "Successfully removed keyword")
@keyword_blueprint.route('/keywords', methods=['GET'])
@ -62,10 +67,10 @@ def remove_keyword(data):
@keyword_blueprint.auth_required(auth)
@keyword_blueprint.doc(summary="Returns all keywords", description="Returns all keywords for current user")
def get_keywords():
username = get_username_or_abort_401()
email = get_email_or_abort_401()
return_keywords = []
keywords = db.session.query(Keyword).filter_by(user_id=get_user_id_from_username(username)).all()
keywords = db.session.query(Keyword).filter_by(email=email).all()
if keywords is not None:
for row in keywords:

View File

@ -2,9 +2,9 @@ import os
from apiflask import APIBlueprint
from api.schema import PortfolioResponseSchema
from db import db
from helper_functions import get_user_id_from_username, get_username_or_abort_401, make_response
from models import Transaction
from helper_functions import make_response, get_email_or_abort_401
from auth import auth
portfolio_blueprint = APIBlueprint('portfolio', __name__, url_prefix='/api')
@ -12,21 +12,22 @@ __location__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file
@portfolio_blueprint.route('/portfolio', methods=['GET'])
@portfolio_blueprint.output(200)
@portfolio_blueprint.output(PortfolioResponseSchema(many=True), 200)
@portfolio_blueprint.auth_required(auth)
@portfolio_blueprint.doc(summary="Returns portfolio", description="Returns all shares of current user")
def get_portfolio():
username = get_username_or_abort_401()
email = get_email_or_abort_401()
return_portfolio = {}
transactions = db.session.query(Transaction).filter_by(user_id=get_user_id_from_username(username)).all()
return_portfolio = []
transactions = db.session.execute("SELECT symbol, SUM(count), SUM(price), MAX(time) FROM `transactions` WHERE email = '" + email + "' GROUP BY symbol;").all()
if transactions is not None:
for row in transactions:
if row.symbol in return_portfolio:
return_portfolio[row.symbol]['count'] += row.count
return_portfolio[row.symbol]['last_transaction'] = row.time
else:
return_portfolio[row.symbol] = {"count": row.count, "last_transaction": row.time}
return_portfolio.append({
"symbol": row[0],
"count": row[1],
# "price": row[2],
"last_transaction": row[3]
})
return make_response(return_portfolio, 200, "Successfully loaded symbols")

View File

@ -4,7 +4,7 @@ from apiflask import APIBlueprint, abort
from auth import auth
from db import db
from helper_functions import get_user_id_from_username, get_username_or_abort_401, make_response
from helper_functions import make_response, get_email_or_abort_401
from models import Share
from schema import SymbolSchema, SymbolResponseSchema, DeleteSuccessfulSchema
@ -18,17 +18,17 @@ __location__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file
@shares_blueprint.auth_required(auth)
@shares_blueprint.doc(summary="Add new symbol", description="Adds new symbol for current user")
def add_symbol(data):
username = get_username_or_abort_401()
email = get_email_or_abort_401()
check_if_symbol_data_exists(data)
symbol = data['symbol']
check_share = db.session.query(Share).filter_by(symbol=symbol, user_id=get_user_id_from_username(username)).first()
check_share = db.session.query(Share).filter_by(symbol=symbol, email=email).first()
if check_share is None:
# Keyword doesn't exist yet for this user
new_symbol = Share(
user_id=get_user_id_from_username(username),
email=email,
symbol=symbol
)
db.session.add(new_symbol)
@ -45,16 +45,21 @@ def add_symbol(data):
@shares_blueprint.auth_required(auth)
@shares_blueprint.doc(summary="Removes existing symbol", description="Removes existing symbol for current user")
def remove_symbol(data):
username = get_username_or_abort_401()
email = get_email_or_abort_401()
check_if_symbol_data_exists(data)
symbol = data['symbol']
db.session.query(Share).filter_by(symbol=symbol, user_id=get_user_id_from_username(username)).delete()
db.session.commit()
check_share = db.session.query(Share).filter_by(symbol=symbol, email=email).first()
return make_response({}, 200, "Successfully removed symbol")
if check_share is None:
return make_response({}, 500, "Symbol doesn't exist for this user")
else:
db.session.query(Share).filter_by(symbol=symbol, email=email).delete()
db.session.commit()
return make_response({}, 200, "Successfully removed symbol")
@shares_blueprint.route('/shares', methods=['GET'])
@ -62,10 +67,10 @@ def remove_symbol(data):
@shares_blueprint.auth_required(auth)
@shares_blueprint.doc(summary="Returns all symbols", description="Returns all symbols for current user")
def get_symbol():
username = get_username_or_abort_401()
email = get_email_or_abort_401()
return_symbols = []
symbols = db.session.query(Share).filter_by(user_id=get_user_id_from_username(username)).all()
symbols = db.session.query(Share).filter_by(email=email).all()
if symbols is not None:
for row in symbols:

View File

@ -0,0 +1,42 @@
import os
from apiflask import APIBlueprint, abort
from db import db
from helper_functions import make_response, get_email_or_abort_401
from auth import auth
from schema import TelegramIdSchema, UsersSchema
from models import User
telegram_blueprint = APIBlueprint('telegram', __name__, url_prefix='/api')
__location__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__)))
@telegram_blueprint.route('/telegram', methods=['POST'])
@telegram_blueprint.output(UsersSchema(many=False), 200)
@telegram_blueprint.input(schema=TelegramIdSchema)
@telegram_blueprint.auth_required(auth)
@telegram_blueprint.doc(summary="Connects telegram user id", description="Connects telegram user id to user account")
def add_keyword(data):
email = get_email_or_abort_401()
check_if_telegram_user_id_data_exists(data)
query_user = db.session.query(User).filter_by(email=email).first()
if query_user is None: # Username doesn't exist
abort(500, message="Unable to login")
query_user.telegram_user_id = data['telegram_user_id']
db.session.commit()
return make_response(query_user.as_dict(), 200, "Successfully connected telegram user")
def check_if_telegram_user_id_data_exists(data):
if "telegram_user_id" not in data:
abort(400, message="User ID missing")
if data['telegram_user_id'] == "" or data['telegram_user_id'] is None:
abort(400, message="User ID missing")

View File

@ -4,9 +4,9 @@ import datetime
from apiflask import abort, APIBlueprint
from db import db
from helper_functions import get_user_id_from_username, get_username_or_abort_401, make_response
from helper_functions import make_response, get_email_or_abort_401
from models import Transaction
from schema import TransactionSchema
from schema import TransactionSchema, TransactionResponseSchema
from auth import auth
transaction_blueprint = APIBlueprint('transaction', __name__, url_prefix='/api')
@ -14,17 +14,17 @@ __location__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file
@transaction_blueprint.route('/transaction', methods=['POST'])
@transaction_blueprint.output((), 200)
@transaction_blueprint.output(TransactionResponseSchema(), 200)
@transaction_blueprint.input(schema=TransactionSchema)
@transaction_blueprint.auth_required(auth)
@transaction_blueprint.doc(summary="Adds new transaction", description="Adds new transaction for current user")
def add_transaction(data):
username = get_username_or_abort_401()
email = get_email_or_abort_401()
check_if_transaction_data_exists(data)
new_transaction = Transaction(
user_id=get_user_id_from_username(username),
email=email,
symbol=data['symbol'],
time=datetime.datetime.strptime(data['time'], '%Y-%m-%dT%H:%M:%S.%fZ'),
count=data['count'],
@ -41,10 +41,10 @@ def add_transaction(data):
@transaction_blueprint.auth_required(auth)
@transaction_blueprint.doc(summary="Returns all transactions", description="Returns all transactions for current user")
def get_transaction():
username = get_username_or_abort_401()
email = get_email_or_abort_401()
return_transactions = []
transactions = db.session.query(Transaction).filter_by(user_id=get_user_id_from_username(username)).all()
transactions = db.session.query(Transaction).filter_by(email=email).all()
if transactions is not None:
for row in transactions:

View File

@ -5,9 +5,9 @@ import jwt
from apiflask import APIBlueprint, abort
from db import db
from helper_functions import check_password, hash_password, get_username_or_abort_401, abort_if_no_admin, make_response
from helper_functions import check_password, hash_password, abort_if_no_admin, make_response, get_email_or_abort_401
from models import User
from schema import UsersSchema, TokenSchema, LoginDataSchema, AdminDataSchema, DeleteUserSchema
from schema import UsersSchema, TokenSchema, LoginDataSchema, AdminDataSchema, DeleteUserSchema, RegisterDataSchema, UpdateUserDataSchema
from auth import auth
users_blueprint = APIBlueprint('users', __name__, url_prefix='/api')
@ -33,9 +33,9 @@ def users():
@users_blueprint.auth_required(auth)
@users_blueprint.doc(summary="Get current user", description="Returns current user")
def user():
username = get_username_or_abort_401()
email = get_email_or_abort_401()
res = db.session.query(User).filter_by(username=username).first().as_dict()
res = db.session.query(User).filter_by(email=email).first().as_dict()
return make_response(res, 200, "Successfully received current user data")
@ -45,40 +45,45 @@ def user():
@users_blueprint.input(schema=LoginDataSchema)
@users_blueprint.doc(summary="Login", description="Returns jwt token if username and password match, otherwise returns error")
def login(data):
check_if_user_data_exists(data)
check_if_email_data_exists(data)
check_if_password_data_exists(data)
username = data['username']
email = data['email']
password = data['password']
query_user = db.session.query(User).filter_by(username=username).first()
query_user = db.session.query(User).filter_by(email=email).first()
if query_user is None: # Username doesn't exist
if query_user is None: # email doesn't exist
abort(500, message="Unable to login")
if not check_password(query_user.password, password): # Password incorrect
abort(500, message="Unable to login")
token = jwt.encode({'username': query_user.username, 'exp': datetime.datetime.utcnow() + datetime.timedelta(minutes=45)}, os.getenv('SECRET_KEY'), "HS256")
token = jwt.encode({'email': query_user.email, 'exp': datetime.datetime.utcnow() + datetime.timedelta(minutes=45)}, os.getenv('SECRET_KEY'), "HS256")
return make_response({"token": token}, 200, "Successfully logged in")
@users_blueprint.route('/user/register', methods=['POST'])
@users_blueprint.output(UsersSchema(), 200)
@users_blueprint.input(schema=LoginDataSchema)
@users_blueprint.input(schema=RegisterDataSchema)
@users_blueprint.doc(summary="Register", description="Registers user")
def register(data):
check_if_user_data_exists(data)
check_if_email_data_exists(data)
check_if_username_data_exists(data)
check_if_password_data_exists(data)
email = data['email']
username = data['username']
password = data['password']
query_user = db.session.query(User).filter_by(username=username).first()
query_user = db.session.query(User).filter_by(email=email).first()
if query_user is not None: # Username already exist
abort(500, message="Username already exist")
abort(500, message="Email already exist")
new_user = User(
email=email,
username=username,
password=hash_password(password),
admin=False
@ -91,26 +96,21 @@ def register(data):
@users_blueprint.route('/user', methods=['PUT'])
@users_blueprint.output({}, 200)
@users_blueprint.input(schema=LoginDataSchema)
@users_blueprint.input(schema=UpdateUserDataSchema)
@users_blueprint.auth_required(auth)
@users_blueprint.doc(summary="Update user", description="Changes password and/or username of current user")
def update_user(data):
username = get_username_or_abort_401()
email = get_email_or_abort_401()
check_if_user_data_exists(data)
new_username = data['username']
new_password = data['password']
query_user = db.session.query(User).filter_by(username=username).first()
query_user = db.session.query(User).filter_by(email=email).first()
if query_user is None: # Username doesn't exist
abort(500, message="Unable to login")
if new_password is not None:
query_user.password = hash_password(new_password)
if new_username is not None:
query_user.username = new_username
if "password" in data and data['password'] is not None:
query_user.password = hash_password(data['password'])
if "username" in data and data['username'] is not None:
query_user.username = data['username']
db.session.commit()
@ -125,12 +125,13 @@ def update_user(data):
def set_admin(data):
abort_if_no_admin() # Only admin users can do this
check_if_email_data_exists(data)
check_if_admin_data_exists(data)
username = data['username']
email = data['email']
admin = data['admin']
query_user = db.session.query(User).filter_by(username=username).first()
query_user = db.session.query(User).filter_by(email=email).first()
if query_user is None: # Username doesn't exist
abort(500, message="Unable to login")
@ -147,29 +148,31 @@ def set_admin(data):
@users_blueprint.auth_required(auth)
@users_blueprint.doc(summary="Delete user", description="Deletes user by username")
def delete_user(data):
check_if_delete_data_exists(data)
check_if_email_data_exists(data)
username = data['username']
email = data['email']
if username == get_username_or_abort_401(): # Username is same as current user
db.session.query(User).filter_by(username=username).delete()
if email == get_email_or_abort_401(): # Username is same as current user
db.session.query(User).filter_by(email=email).delete()
db.session.commit()
else: # Delete different user than my user -> only admin users
abort_if_no_admin()
db.session.query(User).filter_by(username=username).delete()
db.session.query(User).filter_by(email=email).delete()
db.session.commit()
return make_response({}, 200, "Successfully removed user")
def check_if_user_data_exists(data):
if "username" not in data:
abort(400, message="Username missing")
def check_if_email_data_exists(data):
if "email" not in data:
abort(400, message="Email missing")
if data['username'] == "" or data['username'] is None:
abort(400, message="Username missing")
if data['email'] == "" or data['email'] is None:
abort(400, message="Email missing")
def check_if_password_data_exists(data):
if "password" not in data:
abort(400, message="Password missing")
@ -177,23 +180,17 @@ def check_if_user_data_exists(data):
abort(400, message="Password missing")
def check_if_admin_data_exists(data):
def check_if_username_data_exists(data):
if "username" not in data:
abort(400, message="Username missing")
if data['username'] == "" or data['username'] is None:
abort(400, message="Username missing")
def check_if_admin_data_exists(data):
if "admin" not in data:
abort(400, message="Admin state missing")
if data['admin'] == "" or data['admin'] is None:
abort(400, message="Admin state missing")
def check_if_delete_data_exists(data):
if "username" not in data:
abort(400, message="Username missing")
if data['username'] == "" or data['username'] is None:
abort(400, message="Username missing")

View File

@ -5,13 +5,14 @@ from apiflask import APIFlask
from dotenv import load_dotenv
from flask_cors import CORS
from api.api_blueprint_keyword import keyword_blueprint
from api.api_blueprint_portfolio import portfolio_blueprint
from api.api_blueprint_shares import shares_blueprint
from api.api_blueprint_transactions import transaction_blueprint
from api.api_blueprint_telegram import telegram_blueprint
from api.helper_functions import hash_password
from models import *
from api_blueprint_keyword import keyword_blueprint
from api_blueprint_shares import shares_blueprint
from api_blueprint_user import users_blueprint
from api_blueprint_transactions import transaction_blueprint
from api_blueprint_portfolio import portfolio_blueprint
def create_app():
@ -33,25 +34,28 @@ def create_app():
application.register_blueprint(transaction_blueprint)
application.register_blueprint(portfolio_blueprint)
application.register_blueprint(users_blueprint)
application.register_blueprint(telegram_blueprint)
@application.before_first_request
def init_database():
db.create_all()
if os.getenv("BOT_USER") is not None and os.getenv("BOT_PASSWORD") is not None:
if db.session.query(User).filter_by(username=os.getenv("BOT_USER")).first() is None: # Check if user already exist
if os.getenv("BOT_EMAIL") is not None and os.getenv("BOT_USERNAME") is not None and os.getenv("BOT_PASSWORD") is not None:
if db.session.query(User).filter_by(email=os.getenv("BOT_EMAIL")).first() is None: # Check if user already exist
bot = User(
username=os.getenv("BOT_USER"),
email=os.getenv("BOT_EMAIL"),
username=os.getenv("BOT_USERNAME"),
password=hash_password(os.getenv("BOT_PASSWORD")),
admin=False
)
db.session.add(bot)
db.session.commit()
if os.getenv("ADMIN_USER") is not None and os.getenv("ADMIN_PASSWORD") is not None:
if db.session.query(User).filter_by(username=os.getenv("ADMIN_USER")).first() is None: # Check if user already exist
if os.getenv("ADMIN_EMAIL") is not None and os.getenv("ADMIN_USERNAME") is not None and os.getenv("ADMIN_PASSWORD") is not None:
if db.session.query(User).filter_by(email=os.getenv("ADMIN_EMAIL")).first() is None: # Check if user already exist
admin = User(
username=os.getenv("ADMIN_USER"),
email=os.getenv("ADMIN_EMAIL"),
username=os.getenv("ADMIN_USERNAME"),
password=hash_password(os.getenv("ADMIN_PASSWORD")),
admin=True
)

View File

@ -17,5 +17,5 @@ def verify_token(token):
try:
jwt.decode(token, os.getenv('SECRET_KEY'), algorithms=["HS256"])
return True
except jwt.exceptions.DecodeError:
except:
return False

View File

@ -32,53 +32,46 @@ def extract_token_data(token):
if token is not None:
try:
return jwt.decode(token, os.getenv('SECRET_KEY'), algorithms=["HS256"])
except jwt.exceptions.DecodeError:
except:
return None
else:
return None
def get_username_from_token_data():
def get_email_from_token_data():
if 'Authorization' in request.headers:
token = request.headers['Authorization'].split(" ")[1]
if token is not None:
if ':' in token: # Maybe bot token, check if token valid and return username after ":" then
username = token.split(":")[1]
email = token.split(":")[1]
token = token.split(":")[0]
try:
if jwt.decode(token, os.getenv('SECRET_KEY'), algorithms=["HS256"])['username'] == "bot":
return username
if jwt.decode(token, os.getenv('SECRET_KEY'), algorithms=["HS256"])['email'] == os.getenv("BOT_USER"):
return email
else:
return None
except jwt.exceptions.DecodeError:
except:
return None
else: # "Normal" token, extract username from token
try:
return jwt.decode(token, os.getenv('SECRET_KEY'), algorithms=["HS256"])['username']
except jwt.exceptions.DecodeError:
return jwt.decode(token, os.getenv('SECRET_KEY'), algorithms=["HS256"])['email']
except:
return None
return None
def get_user_id_from_username(username):
if username is not None:
return db.session.query(User).filter_by(username=username).first().user_id
else:
return None
def get_username_or_abort_401():
def get_email_or_abort_401():
# get username from jwt token
username = get_username_from_token_data()
email = get_email_from_token_data()
if username is None: # If token not provided or invalid -> return 401 code
if email is None: # If token not provided or invalid -> return 401 code
abort(401, message="Unable to login")
return username
return email
def abort_if_no_admin():
@ -87,10 +80,10 @@ def abort_if_no_admin():
def is_user_admin():
username = get_username_or_abort_401()
email = get_email_or_abort_401()
return db.session.query(User).filter_by(username=username).first().admin
return db.session.query(User).filter_by(email=email).first().admin
def make_response(data, status=200, text=""):
return jsonify({"status": status, "text": text, "data": {"token": data}})
return jsonify({"status": status, "text": text, "data": data})

View File

@ -3,10 +3,10 @@ from db import db
class User(db.Model):
__tablename__ = 'users'
username = db.Column('username', db.String(255), nullable=False, unique=True)
email = db.Column('email', db.String(255), primary_key=True, nullable=False, unique=True)
password = db.Column('password', db.String(255), nullable=False, server_default='')
user_id = db.Column('user_id', db.Integer(), primary_key=True)
telegram_name = db.Column('telegram_name', db.String(255), nullable=True, server_default='')
username = db.Column('username', db.String(255), nullable=False, server_default='')
telegram_user_id = db.Column('telegram_user_id', db.String(255), nullable=True, server_default='')
admin = db.Column('admin', db.Boolean(), server_default='0')
def as_dict(self):
@ -16,7 +16,7 @@ class User(db.Model):
class Transaction(db.Model):
__tablename__ = 'transactions'
t_id = db.Column('t_id', db.Integer(), nullable=False, unique=True, primary_key=True)
user_id = db.Column('user_id', db.Integer(), db.ForeignKey('users.user_id', ondelete='CASCADE'))
email = db.Column('email', db.String(255), db.ForeignKey('users.email', ondelete='CASCADE'))
symbol = db.Column('symbol', db.String(255))
time = db.Column('time', db.DateTime())
count = db.Column('count', db.Integer())
@ -29,7 +29,7 @@ class Transaction(db.Model):
class Keyword(db.Model):
__tablename__ = 'keywords'
s_id = db.Column('s_id', db.Integer(), nullable=False, unique=True, primary_key=True)
user_id = db.Column('user_id', db.Integer(), db.ForeignKey('users.user_id', ondelete='CASCADE'))
email = db.Column('email', db.String(255), db.ForeignKey('users.email', ondelete='CASCADE'))
keyword = db.Column('keyword', db.String(255))
def as_dict(self):
@ -39,7 +39,7 @@ class Keyword(db.Model):
class Share(db.Model):
__tablename__ = 'shares'
a_id = db.Column('a_id', db.Integer(), nullable=False, unique=True, primary_key=True)
user_id = db.Column('user_id', db.Integer(), db.ForeignKey('users.user_id', ondelete='CASCADE'))
email = db.Column('email', db.String(255), db.ForeignKey('users.email', ondelete='CASCADE'))
symbol = db.Column('symbol', db.String(255))
def as_dict(self):

View File

@ -1,5 +1,7 @@
from apiflask import Schema
from apiflask.fields import Integer, String, Boolean, Field, Float
from marshmallow import validate
from marshmallow.fields import Email
class BaseResponseSchema(Schema):
@ -11,13 +13,13 @@ class BaseResponseSchema(Schema):
class UsersSchema(Schema):
admin = Boolean()
password = String()
telegram_name = String()
user_id = Integer()
username = String()
telegram_user_id = String()
email = Email()
class AdminDataSchema(Schema):
username = String()
email = Email()
admin = Boolean()
@ -26,12 +28,23 @@ class TokenSchema(Schema):
class LoginDataSchema(Schema):
email = Email()
password = String()
class RegisterDataSchema(Schema):
email = Email()
username = String()
password = String()
class UpdateUserDataSchema(Schema):
username = String(required=False)
password = String(required=False)
class DeleteUserSchema(Schema):
username = String()
email = Email()
class ChangePasswordSchema(Schema):
@ -50,7 +63,7 @@ class KeywordSchema(Schema):
class KeywordResponseSchema(Schema):
keyword = String()
s_id = Integer()
user_id = Integer()
email = Email()
class SymbolSchema(Schema):
@ -60,7 +73,7 @@ class SymbolSchema(Schema):
class SymbolResponseSchema(Schema):
symbol = String()
s_id = Integer()
user_id = Integer()
email = Email()
class PortfolioShareResponseSchema(Schema):
@ -69,12 +82,30 @@ class PortfolioShareResponseSchema(Schema):
class TransactionSchema(Schema):
user_id = Integer()
symbol = String()
time = String(validate=validate.Regexp(r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z"))
count = Integer()
price = Float()
class TransactionResponseSchema(Schema):
email = Email()
symbol = String()
time = String()
count = Integer()
price = Float()
class TelegramIdSchema(Schema):
telegram_user_id = String()
class PortfolioResponseSchema(Schema):
symbol = String()
last_transaction = String()
count = Integer()
# price = Float()
class DeleteSuccessfulSchema(Schema):
pass

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
{
"info": {
"_postman_id": "b478b800-af91-45a7-8713-b199bcc41866",
"_postman_id": "eed3eb48-b932-4d72-979a-38de9ae2cbf0",
"name": "APIFlask",
"description": "Webengineering 2 | Telegram Aktienbot",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
@ -35,7 +35,7 @@
],
"body": {
"mode": "raw",
"raw": "{\n \"keyword\": \"elit Lorem\"\n}",
"raw": "{\n \"keyword\": \"nisi\"\n}",
"options": {
"raw": {
"language": "json"
@ -68,7 +68,7 @@
],
"body": {
"mode": "raw",
"raw": "{\n \"keyword\": \"elit Lorem\"\n}",
"raw": "{\n \"keyword\": \"nisi\"\n}",
"options": {
"raw": {
"language": "json"
@ -96,7 +96,7 @@
}
],
"cookie": [],
"body": "{\n \"data\": {},\n \"status\": 261201,\n \"text\": \"aliqua amet consectetur elit\"\n}"
"body": "{\n \"data\": {},\n \"status\": -35854777,\n \"text\": \"sint in\"\n}"
},
{
"name": "Validation error",
@ -111,7 +111,7 @@
],
"body": {
"mode": "raw",
"raw": "{\n \"keyword\": \"elit Lorem\"\n}",
"raw": "{\n \"keyword\": \"nisi\"\n}",
"options": {
"raw": {
"language": "json"
@ -139,7 +139,7 @@
}
],
"cookie": [],
"body": "{\n \"detail\": {\n \"<location>\": {\n \"<field_name>\": [\n \"labore\",\n \"\"\n ]\n }\n },\n \"message\": \"pariatur cillum qui aute\"\n}"
"body": "{\n \"detail\": {\n \"<location>\": {\n \"<field_name>\": [\n \"anim quis\",\n \"in velit ali\"\n ]\n }\n },\n \"message\": \"nostrud\"\n}"
},
{
"name": "Authentication error",
@ -154,7 +154,7 @@
],
"body": {
"mode": "raw",
"raw": "{\n \"keyword\": \"elit Lorem\"\n}",
"raw": "{\n \"keyword\": \"nisi\"\n}",
"options": {
"raw": {
"language": "json"
@ -182,7 +182,7 @@
}
],
"cookie": [],
"body": "{\n \"detail\": {},\n \"message\": \"eiusmod enim ipsum\"\n}"
"body": "{\n \"detail\": {},\n \"message\": \"irure ad do quis\"\n}"
}
]
},
@ -212,7 +212,7 @@
],
"body": {
"mode": "raw",
"raw": "{\n \"keyword\": \"elit Lorem\"\n}",
"raw": "{\n \"keyword\": \"nisi\"\n}",
"options": {
"raw": {
"language": "json"
@ -245,7 +245,7 @@
],
"body": {
"mode": "raw",
"raw": "{\n \"keyword\": \"elit Lorem\"\n}",
"raw": "{\n \"keyword\": \"nisi\"\n}",
"options": {
"raw": {
"language": "json"
@ -273,7 +273,7 @@
}
],
"cookie": [],
"body": "{\n \"data\": [\n {\n \"keyword\": \"tempor dolor commodo ipsum non\",\n \"s_id\": -64068772,\n \"user_id\": 82510382\n },\n {\n \"keyword\": \"in aute ex\",\n \"s_id\": 60028598,\n \"user_id\": -36905324\n }\n ],\n \"status\": 63124172,\n \"text\": \"amet\"\n}"
"body": "{\n \"data\": [\n {\n \"email\": \"8Es0sp5sb@wvQoAOvD.bzz\",\n \"keyword\": \"eiusmo\",\n \"s_id\": -48384117\n },\n {\n \"email\": \"MZ0cnQ1mwRV@oONtzNaRnVSaUXAReoDzwztMr.fiz\",\n \"keyword\": \"ullamco ad\",\n \"s_id\": -36966818\n }\n ],\n \"status\": 55335664,\n \"text\": \"dolor id ex\"\n}"
},
{
"name": "Validation error",
@ -288,7 +288,7 @@
],
"body": {
"mode": "raw",
"raw": "{\n \"keyword\": \"elit Lorem\"\n}",
"raw": "{\n \"keyword\": \"nisi\"\n}",
"options": {
"raw": {
"language": "json"
@ -316,7 +316,7 @@
}
],
"cookie": [],
"body": "{\n \"detail\": {\n \"<location>\": {\n \"<field_name>\": [\n \"labore\",\n \"\"\n ]\n }\n },\n \"message\": \"pariatur cillum qui aute\"\n}"
"body": "{\n \"detail\": {\n \"<location>\": {\n \"<field_name>\": [\n \"anim quis\",\n \"in velit ali\"\n ]\n }\n },\n \"message\": \"nostrud\"\n}"
},
{
"name": "Authentication error",
@ -331,7 +331,7 @@
],
"body": {
"mode": "raw",
"raw": "{\n \"keyword\": \"elit Lorem\"\n}",
"raw": "{\n \"keyword\": \"nisi\"\n}",
"options": {
"raw": {
"language": "json"
@ -359,7 +359,7 @@
}
],
"cookie": [],
"body": "{\n \"detail\": {},\n \"message\": \"eiusmod enim ipsum\"\n}"
"body": "{\n \"detail\": {},\n \"message\": \"irure ad do quis\"\n}"
}
]
},
@ -428,7 +428,7 @@
}
],
"cookie": [],
"body": "{\n \"data\": [\n {\n \"keyword\": \"tempor dolor commodo ipsum non\",\n \"s_id\": -64068772,\n \"user_id\": 82510382\n },\n {\n \"keyword\": \"in aute ex\",\n \"s_id\": 60028598,\n \"user_id\": -36905324\n }\n ],\n \"status\": 63124172,\n \"text\": \"amet\"\n}"
"body": "{\n \"data\": [\n {\n \"email\": \"8Es0sp5sb@wvQoAOvD.bzz\",\n \"keyword\": \"eiusmo\",\n \"s_id\": -48384117\n },\n {\n \"email\": \"MZ0cnQ1mwRV@oONtzNaRnVSaUXAReoDzwztMr.fiz\",\n \"keyword\": \"ullamco ad\",\n \"s_id\": -36966818\n }\n ],\n \"status\": 55335664,\n \"text\": \"dolor id ex\"\n}"
},
{
"name": "Authentication error",
@ -462,7 +462,7 @@
}
],
"cookie": [],
"body": "{\n \"detail\": {},\n \"message\": \"eiusmod enim ipsum\"\n}"
"body": "{\n \"detail\": {},\n \"message\": \"irure ad do quis\"\n}"
}
]
}
@ -497,7 +497,7 @@
],
"body": {
"mode": "raw",
"raw": "{\n \"symbol\": \"aliquip ullamco Ut\"\n}",
"raw": "{\n \"symbol\": \"magna Excepteur ullamco aute velit\"\n}",
"options": {
"raw": {
"language": "json"
@ -530,7 +530,7 @@
],
"body": {
"mode": "raw",
"raw": "{\n \"symbol\": \"aliquip ullamco Ut\"\n}",
"raw": "{\n \"symbol\": \"magna Excepteur ullamco aute velit\"\n}",
"options": {
"raw": {
"language": "json"
@ -558,7 +558,7 @@
}
],
"cookie": [],
"body": "{\n \"data\": {},\n \"status\": 261201,\n \"text\": \"aliqua amet consectetur elit\"\n}"
"body": "{\n \"data\": {},\n \"status\": -35854777,\n \"text\": \"sint in\"\n}"
},
{
"name": "Validation error",
@ -573,7 +573,7 @@
],
"body": {
"mode": "raw",
"raw": "{\n \"symbol\": \"aliquip ullamco Ut\"\n}",
"raw": "{\n \"symbol\": \"magna Excepteur ullamco aute velit\"\n}",
"options": {
"raw": {
"language": "json"
@ -601,7 +601,7 @@
}
],
"cookie": [],
"body": "{\n \"detail\": {\n \"<location>\": {\n \"<field_name>\": [\n \"labore\",\n \"\"\n ]\n }\n },\n \"message\": \"pariatur cillum qui aute\"\n}"
"body": "{\n \"detail\": {\n \"<location>\": {\n \"<field_name>\": [\n \"anim quis\",\n \"in velit ali\"\n ]\n }\n },\n \"message\": \"nostrud\"\n}"
},
{
"name": "Authentication error",
@ -616,7 +616,7 @@
],
"body": {
"mode": "raw",
"raw": "{\n \"symbol\": \"aliquip ullamco Ut\"\n}",
"raw": "{\n \"symbol\": \"magna Excepteur ullamco aute velit\"\n}",
"options": {
"raw": {
"language": "json"
@ -644,7 +644,7 @@
}
],
"cookie": [],
"body": "{\n \"detail\": {},\n \"message\": \"eiusmod enim ipsum\"\n}"
"body": "{\n \"detail\": {},\n \"message\": \"irure ad do quis\"\n}"
}
]
},
@ -674,7 +674,7 @@
],
"body": {
"mode": "raw",
"raw": "{\n \"symbol\": \"aliquip ullamco Ut\"\n}",
"raw": "{\n \"symbol\": \"magna Excepteur ullamco aute velit\"\n}",
"options": {
"raw": {
"language": "json"
@ -707,7 +707,7 @@
],
"body": {
"mode": "raw",
"raw": "{\n \"symbol\": \"aliquip ullamco Ut\"\n}",
"raw": "{\n \"symbol\": \"magna Excepteur ullamco aute velit\"\n}",
"options": {
"raw": {
"language": "json"
@ -735,7 +735,7 @@
}
],
"cookie": [],
"body": "{\n \"data\": [\n {\n \"s_id\": -53227093,\n \"symbol\": \"veniam ea amet irure\",\n \"user_id\": 7468241\n },\n {\n \"s_id\": -37877246,\n \"symbol\": \"ut tempor labore non\",\n \"user_id\": -72644124\n }\n ],\n \"status\": 87653200,\n \"text\": \"aliquip reprehenderit dolore\"\n}"
"body": "{\n \"data\": [\n {\n \"email\": \"j32mUuC@iIJKfYQWSepoVsngEZYbfEmOwCzXXxVMP.alp\",\n \"s_id\": 86469214,\n \"symbol\": \"labore ea\"\n },\n {\n \"email\": \"PwKotAxaLBa8nY@nSsGmaxZeZqnRhOGmHhbICYhqTGLESrq.xy\",\n \"s_id\": 63768957,\n \"symbol\": \"laboris pariatur commodo\"\n }\n ],\n \"status\": -1862021,\n \"text\": \"culpa nulla\"\n}"
},
{
"name": "Validation error",
@ -750,7 +750,7 @@
],
"body": {
"mode": "raw",
"raw": "{\n \"symbol\": \"aliquip ullamco Ut\"\n}",
"raw": "{\n \"symbol\": \"magna Excepteur ullamco aute velit\"\n}",
"options": {
"raw": {
"language": "json"
@ -778,7 +778,7 @@
}
],
"cookie": [],
"body": "{\n \"detail\": {\n \"<location>\": {\n \"<field_name>\": [\n \"labore\",\n \"\"\n ]\n }\n },\n \"message\": \"pariatur cillum qui aute\"\n}"
"body": "{\n \"detail\": {\n \"<location>\": {\n \"<field_name>\": [\n \"anim quis\",\n \"in velit ali\"\n ]\n }\n },\n \"message\": \"nostrud\"\n}"
},
{
"name": "Authentication error",
@ -793,7 +793,7 @@
],
"body": {
"mode": "raw",
"raw": "{\n \"symbol\": \"aliquip ullamco Ut\"\n}",
"raw": "{\n \"symbol\": \"magna Excepteur ullamco aute velit\"\n}",
"options": {
"raw": {
"language": "json"
@ -821,7 +821,7 @@
}
],
"cookie": [],
"body": "{\n \"detail\": {},\n \"message\": \"eiusmod enim ipsum\"\n}"
"body": "{\n \"detail\": {},\n \"message\": \"irure ad do quis\"\n}"
}
]
},
@ -890,7 +890,7 @@
}
],
"cookie": [],
"body": "{\n \"data\": [\n {\n \"s_id\": -53227093,\n \"symbol\": \"veniam ea amet irure\",\n \"user_id\": 7468241\n },\n {\n \"s_id\": -37877246,\n \"symbol\": \"ut tempor labore non\",\n \"user_id\": -72644124\n }\n ],\n \"status\": 87653200,\n \"text\": \"aliquip reprehenderit dolore\"\n}"
"body": "{\n \"data\": [\n {\n \"email\": \"j32mUuC@iIJKfYQWSepoVsngEZYbfEmOwCzXXxVMP.alp\",\n \"s_id\": 86469214,\n \"symbol\": \"labore ea\"\n },\n {\n \"email\": \"PwKotAxaLBa8nY@nSsGmaxZeZqnRhOGmHhbICYhqTGLESrq.xy\",\n \"s_id\": 63768957,\n \"symbol\": \"laboris pariatur commodo\"\n }\n ],\n \"status\": -1862021,\n \"text\": \"culpa nulla\"\n}"
},
{
"name": "Authentication error",
@ -924,7 +924,7 @@
}
],
"cookie": [],
"body": "{\n \"detail\": {},\n \"message\": \"eiusmod enim ipsum\"\n}"
"body": "{\n \"detail\": {},\n \"message\": \"irure ad do quis\"\n}"
}
]
}
@ -959,7 +959,7 @@
],
"body": {
"mode": "raw",
"raw": "{\n \"count\": 96634001,\n \"price\": -71028444.15053315,\n \"symbol\": \"deserunt officia dolore\",\n \"time\": \"magna occaecat est\",\n \"user_id\": -71272721\n}",
"raw": "{\n \"count\": 76782033,\n \"price\": -9709838.042264134,\n \"symbol\": \"mollit esse ex in\",\n \"time\": \"2120-69-63T43:76:75.378Z\"\n}",
"options": {
"raw": {
"language": "json"
@ -992,7 +992,7 @@
],
"body": {
"mode": "raw",
"raw": "{\n \"count\": 96634001,\n \"price\": -71028444.15053315,\n \"symbol\": \"deserunt officia dolore\",\n \"time\": \"magna occaecat est\",\n \"user_id\": -71272721\n}",
"raw": "{\n \"count\": 76782033,\n \"price\": -9709838.042264134,\n \"symbol\": \"mollit esse ex in\",\n \"time\": \"2120-69-63T43:76:75.378Z\"\n}",
"options": {
"raw": {
"language": "json"
@ -1020,7 +1020,7 @@
}
],
"cookie": [],
"body": "{\n \"data\": {\n \"value\": \"reference #/components/schemas/() not found in the OpenAPI spec\"\n },\n \"status\": 14310780,\n \"text\": \"in sint sit\"\n}"
"body": "{\n \"data\": {\n \"count\": 99691073,\n \"email\": \"DAX6XjHTr8eA6M@xsoUe.id\",\n \"price\": -14617384.086570382,\n \"symbol\": \"eu ad deserunt\",\n \"time\": \"ipsum nisi in laboris\"\n },\n \"status\": -51137224,\n \"text\": \"ipsum culpa amet\"\n}"
},
{
"name": "Validation error",
@ -1035,7 +1035,7 @@
],
"body": {
"mode": "raw",
"raw": "{\n \"count\": 96634001,\n \"price\": -71028444.15053315,\n \"symbol\": \"deserunt officia dolore\",\n \"time\": \"magna occaecat est\",\n \"user_id\": -71272721\n}",
"raw": "{\n \"count\": 76782033,\n \"price\": -9709838.042264134,\n \"symbol\": \"mollit esse ex in\",\n \"time\": \"2120-69-63T43:76:75.378Z\"\n}",
"options": {
"raw": {
"language": "json"
@ -1063,7 +1063,7 @@
}
],
"cookie": [],
"body": "{\n \"detail\": {\n \"<location>\": {\n \"<field_name>\": [\n \"labore\",\n \"\"\n ]\n }\n },\n \"message\": \"pariatur cillum qui aute\"\n}"
"body": "{\n \"detail\": {\n \"<location>\": {\n \"<field_name>\": [\n \"anim quis\",\n \"in velit ali\"\n ]\n }\n },\n \"message\": \"nostrud\"\n}"
},
{
"name": "Authentication error",
@ -1078,7 +1078,7 @@
],
"body": {
"mode": "raw",
"raw": "{\n \"count\": 96634001,\n \"price\": -71028444.15053315,\n \"symbol\": \"deserunt officia dolore\",\n \"time\": \"magna occaecat est\",\n \"user_id\": -71272721\n}",
"raw": "{\n \"count\": 76782033,\n \"price\": -9709838.042264134,\n \"symbol\": \"mollit esse ex in\",\n \"time\": \"2120-69-63T43:76:75.378Z\"\n}",
"options": {
"raw": {
"language": "json"
@ -1106,7 +1106,7 @@
}
],
"cookie": [],
"body": "{\n \"detail\": {},\n \"message\": \"eiusmod enim ipsum\"\n}"
"body": "{\n \"detail\": {},\n \"message\": \"irure ad do quis\"\n}"
}
]
},
@ -1175,7 +1175,7 @@
}
],
"cookie": [],
"body": "{\n \"data\": {\n \"count\": -19053100,\n \"price\": 39909986.26075193,\n \"symbol\": \"sit nisi\",\n \"time\": \"pariatur eu proident\",\n \"user_id\": 54782742\n },\n \"status\": 87070947,\n \"text\": \"null\"\n}"
"body": "{\n \"data\": {\n \"count\": -37878076,\n \"price\": -40419772.172105886,\n \"symbol\": \"velit ut Ut elit esse\",\n \"time\": \"5462-92-97T03:27:22.076Z\"\n },\n \"status\": -509477,\n \"text\": \"proident\"\n}"
},
{
"name": "Authentication error",
@ -1209,7 +1209,7 @@
}
],
"cookie": [],
"body": "{\n \"detail\": {},\n \"message\": \"eiusmod enim ipsum\"\n}"
"body": "{\n \"detail\": {},\n \"message\": \"irure ad do quis\"\n}"
}
]
}
@ -1283,7 +1283,7 @@
}
],
"cookie": [],
"body": "{\n \"data\": {\n \"value\": \"reference #/components/schemas/200 not found in the OpenAPI spec\"\n },\n \"status\": 14426134,\n \"text\": \"velit in ad dolore\"\n}"
"body": "{\n \"data\": [\n {\n \"count\": 75537465,\n \"last_transaction\": \"dolor enim\",\n \"symbol\": \"enim nostrud non deserunt\"\n },\n {\n \"count\": -69490418,\n \"last_transaction\": \"et\",\n \"symbol\": \"Excepteur irure est enim\"\n }\n ],\n \"status\": 7099250,\n \"text\": \"dolore in ad\"\n}"
},
{
"name": "Authentication error",
@ -1317,7 +1317,7 @@
}
],
"cookie": [],
"body": "{\n \"detail\": {},\n \"message\": \"eiusmod enim ipsum\"\n}"
"body": "{\n \"detail\": {},\n \"message\": \"irure ad do quis\"\n}"
}
]
}
@ -1352,7 +1352,7 @@
],
"body": {
"mode": "raw",
"raw": "{\n \"username\": \"aliqua dolor do\"\n}",
"raw": "{\n \"email\": \"HqkZQ@KMWQFPMhWGvBHrdzOdOampAHweUvPCej.kvbl\"\n}",
"options": {
"raw": {
"language": "json"
@ -1385,7 +1385,7 @@
],
"body": {
"mode": "raw",
"raw": "{\n \"username\": \"aliqua dolor do\"\n}",
"raw": "{\n \"email\": \"HqkZQ@KMWQFPMhWGvBHrdzOdOampAHweUvPCej.kvbl\"\n}",
"options": {
"raw": {
"language": "json"
@ -1428,7 +1428,7 @@
],
"body": {
"mode": "raw",
"raw": "{\n \"username\": \"aliqua dolor do\"\n}",
"raw": "{\n \"email\": \"HqkZQ@KMWQFPMhWGvBHrdzOdOampAHweUvPCej.kvbl\"\n}",
"options": {
"raw": {
"language": "json"
@ -1456,7 +1456,7 @@
}
],
"cookie": [],
"body": "{\n \"detail\": {\n \"<location>\": {\n \"<field_name>\": [\n \"cupidatat mollit laborum aute\",\n \"aute in laboris dolor\"\n ]\n }\n },\n \"message\": \"in dolore exercitation eu elit\"\n}"
"body": "{\n \"detail\": {\n \"<location>\": {\n \"<field_name>\": [\n \"anim quis\",\n \"in velit ali\"\n ]\n }\n },\n \"message\": \"nostrud\"\n}"
},
{
"name": "Authentication error",
@ -1471,7 +1471,7 @@
],
"body": {
"mode": "raw",
"raw": "{\n \"username\": \"aliqua dolor do\"\n}",
"raw": "{\n \"email\": \"HqkZQ@KMWQFPMhWGvBHrdzOdOampAHweUvPCej.kvbl\"\n}",
"options": {
"raw": {
"language": "json"
@ -1499,7 +1499,7 @@
}
],
"cookie": [],
"body": "{\n \"detail\": {},\n \"message\": \"eiusmod enim ipsum\"\n}"
"body": "{\n \"detail\": {},\n \"message\": \"irure ad do quis\"\n}"
}
]
},
@ -1568,7 +1568,7 @@
}
],
"cookie": [],
"body": "{\n \"data\": {\n \"admin\": false,\n \"password\": \"voluptate magna esse\",\n \"telegram_name\": \"id\",\n \"user_id\": -55336867,\n \"username\": \"do exercitation\"\n },\n \"status\": -11469710,\n \"text\": \"aute\"\n}"
"body": "{\n \"data\": {\n \"admin\": false,\n \"email\": \"VNB@NeqjbTmHnkWDwPacdUoXgpYVTNlD.iip\",\n \"password\": \"fugiat ipsum\",\n \"telegram_user_id\": \"et\",\n \"username\": \"nostrud laborum\"\n },\n \"status\": -78288268,\n \"text\": \"laborum minim\"\n}"
},
{
"name": "Authentication error",
@ -1602,7 +1602,7 @@
}
],
"cookie": [],
"body": "{\n \"detail\": {},\n \"message\": \"eiusmod enim ipsum\"\n}"
"body": "{\n \"detail\": {},\n \"message\": \"irure ad do quis\"\n}"
}
]
},
@ -1632,7 +1632,7 @@
],
"body": {
"mode": "raw",
"raw": "{\n \"password\": \"ut minim\",\n \"username\": \"esse sit enim consectetur\"\n}",
"raw": "{\n \"password\": \"elit do in esse\",\n \"username\": \"mollit velit sed reprehenderit\"\n}",
"options": {
"raw": {
"language": "json"
@ -1665,7 +1665,7 @@
],
"body": {
"mode": "raw",
"raw": "{\n \"password\": \"ut minim\",\n \"username\": \"esse sit enim consectetur\"\n}",
"raw": "{\n \"password\": \"elit do in esse\",\n \"username\": \"mollit velit sed reprehenderit\"\n}",
"options": {
"raw": {
"language": "json"
@ -1708,7 +1708,7 @@
],
"body": {
"mode": "raw",
"raw": "{\n \"password\": \"ut minim\",\n \"username\": \"esse sit enim consectetur\"\n}",
"raw": "{\n \"password\": \"elit do in esse\",\n \"username\": \"mollit velit sed reprehenderit\"\n}",
"options": {
"raw": {
"language": "json"
@ -1736,7 +1736,7 @@
}
],
"cookie": [],
"body": "{\n \"detail\": {\n \"<location>\": {\n \"<field_name>\": [\n \"labore\",\n \"\"\n ]\n }\n },\n \"message\": \"pariatur cillum qui aute\"\n}"
"body": "{\n \"detail\": {\n \"<location>\": {\n \"<field_name>\": [\n \"anim quis\",\n \"in velit ali\"\n ]\n }\n },\n \"message\": \"nostrud\"\n}"
},
{
"name": "Authentication error",
@ -1751,7 +1751,7 @@
],
"body": {
"mode": "raw",
"raw": "{\n \"password\": \"ut minim\",\n \"username\": \"esse sit enim consectetur\"\n}",
"raw": "{\n \"password\": \"elit do in esse\",\n \"username\": \"mollit velit sed reprehenderit\"\n}",
"options": {
"raw": {
"language": "json"
@ -1779,7 +1779,7 @@
}
],
"cookie": [],
"body": "{\n \"detail\": {},\n \"message\": \"eiusmod enim ipsum\"\n}"
"body": "{\n \"detail\": {},\n \"message\": \"irure ad do quis\"\n}"
}
]
},
@ -1799,7 +1799,7 @@
],
"body": {
"mode": "raw",
"raw": "{\n \"password\": \"ut minim\",\n \"username\": \"esse sit enim consectetur\"\n}",
"raw": "{\n \"email\": \"YKQkCdcOoJ3vH@wbOpjGTXH.avm\",\n \"password\": \"veniam\"\n}",
"options": {
"raw": {
"language": "json"
@ -1827,7 +1827,7 @@
"header": [],
"body": {
"mode": "raw",
"raw": "{\n \"password\": \"ut minim\",\n \"username\": \"esse sit enim consectetur\"\n}",
"raw": "{\n \"email\": \"YKQkCdcOoJ3vH@wbOpjGTXH.avm\",\n \"password\": \"veniam\"\n}",
"options": {
"raw": {
"language": "json"
@ -1856,7 +1856,7 @@
}
],
"cookie": [],
"body": "{\n \"data\": {\n \"token\": \"minim\"\n },\n \"status\": 86563099,\n \"text\": \"non tempor quis ullamco est\"\n}"
"body": "{\n \"data\": {\n \"token\": \"do ipsu\"\n },\n \"status\": 31961350,\n \"text\": \"Lorem dolor commodo laborum cillum\"\n}"
},
{
"name": "Validation error",
@ -1865,7 +1865,7 @@
"header": [],
"body": {
"mode": "raw",
"raw": "{\n \"password\": \"ut minim\",\n \"username\": \"esse sit enim consectetur\"\n}",
"raw": "{\n \"email\": \"YKQkCdcOoJ3vH@wbOpjGTXH.avm\",\n \"password\": \"veniam\"\n}",
"options": {
"raw": {
"language": "json"
@ -1894,7 +1894,7 @@
}
],
"cookie": [],
"body": "{\n \"detail\": {\n \"<location>\": {\n \"<field_name>\": [\n \"labore\",\n \"\"\n ]\n }\n },\n \"message\": \"pariatur cillum qui aute\"\n}"
"body": "{\n \"detail\": {\n \"<location>\": {\n \"<field_name>\": [\n \"anim quis\",\n \"in velit ali\"\n ]\n }\n },\n \"message\": \"nostrud\"\n}"
}
]
},
@ -1914,7 +1914,7 @@
],
"body": {
"mode": "raw",
"raw": "{\n \"password\": \"ut minim\",\n \"username\": \"esse sit enim consectetur\"\n}",
"raw": "{\n \"email\": \"DJR029Ov-keM@pyhCxnpZmcVMxADSiCjmsGRZksCf.zz\",\n \"password\": \"sed voluptate\",\n \"username\": \"voluptate aute proident\"\n}",
"options": {
"raw": {
"language": "json"
@ -1942,7 +1942,7 @@
"header": [],
"body": {
"mode": "raw",
"raw": "{\n \"password\": \"ut minim\",\n \"username\": \"esse sit enim consectetur\"\n}",
"raw": "{\n \"email\": \"DJR029Ov-keM@pyhCxnpZmcVMxADSiCjmsGRZksCf.zz\",\n \"password\": \"sed voluptate\",\n \"username\": \"voluptate aute proident\"\n}",
"options": {
"raw": {
"language": "json"
@ -1971,7 +1971,7 @@
}
],
"cookie": [],
"body": "{\n \"data\": {\n \"admin\": false,\n \"password\": \"voluptate magna esse\",\n \"telegram_name\": \"id\",\n \"user_id\": -55336867,\n \"username\": \"do exercitation\"\n },\n \"status\": -11469710,\n \"text\": \"aute\"\n}"
"body": "{\n \"data\": {\n \"admin\": false,\n \"email\": \"VNB@NeqjbTmHnkWDwPacdUoXgpYVTNlD.iip\",\n \"password\": \"fugiat ipsum\",\n \"telegram_user_id\": \"et\",\n \"username\": \"nostrud laborum\"\n },\n \"status\": -78288268,\n \"text\": \"laborum minim\"\n}"
},
{
"name": "Validation error",
@ -1980,7 +1980,7 @@
"header": [],
"body": {
"mode": "raw",
"raw": "{\n \"password\": \"ut minim\",\n \"username\": \"esse sit enim consectetur\"\n}",
"raw": "{\n \"email\": \"DJR029Ov-keM@pyhCxnpZmcVMxADSiCjmsGRZksCf.zz\",\n \"password\": \"sed voluptate\",\n \"username\": \"voluptate aute proident\"\n}",
"options": {
"raw": {
"language": "json"
@ -2009,7 +2009,7 @@
}
],
"cookie": [],
"body": "{\n \"detail\": {\n \"<location>\": {\n \"<field_name>\": [\n \"labore\",\n \"\"\n ]\n }\n },\n \"message\": \"pariatur cillum qui aute\"\n}"
"body": "{\n \"detail\": {\n \"<location>\": {\n \"<field_name>\": [\n \"anim quis\",\n \"in velit ali\"\n ]\n }\n },\n \"message\": \"nostrud\"\n}"
}
]
},
@ -2039,7 +2039,7 @@
],
"body": {
"mode": "raw",
"raw": "{\n \"admin\": true,\n \"username\": \"sunt\"\n}",
"raw": "{\n \"admin\": false,\n \"email\": \"qUgn5u1bWI4cwc@LjiesdFcoYwvweQto.dj\"\n}",
"options": {
"raw": {
"language": "json"
@ -2073,7 +2073,7 @@
],
"body": {
"mode": "raw",
"raw": "{\n \"admin\": true,\n \"username\": \"sunt\"\n}",
"raw": "{\n \"admin\": false,\n \"email\": \"qUgn5u1bWI4cwc@LjiesdFcoYwvweQto.dj\"\n}",
"options": {
"raw": {
"language": "json"
@ -2117,7 +2117,7 @@
],
"body": {
"mode": "raw",
"raw": "{\n \"admin\": true,\n \"username\": \"sunt\"\n}",
"raw": "{\n \"admin\": false,\n \"email\": \"qUgn5u1bWI4cwc@LjiesdFcoYwvweQto.dj\"\n}",
"options": {
"raw": {
"language": "json"
@ -2146,7 +2146,7 @@
}
],
"cookie": [],
"body": "{\n \"detail\": {\n \"<location>\": {\n \"<field_name>\": [\n \"labore\",\n \"\"\n ]\n }\n },\n \"message\": \"pariatur cillum qui aute\"\n}"
"body": "{\n \"detail\": {\n \"<location>\": {\n \"<field_name>\": [\n \"anim quis\",\n \"in velit ali\"\n ]\n }\n },\n \"message\": \"nostrud\"\n}"
},
{
"name": "Authentication error",
@ -2161,7 +2161,7 @@
],
"body": {
"mode": "raw",
"raw": "{\n \"admin\": true,\n \"username\": \"sunt\"\n}",
"raw": "{\n \"admin\": false,\n \"email\": \"qUgn5u1bWI4cwc@LjiesdFcoYwvweQto.dj\"\n}",
"options": {
"raw": {
"language": "json"
@ -2190,7 +2190,7 @@
}
],
"cookie": [],
"body": "{\n \"detail\": {},\n \"message\": \"eiusmod enim ipsum\"\n}"
"body": "{\n \"detail\": {},\n \"message\": \"irure ad do quis\"\n}"
}
]
},
@ -2259,7 +2259,7 @@
}
],
"cookie": [],
"body": "{\n \"data\": [\n {\n \"admin\": true,\n \"password\": \"incididunt id dolore\",\n \"telegram_name\": \"id sed\",\n \"user_id\": 15906508,\n \"username\": \"dolor consequat ullamco\"\n },\n {\n \"admin\": true,\n \"password\": \"voluptate non\",\n \"telegram_name\": \"dolor sunt fugiat exercitation\",\n \"user_id\": 95246024,\n \"username\": \"Duis qui culpa Ut labore\"\n }\n ],\n \"status\": 81180129,\n \"text\": \"in ullamco\"\n}"
"body": "{\n \"data\": [\n {\n \"admin\": false,\n \"email\": \"paghoo4COL6gQNz@SJXcMSOC.kus\",\n \"password\": \"exercitation laboris Ut cillum nisi\",\n \"telegram_user_id\": \"id in incididunt sint\",\n \"username\": \"sed laborum cill\"\n },\n {\n \"admin\": false,\n \"email\": \"WFYb2q0XXey6WZa@JNSezyFkIVzneuifIXi.la\",\n \"password\": \"velit irure veniam\",\n \"telegram_user_id\": \"pariatur sed commodo\",\n \"username\": \"incididunt consequat\"\n }\n ],\n \"status\": -92106336,\n \"text\": \"commodo ull\"\n}"
},
{
"name": "Authentication error",
@ -2293,7 +2293,189 @@
}
],
"cookie": [],
"body": "{\n \"detail\": {},\n \"message\": \"eiusmod enim ipsum\"\n}"
"body": "{\n \"detail\": {},\n \"message\": \"irure ad do quis\"\n}"
}
]
}
]
},
{
"name": "Telegram",
"item": [
{
"name": "Connects telegram user id",
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "<Bearer Token>",
"type": "string"
}
]
},
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
},
{
"key": "Accept",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"telegram_user_id\": \"do quis\"\n}",
"options": {
"raw": {
"language": "json"
}
}
},
"url": {
"raw": "{{baseUrl}}/api/telegram",
"host": [
"{{baseUrl}}"
],
"path": [
"api",
"telegram"
]
},
"description": "Connects telegram user id to user account"
},
"response": [
{
"name": "Successful response",
"originalRequest": {
"method": "POST",
"header": [
{
"description": "Added as a part of security scheme: bearer",
"key": "Authorization",
"value": "Bearer <token>"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"telegram_user_id\": \"do quis\"\n}",
"options": {
"raw": {
"language": "json"
}
}
},
"url": {
"raw": "{{baseUrl}}/api/telegram",
"host": [
"{{baseUrl}}"
],
"path": [
"api",
"telegram"
]
}
},
"status": "OK",
"code": 200,
"_postman_previewlanguage": "json",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"cookie": [],
"body": "{\n \"data\": {\n \"admin\": false,\n \"email\": \"VNB@NeqjbTmHnkWDwPacdUoXgpYVTNlD.iip\",\n \"password\": \"fugiat ipsum\",\n \"telegram_user_id\": \"et\",\n \"username\": \"nostrud laborum\"\n },\n \"status\": -78288268,\n \"text\": \"laborum minim\"\n}"
},
{
"name": "Validation error",
"originalRequest": {
"method": "POST",
"header": [
{
"description": "Added as a part of security scheme: bearer",
"key": "Authorization",
"value": "Bearer <token>"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"telegram_user_id\": \"do quis\"\n}",
"options": {
"raw": {
"language": "json"
}
}
},
"url": {
"raw": "{{baseUrl}}/api/telegram",
"host": [
"{{baseUrl}}"
],
"path": [
"api",
"telegram"
]
}
},
"status": "Bad Request",
"code": 400,
"_postman_previewlanguage": "json",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"cookie": [],
"body": "{\n \"detail\": {\n \"<location>\": {\n \"<field_name>\": [\n \"velit\",\n \"ut laboris\"\n ]\n }\n },\n \"message\": \"dolore nostrud officia ex\"\n}"
},
{
"name": "Authentication error",
"originalRequest": {
"method": "POST",
"header": [
{
"description": "Added as a part of security scheme: bearer",
"key": "Authorization",
"value": "Bearer <token>"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"telegram_user_id\": \"do quis\"\n}",
"options": {
"raw": {
"language": "json"
}
}
},
"url": {
"raw": "{{baseUrl}}/api/telegram",
"host": [
"{{baseUrl}}"
],
"path": [
"api",
"telegram"
]
}
},
"status": "Unauthorized",
"code": 401,
"_postman_previewlanguage": "json",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"cookie": [],
"body": "{\n \"detail\": {},\n \"message\": \"irure ad do quis\"\n}"
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

View File

@ -1,105 +1,26 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<diagram program="umlet" version="14.3.0">
<zoom_level>10</zoom_level>
<element>
<id>UMLClass</id>
<coordinates>
<x>580</x>
<y>320</y>
<w>210</w>
<h>80</h>
</coordinates>
<panel_attributes>Stichwort
<diagram program="umletino" version="14.3.0"><zoom_level>10</zoom_level><help_text>Database V0.1</help_text><element><id>UMLClass</id><coordinates><x>705</x><y>360</y><w>210</w><h>80</h></coordinates><panel_attributes>keywords
--
PK: s_id
FK: username
Stichwort</panel_attributes>
<additional_attributes/>
</element>
<element>
<id>UMLClass</id>
<coordinates>
<x>580</x>
<y>100</y>
<w>210</w>
<h>130</h>
</coordinates>
<panel_attributes>User
PK: s_id int(11)
FK: email varchar(255)
keyword varchar(255)</panel_attributes><additional_attributes></additional_attributes></element><element><id>UMLClass</id><coordinates><x>425</x><y>240</y><w>210</w><h>130</h></coordinates><panel_attributes>users
--
PK: username
password
user_id
telegramname
Rolle
</panel_attributes>
<additional_attributes/>
</element>
<element>
<id>UMLClass</id>
<coordinates>
<x>930</x>
<y>80</y>
<w>210</w>
<h>90</h>
</coordinates>
<panel_attributes>Aktie
PK: email varchar(255)
password varchar(255)
username varchar(255)
telegram_user_id varchar(255)
admin tinyint(1)
</panel_attributes><additional_attributes></additional_attributes></element><element><id>UMLClass</id><coordinates><x>705</x><y>150</y><w>210</w><h>70</h></coordinates><panel_attributes>shares
--
PK: a_id
FK: username
Aktiensymbol
</panel_attributes>
<additional_attributes/>
</element>
<element>
<id>UMLClass</id>
<coordinates>
<x>200</x>
<y>320</y>
<w>210</w>
<h>130</h>
</coordinates>
<panel_attributes>Transaktion
PK: a_id int(11)
FK: email varchar(255)
symbol varchar(255)
</panel_attributes><additional_attributes></additional_attributes></element><element><id>UMLClass</id><coordinates><x>135</x><y>150</y><w>210</w><h>130</h></coordinates><panel_attributes>transaction
--
PK: t_id
FK: username
FK: Aktiensymbol
Zeitpunkt
Anzahl(+/-)
Preis(+/-)
</panel_attributes>
<additional_attributes/>
</element>
<element>
<id>Relation</id>
<coordinates>
<x>780</x>
<y>120</y>
<w>170</w>
<h>30</h>
</coordinates>
<panel_attributes>lt=&lt;-</panel_attributes>
<additional_attributes>150.0;10.0;10.0;10.0</additional_attributes>
</element>
<element>
<id>Relation</id>
<coordinates>
<x>400</x>
<y>120</y>
<w>200</w>
<h>260</h>
</coordinates>
<panel_attributes>lt=&lt;-</panel_attributes>
<additional_attributes>10.0;240.0;180.0;10.0</additional_attributes>
</element>
<element>
<id>Relation</id>
<coordinates>
<x>510</x>
<y>200</y>
<w>90</w>
<h>190</h>
</coordinates>
<panel_attributes>lt=&lt;-</panel_attributes>
<additional_attributes>70.0;170.0;10.0;10.0</additional_attributes>
</element>
</diagram>
PK: t_id int(11)
FK: email varchar(255)
symbol varchar(255)
time datetime
count int(11)
price float
</panel_attributes><additional_attributes></additional_attributes></element><element><id>Relation</id><coordinates><x>335</x><y>190</y><w>110</w><h>100</h></coordinates><panel_attributes>lt=&lt;&lt;-
group=1</panel_attributes><additional_attributes>10;10;60;10;60;80;90;80</additional_attributes></element><element><id>Relation</id><coordinates><x>625</x><y>190</y><w>100</w><h>100</h></coordinates><panel_attributes>lt=&lt;&lt;-</panel_attributes><additional_attributes>80;10;50;10;50;80;10;80</additional_attributes></element><element><id>Relation</id><coordinates><x>625</x><y>260</y><w>100</w><h>160</h></coordinates><panel_attributes>lt=&lt;&lt;-</panel_attributes><additional_attributes>80;140;50;140;50;10;10;10</additional_attributes></element><element><id>UMLClass</id><coordinates><x>140</x><y>410</y><w>100</w><h>30</h></coordinates><panel_attributes>Database V0.1</panel_attributes><additional_attributes></additional_attributes></element></diagram>