wcp-library 1.4.6__tar.gz → 1.5.1__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.
- {wcp_library-1.4.6 → wcp_library-1.5.1}/PKG-INFO +3 -2
- {wcp_library-1.4.6 → wcp_library-1.5.1}/pyproject.toml +4 -3
- wcp_library-1.5.1/wcp_library/selenium/__init__.py +0 -0
- wcp_library-1.4.6/wcp_library/selenium_helper.py → wcp_library-1.5.1/wcp_library/selenium/_selenium_driver.py +9 -29
- wcp_library-1.5.1/wcp_library/selenium/selenium_helper.py +53 -0
- {wcp_library-1.4.6 → wcp_library-1.5.1}/wcp_library/sql/__init__.py +2 -2
- {wcp_library-1.4.6 → wcp_library-1.5.1}/README.md +0 -0
- {wcp_library-1.4.6 → wcp_library-1.5.1}/wcp_library/__init__.py +0 -0
- {wcp_library-1.4.6 → wcp_library-1.5.1}/wcp_library/credentials/__init__.py +0 -0
- {wcp_library-1.4.6 → wcp_library-1.5.1}/wcp_library/credentials/_credential_manager_asynchronous.py +0 -0
- {wcp_library-1.4.6 → wcp_library-1.5.1}/wcp_library/credentials/_credential_manager_synchronous.py +0 -0
- {wcp_library-1.4.6 → wcp_library-1.5.1}/wcp_library/credentials/api.py +0 -0
- {wcp_library-1.4.6 → wcp_library-1.5.1}/wcp_library/credentials/ftp.py +0 -0
- {wcp_library-1.4.6 → wcp_library-1.5.1}/wcp_library/credentials/internet.py +0 -0
- {wcp_library-1.4.6 → wcp_library-1.5.1}/wcp_library/credentials/oracle.py +0 -0
- {wcp_library-1.4.6 → wcp_library-1.5.1}/wcp_library/credentials/postgres.py +0 -0
- {wcp_library-1.4.6 → wcp_library-1.5.1}/wcp_library/emailing.py +0 -0
- {wcp_library-1.4.6 → wcp_library-1.5.1}/wcp_library/ftp/__init__.py +0 -0
- {wcp_library-1.4.6 → wcp_library-1.5.1}/wcp_library/ftp/ftp.py +0 -0
- {wcp_library-1.4.6 → wcp_library-1.5.1}/wcp_library/ftp/sftp.py +0 -0
- {wcp_library-1.4.6 → wcp_library-1.5.1}/wcp_library/informatica.py +0 -0
- {wcp_library-1.4.6 → wcp_library-1.5.1}/wcp_library/logging.py +0 -0
- {wcp_library-1.4.6 → wcp_library-1.5.1}/wcp_library/sql/oracle.py +0 -0
- {wcp_library-1.4.6 → wcp_library-1.5.1}/wcp_library/sql/postgres.py +0 -0
- {wcp_library-1.4.6 → wcp_library-1.5.1}/wcp_library/time.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: wcp-library
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.5.1
|
4
4
|
Summary: Common utilites for internal development at WCP
|
5
5
|
Author: Mitch-Petersen
|
6
6
|
Author-email: mitch.petersen@wcap.ca
|
@@ -10,6 +10,7 @@ Classifier: Programming Language :: Python :: 3.12
|
|
10
10
|
Classifier: Programming Language :: Python :: 3.13
|
11
11
|
Requires-Dist: aiohttp (>=3.10.10,<4.0.0)
|
12
12
|
Requires-Dist: ftputil (>=5.1.0,<6.0.0)
|
13
|
+
Requires-Dist: get-gecko-driver (>=1.4,<2.0)
|
13
14
|
Requires-Dist: oracledb (>=2.5.0,<3.0.0)
|
14
15
|
Requires-Dist: pandas (>=2.2.3,<3.0.0)
|
15
16
|
Requires-Dist: paramiko (>=3.5.0,<4.0.0)
|
@@ -20,7 +21,7 @@ Requires-Dist: psycopg-pool (>=3.2.3,<4.0.0)
|
|
20
21
|
Requires-Dist: pycryptodome (>=3.21.0,<4.0.0)
|
21
22
|
Requires-Dist: pytz (>=2024.2,<2025.0)
|
22
23
|
Requires-Dist: requests (>=2.32.3,<3.0.0)
|
23
|
-
Requires-Dist: selenium (>=4.
|
24
|
+
Requires-Dist: selenium (>=4.31.0,<5.0.0)
|
24
25
|
Requires-Dist: webdriver-manager (>=4.0.2,<5.0.0)
|
25
26
|
Requires-Dist: yarl (>=1.17.1,<2.0.0)
|
26
27
|
Project-URL: Documentation, https://github.com/Whitecap-DNA/WCP-Library/wiki
|
@@ -1,6 +1,6 @@
|
|
1
1
|
[tool.poetry]
|
2
2
|
name = "wcp-library"
|
3
|
-
version = "1.
|
3
|
+
version = "1.5.1"
|
4
4
|
description = "Common utilites for internal development at WCP"
|
5
5
|
authors = ["Mitch-Petersen <mitch.petersen@wcap.ca>"]
|
6
6
|
readme = "README.md"
|
@@ -12,6 +12,7 @@ packages = [{include = "wcp_library"}]
|
|
12
12
|
python = "^3.12"
|
13
13
|
aiohttp = "^3.10.10"
|
14
14
|
ftputil = "^5.1.0"
|
15
|
+
get-gecko-driver = "^1.4"
|
15
16
|
oracledb = "^2.5.0"
|
16
17
|
pandas = "^2.2.3"
|
17
18
|
paramiko = "^3.5.0"
|
@@ -20,11 +21,11 @@ psycopg = "^3.2.3"
|
|
20
21
|
psycopg-binary = "^3.2.3"
|
21
22
|
psycopg-pool = "^3.2.3"
|
22
23
|
pycryptodome = "^3.21.0"
|
24
|
+
pytz = "^2024.2"
|
23
25
|
requests = "^2.32.3"
|
24
|
-
selenium = "^4.
|
26
|
+
selenium = "^4.31.0"
|
25
27
|
webdriver-manager = "^4.0.2"
|
26
28
|
yarl = "^1.17.1"
|
27
|
-
pytz = "^2024.2"
|
28
29
|
|
29
30
|
[build-system]
|
30
31
|
requires = ["poetry-core"]
|
File without changes
|
@@ -1,40 +1,20 @@
|
|
1
|
-
from
|
1
|
+
from abc import ABC
|
2
|
+
from dataclasses import field
|
2
3
|
from typing import Optional
|
3
4
|
|
4
|
-
from selenium import webdriver
|
5
5
|
from selenium.webdriver.common.by import By
|
6
|
-
from selenium.webdriver.
|
6
|
+
from selenium.webdriver.remote.webelement import WebElement
|
7
7
|
from selenium.webdriver.support import expected_conditions
|
8
8
|
from selenium.webdriver.support.wait import WebDriverWait
|
9
|
-
from selenium.webdriver.remote.webelement import WebElement
|
10
|
-
from webdriver_manager.chrome import ChromeDriverManager
|
11
9
|
|
12
10
|
|
13
|
-
class
|
14
|
-
def __init__(self, headless: bool =
|
11
|
+
class SeleniumDriver(ABC):
|
12
|
+
def __init__(self, headless: bool = True, download_path: str = None):
|
15
13
|
self._headless = headless
|
16
14
|
self._download_path = download_path
|
15
|
+
self.driver = field(init=False)
|
17
16
|
|
18
|
-
|
19
|
-
opt.add_argument("--start-maximized")
|
20
|
-
if headless:
|
21
|
-
opt.add_argument('headless')
|
22
|
-
|
23
|
-
opt.page_load_strategy = 'eager'
|
24
|
-
|
25
|
-
experimental_options_dict = {"download.prompt_for_download": False,
|
26
|
-
"download.directory_upgrade": True,
|
27
|
-
"safebrowsing.enabled": True}
|
28
|
-
if download_path:
|
29
|
-
experimental_options_dict["download.default_directory"] = str(download_path)
|
30
|
-
|
31
|
-
opt.add_experimental_option("prefs", experimental_options_dict)
|
32
|
-
opt.timeouts = {'implicit': 5000}
|
33
|
-
|
34
|
-
self.driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=opt)
|
35
|
-
|
36
|
-
|
37
|
-
def find_button_by_text(self, text: str) -> WebElement:
|
17
|
+
def find_button_by_text(self, text: str) -> WebElement | None:
|
38
18
|
"""
|
39
19
|
Find a button by its text
|
40
20
|
|
@@ -52,7 +32,7 @@ class SeleniumHelper:
|
|
52
32
|
if text in b.text:
|
53
33
|
return b
|
54
34
|
|
55
|
-
def find_span_by_text(self, text: str) -> WebElement:
|
35
|
+
def find_span_by_text(self, text: str) -> WebElement | None:
|
56
36
|
"""
|
57
37
|
Find a span by its text
|
58
38
|
|
@@ -105,4 +85,4 @@ class SeleniumHelper:
|
|
105
85
|
if css_element:
|
106
86
|
WebDriverWait(self.driver, timeout).until(expected_conditions.element_to_be_clickable((By.CSS_SELECTOR, css_element)))
|
107
87
|
elif link_text:
|
108
|
-
WebDriverWait(self.driver, timeout).until(expected_conditions.element_to_be_clickable((By.LINK_TEXT, link_text)))
|
88
|
+
WebDriverWait(self.driver, timeout).until(expected_conditions.element_to_be_clickable((By.LINK_TEXT, link_text)))
|
@@ -0,0 +1,53 @@
|
|
1
|
+
from pathlib import Path
|
2
|
+
from typing import Optional
|
3
|
+
|
4
|
+
from get_gecko_driver import GetGeckoDriver
|
5
|
+
from selenium import webdriver
|
6
|
+
from selenium.webdriver.chrome.service import Service
|
7
|
+
from webdriver_manager.chrome import ChromeDriverManager
|
8
|
+
|
9
|
+
from wcp_library.selenium._selenium_driver import SeleniumDriver
|
10
|
+
|
11
|
+
|
12
|
+
class ChromeSeleniumHelper(SeleniumDriver):
|
13
|
+
def __init__(self, headless: bool = False, download_path: Optional[Path] = None):
|
14
|
+
super().__init__(headless, download_path)
|
15
|
+
|
16
|
+
opt = webdriver.ChromeOptions()
|
17
|
+
opt.add_argument("--start-maximized")
|
18
|
+
if headless:
|
19
|
+
opt.add_argument('headless')
|
20
|
+
|
21
|
+
opt.page_load_strategy = 'eager'
|
22
|
+
|
23
|
+
experimental_options_dict = {"download.prompt_for_download": False,
|
24
|
+
"download.directory_upgrade": True,
|
25
|
+
"safebrowsing.enabled": True}
|
26
|
+
if download_path:
|
27
|
+
experimental_options_dict["download.default_directory"] = str(download_path)
|
28
|
+
|
29
|
+
opt.add_experimental_option("prefs", experimental_options_dict)
|
30
|
+
opt.timeouts = {'implicit': 5000}
|
31
|
+
|
32
|
+
self.driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=opt)
|
33
|
+
|
34
|
+
|
35
|
+
class FirefoxSeleniumHelper(SeleniumDriver):
|
36
|
+
def __init__(self, headless: bool = False, download_path: Optional[Path] = None):
|
37
|
+
super().__init__(headless, download_path)
|
38
|
+
|
39
|
+
opt = webdriver.FirefoxOptions()
|
40
|
+
opt.add_argument("--start-maximized")
|
41
|
+
if headless:
|
42
|
+
opt.add_argument('headless')
|
43
|
+
|
44
|
+
opt.page_load_strategy = 'eager'
|
45
|
+
|
46
|
+
if download_path:
|
47
|
+
opt.set_preference("browser.download.folderList", 2)
|
48
|
+
opt.set_preference("browser.download.dir", str(download_path))
|
49
|
+
opt.set_preference("browser.helperApps.neverAsk.saveToDisk", "application/octet-stream")
|
50
|
+
|
51
|
+
get_driver = GetGeckoDriver()
|
52
|
+
get_driver.install()
|
53
|
+
self.driver = webdriver.Firefox(options=opt)
|
@@ -23,7 +23,7 @@ def retry(f: callable) -> callable:
|
|
23
23
|
while True:
|
24
24
|
try:
|
25
25
|
return f(self, *args, **kwargs)
|
26
|
-
except (oracledb.OperationalError, psycopg.OperationalError) as e:
|
26
|
+
except (oracledb.OperationalError, oracledb.DatabaseError, psycopg.OperationalError) as e:
|
27
27
|
error_obj, = e.args
|
28
28
|
if error_obj.full_code in self.retry_error_codes and self._retry_count < self.retry_limit:
|
29
29
|
self._retry_count += 1
|
@@ -50,7 +50,7 @@ def async_retry(f: callable) -> callable:
|
|
50
50
|
while True:
|
51
51
|
try:
|
52
52
|
return await f(self, *args, **kwargs)
|
53
|
-
except (oracledb.OperationalError, psycopg.OperationalError) as e:
|
53
|
+
except (oracledb.OperationalError, oracledb.DatabaseError, psycopg.OperationalError) as e:
|
54
54
|
error_obj, = e.args
|
55
55
|
if error_obj.full_code in self.retry_error_codes and self._retry_count < self.retry_limit:
|
56
56
|
self._retry_count += 1
|
File without changes
|
File without changes
|
File without changes
|
{wcp_library-1.4.6 → wcp_library-1.5.1}/wcp_library/credentials/_credential_manager_asynchronous.py
RENAMED
File without changes
|
{wcp_library-1.4.6 → wcp_library-1.5.1}/wcp_library/credentials/_credential_manager_synchronous.py
RENAMED
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
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|