afgutils 1.0.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- afgutils-1.0.6/PKG-INFO +10 -0
- afgutils-1.0.6/afgutils/__init__.py +10 -0
- afgutils-1.0.6/afgutils/advanceai_util.py +21 -0
- afgutils-1.0.6/afgutils/credolab.py +68 -0
- afgutils-1.0.6/afgutils/db.py +93 -0
- afgutils-1.0.6/afgutils/email.py +23 -0
- afgutils-1.0.6/afgutils/s3.py +41 -0
- afgutils-1.0.6/afgutils/trandata.py +134 -0
- afgutils-1.0.6/afgutils/utils.py +132 -0
- afgutils-1.0.6/afgutils.egg-info/PKG-INFO +10 -0
- afgutils-1.0.6/afgutils.egg-info/SOURCES.txt +14 -0
- afgutils-1.0.6/afgutils.egg-info/dependency_links.txt +1 -0
- afgutils-1.0.6/afgutils.egg-info/requires.txt +6 -0
- afgutils-1.0.6/afgutils.egg-info/top_level.txt +1 -0
- afgutils-1.0.6/setup.cfg +4 -0
- afgutils-1.0.6/setup.py +24 -0
afgutils-1.0.6/PKG-INFO
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import atexit
|
|
2
|
+
from dotenv import load_dotenv as _load_dotenv
|
|
3
|
+
from .db import DB, sql
|
|
4
|
+
from .email import send_email
|
|
5
|
+
from .s3 import save_to_s3, get_from_s3
|
|
6
|
+
from .utils import *
|
|
7
|
+
from .trandata import *
|
|
8
|
+
|
|
9
|
+
_load_dotenv()
|
|
10
|
+
atexit.register(DB.close_connections)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from os import getenv
|
|
2
|
+
from datetime import datetime, timezone
|
|
3
|
+
import hashlib
|
|
4
|
+
import json
|
|
5
|
+
import requests
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def generate_token() -> str:
|
|
9
|
+
access_key = getenv("advanceai_access_key")
|
|
10
|
+
secret_key = getenv("advanceai_secret_key")
|
|
11
|
+
utc_now = datetime.now(timezone.utc)
|
|
12
|
+
time_epoch_now = int(utc_now.timestamp()*1000)
|
|
13
|
+
signature = hashlib.sha256(f"{access_key}{secret_key}{time_epoch_now}".encode()).hexdigest()
|
|
14
|
+
|
|
15
|
+
token_url = "https://sg-api.advance.ai/openapi/auth/ticket/v1/generate-token"
|
|
16
|
+
token_body = json.dumps({'accessKey': access_key,
|
|
17
|
+
'signature': signature,
|
|
18
|
+
'timestamp': time_epoch_now})
|
|
19
|
+
token_headers = {'Content-Type': 'application/json'}
|
|
20
|
+
token_response = requests.post(token_url, headers=token_headers, data=token_body)
|
|
21
|
+
return token_response.json()['data']['token']
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
from os import getenv
|
|
2
|
+
from afgutils.db import DB
|
|
3
|
+
import requests
|
|
4
|
+
from datetime import datetime
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class CredoLab:
|
|
8
|
+
GET_TOKEN_QUERY = """
|
|
9
|
+
SELECT * FROM credolab.token ORDER BY id DESC LIMIT 1;
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
INSERT_TOKEN_QUERY = """
|
|
13
|
+
INSERT INTO credolab.token (access_token, token_type, issued, expires, refresh_token)
|
|
14
|
+
VALUES (?, ?, ?, ?, ?);
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
def __init__(self):
|
|
18
|
+
self.email = getenv('credolab_user_email')
|
|
19
|
+
self.password = getenv('credolab_password')
|
|
20
|
+
self.token = None
|
|
21
|
+
self.rep_conn = DB.get_connection('rep')
|
|
22
|
+
self.service_url = getenv('credolab_base_url')
|
|
23
|
+
|
|
24
|
+
def get_token(self):
|
|
25
|
+
if self.token is None:
|
|
26
|
+
self.token = self._get_token()
|
|
27
|
+
return self.token
|
|
28
|
+
|
|
29
|
+
def _get_token(self):
|
|
30
|
+
with self.rep_conn.cursor() as cursor:
|
|
31
|
+
token_details = DB.execute(cursor, self.GET_TOKEN_QUERY, fetch='one')
|
|
32
|
+
|
|
33
|
+
if token_details is None or token_details['expires'] < datetime.utcnow():
|
|
34
|
+
token = self._fetch_token()
|
|
35
|
+
else:
|
|
36
|
+
token = token_details['access_token']
|
|
37
|
+
|
|
38
|
+
return token
|
|
39
|
+
|
|
40
|
+
def _fetch_token(self):
|
|
41
|
+
url = f'{self.service_url}/v6.0/account/login'
|
|
42
|
+
payload = {'userEmail': self.email, 'password': self.password}
|
|
43
|
+
response = requests.post(url, json=payload)
|
|
44
|
+
if response.status_code != 200:
|
|
45
|
+
raise Exception(f'Failed to fetch token from CredoLab: {response.text}')
|
|
46
|
+
token_details = response.json()
|
|
47
|
+
self._save_token(token_details)
|
|
48
|
+
return token_details['access_token']
|
|
49
|
+
|
|
50
|
+
def _save_token(self, token: dict) -> None:
|
|
51
|
+
|
|
52
|
+
with self.rep_conn.cursor() as cursor:
|
|
53
|
+
DB.execute(cursor, self.INSERT_TOKEN_QUERY,
|
|
54
|
+
parameters=(token['access_token'], token['token_type'], token['.issued'],
|
|
55
|
+
token['.expires'], token['refresh_token']))
|
|
56
|
+
self.rep_conn.commit()
|
|
57
|
+
return token['access_token']
|
|
58
|
+
|
|
59
|
+
def _refresh_token(self, bearer_token: str, refresh_token: str) -> str:
|
|
60
|
+
url = f'{self.service_url}/v6.0/account/login/refreshToken'
|
|
61
|
+
payload = {'refreshToken': refresh_token}
|
|
62
|
+
headers = {'Authorization': f'Bearer {bearer_token}'}
|
|
63
|
+
response = requests.post(url, json=payload)
|
|
64
|
+
if response.status_code != 200:
|
|
65
|
+
raise Exception(f'Failed to refresh token from CredoLab: {response.text}')
|
|
66
|
+
token_details = response.json()
|
|
67
|
+
self._save_token(token_details)
|
|
68
|
+
return token_details['access_token']
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
from os import getenv
|
|
2
|
+
import pyodbc
|
|
3
|
+
from pyodbc import Cursor
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class DB:
|
|
7
|
+
__connections = {}
|
|
8
|
+
|
|
9
|
+
@classmethod
|
|
10
|
+
def get_connection(cls, db_name: str):
|
|
11
|
+
if cls.__connections.get(db_name):
|
|
12
|
+
return cls.__connections.get(db_name)
|
|
13
|
+
return cls._create_connection(db_name)
|
|
14
|
+
|
|
15
|
+
@classmethod
|
|
16
|
+
def _create_connection(cls, db_name):
|
|
17
|
+
prefix = db_name
|
|
18
|
+
|
|
19
|
+
dsn = getenv(prefix + '_dsn')
|
|
20
|
+
|
|
21
|
+
driver = getenv(prefix + '_driver')
|
|
22
|
+
database = getenv(prefix + '_db')
|
|
23
|
+
user = getenv(prefix + '_user')
|
|
24
|
+
password = getenv(prefix + '_pass')
|
|
25
|
+
server = getenv(prefix + '_host')
|
|
26
|
+
port = getenv(prefix + '_port')
|
|
27
|
+
|
|
28
|
+
if dsn:
|
|
29
|
+
conn_str = f"DSN={dsn}"
|
|
30
|
+
elif prefix and driver and driver and user and password and server and port:
|
|
31
|
+
conn_str = (
|
|
32
|
+
f"DRIVER={driver};"
|
|
33
|
+
f"DATABASE={database};"
|
|
34
|
+
f"UID={user};"
|
|
35
|
+
f"PWD={password};"
|
|
36
|
+
f"SERVER={server};"
|
|
37
|
+
f"PORT={port};"
|
|
38
|
+
)
|
|
39
|
+
else:
|
|
40
|
+
raise ValueError(f"DB configurations could not be found for {db_name}")
|
|
41
|
+
|
|
42
|
+
conn = pyodbc.connect(conn_str)
|
|
43
|
+
cls.__connections[db_name] = conn
|
|
44
|
+
return conn
|
|
45
|
+
|
|
46
|
+
@classmethod
|
|
47
|
+
def close_connections(cls):
|
|
48
|
+
# print("Connections are closed")
|
|
49
|
+
for key in cls.__connections:
|
|
50
|
+
cls.__connections[key].close()
|
|
51
|
+
cls.__connections = {}
|
|
52
|
+
|
|
53
|
+
@staticmethod
|
|
54
|
+
def execute(cursor: Cursor, query: str, fetch=None, parameters=None, commit: bool=False):
|
|
55
|
+
# Execute the query
|
|
56
|
+
if parameters:
|
|
57
|
+
cursor.execute(query, parameters)
|
|
58
|
+
else:
|
|
59
|
+
cursor.execute(query)
|
|
60
|
+
if commit:
|
|
61
|
+
cursor.connection.commit()
|
|
62
|
+
|
|
63
|
+
if cursor.rowcount and fetch:
|
|
64
|
+
# Fetch the rows
|
|
65
|
+
if fetch == 'all':
|
|
66
|
+
rows = cursor.fetchall()
|
|
67
|
+
else:
|
|
68
|
+
rows = cursor.fetchone()
|
|
69
|
+
|
|
70
|
+
index_map = {index: column[0] for index, column in enumerate(cursor.description)}
|
|
71
|
+
if type(rows) == list:
|
|
72
|
+
dict_rows = []
|
|
73
|
+
for row in rows:
|
|
74
|
+
new_row = {index_map[index]: value for index, value in enumerate(row)}
|
|
75
|
+
dict_rows.append(new_row)
|
|
76
|
+
return dict_rows
|
|
77
|
+
else:
|
|
78
|
+
return {index_map[index]: value for index, value in enumerate(rows)}
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def sql(sql_name, sql_version, sql_custom_folder=None):
|
|
82
|
+
if sql_custom_folder:
|
|
83
|
+
afg_sqls_folder = sql_custom_folder
|
|
84
|
+
else:
|
|
85
|
+
afg_sqls_folder = getenv("afg_sqls_folder")
|
|
86
|
+
|
|
87
|
+
sql_filename = afg_sqls_folder + sql_name + "/" + sql_name + "." + str(sql_version).zfill(3) + ".sql"
|
|
88
|
+
|
|
89
|
+
sql_file = open(sql_filename, "r")
|
|
90
|
+
sql_text = sql_file.read()
|
|
91
|
+
sql_file.close()
|
|
92
|
+
|
|
93
|
+
return sql_text
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from os import getenv
|
|
2
|
+
import win32com.client as win32
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def send_email(to: str = None, subject: str = None, message: str = "Empty Message"):
|
|
6
|
+
# initial check
|
|
7
|
+
if to is None and getenv('mail_to') is None:
|
|
8
|
+
raise Exception("to should be passed as parameter or defined as env variable as mail_to")
|
|
9
|
+
if to is None and getenv('mail_to'):
|
|
10
|
+
to = getenv('mail_to')
|
|
11
|
+
outlook = win32.Dispatch('outlook.application')
|
|
12
|
+
mail = outlook.CreateItem(0)
|
|
13
|
+
mail.To = to
|
|
14
|
+
mail.Body = message
|
|
15
|
+
|
|
16
|
+
# To send html content
|
|
17
|
+
# mail.HTMLBody = '<h2>HTML Message body</h2>'
|
|
18
|
+
|
|
19
|
+
# To attach a file to the email (optional):
|
|
20
|
+
# attachment = "Path to the attachment"
|
|
21
|
+
# mail.Attachments.Add(attachment)
|
|
22
|
+
|
|
23
|
+
mail.Send()
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import boto3
|
|
2
|
+
from os import getenv as _getenv
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def save_to_s3(s3_key: str, content_body: str, aws_access_key_id=None,
|
|
6
|
+
aws_secret_access_key=None, aws_region=None, s3_bucket=None):
|
|
7
|
+
if aws_access_key_id is None: aws_access_key_id = _getenv('aws_access_key_id')
|
|
8
|
+
if aws_secret_access_key is None: aws_secret_access_key = _getenv('aws_secret_access_key')
|
|
9
|
+
if aws_region is None: aws_region = _getenv('aws_region')
|
|
10
|
+
if s3_bucket is None: s3_bucket = _getenv('s3_bucket_risk')
|
|
11
|
+
|
|
12
|
+
s3_client = boto3.client('s3'
|
|
13
|
+
, aws_access_key_id=aws_access_key_id
|
|
14
|
+
, aws_secret_access_key=aws_secret_access_key
|
|
15
|
+
, region_name=aws_region)
|
|
16
|
+
s3_client.put_object(Bucket=s3_bucket
|
|
17
|
+
, Body=content_body
|
|
18
|
+
, Key=s3_key
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def get_from_s3(s3_key, filename, aws_access_key_id=None, aws_secret_access_key=None, aws_region=None, s3_bucket=None):
|
|
23
|
+
if aws_access_key_id is None: aws_access_key_id = _getenv('aws_access_key_id')
|
|
24
|
+
if aws_secret_access_key is None: aws_secret_access_key = _getenv('aws_secret_access_key')
|
|
25
|
+
if aws_region is None: aws_region = _getenv('aws_region_name')
|
|
26
|
+
if s3_bucket is None: s3_bucket = _getenv('s3_bucket_lms')
|
|
27
|
+
|
|
28
|
+
s3_client = boto3.client(
|
|
29
|
+
's3',
|
|
30
|
+
aws_access_key_id=aws_access_key_id,
|
|
31
|
+
aws_secret_access_key=aws_secret_access_key,
|
|
32
|
+
region_name=aws_region
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
s3_result = s3_client.download_file(
|
|
36
|
+
Bucket=s3_bucket,
|
|
37
|
+
Key=s3_key,
|
|
38
|
+
Filename=filename
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
return s3_result
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import random
|
|
2
|
+
from .db import DB, sql
|
|
3
|
+
from os import getenv
|
|
4
|
+
import requests
|
|
5
|
+
import string
|
|
6
|
+
|
|
7
|
+
trandata_auth_url = "https://api.trandata.io/account/unauth/v1/login"
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# VARS INIT
|
|
11
|
+
# trandata_select_token_query = """
|
|
12
|
+
# SELECT token from kr.token
|
|
13
|
+
# WHERE created_at > now() - interval '23 HOURS'
|
|
14
|
+
# ORDER BY created_at desc limit 1
|
|
15
|
+
# """
|
|
16
|
+
#
|
|
17
|
+
# trandata_insert_token_query = """INSERT INTO kr.token(token) VALUES (?)"""
|
|
18
|
+
# trandata_lms_query = """
|
|
19
|
+
# SELECT lar.client_id,
|
|
20
|
+
# c.firstname AS client_firstname,
|
|
21
|
+
# c.lastname AS client_lastname,
|
|
22
|
+
# c.date_of_birth AS client_dob,
|
|
23
|
+
# c.mobile_no AS client_mobile,
|
|
24
|
+
# c.email_id AS client_email,
|
|
25
|
+
# ci.document_key AS pan_number,
|
|
26
|
+
# fd.firstname AS client_father_name,
|
|
27
|
+
# ad.address_line_one AS client_res_address,
|
|
28
|
+
# ad.district_name AS client_res_vilage,
|
|
29
|
+
# ad.district_name AS client_res_city,
|
|
30
|
+
# 'xxx' AS client_res_state,
|
|
31
|
+
# ad.postal_code AS client_res_pincode,
|
|
32
|
+
# 'vietnam' AS client_res_country,
|
|
33
|
+
# bad.account_number AS client_bank_acc,
|
|
34
|
+
# ci.document_key as national_id
|
|
35
|
+
# FROM f_loan_application_reference lar
|
|
36
|
+
# LEFT JOIN f_bank_account_detail_associations bada ON bada.entity_id = lar.client_id AND bada.entity_type_enum = 1
|
|
37
|
+
# LEFT JOIN f_bank_account_details bad ON bad.id = bada.bank_account_detail_id -- bank account
|
|
38
|
+
# LEFT JOIN m_client c ON c.id = lar.client_id
|
|
39
|
+
# LEFT JOIN m_client_identifier ci ON ci.client_id = c.id AND ci.document_type_id = 303
|
|
40
|
+
# LEFT JOIN f_address_entity ae ON ae.entity_id = c.id AND ae.entity_type_enum =1 AND ae.address_type = 14
|
|
41
|
+
# LEFT JOIN f_address ad ON ad.id = ae.address_id
|
|
42
|
+
# LEFT JOIN f_family_details as fd ON fd.client_id = c.id AND fd.relationship_cv_id = 20
|
|
43
|
+
# WHERE lar.loan_application_reference_no=? LIMIT 1
|
|
44
|
+
# """
|
|
45
|
+
|
|
46
|
+
# MAIN CODE
|
|
47
|
+
|
|
48
|
+
# SQLS
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
# FUNCS
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
# Trandata
|
|
58
|
+
def trandata_update_token():
|
|
59
|
+
"""
|
|
60
|
+
Get log in and parse the Authentication Token.
|
|
61
|
+
:return: token
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
rep_conn = DB.get_connection('repserv')
|
|
65
|
+
rep_cursor = rep_conn.cursor()
|
|
66
|
+
|
|
67
|
+
username = getenv("trandata_username")
|
|
68
|
+
password = getenv("trandata_password")
|
|
69
|
+
|
|
70
|
+
url = trandata_auth_url
|
|
71
|
+
payload = "{\n \"username\": \"" + username + "\",\n \"password\": \"" + password + "\"\n}"
|
|
72
|
+
headers = {
|
|
73
|
+
'Content-Type': 'application/json'
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
response = requests.request("POST", url, headers=headers, data=payload)
|
|
77
|
+
|
|
78
|
+
if 300 > response.status_code >= 200:
|
|
79
|
+
data = response.json()
|
|
80
|
+
token = data["Data"]["sessionToken"]
|
|
81
|
+
|
|
82
|
+
DB.execute(
|
|
83
|
+
cursor=rep_cursor,
|
|
84
|
+
query=sql("trandata_insert_token_query", 1),
|
|
85
|
+
parameters=(token,)
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
rep_cursor.commit()
|
|
89
|
+
rep_cursor.close()
|
|
90
|
+
|
|
91
|
+
return token
|
|
92
|
+
|
|
93
|
+
raise ValueError(response.text)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def trandata_get_token():
|
|
97
|
+
rep_conn = DB.get_connection('repserv')
|
|
98
|
+
rep_cursor = rep_conn.cursor()
|
|
99
|
+
|
|
100
|
+
token_res = DB.execute(
|
|
101
|
+
cursor=rep_cursor,
|
|
102
|
+
query=sql("trandata_select_token_query", 1),
|
|
103
|
+
fetch='one'
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
rep_cursor.close()
|
|
107
|
+
|
|
108
|
+
if not token_res:
|
|
109
|
+
token = trandata_update_token()
|
|
110
|
+
|
|
111
|
+
return token
|
|
112
|
+
|
|
113
|
+
return token_res["token"]
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
# print(trandata_get_token())
|
|
117
|
+
|
|
118
|
+
def trandata_gen_req_id(appl_ref):
|
|
119
|
+
ran_text = ''.join(random.choices(string.ascii_letters + string.digits, k=16))
|
|
120
|
+
result = appl_ref + "_" + ran_text
|
|
121
|
+
return result
|
|
122
|
+
|
|
123
|
+
# def trandata_save2boto3(acc_key_id, sec_acc_key, region, response_text, bucket, key):
|
|
124
|
+
# s3_client = boto3.client(
|
|
125
|
+
# 's3',
|
|
126
|
+
# aws_access_key_id=acc_key_id,
|
|
127
|
+
# aws_secret_access_key=sec_acc_key,
|
|
128
|
+
# region_name=region
|
|
129
|
+
# )
|
|
130
|
+
# s3_client.put_object(
|
|
131
|
+
# Bucket=bucket,
|
|
132
|
+
# Body=response_text,
|
|
133
|
+
# Key=key
|
|
134
|
+
# )
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import time
|
|
2
|
+
from os import environ
|
|
3
|
+
from .db import DB, sql
|
|
4
|
+
from pandas import json_normalize
|
|
5
|
+
from pandas import DataFrame
|
|
6
|
+
|
|
7
|
+
session_token_cookie_name = "uwtool_session_token"
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def print_log(log_line):
|
|
11
|
+
print(time.strftime('%Y-%m-%d %H:%M:%S'), log_line)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def ci(cursor, column_name):
|
|
15
|
+
column_index_cnt = -1
|
|
16
|
+
column_index = -1
|
|
17
|
+
for column in cursor.description:
|
|
18
|
+
column_index_cnt = column_index_cnt + 1
|
|
19
|
+
if column[0] == column_name:
|
|
20
|
+
column_index = column_index_cnt
|
|
21
|
+
break
|
|
22
|
+
if column_index == -1:
|
|
23
|
+
raise SystemExit("ERROR: Column index not found for column: " + column_name)
|
|
24
|
+
return column_index
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def nvl(s, d):
|
|
28
|
+
if s is None:
|
|
29
|
+
return d
|
|
30
|
+
else:
|
|
31
|
+
return s
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def iif(bool_val, ret_true, ret_false):
|
|
35
|
+
if bool_val:
|
|
36
|
+
aaa = ret_true
|
|
37
|
+
else:
|
|
38
|
+
aaa = ret_false
|
|
39
|
+
return aaa
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def isnullorempty(v):
|
|
43
|
+
if v is None:
|
|
44
|
+
return True
|
|
45
|
+
if type(v) == str:
|
|
46
|
+
v = v.strip()
|
|
47
|
+
if len(v) == 0:
|
|
48
|
+
return True
|
|
49
|
+
return False
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def clear_mfv(mfv):
|
|
53
|
+
if type(mfv) == dict:
|
|
54
|
+
for i in mfv.keys():
|
|
55
|
+
mfv[i] = None
|
|
56
|
+
return mfv
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def get_username():
|
|
60
|
+
conn_repserv = DB.get_connection('repserv')
|
|
61
|
+
cursor_repserv = conn_repserv.cursor()
|
|
62
|
+
|
|
63
|
+
username = None
|
|
64
|
+
|
|
65
|
+
if 'HTTP_COOKIE' in environ:
|
|
66
|
+
for cookie in map(str.strip, environ['HTTP_COOKIE'].split(';')):
|
|
67
|
+
key, value = cookie.split('=')
|
|
68
|
+
if key == session_token_cookie_name:
|
|
69
|
+
uwtool_session_token = value
|
|
70
|
+
result = DB.execute(cursor=cursor_repserv,
|
|
71
|
+
query=sql("find_session", 2),
|
|
72
|
+
fetch='one',
|
|
73
|
+
parameters=uwtool_session_token)
|
|
74
|
+
if result: # can be replaced by "if cursor_repserv.rowcount"
|
|
75
|
+
username = result['username']
|
|
76
|
+
DB.execute(cursor_repserv, sql("update_session", 1), None, (uwtool_session_token, username))
|
|
77
|
+
cursor_repserv.commit()
|
|
78
|
+
|
|
79
|
+
cursor_repserv.close()
|
|
80
|
+
|
|
81
|
+
return username
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def data_vector_to_sql_insert(data_vector: dict | DataFrame, insert_sql_tpl: str = None,
|
|
85
|
+
existing_values: list = None) -> (list, str):
|
|
86
|
+
column_names_insert_text = ""
|
|
87
|
+
item_values = []
|
|
88
|
+
|
|
89
|
+
# convert data vector into a list
|
|
90
|
+
if isinstance(data_vector, DataFrame):
|
|
91
|
+
for column_name in data_vector.columns.tolist():
|
|
92
|
+
column_names_insert_text = (column_names_insert_text + "," + column_name + "\r\n").replace(".", "_")
|
|
93
|
+
item_values.append(data_vector.loc[0, column_name])
|
|
94
|
+
|
|
95
|
+
elif type(data_vector) is dict:
|
|
96
|
+
pass
|
|
97
|
+
|
|
98
|
+
else:
|
|
99
|
+
raise TypeError("data_vector_to_sql_insert: data_vector must be a pandas.DataFrame or a dictionary")
|
|
100
|
+
|
|
101
|
+
# text-serialize any embedded lists or dictionaries
|
|
102
|
+
item_values = [str(item_value) if type(item_value) in (list, dict) else item_value for item_value in item_values]
|
|
103
|
+
# convert any string booleans to actual booleans
|
|
104
|
+
item_values = [_convert_string_to_boolean(item_value) if type(item_value) is str else item_value for item_value in
|
|
105
|
+
item_values]
|
|
106
|
+
|
|
107
|
+
# combine existing values with new values
|
|
108
|
+
if type(existing_values) is list:
|
|
109
|
+
result_items = existing_values + item_values
|
|
110
|
+
elif existing_values is None:
|
|
111
|
+
result_items = item_values
|
|
112
|
+
else:
|
|
113
|
+
raise TypeError("data_vector_to_sql_insert: existing_values must be a list or None")
|
|
114
|
+
|
|
115
|
+
# generate SQL
|
|
116
|
+
if type(insert_sql_tpl) is str:
|
|
117
|
+
result_sql = insert_sql_tpl.format(column_names_insert_text, f"{', ?' * len(item_values)}")
|
|
118
|
+
elif insert_sql_tpl is None:
|
|
119
|
+
result_sql = column_names_insert_text
|
|
120
|
+
else:
|
|
121
|
+
raise TypeError("data_vector_to_sql_insert: insert_sql_tpl must be a string or None")
|
|
122
|
+
|
|
123
|
+
return result_items, result_sql
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def _convert_string_to_boolean(s: str) -> bool:
|
|
127
|
+
if s.lower() in ('true', 't', '1', 'y', 'yes'):
|
|
128
|
+
return True
|
|
129
|
+
elif s.lower() in ('false', 'f', '0', 'n', 'no'):
|
|
130
|
+
return False
|
|
131
|
+
else:
|
|
132
|
+
return s
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
setup.py
|
|
2
|
+
afgutils/__init__.py
|
|
3
|
+
afgutils/advanceai_util.py
|
|
4
|
+
afgutils/credolab.py
|
|
5
|
+
afgutils/db.py
|
|
6
|
+
afgutils/email.py
|
|
7
|
+
afgutils/s3.py
|
|
8
|
+
afgutils/trandata.py
|
|
9
|
+
afgutils/utils.py
|
|
10
|
+
afgutils.egg-info/PKG-INFO
|
|
11
|
+
afgutils.egg-info/SOURCES.txt
|
|
12
|
+
afgutils.egg-info/dependency_links.txt
|
|
13
|
+
afgutils.egg-info/requires.txt
|
|
14
|
+
afgutils.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
afgutils
|
afgutils-1.0.6/setup.cfg
ADDED
afgutils-1.0.6/setup.py
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
|
|
3
|
+
VERSION = '1.0.6'
|
|
4
|
+
DESCRIPTION = 'Shared support functions'
|
|
5
|
+
LONG_DESCRIPTION = 'Shared support functions'
|
|
6
|
+
|
|
7
|
+
setup(
|
|
8
|
+
name="afgutils",
|
|
9
|
+
version=VERSION,
|
|
10
|
+
description=DESCRIPTION,
|
|
11
|
+
long_description=LONG_DESCRIPTION,
|
|
12
|
+
author="Araz Heydarov",
|
|
13
|
+
author_email="arazheyderov@gmail.com",
|
|
14
|
+
python_requires='>=3.10',
|
|
15
|
+
license='copyright',
|
|
16
|
+
packages=find_packages(),
|
|
17
|
+
install_requires=[
|
|
18
|
+
'requests==2.31.0',
|
|
19
|
+
'pyodbc==4.0.39',
|
|
20
|
+
'pywin32==306',
|
|
21
|
+
'python-dotenv==1.0.0',
|
|
22
|
+
'boto3==1.27.0',
|
|
23
|
+
'pandas==2.0.3']
|
|
24
|
+
)
|