data-manipulation 0.40__tar.gz → 0.42__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.
Files changed (31) hide show
  1. {data_manipulation-0.40/data_manipulation.egg-info → data_manipulation-0.42}/PKG-INFO +4 -1
  2. {data_manipulation-0.40 → data_manipulation-0.42}/data_manipulation/_version.py +3 -3
  3. {data_manipulation-0.40 → data_manipulation-0.42}/data_manipulation/base.py +23 -10
  4. {data_manipulation-0.40 → data_manipulation-0.42}/data_manipulation/beautifulsoup_.py +2 -4
  5. {data_manipulation-0.40 → data_manipulation-0.42}/data_manipulation/boto3_.py +5 -7
  6. {data_manipulation-0.40 → data_manipulation-0.42}/data_manipulation/cryptography_.py +2 -5
  7. {data_manipulation-0.40 → data_manipulation-0.42}/data_manipulation/django_.py +3 -5
  8. {data_manipulation-0.40 → data_manipulation-0.42}/data_manipulation/kerberos_.py +2 -3
  9. {data_manipulation-0.40 → data_manipulation-0.42}/data_manipulation/mysql_connector_python_.py +7 -7
  10. {data_manipulation-0.40 → data_manipulation-0.42}/data_manipulation/pandas_.py +25 -4
  11. {data_manipulation-0.40 → data_manipulation-0.42}/data_manipulation/psycopg2_.py +1 -4
  12. {data_manipulation-0.40 → data_manipulation-0.42}/data_manipulation/psycopg_.py +1 -4
  13. {data_manipulation-0.40 → data_manipulation-0.42}/data_manipulation/pyspark_.py +5 -4
  14. {data_manipulation-0.40 → data_manipulation-0.42}/data_manipulation/smtplib_.py +6 -4
  15. {data_manipulation-0.40 → data_manipulation-0.42}/data_manipulation/sqlalchemy_.py +1 -5
  16. {data_manipulation-0.40 → data_manipulation-0.42/data_manipulation.egg-info}/PKG-INFO +4 -1
  17. {data_manipulation-0.40 → data_manipulation-0.42}/data_manipulation.egg-info/requires.txt +3 -0
  18. {data_manipulation-0.40 → data_manipulation-0.42}/setup.py +3 -0
  19. {data_manipulation-0.40 → data_manipulation-0.42}/LICENSE +0 -0
  20. {data_manipulation-0.40 → data_manipulation-0.42}/MANIFEST.in +0 -0
  21. {data_manipulation-0.40 → data_manipulation-0.42}/README.md +0 -0
  22. {data_manipulation-0.40 → data_manipulation-0.42}/data_manipulation/__init__.py +0 -0
  23. {data_manipulation-0.40 → data_manipulation-0.42}/data_manipulation/flask_.py +0 -0
  24. {data_manipulation-0.40 → data_manipulation-0.42}/data_manipulation/geopandas_.py +0 -0
  25. {data_manipulation-0.40 → data_manipulation-0.42}/data_manipulation/openldap_.py +0 -0
  26. {data_manipulation-0.40 → data_manipulation-0.42}/data_manipulation/prometheus_.py +0 -0
  27. {data_manipulation-0.40 → data_manipulation-0.42}/data_manipulation.egg-info/SOURCES.txt +0 -0
  28. {data_manipulation-0.40 → data_manipulation-0.42}/data_manipulation.egg-info/dependency_links.txt +0 -0
  29. {data_manipulation-0.40 → data_manipulation-0.42}/data_manipulation.egg-info/top_level.txt +0 -0
  30. {data_manipulation-0.40 → data_manipulation-0.42}/setup.cfg +0 -0
  31. {data_manipulation-0.40 → data_manipulation-0.42}/versioneer.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: data_manipulation
3
- Version: 0.40
3
+ Version: 0.42
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-05-26T15:48:20+0800",
11
+ "date": "2024-08-03T10:19:19+0800",
12
12
  "dirty": false,
13
13
  "error": null,
14
- "full-revisionid": "805e0463f2f7f444a10afa22b658bc31ea864fed",
15
- "version": "0.40"
14
+ "full-revisionid": "30171014f9c6ac9bcb9c5aad60d40e662d35ab79",
15
+ "version": "0.42"
16
16
  }
17
17
  ''' # END VERSION_JSON
18
18
 
@@ -1,9 +1,13 @@
1
- import logging
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
- logging.basicConfig(level=logging.INFO)
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
 
@@ -119,6 +121,22 @@ def get_country_name_variation() -> dict:
119
121
  return variations
120
122
 
121
123
 
124
+ def get_country_code_variation() -> dict:
125
+ variations = {
126
+ "BA": ["BOSNIA"],
127
+ "BW": ["AFRICA"],
128
+ "CN": ["REPUBLIC OF CHINA"],
129
+ "CZ": ["CZECH REPUBLIC"],
130
+ "KR": ["REPUBLIC OF KOREA"],
131
+ "MK": ["MACEDONIA"],
132
+ "RU": ["RUSSIAN FEDERATION"],
133
+ "SK": ["SLAVONIC", "SLOVAK REPUBLIC"],
134
+ "TR": ["TURKEY", "TURKIYE"],
135
+ "US": ["UNITED STATES"],
136
+ }
137
+ return variations
138
+
139
+
122
140
  def list_tuple_without_none(list_tuple: list | tuple) -> list | tuple:
123
141
  """
124
142
  Return the given list / tuple without None variation
@@ -188,7 +206,6 @@ def string_boolean_to_int(boolean_str_rep: str) -> int:
188
206
  int
189
207
  _description_
190
208
  """
191
- from distutils.util import strtobool
192
209
 
193
210
  int_ = strtobool(string_str_to_str(boolean_str_rep))
194
211
  return int_
@@ -223,7 +240,6 @@ def string_dlt_to_dlt(dlt_str_rep: str) -> dict | list | tuple:
223
240
  dict | list | tuple
224
241
  _description_
225
242
  """
226
- from ast import literal_eval
227
243
 
228
244
  dlt = literal_eval(dlt_str_rep)
229
245
  return dlt
@@ -302,7 +318,6 @@ def get_path_files(path: str, keywords: list) -> list:
302
318
  list
303
319
  Sorted list
304
320
  """
305
- import os
306
321
 
307
322
  list_ = []
308
323
  for file in sorted(os.listdir(path)):
@@ -335,7 +350,6 @@ def remove_path_file(path: str, keyword: str, n: int = 2) -> None:
335
350
  >>> get_path_files("test_base_folder", ["py"])
336
351
  ['test4.py', 'test5.py']
337
352
  """
338
- import os
339
353
 
340
354
  to_delete = get_path_files(path=path, keywords=[keyword])[:-n]
341
355
  for file in to_delete:
@@ -385,7 +399,6 @@ def create_encode_url(url: str, query_params: dict = {}) -> str:
385
399
  str
386
400
  encoded url
387
401
  """
388
- from urllib.parse import urlencode
389
402
 
390
403
  return f"{url}{urlencode(query_params)}"
391
404
 
@@ -1,8 +1,7 @@
1
- import logging
1
+ import re
2
2
  from typing import Optional
3
3
 
4
- logging.basicConfig(level=logging.INFO)
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 logging
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
- logging.basicConfig(level=logging.INFO)
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 logging
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 logging
1
+ import os
2
+ import sys
2
3
 
3
- logging.basicConfig(level=logging.INFO)
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
- logging.basicConfig(level=logging.INFO)
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,
@@ -1,10 +1,6 @@
1
- import logging
2
1
  from typing import Optional, Union
3
2
 
4
- import mysql.connector
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
- ) -> mysql.connector.connection_cext.CMySQLConnection:
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: mysql.connector.connection_cext.CMySQLConnection,
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
@@ -23,6 +20,30 @@ def config_pandas_display():
23
20
  pd.set_option("display.expand_frame_repr", True)
24
21
 
25
22
 
23
+ # JUPYTER
24
+ def is_running_in_jupyter():
25
+ """
26
+ Running in jupyter?
27
+
28
+ Returns
29
+ -------
30
+ bool
31
+ True means running in jupyter env
32
+ """
33
+ try:
34
+ # Check if the IPython module is available
35
+ from IPython import get_ipython
36
+
37
+ # Check if we are in a notebook environment
38
+ if "IPKernelApp" in get_ipython().config:
39
+ return True
40
+ else:
41
+ return False
42
+ # IPython module not found, not running in Jupyter Notebook
43
+ except ImportError:
44
+ return False
45
+
46
+
26
47
  # COLUMN
27
48
  def add_type_columns(dataframe):
28
49
  """
@@ -1,11 +1,8 @@
1
- import logging
2
1
  from typing import Optional, Union
3
2
 
4
3
  import pandas as pd
5
4
  import psycopg2
6
-
7
- logging.basicConfig(level=logging.INFO)
8
- logger = logging.getLogger(__file__)
5
+ from loguru import logger
9
6
 
10
7
 
11
8
  def create_connection(
@@ -1,11 +1,8 @@
1
- import logging
2
1
  from typing import Optional, Union
3
2
 
4
3
  import pandas as pd
5
4
  import psycopg
6
-
7
- logging.basicConfig(level=logging.INFO)
8
- logger = logging.getLogger(__file__)
5
+ from loguru import logger
9
6
 
10
7
 
11
8
  def create_connection(
@@ -1,4 +1,7 @@
1
- import pandas as pd
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,9 +1,5 @@
1
- import logging
2
-
3
1
  import sqlalchemy
4
-
5
- logging.basicConfig(level=logging.INFO)
6
- logger = logging.getLogger(__file__)
2
+ from loguru import logger
7
3
 
8
4
 
9
5
  def create_sqlalchemy_url(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: data_manipulation
3
- Version: 0.40
3
+ Version: 0.42
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
@@ -3,7 +3,10 @@ boto3
3
3
  django
4
4
  flask
5
5
  geopandas
6
+ ipython
7
+ loguru
6
8
  mysql-connector-python
9
+ numpy
7
10
  pandas
8
11
  psycopg
9
12
  psycopg2
@@ -27,7 +27,10 @@ DEPENDENCIES = [
27
27
  "django",
28
28
  "flask",
29
29
  "geopandas",
30
+ "ipython",
31
+ "loguru",
30
32
  "mysql-connector-python",
33
+ "numpy",
31
34
  "pandas",
32
35
  "psycopg",
33
36
  "psycopg2",