2022-03-29 07:26:50 +00:00
"""
script for communicating with webservice to get data from database
"""
__author__ = " Florian Kellermann, Linus Eickhoff "
2022-05-10 15:37:20 +00:00
__date__ = " 10.05.2022 "
2022-05-11 21:33:48 +00:00
__version__ = " 1.0.2 "
2022-03-29 07:26:50 +00:00
__license__ = " None "
2022-05-11 21:33:48 +00:00
# side-dependencies: none
# Work in Progress
2022-03-29 07:26:50 +00:00
import os
2022-05-11 21:33:48 +00:00
import sys
2022-03-29 07:26:50 +00:00
import requests as r
2022-05-11 21:33:48 +00:00
from croniter import croniter # used for checking cron formatting
2022-04-26 10:44:52 +00:00
from dotenv import load_dotenv
2022-05-11 21:33:48 +00:00
load_dotenv ( ) # loads environment vars
2022-03-29 07:26:50 +00:00
2022-04-25 16:50:29 +00:00
# note: for more information about the api visit swagger documentation on https://gruppe1.testsites.info/api/docs#/
2022-03-29 07:26:50 +00:00
class API_Handler :
""" class for interacting with the api webservice
Attributes :
db_adress ( string ) : adress of the database
token ( string ) : auth token for api
Methods :
reauthorize ( email , password ) : set new credentials
get_user_keywords ( user_id ) : gets the keywords of the user
set_keyword ( user_id , keyword ) : sets the keyword of the user
delete_keyword ( user_id , keyword ) : deletes the keyword of the user
get_user_shares ( user_id ) : gets the shares of the user
set_share ( user_id , symbol ) : sets the share of the user
delete_share ( user_id , symbol ) : deletes the share of the user
get_user_transactions ( user_id ) : gets the transactions of the user
set_transaction ( user_id , transaction ) : sets the transaction of the user
2022-04-17 09:57:28 +00:00
get_user_portfolio ( user_id ) : gets the portfolio of the user
set_portfolio ( user_id , portfolio ) : sets the portfolio of the user
delete_portfolio ( user_id , portfolio ) : deletes the portfolio of the user
set_cron_interval ( user_id , interval ) : sets the cron interval of the user
2022-04-25 17:56:41 +00:00
set_admin ( email , is_admin ) : sets the admin status of the user with the given email
2022-03-29 07:26:50 +00:00
"""
2022-05-11 21:33:48 +00:00
2022-03-29 07:26:50 +00:00
def __init__ ( self , db_adress , email , password ) :
""" initializes the API_Handler class
Args :
db_adress ( string ) : adress of the database
email ( string ) : email of the user
password ( string ) : password of the user
"""
self . db_adress = db_adress
2022-05-11 21:33:48 +00:00
payload = { ' email ' : email , ' password ' : password } # credentials for admin account that has all permissions to get and set data (in this case bot account)
with r . Session ( ) as s : # open session
p = s . post ( self . db_adress + " /user/login " , json = payload ) # login to webservice
2022-03-29 07:26:50 +00:00
if p . status_code == 200 :
2022-05-11 21:33:48 +00:00
self . token = p . json ( ) [ " data " ] [ ' token ' ] # store token for further authentication of requests
2022-03-29 07:26:50 +00:00
else :
print ( " Error: " + str ( p . status_code ) + " invalid credentials " )
self . token = None
2022-05-11 21:33:48 +00:00
def reauthorize ( self , email , password ) : # can be used if token expired
2022-03-29 07:26:50 +00:00
""" set new credentials
Args :
email ( string ) : email of the user
password ( string ) : password of the user
2022-05-10 07:55:41 +00:00
Returns :
token ( string ) : new token or None if not 200
Raises :
None
2022-03-29 07:26:50 +00:00
"""
payload = { ' email ' : email , ' password ' : password }
with r . Session ( ) as s :
p = s . post ( self . db_adress + " /user/login " , json = payload )
if p . status_code == 200 :
self . token = p . json ( ) [ " data " ] [ ' token ' ]
return p . json ( ) [ " data " ] [ ' token ' ]
else :
self . token = None
return None
2022-05-11 21:33:48 +00:00
def get_user ( self , user_id , max_retries = 10 ) : # max retries are used recursively if the request fails
2022-04-12 08:41:48 +00:00
""" gets the shares of the user
Args :
user_id ( int ) : id of the user
max_retries ( int ) : max retries for the request
Returns :
json : json of user infos
2022-05-10 07:55:41 +00:00
Raises :
None
2022-04-12 08:41:48 +00:00
"""
if max_retries < = 0 :
return None
with r . Session ( ) as s :
2022-05-11 21:33:48 +00:00
headers = { ' Authorization ' : ' Bearer ' + self . token + " : " + str ( user_id ) } # authorization is bot_token:user_id (user_id is the id of the user you want to get data from)
2022-04-12 08:41:48 +00:00
req = s . get ( self . db_adress + " /user " , headers = headers )
2022-05-11 21:33:48 +00:00
if ( req . status_code == 200 ) :
2022-04-12 08:41:48 +00:00
return req . json ( ) [ " data " ]
2022-05-11 21:33:48 +00:00
2022-04-12 08:41:48 +00:00
else :
2022-05-11 21:33:48 +00:00
return self . get_user ( user_id , max_retries - 1 ) # if request fails try again recursively
2022-04-12 08:41:48 +00:00
def get_all_users ( self , max_retries = 10 ) :
""" gets all users
Args :
max_retries ( int ) : max retries for the request
Returns :
list : list of users
2022-05-10 07:55:41 +00:00
Raises :
None
2022-04-12 08:41:48 +00:00
"""
if max_retries < = 0 :
return None
with r . Session ( ) as s :
headers = { ' Authorization ' : ' Bearer ' + self . token }
req = s . get ( self . db_adress + " /users " , headers = headers )
2022-05-11 21:33:48 +00:00
if ( req . status_code == 200 ) :
2022-04-12 08:41:48 +00:00
return req . json ( ) [ " data " ]
2022-05-11 21:33:48 +00:00
else :
return self . get_all_users ( max_retries - 1 )
2022-04-12 08:41:48 +00:00
2022-04-04 14:54:25 +00:00
def get_user_keywords ( self , user_id , max_retries = 10 ) :
2022-03-29 07:26:50 +00:00
""" gets the keywords of the user
Args :
user_id ( int ) : id of the user
2022-04-04 14:54:25 +00:00
max_retries ( int ) : max retries for the request
2022-03-29 07:26:50 +00:00
Returns :
list : list of keywords
2022-05-10 07:55:41 +00:00
Raises :
None
2022-03-29 07:26:50 +00:00
"""
2022-04-04 14:54:25 +00:00
if max_retries < = 0 :
return None
2022-05-11 21:33:48 +00:00
2022-03-29 10:04:49 +00:00
keywords = [ ]
2022-03-29 07:26:50 +00:00
with r . Session ( ) as s :
headers = { ' Authorization ' : ' Bearer ' + self . token + " : " + str ( user_id ) }
req = s . get ( self . db_adress + " /keywords " , headers = headers )
2022-05-11 21:33:48 +00:00
if ( req . status_code == 200 ) :
2022-03-29 10:04:49 +00:00
keywords_json = req . json ( ) [ " data " ]
2022-05-11 21:33:48 +00:00
for keyword in keywords_json : # keywords_json is a list of dictionaries
2022-03-29 10:04:49 +00:00
keywords . append ( keyword [ " keyword " ] )
2022-05-11 21:33:48 +00:00
return keywords # will be empty if no keywords are set
2022-03-29 10:04:49 +00:00
else :
2022-05-11 21:33:48 +00:00
return self . get_user_keywords ( user_id , max_retries - 1 )
2022-03-29 07:26:50 +00:00
def set_keyword ( self , user_id , keyword ) :
""" sets the keyword of the user
Args :
user_id ( int ) : id of the user
keyword ( int ) : keyword of the user
Returns :
int : status code
2022-05-10 07:55:41 +00:00
Raises :
None
2022-03-29 07:26:50 +00:00
"""
with r . Session ( ) as s :
headers = { ' Authorization ' : ' Bearer ' + self . token + " : " + str ( user_id ) }
req = s . post ( self . db_adress + " /keyword " , json = { " keyword " : keyword } , headers = headers )
2022-05-11 21:33:48 +00:00
return req . status_code
2022-03-29 07:26:50 +00:00
def delete_keyword ( self , user_id , keyword ) :
""" deletes the keyword of the user
Args :
user_id ( int ) : id of the user
keyword ( string ) : keyword of the user
Returns :
int : status code
2022-05-10 07:55:41 +00:00
Raises :
None
2022-03-29 07:26:50 +00:00
"""
with r . Session ( ) as s :
headers = { ' Authorization ' : ' Bearer ' + self . token + " : " + str ( user_id ) }
req = s . delete ( self . db_adress + " /keyword " , json = { " keyword " : keyword } , headers = headers )
2022-05-11 21:33:48 +00:00
return req . status_code
2022-03-29 07:26:50 +00:00
2022-04-04 14:54:25 +00:00
def get_user_shares ( self , user_id , max_retries = 10 ) :
2022-03-29 07:26:50 +00:00
""" gets the shares of the user
Args :
user_id ( int ) : id of the user
2022-04-04 14:54:25 +00:00
max_retries ( int ) : max retries for the request
2022-03-29 07:26:50 +00:00
Returns :
list : list of shares
2022-05-10 07:55:41 +00:00
Raises :
None
2022-03-29 07:26:50 +00:00
"""
2022-04-04 14:54:25 +00:00
if max_retries < = 0 :
return None
2022-03-29 07:26:50 +00:00
with r . Session ( ) as s :
headers = { ' Authorization ' : ' Bearer ' + self . token + " : " + str ( user_id ) }
req = s . get ( self . db_adress + " /shares " , headers = headers )
2022-05-11 21:33:48 +00:00
if ( req . status_code == 200 ) :
2022-04-04 14:54:25 +00:00
shares_json = req . json ( ) [ " data " ]
shares = [ ]
for share in shares_json :
2022-05-11 21:33:48 +00:00
shares . append ( share [ " isin " ] ) # we only want the isin of the shares
2022-03-29 07:26:50 +00:00
2022-04-04 14:54:25 +00:00
return shares
2022-03-29 07:26:50 +00:00
2022-05-11 21:33:48 +00:00
else :
return self . get_user_shares ( user_id , max_retries - 1 )
2022-03-29 07:26:50 +00:00
2022-04-25 16:50:29 +00:00
def set_share ( self , user_id , isin , comment ) :
2022-03-29 07:26:50 +00:00
""" sets the share of the user
Args :
user_id ( int ) : id of the user
2022-05-10 06:57:56 +00:00
isin ( string ) : identifier of the share ( standard is isin )
2022-04-25 16:50:29 +00:00
comment ( string ) : comment of the share
2022-03-29 07:26:50 +00:00
Returns :
int : status code
2022-05-10 07:55:41 +00:00
Raises :
None
2022-03-29 07:26:50 +00:00
"""
with r . Session ( ) as s :
headers = { ' Authorization ' : ' Bearer ' + self . token + " : " + str ( user_id ) }
2022-05-11 21:33:48 +00:00
req = s . post ( self . db_adress + " /share " , json = { " comment " : comment , " isin " : isin } ,
headers = headers ) # set share by setting comment and isin, comment can be the real name of the share e.g. "Apple Inc."
2022-03-29 07:26:50 +00:00
return req . status_code
2022-04-25 16:50:29 +00:00
def delete_share ( self , user_id , isin ) :
2022-03-29 07:26:50 +00:00
""" deletes the share of the user
Args :
user_id ( int ) : id of the user
2022-05-10 06:57:56 +00:00
isin ( string ) : identifier of the share ( standard is isin )
2022-03-29 07:26:50 +00:00
Returns :
int : status code
2022-05-10 07:55:41 +00:00
Raises :
None
2022-03-29 07:26:50 +00:00
"""
with r . Session ( ) as s :
headers = { ' Authorization ' : ' Bearer ' + self . token + " : " + str ( user_id ) }
2022-05-11 21:33:48 +00:00
req = s . delete ( self . db_adress + " /share " , json = { " isin " : str ( isin ) } , headers = headers ) # to delete a share only the isin is needed because it is unique, shares are not transactions!
2022-03-29 07:26:50 +00:00
return req . status_code
2022-04-04 14:54:25 +00:00
def get_user_transactions ( self , user_id , max_retries = 10 ) :
2022-03-29 07:26:50 +00:00
""" gets the transactions of the user
Args :
user_id ( int ) : id of the user
2022-04-04 14:54:25 +00:00
max_retries ( int ) : max retries for the request
2022-03-29 07:26:50 +00:00
Returns :
dict : dictionary of transactions
2022-05-10 07:55:41 +00:00
Raises :
None
2022-03-29 07:26:50 +00:00
"""
2022-04-04 14:54:25 +00:00
if max_retries < = 0 :
return None
2022-03-29 07:26:50 +00:00
with r . Session ( ) as s :
headers = { ' Authorization ' : ' Bearer ' + self . token + " : " + str ( user_id ) }
req = s . get ( self . db_adress + " /transactions " , headers = headers )
2022-03-29 10:04:49 +00:00
if req . status_code == 200 :
2022-04-17 09:21:49 +00:00
transactions_dict = req . json ( ) [ " data " ]
2022-03-29 10:04:49 +00:00
return transactions_dict
2022-04-04 14:54:25 +00:00
else :
2022-05-11 21:33:48 +00:00
return self . get_user_transactions ( user_id , max_retries - 1 )
2022-03-29 07:26:50 +00:00
2022-04-19 19:36:16 +00:00
def set_transaction ( self , user_id , comment , isin , count , price , time ) :
2022-03-29 07:26:50 +00:00
""" sets the transaction of the user
Args :
user_id ( int ) : id of the user
2022-04-19 19:36:16 +00:00
comment ( string ) : comment of the transaction
isin ( string ) : isin of the transaction
2022-04-25 16:50:29 +00:00
count ( float ) : count of the transaction
2022-03-29 07:26:50 +00:00
price ( float ) : price of the transaction
2022-04-25 16:50:29 +00:00
time ( string ) : time of the transaction formatted like e . g . " 2011-10-05T14:48:00.000Z "
2022-03-29 07:26:50 +00:00
Returns :
int : status code
2022-05-10 07:55:41 +00:00
Raises :
None
2022-03-29 07:26:50 +00:00
"""
with r . Session ( ) as s :
2022-05-11 21:33:48 +00:00
time = time [ : - 3 ] + " Z " # remove last character and add Z to make it a valid date for db
2022-03-29 07:26:50 +00:00
headers = { ' Authorization ' : ' Bearer ' + self . token + " : " + str ( user_id ) }
2022-05-11 21:33:48 +00:00
transaction = { " comment " : str ( comment ) , " count " : float ( count ) , " isin " : str ( isin ) , " price " : float ( price ) ,
" time " : str ( time ) } # set transaction as JSON with all the attributes needed according to Swagger docs
2022-03-29 07:26:50 +00:00
req = s . post ( self . db_adress + " /transaction " , json = transaction , headers = headers )
return req . status_code
2022-04-04 14:54:25 +00:00
def get_user_portfolio ( self , user_id , max_retries = 10 ) :
2022-03-29 07:26:50 +00:00
""" gets the portfolio of the user
Args :
user_id ( int ) : id of the user
2022-04-04 14:54:25 +00:00
max_retries ( int ) : max retries for the request
2022-03-29 07:26:50 +00:00
Returns :
dict : dictionary of portfolio
2022-05-10 07:55:41 +00:00
Raises :
None
2022-03-29 07:26:50 +00:00
"""
2022-04-04 14:54:25 +00:00
if max_retries < = 0 :
return None
2022-03-29 07:26:50 +00:00
with r . Session ( ) as s :
headers = { ' Authorization ' : ' Bearer ' + self . token + " : " + str ( user_id ) }
2022-05-11 21:33:48 +00:00
req = s . get ( self . db_adress + " /portfolio " , headers = headers ) # get portfolio as JSON
2022-04-04 14:54:25 +00:00
if req . status_code == 200 :
2022-05-11 21:33:48 +00:00
portfolio_dict = req . json ( ) [ " data " ] # get the data of the JSON
2022-04-04 14:54:25 +00:00
return portfolio_dict
else :
2022-05-11 21:33:48 +00:00
return self . get_user_portfolio ( user_id , max_retries - 1 )
2022-04-12 08:08:41 +00:00
def set_cron_interval ( self , user_id , cron_interval ) :
""" sets the cron interval of the user
2022-03-29 07:26:50 +00:00
2022-04-12 08:08:41 +00:00
Args :
user_id ( int ) : id of the user
cron_interval ( String ) : Update interval in cron format = > see https : / / crontab . guru / for formatting
Returns :
int : status code
2022-05-10 07:55:41 +00:00
Raises :
None
2022-04-12 08:08:41 +00:00
"""
2022-05-11 21:33:48 +00:00
if not croniter . is_valid ( cron_interval ) : # check if cron_interval is in valid format
2022-04-17 10:20:53 +00:00
print ( " Error: Invalid cron format " )
2022-05-11 21:33:48 +00:00
return - 1 # return error code -1 if invalid cron format
2022-04-17 10:20:53 +00:00
2022-04-12 08:08:41 +00:00
with r . Session ( ) as s :
headers = { ' Authorization ' : ' Bearer ' + self . token + " : " + str ( user_id ) }
2022-05-11 21:33:48 +00:00
req = s . put ( self . db_adress + " /user/setCron " , json = { " cron " : str ( cron_interval ) } , headers = headers ) # put not post (see swagger docs)
2022-04-12 08:08:41 +00:00
return req . status_code
2022-03-29 07:26:50 +00:00
2022-04-25 17:56:41 +00:00
def set_admin ( self , email , is_admin ) :
""" sets the admin of the user
Args :
email ( string ) : email of the user
2022-04-26 10:21:37 +00:00
is_admin ( bool ) : " true " if user should be Admin , " false " if not
2022-04-25 17:56:41 +00:00
Returns :
int : status code
2022-05-10 07:55:41 +00:00
Raises :
None
2022-04-25 17:56:41 +00:00
"""
with r . Session ( ) as s :
2022-05-11 21:33:48 +00:00
headers = { ' Authorization ' : ' Bearer ' + self . token } # only bot token is needed, user is chosen by email
req = s . put ( self . db_adress + " /user/setAdmin " , json = { " admin " : is_admin , " email " : str ( email ) } , headers = headers )
2022-04-25 17:56:41 +00:00
return req . status_code
2022-05-11 21:33:48 +00:00
if __name__ == " __main__ " : # editable, just for basic on the go testing of new functions
2022-03-29 07:26:50 +00:00
print ( " This is a module for the telegram bot. It is not intended to be run directly. " )
2022-05-11 21:33:48 +00:00
handler = API_Handler ( " https://gruppe1.testsites.info/api " , str ( os . getenv ( " BOT_EMAIL " ) ) , str ( os . getenv ( " BOT_PASSWORD " ) ) ) # get creds from env
2022-03-29 07:26:50 +00:00
print ( handler . token )
2022-05-11 21:33:48 +00:00
keywords = handler . get_user_keywords ( user_id = 1709356058 ) # user_id here is currently mine (Linus)
2022-03-29 07:26:50 +00:00
print ( keywords )
2022-05-11 21:33:48 +00:00
shares = handler . get_user_portfolio ( user_id = 1709356058 )
print ( " set cron with status: " + str ( handler . set_cron_interval ( user_id = 1709356058 , cron_interval = " 0 0 * * * " ) ) )
user = handler . get_user ( user_id = 1709356058 )
2022-04-12 09:33:21 +00:00
print ( user )
all_users = handler . get_all_users ( )
2022-04-25 17:56:41 +00:00
admin_status = handler . set_admin ( " test@test.com " , " true " )
print ( admin_status )
2022-04-12 09:33:21 +00:00
print ( all_users )
2022-04-04 14:38:15 +00:00
print ( shares )
2022-05-11 21:33:48 +00:00
sys . exit ( 1 )