data-manipulation 0.40__tar.gz → 0.41__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.
- {data_manipulation-0.40/data_manipulation.egg-info → data_manipulation-0.41}/PKG-INFO +4 -1
- {data_manipulation-0.40 → data_manipulation-0.41}/data_manipulation/_version.py +3 -3
- {data_manipulation-0.40 → data_manipulation-0.41}/data_manipulation/base.py +7 -10
- {data_manipulation-0.40 → data_manipulation-0.41}/data_manipulation/beautifulsoup_.py +2 -4
- {data_manipulation-0.40 → data_manipulation-0.41}/data_manipulation/boto3_.py +5 -7
- {data_manipulation-0.40 → data_manipulation-0.41}/data_manipulation/cryptography_.py +2 -5
- {data_manipulation-0.40 → data_manipulation-0.41}/data_manipulation/django_.py +3 -5
- {data_manipulation-0.40 → data_manipulation-0.41}/data_manipulation/kerberos_.py +2 -3
- {data_manipulation-0.40 → data_manipulation-0.41}/data_manipulation/mysql_connector_python_.py +7 -7
- {data_manipulation-0.40 → data_manipulation-0.41}/data_manipulation/pandas_.py +1 -4
- {data_manipulation-0.40 → data_manipulation-0.41}/data_manipulation/psycopg2_.py +1 -4
- {data_manipulation-0.40 → data_manipulation-0.41}/data_manipulation/psycopg_.py +1 -4
- {data_manipulation-0.40 → data_manipulation-0.41}/data_manipulation/pyspark_.py +5 -4
- {data_manipulation-0.40 → data_manipulation-0.41}/data_manipulation/smtplib_.py +6 -4
- {data_manipulation-0.40 → data_manipulation-0.41}/data_manipulation/sqlalchemy_.py +1 -5
- {data_manipulation-0.40 → data_manipulation-0.41/data_manipulation.egg-info}/PKG-INFO +4 -1
- {data_manipulation-0.40 → data_manipulation-0.41}/data_manipulation.egg-info/requires.txt +3 -0
- {data_manipulation-0.40 → data_manipulation-0.41}/setup.py +3 -0
- {data_manipulation-0.40 → data_manipulation-0.41}/LICENSE +0 -0
- {data_manipulation-0.40 → data_manipulation-0.41}/MANIFEST.in +0 -0
- {data_manipulation-0.40 → data_manipulation-0.41}/README.md +0 -0
- {data_manipulation-0.40 → data_manipulation-0.41}/data_manipulation/__init__.py +0 -0
- {data_manipulation-0.40 → data_manipulation-0.41}/data_manipulation/flask_.py +0 -0
- {data_manipulation-0.40 → data_manipulation-0.41}/data_manipulation/geopandas_.py +0 -0
- {data_manipulation-0.40 → data_manipulation-0.41}/data_manipulation/openldap_.py +0 -0
- {data_manipulation-0.40 → data_manipulation-0.41}/data_manipulation/prometheus_.py +0 -0
- {data_manipulation-0.40 → data_manipulation-0.41}/data_manipulation.egg-info/SOURCES.txt +0 -0
- {data_manipulation-0.40 → data_manipulation-0.41}/data_manipulation.egg-info/dependency_links.txt +0 -0
- {data_manipulation-0.40 → data_manipulation-0.41}/data_manipulation.egg-info/top_level.txt +0 -0
- {data_manipulation-0.40 → data_manipulation-0.41}/setup.cfg +0 -0
- {data_manipulation-0.40 → data_manipulation-0.41}/versioneer.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: data_manipulation
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.41
|
|
4
4
|
Summary: Powerful data manipulation
|
|
5
5
|
Home-page: https://github.com/shawnngtq/data-manipulation
|
|
6
6
|
Author: Shawn Ng
|
|
@@ -24,7 +24,10 @@ Requires-Dist: boto3
|
|
|
24
24
|
Requires-Dist: django
|
|
25
25
|
Requires-Dist: flask
|
|
26
26
|
Requires-Dist: geopandas
|
|
27
|
+
Requires-Dist: ipython
|
|
28
|
+
Requires-Dist: loguru
|
|
27
29
|
Requires-Dist: mysql-connector-python
|
|
30
|
+
Requires-Dist: numpy
|
|
28
31
|
Requires-Dist: pandas
|
|
29
32
|
Requires-Dist: psycopg
|
|
30
33
|
Requires-Dist: psycopg2
|
|
@@ -8,11 +8,11 @@ import json
|
|
|
8
8
|
|
|
9
9
|
version_json = '''
|
|
10
10
|
{
|
|
11
|
-
"date": "2024-
|
|
11
|
+
"date": "2024-06-02T13:56:45+0800",
|
|
12
12
|
"dirty": false,
|
|
13
13
|
"error": null,
|
|
14
|
-
"full-revisionid": "
|
|
15
|
-
"version": "0.
|
|
14
|
+
"full-revisionid": "87e16d5a881cc730eaa2b216d040ab445495cac6",
|
|
15
|
+
"version": "0.41"
|
|
16
16
|
}
|
|
17
17
|
''' # END VERSION_JSON
|
|
18
18
|
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
import
|
|
1
|
+
import itertools
|
|
2
|
+
import os
|
|
3
|
+
import re
|
|
2
4
|
import subprocess
|
|
5
|
+
from ast import literal_eval
|
|
6
|
+
from distutils.util import strtobool
|
|
3
7
|
from typing import List
|
|
8
|
+
from urllib.parse import urlencode
|
|
4
9
|
|
|
5
|
-
|
|
6
|
-
logger = logging.getLogger(__file__)
|
|
10
|
+
from loguru import logger
|
|
7
11
|
|
|
8
12
|
|
|
9
13
|
# DATA STRUCTURE
|
|
@@ -38,7 +42,6 @@ def clean_string(
|
|
|
38
42
|
str
|
|
39
43
|
Uppercase cleaned string
|
|
40
44
|
"""
|
|
41
|
-
import re
|
|
42
45
|
|
|
43
46
|
if remove_parenthesis:
|
|
44
47
|
string = re.sub(r"\(.*\)", "", string)
|
|
@@ -69,7 +72,6 @@ def get_string_case_combination(str_: str) -> list:
|
|
|
69
72
|
list
|
|
70
73
|
Case combinations
|
|
71
74
|
"""
|
|
72
|
-
import itertools
|
|
73
75
|
|
|
74
76
|
return list(map("".join, itertools.product(*zip(str_.upper(), str_.lower()))))
|
|
75
77
|
|
|
@@ -188,7 +190,6 @@ def string_boolean_to_int(boolean_str_rep: str) -> int:
|
|
|
188
190
|
int
|
|
189
191
|
_description_
|
|
190
192
|
"""
|
|
191
|
-
from distutils.util import strtobool
|
|
192
193
|
|
|
193
194
|
int_ = strtobool(string_str_to_str(boolean_str_rep))
|
|
194
195
|
return int_
|
|
@@ -223,7 +224,6 @@ def string_dlt_to_dlt(dlt_str_rep: str) -> dict | list | tuple:
|
|
|
223
224
|
dict | list | tuple
|
|
224
225
|
_description_
|
|
225
226
|
"""
|
|
226
|
-
from ast import literal_eval
|
|
227
227
|
|
|
228
228
|
dlt = literal_eval(dlt_str_rep)
|
|
229
229
|
return dlt
|
|
@@ -302,7 +302,6 @@ def get_path_files(path: str, keywords: list) -> list:
|
|
|
302
302
|
list
|
|
303
303
|
Sorted list
|
|
304
304
|
"""
|
|
305
|
-
import os
|
|
306
305
|
|
|
307
306
|
list_ = []
|
|
308
307
|
for file in sorted(os.listdir(path)):
|
|
@@ -335,7 +334,6 @@ def remove_path_file(path: str, keyword: str, n: int = 2) -> None:
|
|
|
335
334
|
>>> get_path_files("test_base_folder", ["py"])
|
|
336
335
|
['test4.py', 'test5.py']
|
|
337
336
|
"""
|
|
338
|
-
import os
|
|
339
337
|
|
|
340
338
|
to_delete = get_path_files(path=path, keywords=[keyword])[:-n]
|
|
341
339
|
for file in to_delete:
|
|
@@ -385,7 +383,6 @@ def create_encode_url(url: str, query_params: dict = {}) -> str:
|
|
|
385
383
|
str
|
|
386
384
|
encoded url
|
|
387
385
|
"""
|
|
388
|
-
from urllib.parse import urlencode
|
|
389
386
|
|
|
390
387
|
return f"{url}{urlencode(query_params)}"
|
|
391
388
|
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import
|
|
1
|
+
import re
|
|
2
2
|
from typing import Optional
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
logger = logging.getLogger(__file__)
|
|
4
|
+
from loguru import logger
|
|
6
5
|
|
|
7
6
|
|
|
8
7
|
def preprocess(html: str) -> Optional[str]:
|
|
@@ -25,7 +24,6 @@ def preprocess(html: str) -> Optional[str]:
|
|
|
25
24
|
Optional[str]
|
|
26
25
|
cleaned html
|
|
27
26
|
"""
|
|
28
|
-
import re
|
|
29
27
|
|
|
30
28
|
# remove leading and trailing whitespaces
|
|
31
29
|
pattern = re.compile("(^[\s]+)|([\s]+$)", re.MULTILINE)
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import
|
|
1
|
+
import os
|
|
2
|
+
from email.mime.application import MIMEApplication
|
|
3
|
+
from email.mime.multipart import MIMEMultipart
|
|
4
|
+
from email.mime.text import MIMEText
|
|
2
5
|
|
|
3
|
-
|
|
4
|
-
logger = logging.getLogger(__file__)
|
|
6
|
+
from loguru import logger
|
|
5
7
|
|
|
6
8
|
|
|
7
9
|
def send_aws_ses_email(
|
|
@@ -42,10 +44,6 @@ def send_aws_ses_email(
|
|
|
42
44
|
---------
|
|
43
45
|
- https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ses/client/send_raw_email.html
|
|
44
46
|
"""
|
|
45
|
-
import os
|
|
46
|
-
from email.mime.application import MIMEApplication
|
|
47
|
-
from email.mime.multipart import MIMEMultipart
|
|
48
|
-
from email.mime.text import MIMEText
|
|
49
47
|
|
|
50
48
|
from botocore.exceptions import BotoCoreError, ClientError
|
|
51
49
|
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
import
|
|
1
|
+
import os
|
|
2
2
|
|
|
3
3
|
from cryptography.fernet import Fernet
|
|
4
|
-
|
|
5
|
-
logging.basicConfig(level=logging.INFO)
|
|
6
|
-
logger = logging.getLogger(__file__)
|
|
4
|
+
from loguru import logger
|
|
7
5
|
|
|
8
6
|
|
|
9
7
|
def generate_fernet_key(output_directory: str, output_filename: str) -> bytes:
|
|
@@ -22,7 +20,6 @@ def generate_fernet_key(output_directory: str, output_filename: str) -> bytes:
|
|
|
22
20
|
bytes
|
|
23
21
|
Fernet key in bytes
|
|
24
22
|
"""
|
|
25
|
-
import os
|
|
26
23
|
|
|
27
24
|
key = None
|
|
28
25
|
if os.path.isdir(output_directory):
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
logger = logging.getLogger(__file__)
|
|
4
|
+
from loguru import logger
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
def init_django(django_dir: str, project_name: str) -> None:
|
|
@@ -15,8 +15,6 @@ def init_django(django_dir: str, project_name: str) -> None:
|
|
|
15
15
|
project_name : str
|
|
16
16
|
Django project name
|
|
17
17
|
"""
|
|
18
|
-
import os
|
|
19
|
-
import sys
|
|
20
18
|
|
|
21
19
|
import django
|
|
22
20
|
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import logging
|
|
2
1
|
import subprocess
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
logger = logging.getLogger(__file__)
|
|
3
|
+
from loguru import logger
|
|
6
4
|
|
|
7
5
|
|
|
8
6
|
def keytab_valid(
|
|
@@ -24,6 +22,7 @@ def keytab_valid(
|
|
|
24
22
|
subprocess.CompletedProcess
|
|
25
23
|
Subprocess object
|
|
26
24
|
"""
|
|
25
|
+
|
|
27
26
|
output = subprocess.run(
|
|
28
27
|
f"kinit -kt {keytab_filepath} {principal_name}",
|
|
29
28
|
capture_output=True,
|
{data_manipulation-0.40 → data_manipulation-0.41}/data_manipulation/mysql_connector_python_.py
RENAMED
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
import logging
|
|
2
1
|
from typing import Optional, Union
|
|
3
2
|
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
logging.basicConfig(level=logging.INFO)
|
|
7
|
-
logger = logging.getLogger(__file__)
|
|
3
|
+
from loguru import logger
|
|
8
4
|
|
|
9
5
|
|
|
10
6
|
def create_connection(
|
|
@@ -13,7 +9,7 @@ def create_connection(
|
|
|
13
9
|
user: str,
|
|
14
10
|
password: str,
|
|
15
11
|
port=3306,
|
|
16
|
-
)
|
|
12
|
+
):
|
|
17
13
|
"""
|
|
18
14
|
Return MySQL connection
|
|
19
15
|
|
|
@@ -37,6 +33,8 @@ def create_connection(
|
|
|
37
33
|
mysql.connector.connection_cext.CMySQLConnection
|
|
38
34
|
Connection object
|
|
39
35
|
"""
|
|
36
|
+
import mysql.connector
|
|
37
|
+
|
|
40
38
|
connection = None
|
|
41
39
|
try:
|
|
42
40
|
connection = mysql.connector.connect(
|
|
@@ -53,7 +51,7 @@ def create_connection(
|
|
|
53
51
|
|
|
54
52
|
|
|
55
53
|
def execute_query(
|
|
56
|
-
connection
|
|
54
|
+
connection,
|
|
57
55
|
sql_query: str,
|
|
58
56
|
data: Union[dict, tuple],
|
|
59
57
|
commit=True,
|
|
@@ -77,6 +75,8 @@ def execute_query(
|
|
|
77
75
|
Optional[int]
|
|
78
76
|
Query id should be int
|
|
79
77
|
"""
|
|
78
|
+
import mysql.connector
|
|
79
|
+
|
|
80
80
|
cursor = connection.cursor()
|
|
81
81
|
try:
|
|
82
82
|
cursor.execute(sql_query, data)
|
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
import logging
|
|
2
1
|
import subprocess
|
|
3
2
|
from itertools import combinations
|
|
4
3
|
|
|
5
4
|
import numpy as np
|
|
6
5
|
import pandas as pd
|
|
7
6
|
from IPython.display import display
|
|
8
|
-
|
|
9
|
-
logging.basicConfig(level=logging.INFO)
|
|
10
|
-
logger = logging.getLogger(__file__)
|
|
7
|
+
from loguru import logger
|
|
11
8
|
|
|
12
9
|
|
|
13
10
|
# CONFIG
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import
|
|
1
|
+
import math
|
|
2
|
+
import multiprocessing
|
|
3
|
+
import os
|
|
4
|
+
|
|
2
5
|
import pyspark
|
|
3
6
|
import pyspark.sql.functions as F
|
|
4
7
|
|
|
@@ -44,9 +47,6 @@ def config_spark_local(autoset=True):
|
|
|
44
47
|
-------
|
|
45
48
|
None
|
|
46
49
|
"""
|
|
47
|
-
import math
|
|
48
|
-
import multiprocessing
|
|
49
|
-
import os
|
|
50
50
|
|
|
51
51
|
def round_down_or_one(x):
|
|
52
52
|
if math.floor(x) == 0:
|
|
@@ -360,6 +360,7 @@ def group_count(dataframe, columns, n=10):
|
|
|
360
360
|
|
|
361
361
|
Examples
|
|
362
362
|
--------
|
|
363
|
+
>>> import pandas as pd
|
|
363
364
|
>>> data = {'id': [1, 1, 1, 2, 2, 3], 'value': [5, 2, 5, 2135, 124390, 213]}
|
|
364
365
|
>>> df = spark.createDataFrame(pd.DataFrame(data))
|
|
365
366
|
>>> group_count(df, ["id"]).show()
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import smtplib
|
|
3
|
+
from email.mime.multipart import MIMEMultipart
|
|
4
|
+
from email.mime.text import MIMEText
|
|
5
|
+
|
|
6
|
+
|
|
1
7
|
def send_email(
|
|
2
8
|
logname: str,
|
|
3
9
|
message_subject: str,
|
|
@@ -24,10 +30,6 @@ def send_email(
|
|
|
24
30
|
smtp_address: str
|
|
25
31
|
SMTP address
|
|
26
32
|
"""
|
|
27
|
-
import logging
|
|
28
|
-
import smtplib
|
|
29
|
-
from email.mime.multipart import MIMEMultipart
|
|
30
|
-
from email.mime.text import MIMEText
|
|
31
33
|
|
|
32
34
|
if all(
|
|
33
35
|
isinstance(i, str)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: data_manipulation
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.41
|
|
4
4
|
Summary: Powerful data manipulation
|
|
5
5
|
Home-page: https://github.com/shawnngtq/data-manipulation
|
|
6
6
|
Author: Shawn Ng
|
|
@@ -24,7 +24,10 @@ Requires-Dist: boto3
|
|
|
24
24
|
Requires-Dist: django
|
|
25
25
|
Requires-Dist: flask
|
|
26
26
|
Requires-Dist: geopandas
|
|
27
|
+
Requires-Dist: ipython
|
|
28
|
+
Requires-Dist: loguru
|
|
27
29
|
Requires-Dist: mysql-connector-python
|
|
30
|
+
Requires-Dist: numpy
|
|
28
31
|
Requires-Dist: pandas
|
|
29
32
|
Requires-Dist: psycopg
|
|
30
33
|
Requires-Dist: psycopg2
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{data_manipulation-0.40 → data_manipulation-0.41}/data_manipulation.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|