Save symbol price in database

This commit is contained in:
Administrator 2022-04-05 15:08:57 +02:00
parent 852dedfc0c
commit 695b7593be
9 changed files with 151 additions and 6 deletions

View File

@ -16,3 +16,6 @@ BOT_PASSWORD=
ADMIN_EMAIL= ADMIN_EMAIL=
ADMIN_USERNAME= ADMIN_USERNAME=
ADMIN_PASSWORD= ADMIN_PASSWORD=
# API URL (used for load_share_price.py and generate_sample_transactions.py)
API_URL=

View File

@ -7,6 +7,7 @@ from flask_cors import CORS
from app.blueprints.keyword import keyword_blueprint from app.blueprints.keyword import keyword_blueprint
from app.blueprints.portfolio import portfolio_blueprint from app.blueprints.portfolio import portfolio_blueprint
from app.blueprints.shares import shares_blueprint from app.blueprints.shares import shares_blueprint
from app.blueprints.share_price import share_price_blueprint
from app.blueprints.transactions import transaction_blueprint from app.blueprints.transactions import transaction_blueprint
from app.blueprints.telegram import telegram_blueprint from app.blueprints.telegram import telegram_blueprint
from app.blueprints.user import users_blueprint from app.blueprints.user import users_blueprint
@ -28,6 +29,7 @@ def create_app(config_filename=None):
# api blueprints # api blueprints
application.register_blueprint(keyword_blueprint) application.register_blueprint(keyword_blueprint)
application.register_blueprint(shares_blueprint) application.register_blueprint(shares_blueprint)
application.register_blueprint(share_price_blueprint)
application.register_blueprint(transaction_blueprint) application.register_blueprint(transaction_blueprint)
application.register_blueprint(portfolio_blueprint) application.register_blueprint(portfolio_blueprint)
application.register_blueprint(users_blueprint) application.register_blueprint(users_blueprint)

View File

@ -0,0 +1,88 @@
import datetime
import os
from apiflask import APIBlueprint, abort
from app.models import SharePrice
from app.db import database as db
from app.helper_functions import make_response
from app.auth import auth
from app.schema import SymbolPriceSchema
share_price_blueprint = APIBlueprint('share_price', __name__, url_prefix='/api')
__location__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__)))
@share_price_blueprint.route('/symbols', methods=['GET'])
@share_price_blueprint.output({}, 200)
@share_price_blueprint.auth_required(auth)
@share_price_blueprint.doc(summary="Returns all transaction symbols", description="Returns all transaction symbols for all users")
def get_transaction_symbols():
symbols = db.session.execute("SELECT symbol FROM `transactions` GROUP BY symbol;").all()
return_symbols = []
for s in symbols:
return_symbols.append(s[0])
return make_response(return_symbols, 200, "Successfully loaded symbols")
@share_price_blueprint.route('/symbol', methods=['POST'])
@share_price_blueprint.output({}, 200)
@share_price_blueprint.input(schema=SymbolPriceSchema)
@share_price_blueprint.auth_required(auth)
@share_price_blueprint.doc(summary="Returns all transaction symbols", description="Returns all transaction symbols for all users")
def add_symbol_price(data):
if not check_if_symbol_data_exists(data):
abort(400, message="Symbol missing")
if not check_if_price_data_exists(data):
abort(400, message="Price missing")
if not check_if_time_data_exists(data):
abort(400, message="Time missing")
symbol = data['symbol']
price = data['price']
time = data['time']
share_price = SharePrice(
symbol=symbol,
price=price,
date=datetime.datetime.strptime(time, '%Y-%m-%dT%H:%M:%S.%fZ'),
)
db.session.add(share_price)
db.session.commit()
return make_response(share_price.as_dict(), 200, "Successfully added price")
def check_if_symbol_data_exists(data):
if 'symbol' not in data:
return False
if data['symbol'] == "" or data['symbol'] is None:
return False
return True
def check_if_price_data_exists(data):
if 'price' not in data:
return False
if data['price'] == "" or data['price'] is None:
return False
return True
def check_if_time_data_exists(data):
if 'time' not in data:
return False
if data['time'] == "" or data['time'] is None:
return False
return True

View File

@ -1,13 +1,13 @@
import os
import datetime import datetime
import os
from apiflask import abort, APIBlueprint from apiflask import abort, APIBlueprint
from app.auth import auth
from app.db import database as db from app.db import database as db
from app.helper_functions import make_response, get_email_or_abort_401 from app.helper_functions import make_response, get_email_or_abort_401
from app.models import Transaction from app.models import Transaction
from app.schema import TransactionSchema, TransactionResponseSchema from app.schema import TransactionSchema, TransactionResponseSchema
from app.auth import auth
transaction_blueprint = APIBlueprint('transaction', __name__, url_prefix='/api') transaction_blueprint = APIBlueprint('transaction', __name__, url_prefix='/api')
__location__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__))) __location__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__)))

View File

@ -51,3 +51,14 @@ class Share(db.Model):
def as_dict(self): def as_dict(self):
return {c.name: getattr(self, c.name) for c in self.__table__.columns} return {c.name: getattr(self, c.name) for c in self.__table__.columns}
class SharePrice(db.Model):
__tablename__ = 'share_price'
id = db.Column('id', db.Integer(), nullable=False, unique=True, primary_key=True)
symbol = db.Column('symbol', db.String(255))
price = db.Column('price', db.Float())
date = db.Column('date', db.DateTime())
def as_dict(self):
return {c.name: getattr(self, c.name) for c in self.__table__.columns}

View File

@ -75,6 +75,12 @@ class TransactionSchema(Schema):
price = Float() price = Float()
class SymbolPriceSchema(Schema):
symbol = String()
time = String(validate=validate.Regexp(r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z"))
price = Float()
class TelegramIdSchema(Schema): class TelegramIdSchema(Schema):
telegram_user_id = String() telegram_user_id = String()

View File

@ -1,9 +1,9 @@
import os
import random import random
import faker import faker
import requests import requests
url = 'http://127.0.0.1:5000/api'
username = '' username = ''
password = '' password = ''
@ -12,7 +12,7 @@ shares = ["TWTR", "GOOG", "AAPL", "MSFT", "AMZN", "FB", "NFLX", "TSLA", "BABA",
fake = faker.Faker() fake = faker.Faker()
token = requests.post(url + '/user/login', json={"email": username, "password": password}).json()['data']['token'] token = requests.post(os.getenv("API_URL") + '/user/login', json={"email": username, "password": password}).json()['data']['token']
for i in range(1, 1000): for i in range(1, 1000):
payload = { payload = {
@ -22,4 +22,4 @@ for i in range(1, 1000):
"time": fake.date_time().isoformat() + ".000Z" "time": fake.date_time().isoformat() + ".000Z"
} }
response = requests.post(url + '/transaction', json=payload, headers={'Authorization': 'Bearer ' + token}) response = requests.post(os.getenv("API_URL") + '/transaction', json=payload, headers={'Authorization': 'Bearer ' + token})

33
api/load_share_price.py Normal file
View File

@ -0,0 +1,33 @@
import datetime
import os
import threading
import requests
import yfinance
def thread_function(s):
my_share_info = yfinance.Ticker(s)
my_share_data = my_share_info.info
if my_share_data['regularMarketPrice'] is not None:
payload = {
"symbol": s,
"price": float(my_share_data['regularMarketPrice']),
"time": datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%S.000Z")
}
requests.post(os.getenv("API_URL") + '/symbol', json=payload, headers={'Authorization': 'Bearer ' + token})
username = os.getenv('ADMIN_EMAIL')
password = os.getenv('ADMIN_PASSWORD')
token = requests.post(os.getenv("API_URL") + '/user/login', json={"email": username, "password": password}).json()['data']['token']
response = requests.get(os.getenv("API_URL") + '/symbols', headers={'Authorization': 'Bearer ' + token}).json()['data']
for symbol in response:
x = threading.Thread(target=thread_function, args=(symbol,))
x.start()

View File

@ -11,4 +11,6 @@ bcrypt==3.2.0
pytest~=7.1.1 pytest~=7.1.1
pytest-cov pytest-cov
marshmallow~=3.15.0 marshmallow~=3.15.0
faker~=4.0.0 faker~=4.0.0
yfinance~=0.1.6
requests~=2.22.0