pipetasks 0.1.0__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.
- pipetasks-0.1.0/.circleci/config.yml +111 -0
- pipetasks-0.1.0/.gitignore +32 -0
- pipetasks-0.1.0/.pre-commit-config.yaml +30 -0
- pipetasks-0.1.0/.python-version +1 -0
- pipetasks-0.1.0/.vscode/launch.json +23 -0
- pipetasks-0.1.0/.vscode/settings.json +11 -0
- pipetasks-0.1.0/CHANGELOG.md +12 -0
- pipetasks-0.1.0/PKG-INFO +20 -0
- pipetasks-0.1.0/README.md +3 -0
- pipetasks-0.1.0/pipetasks/__init__.py +0 -0
- pipetasks-0.1.0/pipetasks/pipeline.py +9 -0
- pipetasks-0.1.0/pipetasks/scraping/__init__.py +0 -0
- pipetasks-0.1.0/pipetasks/scraping/pipeline.py +126 -0
- pipetasks-0.1.0/pyproject.toml +117 -0
- pipetasks-0.1.0/tests/__init__.py +0 -0
- pipetasks-0.1.0/tests/scraping/__init__.py +0 -0
- pipetasks-0.1.0/tests/scraping/conftest.py +19 -0
- pipetasks-0.1.0/tests/scraping/test_pipeline.py +164 -0
- pipetasks-0.1.0/tests/scraping/test_pipeline_integration.py +13 -0
- pipetasks-0.1.0/tests/test_pipeline.py +2 -0
- pipetasks-0.1.0/uv.lock +847 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
version: 2.1
|
|
2
|
+
orbs:
|
|
3
|
+
node: circleci/node@4.3
|
|
4
|
+
gh: circleci/github-cli@1.0
|
|
5
|
+
jobs:
|
|
6
|
+
build_test:
|
|
7
|
+
docker:
|
|
8
|
+
- image: cimg/python:3.11.7
|
|
9
|
+
steps:
|
|
10
|
+
- checkout # checkout source code to working directory
|
|
11
|
+
- run:
|
|
12
|
+
name: Install uv
|
|
13
|
+
command: |
|
|
14
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
15
|
+
echo 'export PATH="$HOME/.local/bin:$PATH"' >> $BASH_ENV
|
|
16
|
+
- run:
|
|
17
|
+
name: Install dependencies
|
|
18
|
+
command: |
|
|
19
|
+
mkdir test-results
|
|
20
|
+
uv sync
|
|
21
|
+
- run:
|
|
22
|
+
name: Run tests
|
|
23
|
+
command: |
|
|
24
|
+
uv run pytest --junitxml=test-results/junit.xml --cov=./ --cov-report=xml
|
|
25
|
+
- run:
|
|
26
|
+
name: Run code coverage
|
|
27
|
+
command: |
|
|
28
|
+
curl -Os https://uploader.codecov.io/latest/linux/codecov
|
|
29
|
+
chmod +x codecov
|
|
30
|
+
./codecov
|
|
31
|
+
- store_test_results:
|
|
32
|
+
path: test-results
|
|
33
|
+
build_verify:
|
|
34
|
+
docker:
|
|
35
|
+
- image: cimg/python:3.11.7
|
|
36
|
+
steps:
|
|
37
|
+
- checkout
|
|
38
|
+
- run:
|
|
39
|
+
name: Install uv
|
|
40
|
+
command: |
|
|
41
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
42
|
+
echo 'export PATH="$HOME/.local/bin:$PATH"' >> $BASH_ENV
|
|
43
|
+
- run:
|
|
44
|
+
name: Build package
|
|
45
|
+
command: uv build
|
|
46
|
+
- run:
|
|
47
|
+
name: Verify build artifacts
|
|
48
|
+
command: |
|
|
49
|
+
ls dist/
|
|
50
|
+
test -f dist/*.whl || (echo "Missing wheel" && exit 1)
|
|
51
|
+
test -f dist/*.tar.gz || (echo "Missing sdist" && exit 1)
|
|
52
|
+
- persist_to_workspace:
|
|
53
|
+
root: .
|
|
54
|
+
paths:
|
|
55
|
+
- dist/
|
|
56
|
+
pypi_publish:
|
|
57
|
+
docker:
|
|
58
|
+
- image: cimg/python:3.11.7
|
|
59
|
+
steps:
|
|
60
|
+
- checkout # checkout source code to working directory
|
|
61
|
+
- attach_workspace:
|
|
62
|
+
at: .
|
|
63
|
+
- run:
|
|
64
|
+
name: Install uv
|
|
65
|
+
command: |
|
|
66
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
67
|
+
echo 'export PATH="$HOME/.local/bin:$PATH"' >> $BASH_ENV
|
|
68
|
+
- run:
|
|
69
|
+
name: Build and publish to PyPI
|
|
70
|
+
command: |
|
|
71
|
+
uv publish \
|
|
72
|
+
--username $TWINE_USERNAME \
|
|
73
|
+
--password $TWINE_PASSWORD
|
|
74
|
+
gh_release:
|
|
75
|
+
docker:
|
|
76
|
+
- image: 'cimg/base:stable'
|
|
77
|
+
steps:
|
|
78
|
+
- checkout # checkout source code to working directory
|
|
79
|
+
- gh/setup
|
|
80
|
+
- run:
|
|
81
|
+
name: "Creating a GitHub Release"
|
|
82
|
+
command: |
|
|
83
|
+
export GITHUB_HOSTNAME="github.com"
|
|
84
|
+
VERSION=$(grep '^version' pyproject.toml | head -1 | cut -d'"' -f2)
|
|
85
|
+
gh release create "$VERSION" \
|
|
86
|
+
--notes-file "./CHANGELOG.md" \
|
|
87
|
+
--title "pipetasks v$VERSION" \
|
|
88
|
+
--repo "$(git config --get remote.origin.url)"
|
|
89
|
+
workflows:
|
|
90
|
+
build_test_publish:
|
|
91
|
+
jobs:
|
|
92
|
+
- build_test
|
|
93
|
+
- build_verify:
|
|
94
|
+
requires:
|
|
95
|
+
- build_test
|
|
96
|
+
filters:
|
|
97
|
+
branches:
|
|
98
|
+
only: [main]
|
|
99
|
+
- pypi_publish:
|
|
100
|
+
requires:
|
|
101
|
+
- build_verify
|
|
102
|
+
filters:
|
|
103
|
+
branches:
|
|
104
|
+
only: [main]
|
|
105
|
+
- gh_release:
|
|
106
|
+
requires:
|
|
107
|
+
- pypi_publish
|
|
108
|
+
context: [GITHUB_CREDENTIALS]
|
|
109
|
+
filters:
|
|
110
|
+
branches:
|
|
111
|
+
only: [main]
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Python-generated files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[oc]
|
|
4
|
+
build/
|
|
5
|
+
dist/
|
|
6
|
+
wheels/
|
|
7
|
+
*.egg-info
|
|
8
|
+
.ruff_cache/
|
|
9
|
+
|
|
10
|
+
# Virtual environments
|
|
11
|
+
.venv
|
|
12
|
+
|
|
13
|
+
node_modules
|
|
14
|
+
|
|
15
|
+
# Output
|
|
16
|
+
.output
|
|
17
|
+
.vercel
|
|
18
|
+
.netlify
|
|
19
|
+
.wrangler
|
|
20
|
+
/.svelte-kit
|
|
21
|
+
/build
|
|
22
|
+
|
|
23
|
+
# OS
|
|
24
|
+
.DS_Store
|
|
25
|
+
Thumbs.db
|
|
26
|
+
|
|
27
|
+
# Env
|
|
28
|
+
.env
|
|
29
|
+
.env.*
|
|
30
|
+
frontend/.env
|
|
31
|
+
!.env.example
|
|
32
|
+
!.env.test.example
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
3
|
+
rev: v4.5.0
|
|
4
|
+
hooks:
|
|
5
|
+
- id: trailing-whitespace
|
|
6
|
+
- id: end-of-file-fixer
|
|
7
|
+
- id: check-yaml
|
|
8
|
+
- id: check-added-large-files
|
|
9
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
10
|
+
rev: v0.7.0
|
|
11
|
+
hooks:
|
|
12
|
+
- id: ruff
|
|
13
|
+
args: ["--fix"]
|
|
14
|
+
- id: ruff-format
|
|
15
|
+
- repo: https://github.com/pre-commit/mirrors-mypy
|
|
16
|
+
rev: v1.13.0
|
|
17
|
+
hooks:
|
|
18
|
+
- id: mypy
|
|
19
|
+
entry: uv run mypy --config-file=pyproject.toml .
|
|
20
|
+
language: system
|
|
21
|
+
pass_filenames: false
|
|
22
|
+
- repo: local
|
|
23
|
+
hooks:
|
|
24
|
+
- id: run-pytest
|
|
25
|
+
name: Run pytest
|
|
26
|
+
entry: .venv/bin/pytest
|
|
27
|
+
args: ["-c", "pyproject.toml", "--maxfail=1", "--disable-warnings"]
|
|
28
|
+
language: system
|
|
29
|
+
always_run: true
|
|
30
|
+
pass_filenames: false
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.11.7
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
// Use IntelliSense to learn about possible attributes.
|
|
3
|
+
// Hover to view descriptions of existing attributes.
|
|
4
|
+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
|
5
|
+
"version": "0.2.0",
|
|
6
|
+
"configurations": [
|
|
7
|
+
{
|
|
8
|
+
"name": "Python: Debug tests",
|
|
9
|
+
"type": "debugpy",
|
|
10
|
+
"request": "launch",
|
|
11
|
+
"module": "pytest",
|
|
12
|
+
"env": {
|
|
13
|
+
"PYTEST_ADDOPTS": "--no-cov"
|
|
14
|
+
},
|
|
15
|
+
"args": [
|
|
16
|
+
"-v",
|
|
17
|
+
],
|
|
18
|
+
"console": "integratedTerminal",
|
|
19
|
+
"justMyCode": false,
|
|
20
|
+
"python": "${workspaceFolder}/.venv/bin/python"
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"python.testing.unittestEnabled": false,
|
|
3
|
+
"python.testing.pytestEnabled": true,
|
|
4
|
+
"python.testing.pytestPath": "${workspaceFolder}/.venv/bin/pytest",
|
|
5
|
+
"python.testing.cwd": "${workspaceFolder}",
|
|
6
|
+
"python.testing.pytestArgs": [
|
|
7
|
+
"tests"
|
|
8
|
+
],
|
|
9
|
+
"python-envs.pythonProjects": [],
|
|
10
|
+
"python.defaultInterpreterPath": "${workspaceFolder}/.venv/bin/python"
|
|
11
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Change Log
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
|
6
|
+
and this project adheres to [Semantic Versioning](http://semver.org/).
|
|
7
|
+
|
|
8
|
+
## [0.1.0] - 2026-03-24
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Initial release.
|
pipetasks-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pipetasks
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Utils to build pipelines
|
|
5
|
+
Author-email: Armando Ezequiel Puerta <armando.ezequiel.puerta@gmail.com>
|
|
6
|
+
License: MIT License
|
|
7
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
8
|
+
Classifier: Intended Audience :: Developers
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Topic :: Software Development
|
|
13
|
+
Requires-Python: >=3.11.7
|
|
14
|
+
Requires-Dist: selenium>=4.41.0
|
|
15
|
+
Requires-Dist: webdriver-manager>=4.0.2
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
|
|
18
|
+
# Pipetasks
|
|
19
|
+
|
|
20
|
+
Utils to build pipelines
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import time
|
|
2
|
+
|
|
3
|
+
from selenium.common.exceptions import (
|
|
4
|
+
NoSuchElementException,
|
|
5
|
+
TimeoutException,
|
|
6
|
+
)
|
|
7
|
+
from selenium.webdriver.chrome.options import Options
|
|
8
|
+
from selenium.webdriver.chrome.service import Service
|
|
9
|
+
from selenium.webdriver.chrome.webdriver import WebDriver as ChromeDriver
|
|
10
|
+
from selenium.webdriver.common.by import By
|
|
11
|
+
from selenium.webdriver.remote.webelement import WebElement
|
|
12
|
+
from selenium.webdriver.support import expected_conditions as EC
|
|
13
|
+
from selenium.webdriver.support.ui import WebDriverWait
|
|
14
|
+
from webdriver_manager.chrome import ChromeDriverManager
|
|
15
|
+
|
|
16
|
+
from pipetasks.pipeline import Pipeline
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class ScrapingPipeline(Pipeline):
|
|
20
|
+
TIMEOUT = 0.5
|
|
21
|
+
name = "Scrapper"
|
|
22
|
+
|
|
23
|
+
def __init__( # type: ignore[no-untyped-def]
|
|
24
|
+
self,
|
|
25
|
+
headless: bool = True,
|
|
26
|
+
*args,
|
|
27
|
+
**kwargs,
|
|
28
|
+
):
|
|
29
|
+
self.driver = self.__init_driver(headless=headless)
|
|
30
|
+
super().__init__(*args, **kwargs)
|
|
31
|
+
|
|
32
|
+
def __init_driver(
|
|
33
|
+
self,
|
|
34
|
+
headless: bool = True,
|
|
35
|
+
) -> ChromeDriver:
|
|
36
|
+
chrome_options = Options()
|
|
37
|
+
if headless:
|
|
38
|
+
chrome_options.add_argument("--headless=new")
|
|
39
|
+
chrome_options.add_argument("--disable-gpu")
|
|
40
|
+
chrome_options.add_argument("--no-sandbox")
|
|
41
|
+
chrome_options.add_argument("--disable-dev-shm-usage")
|
|
42
|
+
|
|
43
|
+
return ChromeDriver(
|
|
44
|
+
service=Service(ChromeDriverManager().install()),
|
|
45
|
+
options=chrome_options,
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
def sleep(self, seconds: float | None = None) -> None:
|
|
49
|
+
secs = seconds if seconds else self.TIMEOUT
|
|
50
|
+
time.sleep(secs)
|
|
51
|
+
|
|
52
|
+
def __timeout(self, seconds: float | None = None) -> float:
|
|
53
|
+
return seconds if seconds is not None else self.TIMEOUT
|
|
54
|
+
|
|
55
|
+
def get(self, dns: str) -> None:
|
|
56
|
+
self.driver.get(dns)
|
|
57
|
+
self.sleep()
|
|
58
|
+
|
|
59
|
+
def find_element(
|
|
60
|
+
self,
|
|
61
|
+
by: str,
|
|
62
|
+
value: str,
|
|
63
|
+
on: WebElement | None = None,
|
|
64
|
+
timeout: float | None = None,
|
|
65
|
+
) -> WebElement:
|
|
66
|
+
if on:
|
|
67
|
+
return on.find_element(by, value)
|
|
68
|
+
else:
|
|
69
|
+
return WebDriverWait(
|
|
70
|
+
self.driver,
|
|
71
|
+
self.__timeout(timeout),
|
|
72
|
+
).until(EC.presence_of_element_located((by, value)))
|
|
73
|
+
|
|
74
|
+
def find_elements(
|
|
75
|
+
self,
|
|
76
|
+
by: str,
|
|
77
|
+
value: str,
|
|
78
|
+
on: WebElement | None = None,
|
|
79
|
+
timeout: float | None = None,
|
|
80
|
+
) -> list[WebElement]:
|
|
81
|
+
if on:
|
|
82
|
+
return on.find_elements(by, value)
|
|
83
|
+
else:
|
|
84
|
+
return WebDriverWait(
|
|
85
|
+
self.driver,
|
|
86
|
+
self.__timeout(timeout),
|
|
87
|
+
).until(EC.presence_of_all_elements_located((by, value)))
|
|
88
|
+
|
|
89
|
+
def click(
|
|
90
|
+
self,
|
|
91
|
+
by: str,
|
|
92
|
+
value: str,
|
|
93
|
+
on: WebElement | None = None,
|
|
94
|
+
timeout: float | None = None,
|
|
95
|
+
) -> None:
|
|
96
|
+
wait_timeout = self.__timeout(timeout)
|
|
97
|
+
element = self.find_element(
|
|
98
|
+
by,
|
|
99
|
+
value,
|
|
100
|
+
on=on,
|
|
101
|
+
timeout=wait_timeout,
|
|
102
|
+
)
|
|
103
|
+
WebDriverWait(self.driver, wait_timeout).until(
|
|
104
|
+
EC.element_to_be_clickable(element)
|
|
105
|
+
).click()
|
|
106
|
+
self.sleep()
|
|
107
|
+
|
|
108
|
+
def retry(
|
|
109
|
+
self,
|
|
110
|
+
*xpaths: str,
|
|
111
|
+
timeout: float | None = None,
|
|
112
|
+
) -> WebElement:
|
|
113
|
+
wait_timeout = self.__timeout(timeout)
|
|
114
|
+
for xpath in xpaths:
|
|
115
|
+
try:
|
|
116
|
+
return self.find_element(
|
|
117
|
+
By.XPATH,
|
|
118
|
+
xpath,
|
|
119
|
+
timeout=wait_timeout,
|
|
120
|
+
)
|
|
121
|
+
except TimeoutException:
|
|
122
|
+
continue
|
|
123
|
+
raise NoSuchElementException("No se encontró el elemento deseado.") from None
|
|
124
|
+
|
|
125
|
+
def run(self) -> None:
|
|
126
|
+
pass
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "pipetasks"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Utils to build pipelines"
|
|
5
|
+
authors = [
|
|
6
|
+
{name = "Armando Ezequiel Puerta", email = "armando.ezequiel.puerta@gmail.com"}
|
|
7
|
+
]
|
|
8
|
+
license = {text = "MIT License"}
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
classifiers = [
|
|
11
|
+
"Development Status :: 5 - Production/Stable",
|
|
12
|
+
"Programming Language :: Python :: 3",
|
|
13
|
+
"Intended Audience :: Developers",
|
|
14
|
+
"License :: OSI Approved :: MIT License",
|
|
15
|
+
"Operating System :: OS Independent",
|
|
16
|
+
"Topic :: Software Development"]
|
|
17
|
+
requires-python = ">=3.11.7"
|
|
18
|
+
dependencies = [
|
|
19
|
+
"selenium>=4.41.0",
|
|
20
|
+
"webdriver-manager>=4.0.2",
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
[dependency-groups]
|
|
24
|
+
dev = [
|
|
25
|
+
"mypy>=1.19.1",
|
|
26
|
+
"pre-commit>=4.5.1",
|
|
27
|
+
"pytest>=9.0.2",
|
|
28
|
+
"pytest-cov>=7.1.0",
|
|
29
|
+
"ruff>=0.15.7",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
[build-system]
|
|
33
|
+
requires = ["hatchling"]
|
|
34
|
+
build-backend = "hatchling.build"
|
|
35
|
+
|
|
36
|
+
[tool.hatch.build.targets.wheel]
|
|
37
|
+
packages = ["pipetasks"]
|
|
38
|
+
|
|
39
|
+
[tool.pytest.ini_options]
|
|
40
|
+
markers = [
|
|
41
|
+
"integration: tests using external resources (Chrome, etc)",
|
|
42
|
+
]
|
|
43
|
+
addopts = "-m 'not integration'"
|
|
44
|
+
|
|
45
|
+
#############################################
|
|
46
|
+
# RUFF
|
|
47
|
+
#############################################
|
|
48
|
+
[tool.ruff]
|
|
49
|
+
line-length = 88
|
|
50
|
+
target-version = "py312"
|
|
51
|
+
extend-exclude = []
|
|
52
|
+
|
|
53
|
+
# Esto activa reglas equivalentes a flake8, isort, pyupgrade,
|
|
54
|
+
# bugs típicos y mejores prácticas.
|
|
55
|
+
lint.select = [
|
|
56
|
+
"E", # errores estilo
|
|
57
|
+
"F", # errores de flake8
|
|
58
|
+
"I", # orden de imports (isort)
|
|
59
|
+
"B", # bugbear
|
|
60
|
+
"UP", # pyupgrade
|
|
61
|
+
"C4", # comprehensions
|
|
62
|
+
"W", # warnings
|
|
63
|
+
]
|
|
64
|
+
|
|
65
|
+
lint.ignore = [
|
|
66
|
+
"E203", # compatibilidad con estilo Black
|
|
67
|
+
"E501",
|
|
68
|
+
]
|
|
69
|
+
|
|
70
|
+
#############################################
|
|
71
|
+
# RUFF ISORT
|
|
72
|
+
#############################################
|
|
73
|
+
[tool.ruff.lint.isort]
|
|
74
|
+
combine-as-imports = true
|
|
75
|
+
known-first-party = ["core"]
|
|
76
|
+
force-single-line = false
|
|
77
|
+
|
|
78
|
+
#############################################
|
|
79
|
+
# RUFF FORMAT
|
|
80
|
+
#############################################
|
|
81
|
+
[tool.ruff.format]
|
|
82
|
+
quote-style = "double"
|
|
83
|
+
indent-style = "space"
|
|
84
|
+
line-ending = "auto"
|
|
85
|
+
|
|
86
|
+
#############################################
|
|
87
|
+
# COVERAGE
|
|
88
|
+
#############################################
|
|
89
|
+
[tool.coverage.run]
|
|
90
|
+
branch = true
|
|
91
|
+
source = ["."]
|
|
92
|
+
omit = [
|
|
93
|
+
"*/__init__.py"
|
|
94
|
+
]
|
|
95
|
+
|
|
96
|
+
[tool.coverage.report]
|
|
97
|
+
show_missing = true
|
|
98
|
+
skip_covered = false
|
|
99
|
+
|
|
100
|
+
#############################################
|
|
101
|
+
# MYPY
|
|
102
|
+
#############################################
|
|
103
|
+
[tool.mypy]
|
|
104
|
+
python_version = "3.11"
|
|
105
|
+
strict = false
|
|
106
|
+
warn_unused_ignores = true
|
|
107
|
+
warn_redundant_casts = true
|
|
108
|
+
warn_return_any = true
|
|
109
|
+
disallow_any_generics = true
|
|
110
|
+
check_untyped_defs = true
|
|
111
|
+
no_implicit_reexport = true
|
|
112
|
+
disallow_untyped_defs = true
|
|
113
|
+
ignore_missing_imports = true
|
|
114
|
+
|
|
115
|
+
[[tool.mypy.overrides]]
|
|
116
|
+
module = "tests.*"
|
|
117
|
+
ignore_errors = true
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from unittest.mock import MagicMock, patch
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@pytest.fixture
|
|
7
|
+
def mock_driver():
|
|
8
|
+
return MagicMock()
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@pytest.fixture
|
|
12
|
+
def scraping_pipeline(mock_driver):
|
|
13
|
+
with (
|
|
14
|
+
patch("pipetasks.scraping.pipeline.ChromeDriverManager"),
|
|
15
|
+
patch("pipetasks.scraping.pipeline.ChromeDriver", return_value=mock_driver),
|
|
16
|
+
):
|
|
17
|
+
from pipetasks.scraping.pipeline import ScrapingPipeline
|
|
18
|
+
|
|
19
|
+
yield ScrapingPipeline()
|