berryworld 1.0.0.185313__py3-none-any.whl → 1.0.0.188349__py3-none-any.whl

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.
berryworld/__init__.py CHANGED
@@ -3,10 +3,9 @@ from .handy_mix import HandyMix, URLResolver
3
3
  from .transportation_solver import TransportationAlgorithm
4
4
  from .allocation_solver import AllocationSolver
5
5
  from .pickle_management import PickleManagement
6
- from .postgres_connection import Postgresql
7
6
  from .email_logging import EmailLogging
8
7
  from .verify_keys import Verify
9
- from .credentials import PostgresCredentials, SnowflakeCredentials, SQLCredentials, BCCredentials, CDSCredentials, SharePointCredentials, \
8
+ from .credentials import SnowflakeCredentials, SQLCredentials, BCCredentials, CDSCredentials, SharePointCredentials, \
10
9
  WebServiceCredentials, MicrosoftTeamsCredentials
11
10
  from .persistent_storage import PersistentStorage
12
11
  from .generate_env import EnvVariables
berryworld/credentials.py CHANGED
@@ -71,40 +71,6 @@ class SQLCredentials:
71
71
  raise ValueError("Variable %s not found" % str(e))
72
72
 
73
73
 
74
- class PostgresCredentials:
75
- def __init__(self, db_name, server_type=None):
76
- if db_name is None:
77
- raise ValueError("Please provide a value for db_name")
78
- self.db_name = db_name
79
- self.server_type = server_type
80
-
81
- def simple_creds(self):
82
- if self.server_type is None:
83
- raise ValueError("Please provide a value for server_type")
84
-
85
- try:
86
- if os.name == 'nt':
87
- server_name = os.environ.get(
88
- "POSTGRESQL_" + self.db_name.upper() + '_' + self.server_type.upper() + '_LOCAL_SERVER_NAME')
89
- else:
90
- server_name = os.environ.get(
91
- "POSTGRESQL_" + self.db_name.upper() + '_' + self.server_type.upper() + '_SERVER_NAME')
92
-
93
- db_name = os.environ.get(
94
- "POSTGRESQL_" + self.db_name.upper() + '_' + self.server_type.upper() + '_DB_NAME')
95
- user_name = os.environ.get(
96
- "POSTGRESQL_" + self.db_name.upper() + '_' + self.server_type.upper() + '_USER_NAME')
97
- password = os.environ.get(
98
- "POSTGRESQL_" + self.db_name.upper() + '_' + self.server_type.upper() + '_PASSWORD')
99
-
100
- return {'server_name': re.sub(r'(\\)\1*', r'\1', server_name),
101
- 'db_name': db_name,
102
- 'user_name': user_name,
103
- 'password': password}
104
- except ValueError as e:
105
- raise ValueError("Variable %s not found" % str(e))
106
-
107
-
108
74
  class BCCredentials:
109
75
  def __init__(self, db_name=None, auth=False):
110
76
  self.db_name = db_name
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: berryworld
3
- Version: 1.0.0.185313
3
+ Version: 1.0.0.188349
4
4
  Summary: Handy classes to improve ETL processes
5
5
  Home-page: https://www.berryworld.com
6
6
  Author: BerryWorld ltd
@@ -17,7 +17,6 @@ Requires-Dist: numpy>=1.25.2
17
17
  Requires-Dist: opencensus>=0.11.0
18
18
  Requires-Dist: opencensus_ext_azure>=1.1.7
19
19
  Requires-Dist: pandas>=1.4.2
20
- Requires-Dist: psycopg2>=2.8.6
21
20
  Requires-Dist: pyodbc>=4.0.39
22
21
  Requires-Dist: python-dotenv>=1.0.0
23
22
  Requires-Dist: PyYAML>=6.0
@@ -35,6 +34,7 @@ Dynamic: classifier
35
34
  Dynamic: description
36
35
  Dynamic: description-content-type
37
36
  Dynamic: home-page
37
+ Dynamic: license-file
38
38
  Dynamic: requires-dist
39
39
  Dynamic: requires-python
40
40
  Dynamic: summary
@@ -1,10 +1,10 @@
1
- berryworld/__init__.py,sha256=FxoH2n864zRK6cVG47s8ciwDldfMB3zVzfa3ZRwtLWk,1185
1
+ berryworld/__init__.py,sha256=WJKsOTkpDuQqBU-MppW2YNdRLnEZ8Q7giOvNI4orCi0,1120
2
2
  berryworld/aks_logs.py,sha256=Gb2_cokiZbEX01Yoptd0MxpDociaug-GrXdwliyxFBo,2293
3
3
  berryworld/allocation_solver.py,sha256=asFtaCAze6-eHUGWXA0kAp67UBS-Upj1KKdrVLj_ttQ,8513
4
4
  berryworld/app_logs.py,sha256=MKzKPYd3JuPfOQNAapIgaeZeFHw1z_w2mbn9I6QCADE,4180
5
5
  berryworld/app_logs_query.py,sha256=U94b-z3X9cuY_KFozupUcfaYciXWBn7p_RHkoRsfROU,4376
6
6
  berryworld/cache_data.py,sha256=AWAhV4PPkilZ4Xb1pUXuuu6UdHICAx8QqDtb9rVnjDM,2254
7
- berryworld/credentials.py,sha256=L70ZzSNaS2mbHtSS8lb3iesd1XSwZNnUzGznlEKxlJY,11018
7
+ berryworld/credentials.py,sha256=jJENjLE-qxR0yBtZPMPEOJ6H83bZeo4hI265AerwcUI,9540
8
8
  berryworld/devops.py,sha256=7mRbyZPGzk5ox-6J2etv3NxCcfP4cprG0_Xelh7prn8,9776
9
9
  berryworld/email_con.py,sha256=uSBzs_Ijz9pUPWt9e7U3TCB7i6q7hU1bB5vhsTB_tmw,14448
10
10
  berryworld/email_logging.py,sha256=LeSrTExhQhar49gJR2wGC1dS0lqsNpFl9pS3eYWqnuo,4936
@@ -15,7 +15,6 @@ berryworld/logic_apps.py,sha256=a0uU4tNO3v2w7grdBv-OOx4hUf7VBIerJpwZ9U-29dQ,1459
15
15
  berryworld/microsoft_teams.py,sha256=8uPo0yku-euBj2VdzBoZCeX3IcsCCOqISLqaVZUVxfA,16030
16
16
  berryworld/persistent_storage.py,sha256=KQA57ez8eVTUCtudYkHPg_S5lcOEa_E7xXcaN1DYMMc,8601
17
17
  berryworld/pickle_management.py,sha256=5o6UuXBpTj23Jgpz6sj9V-vdcdWBK1xMEckWxT-Whj4,2436
18
- berryworld/postgres_connection.py,sha256=whKDnchd5Feqpmxpoh2vlyn36EKHR-dVEULYq0N_4wA,8287
19
18
  berryworld/power_automate.py,sha256=Y11GoeDEwd3Y2RdvtPPhBSFK65APEceAQKtNo4gVLK4,26464
20
19
  berryworld/sharepoint_con.py,sha256=TuH-Vxk1VxjTi7x80KFssf_J8YPLRXpV27RBaFZi37U,22254
21
20
  berryworld/snowflake_conn.py,sha256=52ugfkyVCbR_Xr8YiZtNwPrwe93_1uE9uRy_VNPT6Gs,2428
@@ -26,12 +25,12 @@ berryworld/verify_keys.py,sha256=X4Nuz3o0XbRDYofbJGvxIDeN5gfWj19PN7lhO6T3hR8,435
26
25
  berryworld/vivantio.py,sha256=QfZo0UKqkzVRg_LyiwivNd3aEup4TH57x4KxLZkCJwc,10627
27
26
  berryworld/vivantio_logging.py,sha256=ciy7gA4u3FrgUIpEBnMgocbNPp6jcu9TPoy-kLcrTZU,5736
28
27
  berryworld/xml_parser.py,sha256=HWD71NaTN3DaIOGT6Wzxs4CEsroFhGQwe9iPLIL80Co,957
28
+ berryworld-1.0.0.188349.dist-info/licenses/LICENSE,sha256=vtkVCJM6E2af2gnsi2XxKPr4WY-uIbvzVLXieFND0UU,1074
29
29
  tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
30
30
  tests/test_allocation_config.py,sha256=e12l6fE9U57eSPS35g6ekJ_hol7-RHg89JV60_m1BlE,4633
31
31
  tests/test_handy_mix_config.py,sha256=Un56mz9KJmdn4K4OwzHAHLSRzDU1Xv2nFrONNuzOG04,2594
32
32
  tests/test_xml_parser.py,sha256=3QTlhFEd6KbK6nRFKZnc35tad6wqukTbe4QrFi8mr_8,859
33
- berryworld-1.0.0.185313.dist-info/LICENSE,sha256=vtkVCJM6E2af2gnsi2XxKPr4WY-uIbvzVLXieFND0UU,1074
34
- berryworld-1.0.0.185313.dist-info/METADATA,sha256=55rXTm94wS30gdv7yrlGhfPCe2agFXxSAWNrFbYIKEc,1371
35
- berryworld-1.0.0.185313.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
36
- berryworld-1.0.0.185313.dist-info/top_level.txt,sha256=GIZ5qy-P5oxfEH755vA1IMFeTVdX3-40JxMe6nOe5I8,17
37
- berryworld-1.0.0.185313.dist-info/RECORD,,
33
+ berryworld-1.0.0.188349.dist-info/METADATA,sha256=IQNILK3na6R8NKy5LsS7k4mRTciBjh9mJjsdlVI-Sv0,1362
34
+ berryworld-1.0.0.188349.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
35
+ berryworld-1.0.0.188349.dist-info/top_level.txt,sha256=GIZ5qy-P5oxfEH755vA1IMFeTVdX3-40JxMe6nOe5I8,17
36
+ berryworld-1.0.0.188349.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.8.0)
2
+ Generator: setuptools (78.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,205 +0,0 @@
1
- import re
2
- import pandas as pd
3
- import psycopg2
4
- from .credentials import PostgresCredentials
5
-
6
-
7
- class Postgresql:
8
- def __init__(self, server_creds=None, elastic_pool=False, sslrootcert=None, **kwargs):
9
- """ Initialize the class
10
- -----------------------------
11
- server_creds = {
12
- "server_name": "",
13
- "db_name": "",
14
- "user_name": "",
15
- "password": ""
16
- }
17
-
18
- con_ = SQLConnection(server_creds)
19
- -----------------------------
20
- :param server_creds: Dictionary containing the info to connect to the Postgres Server
21
- :param elastic_pool: Connection to the Elastic Pool in the service or local connection
22
- :param sslrootcert: Path to local ssl root certificate
23
- :param kwargs: Additional parameters to be passed to the connection
24
- """
25
- if (kwargs == {}) & (server_creds is None):
26
- raise ValueError('Please provide a valid server_creds or kwargs')
27
-
28
- if elastic_pool:
29
- self.sslmode = None
30
- else:
31
- self.sslmode = 'require'
32
-
33
- self.sslrootcert = sslrootcert
34
- self.conn_str = None
35
- self.conn = None
36
- self.cur = None
37
-
38
- if kwargs != {}:
39
- try:
40
- db = kwargs['db_name']
41
- server = kwargs['server_type']
42
- server_creds = PostgresCredentials(db, server_type=server).simple_creds()
43
- except KeyError:
44
- raise KeyError('Please provide a valid db_name and server_type')
45
-
46
- self.server = server_creds['server_name']
47
- self.db = server_creds['db_name']
48
- self.user = server_creds['user_name']
49
- self.pw = server_creds['password']
50
-
51
- def connect(self):
52
- """ Open the connection to Postgresql """
53
- """
54
- If sslmode is required connect direct to the server with ssl certificate, else connect to Postgres Elasticpool
55
- without specifying sslmode as the certificate is defined within the kubernetes env with server_tls_sslmode
56
- """
57
- if self.sslmode:
58
- if self.sslrootcert:
59
- self.conn_str = "dbname='%s' user='%s' host='%s' password='%s' port='5432' " \
60
- "sslmode='%s' sslrootcert='%s' " % (
61
- self.db, self.user, self.server, self.pw, self.sslmode, self.sslrootcert)
62
-
63
- else:
64
- self.conn_str = "dbname='%s' user='%s' host='%s' password='%s' port='5432' sslmode='%s' " % (
65
- self.db, self.user, self.server, self.pw, self.sslmode)
66
-
67
- else:
68
- self.conn_str = "dbname='%s' user='%s' host='%s' password='%s' port='5432' " % (
69
- self.db, self.user, self.server, self.pw)
70
-
71
- self.conn = psycopg2.connect(self.conn_str)
72
-
73
- def close(self):
74
- """ Close the connection to Postgresql """
75
- self.conn.close()
76
-
77
- @staticmethod
78
- def _chunker(seq, size):
79
- """ Split the data set in chunks to be sent to SQL
80
- :param seq: Sequence of records to be split
81
- :param size: Size of any of the chunks to split the data
82
- :return: The DataFrame divided in chunks
83
- """
84
- return (seq[pos:pos + size] for pos in range(0, len(seq), size))
85
-
86
- @staticmethod
87
- def convert_decimal_str(string):
88
- """ Method to parse the Decimal type in python
89
- :param string: String variable to parse
90
- """
91
- string = re.sub("'\)(?!(,[ ]+\())(?=([^$]))", "", string)
92
- return re.sub("Decimal\('", "", string)
93
-
94
- def query(self, sql_query):
95
- """ Read data from Postgres SQL according to the sql_query
96
- -----------------------------
97
- query_str = "SELECT * FROM %s" & table
98
- con_.query(query_str)
99
- -----------------------------
100
- :param sql_query: Query to be sent to SQL
101
- :return: DataFrame gathering the requested data
102
- """
103
- cursor = None
104
- self.connect()
105
- try:
106
- cursor = self.conn.cursor()
107
- cursor.execute(sql_query)
108
- rows = cursor.fetchall()
109
- col_names = [desc[0] for desc in cursor.description]
110
- result = pd.DataFrame(rows, columns=col_names)
111
- return result
112
- except Exception as e:
113
- raise Exception(e)
114
- finally:
115
- if cursor:
116
- cursor.close()
117
- self.close()
118
-
119
- def run_statement(self, statement):
120
- """ Execute SQL statement
121
- -----------------------------
122
- query_str = "DELETE FROM %s WHERE Id > 100" & table
123
- con_.run_statement(query_str)
124
- -----------------------------
125
- :param statement: Statement as string to be run in Postgres SQL
126
- :return: Print the number of rows affected
127
- """
128
- cursor = None
129
- self.connect()
130
- try:
131
- cursor = self.conn.cursor()
132
- cursor.execute(statement)
133
- self.conn.commit()
134
- except Exception as e:
135
- raise Exception(e)
136
- finally:
137
- if cursor:
138
- cursor.close()
139
- self.close()
140
-
141
- def insert(self, data, schema, table, truncate=False, output=None, print_sql=False, chunk=1000):
142
- """ Insert data in a table in SQL truncating the table if needed
143
- -----------------------------
144
- df = pd.DataFrame({'col1': ['a', 'b'], 'col2': [1, 2]})
145
- con_.insert(df, table_schema, table_name)
146
- -----------------------------
147
- :param data: DataFrame containing the data to upload
148
- :param schema: Schema of the table in which the data will be uploaded
149
- :param table: Table in which the data will be uploaded
150
- :param truncate: Indicate whether the table has to be truncated before the data is sent or not
151
- :param output: Outputs the columns indicated in this list
152
- :param chunk: Indicate how many rows will be uploaded at once
153
- :param print_sql: boolean to indicate that you want the sql_statement to be printed on the console
154
- :return: A DataFrame with the output columns requested if output is not None, else None
155
- """
156
- if output is None:
157
- output = []
158
- if data is None:
159
- # no data to upload
160
- return ValueError("The data provided is invalid!")
161
-
162
- cursor = None
163
- self.connect()
164
- try:
165
- cursor = self.conn.cursor()
166
- # Truncate table if needed
167
- if truncate:
168
- cursor.execute("TRUNCATE TABLE %s.%s" % (schema, table))
169
-
170
- # Convert category columns to string
171
- cat_cols = data.columns[(data.dtypes == 'category').values].to_list()
172
- data[cat_cols] = data[cat_cols].astype(str)
173
- # Deal with bull values and apostrophes (')
174
- data = data.replace("'NULL'", "NULL")
175
- data = data.replace("'", "~~", regex=True)
176
- data = data.fillna("null")
177
- # Insert data into the table destination
178
- records = [tuple(x) for x in data.values]
179
- insert_ = """INSERT INTO %s.%s """ % (schema, table)
180
- insert_ += str(tuple(data.columns.values)).replace("\'", "") + """ VALUES """
181
- results = pd.DataFrame()
182
- for batch in self._chunker(records, chunk):
183
- rows = str(batch).strip('[]').replace("~~", "''")
184
- rows = rows.replace("'NULL'", "NULL").replace("'null'", 'null')
185
- insert_rows = insert_ + rows
186
- insert_rows = self.convert_decimal_str(insert_rows)
187
- insert_rows = re.sub(r"\';", "'')", insert_rows)
188
- if len(output) > 0:
189
- insert_rows += " RETURNING " + ','.join(output)
190
-
191
- if print_sql:
192
- print(insert_rows)
193
- cursor.execute(insert_rows)
194
- if len(output) > 0:
195
- results = pd.concat([results, pd.DataFrame.from_records(cursor.fetchall(), columns=output)])
196
- self.conn.commit()
197
-
198
- if len(output) > 0:
199
- return results
200
- except Exception as e:
201
- raise Exception(e)
202
- finally:
203
- if cursor:
204
- cursor.close()
205
- self.close()