pyvizion 0.3.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.
- pyvizion-0.3.0/.gitignore +39 -0
- pyvizion-0.3.0/LICENSE +5 -0
- pyvizion-0.3.0/PKG-INFO +166 -0
- pyvizion-0.3.0/README.md +122 -0
- pyvizion-0.3.0/pyproject.toml +91 -0
- pyvizion-0.3.0/src/vizion/__init__.py +178 -0
- pyvizion-0.3.0/src/vizion/bot.py +152 -0
- pyvizion-0.3.0/src/vizion/core/__init__.py +31 -0
- pyvizion-0.3.0/src/vizion/core/actions.py +224 -0
- pyvizion-0.3.0/src/vizion/core/aliases.py +68 -0
- pyvizion-0.3.0/src/vizion/core/catalog.py +57 -0
- pyvizion-0.3.0/src/vizion/core/config.py +169 -0
- pyvizion-0.3.0/src/vizion/core/docs.py +142 -0
- pyvizion-0.3.0/src/vizion/core/doctor.py +32 -0
- pyvizion-0.3.0/src/vizion/core/driver.py +640 -0
- pyvizion-0.3.0/src/vizion/core/element.py +109 -0
- pyvizion-0.3.0/src/vizion/core/exceptions.py +61 -0
- pyvizion-0.3.0/src/vizion/core/overlay.py +74 -0
- pyvizion-0.3.0/src/vizion/core/runtime.py +158 -0
- pyvizion-0.3.0/src/vizion/core/session.py +64 -0
- pyvizion-0.3.0/src/vizion/core/strategies.py +532 -0
- pyvizion-0.3.0/src/vizion/core/tasks.py +188 -0
- pyvizion-0.3.0/src/vizion/core/types.py +198 -0
- pyvizion-0.3.0/src/vizion/desktop/__init__.py +9 -0
- pyvizion-0.3.0/src/vizion/desktop/bot.py +646 -0
- pyvizion-0.3.0/src/vizion/desktop/capture.py +78 -0
- pyvizion-0.3.0/src/vizion/desktop/clipboard.py +23 -0
- pyvizion-0.3.0/src/vizion/desktop/files.py +50 -0
- pyvizion-0.3.0/src/vizion/desktop/input.py +215 -0
- pyvizion-0.3.0/src/vizion/desktop/overlay.py +70 -0
- pyvizion-0.3.0/src/vizion/desktop/virtual_mouse.py +102 -0
- pyvizion-0.3.0/src/vizion/desktop/windows.py +135 -0
- pyvizion-0.3.0/src/vizion/ocr/__init__.py +6 -0
- pyvizion-0.3.0/src/vizion/ocr/engine.py +357 -0
- pyvizion-0.3.0/src/vizion/ocr/preprocess.py +75 -0
- pyvizion-0.3.0/src/vizion/py.typed +1 -0
- pyvizion-0.3.0/src/vizion/utils/__init__.py +6 -0
- pyvizion-0.3.0/src/vizion/utils/image.py +123 -0
- pyvizion-0.3.0/src/vizion/utils/screen.py +102 -0
- pyvizion-0.3.0/src/vizion/vision/__init__.py +6 -0
- pyvizion-0.3.0/src/vizion/vision/matcher.py +310 -0
- pyvizion-0.3.0/src/vizion/vision/relative.py +39 -0
- pyvizion-0.3.0/src/vizion/web/__init__.py +7 -0
- pyvizion-0.3.0/tests/test_actions.py +27 -0
- pyvizion-0.3.0/tests/test_bot.py +90 -0
- pyvizion-0.3.0/tests/test_catalog.py +18 -0
- pyvizion-0.3.0/tests/test_desktop.py +180 -0
- pyvizion-0.3.0/tests/test_driver.py +298 -0
- pyvizion-0.3.0/tests/test_image.py +61 -0
- pyvizion-0.3.0/tests/test_matcher.py +98 -0
- pyvizion-0.3.0/tests/test_ocr.py +73 -0
- pyvizion-0.3.0/tests/test_relative.py +50 -0
- pyvizion-0.3.0/tests/test_screen.py +93 -0
- pyvizion-0.3.0/tests/test_strategies.py +19 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Byte-compiled / cache
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
.mypy_cache/
|
|
8
|
+
.pytest_cache/
|
|
9
|
+
.ruff_cache/
|
|
10
|
+
.coverage
|
|
11
|
+
htmlcov/
|
|
12
|
+
.tox/
|
|
13
|
+
.nox/
|
|
14
|
+
|
|
15
|
+
# Virtualenvs and packaging
|
|
16
|
+
.venv/
|
|
17
|
+
venv/
|
|
18
|
+
env/
|
|
19
|
+
*.egg-info/
|
|
20
|
+
.eggs/
|
|
21
|
+
dist/
|
|
22
|
+
build/
|
|
23
|
+
|
|
24
|
+
# Editors / OS
|
|
25
|
+
.idea/
|
|
26
|
+
.vscode/
|
|
27
|
+
*.swp
|
|
28
|
+
Thumbs.db
|
|
29
|
+
.DS_Store
|
|
30
|
+
|
|
31
|
+
# Secrets and local env
|
|
32
|
+
.env
|
|
33
|
+
.env.*
|
|
34
|
+
!.env.example
|
|
35
|
+
|
|
36
|
+
# Screenshots / debug dumps
|
|
37
|
+
*.png
|
|
38
|
+
*.jpg
|
|
39
|
+
!tests/fixtures/**
|
pyvizion-0.3.0/LICENSE
ADDED
pyvizion-0.3.0/PKG-INFO
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: pyvizion
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: RPA híbrido: Selenium no navegador e visão/OCR na tela, um só pipeline.
|
|
5
|
+
Author: Josias Azevedo da Silva
|
|
6
|
+
License: Copyright (c) 2026 Josias Azevedo da Silva. All rights reserved.
|
|
7
|
+
|
|
8
|
+
This software is proprietary and confidential. Unauthorized copying,
|
|
9
|
+
distribution, modification, or use of this software, via any medium,
|
|
10
|
+
is strictly prohibited without prior written permission.
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: browser-automation,computer-vision,desktop-automation,ocr,opencv,rpa,selenium,template-matching
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: Other/Proprietary License
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering :: Image Recognition
|
|
22
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
23
|
+
Classifier: Typing :: Typed
|
|
24
|
+
Requires-Python: >=3.10
|
|
25
|
+
Requires-Dist: easyocr>=1.7.1
|
|
26
|
+
Requires-Dist: mss>=9.0.0
|
|
27
|
+
Requires-Dist: numpy>=1.24
|
|
28
|
+
Requires-Dist: opencv-python-headless>=4.8
|
|
29
|
+
Requires-Dist: pillow>=10.0.0
|
|
30
|
+
Requires-Dist: psutil>=5.9.0
|
|
31
|
+
Requires-Dist: pyautogui>=0.9.54
|
|
32
|
+
Requires-Dist: pyperclip>=1.8.2
|
|
33
|
+
Requires-Dist: pytesseract>=0.3.10
|
|
34
|
+
Requires-Dist: pywin32>=306; sys_platform == 'win32'
|
|
35
|
+
Requires-Dist: pywinauto>=0.6.8; sys_platform == 'win32'
|
|
36
|
+
Requires-Dist: rapidfuzz>=3.0
|
|
37
|
+
Requires-Dist: selenium>=4.15
|
|
38
|
+
Provides-Extra: dev
|
|
39
|
+
Requires-Dist: mypy>=1.8; extra == 'dev'
|
|
40
|
+
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
|
|
41
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
42
|
+
Requires-Dist: ruff>=0.5; extra == 'dev'
|
|
43
|
+
Description-Content-Type: text/markdown
|
|
44
|
+
|
|
45
|
+
# Vizion
|
|
46
|
+
|
|
47
|
+
RPA em Python para **página no navegador** e **tela do Windows**. Você aponta o alvo — recorte PNG, palavra visível ou seletor Selenium — e o Vizion tenta achar: primeiro no DOM, depois por imagem, depois por OCR.
|
|
48
|
+
|
|
49
|
+
```python
|
|
50
|
+
from vizion import Bot
|
|
51
|
+
|
|
52
|
+
bot = Bot() # área de trabalho
|
|
53
|
+
# bot = Bot(webdriver.Chrome()) # Chrome já aberto
|
|
54
|
+
|
|
55
|
+
bot.click(image="ok.png", timeout=10)
|
|
56
|
+
bot.click(text="Salvar", sendtext="{enter}")
|
|
57
|
+
bot.click(anchor="linha.png", target="editar.png")
|
|
58
|
+
bot.wait(image="spinner.png", timeout=30, gone=True)
|
|
59
|
+
bot.keyboard("Ctrl+S")
|
|
60
|
+
print(bot.result())
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Código em inglês (`click`, `timeout`, `image`). Só este README está em português.
|
|
64
|
+
|
|
65
|
+
## Instalação
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
pip install pyvizion
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
O pacote no PyPI chama-se **pyvizion**; no código você continua com `from vizion import Bot`.
|
|
72
|
+
|
|
73
|
+
Sobe Selenium, OpenCV, EasyOCR, Tesseract (wrapper), PyAutoGUI, mss e, no Windows, pywin32. O executável do Tesseract no sistema continua sendo um requisito do SO se você for usar esse backend.
|
|
74
|
+
|
|
75
|
+
## Como o alvo é encontrado
|
|
76
|
+
|
|
77
|
+
No **navegador** a ordem é:
|
|
78
|
+
|
|
79
|
+
1. seletor DOM (`by` + `value`)
|
|
80
|
+
2. texto visível no DOM
|
|
81
|
+
3. iframe / shadow DOM
|
|
82
|
+
4. recorte OpenCV (várias escalas, HiDPI)
|
|
83
|
+
5. bordas Canny (tema claro/escuro)
|
|
84
|
+
6. ORB + homografia
|
|
85
|
+
7. OCR (EasyOCR, com Tesseract de reserva)
|
|
86
|
+
8. scroll da página e nova passada
|
|
87
|
+
|
|
88
|
+
No **desktop** os passos de DOM somem: recorte → Canny → ORB → OCR.
|
|
89
|
+
|
|
90
|
+
O clique no browser usa coordenada CSS (PNG vs `innerWidth`), não pixel cru da screenshot. No desktop, pixel físico do `mss` vira coordenada lógica do SO.
|
|
91
|
+
|
|
92
|
+
## Navegador
|
|
93
|
+
|
|
94
|
+
```python
|
|
95
|
+
from selenium import webdriver
|
|
96
|
+
from selenium.webdriver.common.by import By
|
|
97
|
+
from vizion import Vizion, VizionConfig
|
|
98
|
+
|
|
99
|
+
pagina = Vizion.web(
|
|
100
|
+
webdriver.Chrome(),
|
|
101
|
+
config=VizionConfig(default_timeout=15, show_overlay=True),
|
|
102
|
+
)
|
|
103
|
+
pagina.get("https://intranet")
|
|
104
|
+
pagina.find_and_click(by=By.ID, value="user", template="user.png", text="Usuário")
|
|
105
|
+
pagina.wait_url("/home")
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
`find_and_click` aceita seletor, recorte e texto **ao mesmo tempo**: se o DOM falhar, a visão e o OCR entram.
|
|
109
|
+
|
|
110
|
+
## Área de trabalho
|
|
111
|
+
|
|
112
|
+
```python
|
|
113
|
+
from vizion import Vizion, VizionConfig
|
|
114
|
+
|
|
115
|
+
tela = Vizion.desktop(config=VizionConfig(use_virtual_mouse=True))
|
|
116
|
+
tela.register_image("ok", "ok.png")
|
|
117
|
+
tela.click_image("ok")
|
|
118
|
+
tela.click_text("Confirmar")
|
|
119
|
+
tela.keyboard("Ctrl+S")
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
`use_virtual_mouse=True` (Windows) clica sem deixar o cursor no alvo.
|
|
123
|
+
|
|
124
|
+
Do desktop dá para abrir o Chrome e continuar no mesmo catálogo de imagens:
|
|
125
|
+
|
|
126
|
+
```python
|
|
127
|
+
tela = Vizion.desktop()
|
|
128
|
+
pagina = tela.open_browser("https://intranet")
|
|
129
|
+
pagina.find_and_click(by="id", value="user")
|
|
130
|
+
tela.click_image("ok.png")
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Vários alvos iguais
|
|
134
|
+
|
|
135
|
+
Quando o mesmo botão aparece várias vezes, passe uma âncora única e o recorte do botão:
|
|
136
|
+
|
|
137
|
+
```python
|
|
138
|
+
bot.click(anchor="aviso.png", target="ok.png")
|
|
139
|
+
# ou
|
|
140
|
+
tela.click_relative("aviso.png", "ok.png", max_distance=200)
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Lote de passos
|
|
144
|
+
|
|
145
|
+
```python
|
|
146
|
+
bot.run([
|
|
147
|
+
{"image": "menu.png", "timeout": 8},
|
|
148
|
+
{"anchor": "linha.png", "target": "editar.png"},
|
|
149
|
+
{"text": "Salvar", "sendtext": "{enter}"},
|
|
150
|
+
{"type": "keyboard", "command": "Ctrl+S"},
|
|
151
|
+
])
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
O motor avançado (`Vizion.web` / `Vizion.desktop`) expõe o mesmo lote em `execute_tasks`.
|
|
155
|
+
|
|
156
|
+
## Ajuste
|
|
157
|
+
|
|
158
|
+
`VizionConfig` controla timeout, limiar OpenCV, overlay, idiomas OCR, mouse virtual. `print(doctor())` lista o que está instalado.
|
|
159
|
+
|
|
160
|
+
No IDE, `help(VizionDriver.find_and_click)` mostra o contrato completo (seletor, recorte, OCR, overlay).
|
|
161
|
+
|
|
162
|
+
## Licença
|
|
163
|
+
|
|
164
|
+
Software proprietário. Ver `LICENSE`.
|
|
165
|
+
|
|
166
|
+
Desenvolvido por Josias Azevedo da Silva.
|
pyvizion-0.3.0/README.md
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# Vizion
|
|
2
|
+
|
|
3
|
+
RPA em Python para **página no navegador** e **tela do Windows**. Você aponta o alvo — recorte PNG, palavra visível ou seletor Selenium — e o Vizion tenta achar: primeiro no DOM, depois por imagem, depois por OCR.
|
|
4
|
+
|
|
5
|
+
```python
|
|
6
|
+
from vizion import Bot
|
|
7
|
+
|
|
8
|
+
bot = Bot() # área de trabalho
|
|
9
|
+
# bot = Bot(webdriver.Chrome()) # Chrome já aberto
|
|
10
|
+
|
|
11
|
+
bot.click(image="ok.png", timeout=10)
|
|
12
|
+
bot.click(text="Salvar", sendtext="{enter}")
|
|
13
|
+
bot.click(anchor="linha.png", target="editar.png")
|
|
14
|
+
bot.wait(image="spinner.png", timeout=30, gone=True)
|
|
15
|
+
bot.keyboard("Ctrl+S")
|
|
16
|
+
print(bot.result())
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Código em inglês (`click`, `timeout`, `image`). Só este README está em português.
|
|
20
|
+
|
|
21
|
+
## Instalação
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pip install pyvizion
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
O pacote no PyPI chama-se **pyvizion**; no código você continua com `from vizion import Bot`.
|
|
28
|
+
|
|
29
|
+
Sobe Selenium, OpenCV, EasyOCR, Tesseract (wrapper), PyAutoGUI, mss e, no Windows, pywin32. O executável do Tesseract no sistema continua sendo um requisito do SO se você for usar esse backend.
|
|
30
|
+
|
|
31
|
+
## Como o alvo é encontrado
|
|
32
|
+
|
|
33
|
+
No **navegador** a ordem é:
|
|
34
|
+
|
|
35
|
+
1. seletor DOM (`by` + `value`)
|
|
36
|
+
2. texto visível no DOM
|
|
37
|
+
3. iframe / shadow DOM
|
|
38
|
+
4. recorte OpenCV (várias escalas, HiDPI)
|
|
39
|
+
5. bordas Canny (tema claro/escuro)
|
|
40
|
+
6. ORB + homografia
|
|
41
|
+
7. OCR (EasyOCR, com Tesseract de reserva)
|
|
42
|
+
8. scroll da página e nova passada
|
|
43
|
+
|
|
44
|
+
No **desktop** os passos de DOM somem: recorte → Canny → ORB → OCR.
|
|
45
|
+
|
|
46
|
+
O clique no browser usa coordenada CSS (PNG vs `innerWidth`), não pixel cru da screenshot. No desktop, pixel físico do `mss` vira coordenada lógica do SO.
|
|
47
|
+
|
|
48
|
+
## Navegador
|
|
49
|
+
|
|
50
|
+
```python
|
|
51
|
+
from selenium import webdriver
|
|
52
|
+
from selenium.webdriver.common.by import By
|
|
53
|
+
from vizion import Vizion, VizionConfig
|
|
54
|
+
|
|
55
|
+
pagina = Vizion.web(
|
|
56
|
+
webdriver.Chrome(),
|
|
57
|
+
config=VizionConfig(default_timeout=15, show_overlay=True),
|
|
58
|
+
)
|
|
59
|
+
pagina.get("https://intranet")
|
|
60
|
+
pagina.find_and_click(by=By.ID, value="user", template="user.png", text="Usuário")
|
|
61
|
+
pagina.wait_url("/home")
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
`find_and_click` aceita seletor, recorte e texto **ao mesmo tempo**: se o DOM falhar, a visão e o OCR entram.
|
|
65
|
+
|
|
66
|
+
## Área de trabalho
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
from vizion import Vizion, VizionConfig
|
|
70
|
+
|
|
71
|
+
tela = Vizion.desktop(config=VizionConfig(use_virtual_mouse=True))
|
|
72
|
+
tela.register_image("ok", "ok.png")
|
|
73
|
+
tela.click_image("ok")
|
|
74
|
+
tela.click_text("Confirmar")
|
|
75
|
+
tela.keyboard("Ctrl+S")
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
`use_virtual_mouse=True` (Windows) clica sem deixar o cursor no alvo.
|
|
79
|
+
|
|
80
|
+
Do desktop dá para abrir o Chrome e continuar no mesmo catálogo de imagens:
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
tela = Vizion.desktop()
|
|
84
|
+
pagina = tela.open_browser("https://intranet")
|
|
85
|
+
pagina.find_and_click(by="id", value="user")
|
|
86
|
+
tela.click_image("ok.png")
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Vários alvos iguais
|
|
90
|
+
|
|
91
|
+
Quando o mesmo botão aparece várias vezes, passe uma âncora única e o recorte do botão:
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
bot.click(anchor="aviso.png", target="ok.png")
|
|
95
|
+
# ou
|
|
96
|
+
tela.click_relative("aviso.png", "ok.png", max_distance=200)
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Lote de passos
|
|
100
|
+
|
|
101
|
+
```python
|
|
102
|
+
bot.run([
|
|
103
|
+
{"image": "menu.png", "timeout": 8},
|
|
104
|
+
{"anchor": "linha.png", "target": "editar.png"},
|
|
105
|
+
{"text": "Salvar", "sendtext": "{enter}"},
|
|
106
|
+
{"type": "keyboard", "command": "Ctrl+S"},
|
|
107
|
+
])
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
O motor avançado (`Vizion.web` / `Vizion.desktop`) expõe o mesmo lote em `execute_tasks`.
|
|
111
|
+
|
|
112
|
+
## Ajuste
|
|
113
|
+
|
|
114
|
+
`VizionConfig` controla timeout, limiar OpenCV, overlay, idiomas OCR, mouse virtual. `print(doctor())` lista o que está instalado.
|
|
115
|
+
|
|
116
|
+
No IDE, `help(VizionDriver.find_and_click)` mostra o contrato completo (seletor, recorte, OCR, overlay).
|
|
117
|
+
|
|
118
|
+
## Licença
|
|
119
|
+
|
|
120
|
+
Software proprietário. Ver `LICENSE`.
|
|
121
|
+
|
|
122
|
+
Desenvolvido por Josias Azevedo da Silva.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "pyvizion"
|
|
7
|
+
version = "0.3.0"
|
|
8
|
+
description = "RPA híbrido: Selenium no navegador e visão/OCR na tela, um só pipeline."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = { file = "LICENSE" }
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
|
+
authors = [
|
|
13
|
+
{ name = "Josias Azevedo da Silva" },
|
|
14
|
+
]
|
|
15
|
+
keywords = [
|
|
16
|
+
"rpa",
|
|
17
|
+
"selenium",
|
|
18
|
+
"opencv",
|
|
19
|
+
"ocr",
|
|
20
|
+
"computer-vision",
|
|
21
|
+
"browser-automation",
|
|
22
|
+
"desktop-automation",
|
|
23
|
+
"template-matching",
|
|
24
|
+
]
|
|
25
|
+
classifiers = [
|
|
26
|
+
"Development Status :: 4 - Beta",
|
|
27
|
+
"Intended Audience :: Developers",
|
|
28
|
+
"License :: Other/Proprietary License",
|
|
29
|
+
"Programming Language :: Python :: 3",
|
|
30
|
+
"Programming Language :: Python :: 3.10",
|
|
31
|
+
"Programming Language :: Python :: 3.11",
|
|
32
|
+
"Programming Language :: Python :: 3.12",
|
|
33
|
+
"Programming Language :: Python :: 3.13",
|
|
34
|
+
"Topic :: Software Development :: Libraries",
|
|
35
|
+
"Topic :: Scientific/Engineering :: Image Recognition",
|
|
36
|
+
"Typing :: Typed",
|
|
37
|
+
]
|
|
38
|
+
dependencies = [
|
|
39
|
+
"selenium>=4.15",
|
|
40
|
+
"opencv-python-headless>=4.8",
|
|
41
|
+
"numpy>=1.24",
|
|
42
|
+
"rapidfuzz>=3.0",
|
|
43
|
+
"easyocr>=1.7.1",
|
|
44
|
+
"pytesseract>=0.3.10",
|
|
45
|
+
"pyautogui>=0.9.54",
|
|
46
|
+
"mss>=9.0.0",
|
|
47
|
+
"Pillow>=10.0.0",
|
|
48
|
+
"pyperclip>=1.8.2",
|
|
49
|
+
"psutil>=5.9.0",
|
|
50
|
+
"pywin32>=306; sys_platform == 'win32'",
|
|
51
|
+
"pywinauto>=0.6.8; sys_platform == 'win32'",
|
|
52
|
+
]
|
|
53
|
+
|
|
54
|
+
[project.optional-dependencies]
|
|
55
|
+
dev = [
|
|
56
|
+
"pytest>=8.0",
|
|
57
|
+
"pytest-cov>=5.0",
|
|
58
|
+
"ruff>=0.5",
|
|
59
|
+
"mypy>=1.8",
|
|
60
|
+
]
|
|
61
|
+
|
|
62
|
+
[tool.hatch.build.targets.wheel]
|
|
63
|
+
packages = ["src/vizion"]
|
|
64
|
+
|
|
65
|
+
[tool.hatch.build.targets.sdist]
|
|
66
|
+
include = [
|
|
67
|
+
"/src",
|
|
68
|
+
"/tests",
|
|
69
|
+
"/README.md",
|
|
70
|
+
"/LICENSE",
|
|
71
|
+
]
|
|
72
|
+
|
|
73
|
+
[tool.pytest.ini_options]
|
|
74
|
+
testpaths = ["tests"]
|
|
75
|
+
pythonpath = ["src"]
|
|
76
|
+
addopts = "-q --strict-markers"
|
|
77
|
+
|
|
78
|
+
[tool.ruff]
|
|
79
|
+
line-length = 100
|
|
80
|
+
target-version = "py310"
|
|
81
|
+
src = ["src", "tests"]
|
|
82
|
+
|
|
83
|
+
[tool.ruff.lint]
|
|
84
|
+
select = ["E", "F", "I", "UP", "B", "SIM"]
|
|
85
|
+
ignore = ["SIM105"]
|
|
86
|
+
|
|
87
|
+
[tool.mypy]
|
|
88
|
+
python_version = "3.10"
|
|
89
|
+
strict = true
|
|
90
|
+
packages = ["vizion"]
|
|
91
|
+
mypy_path = "src"
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
"""Vizion — RPA híbrido: navegador (Selenium + visão + OCR) e desktop.
|
|
2
|
+
|
|
3
|
+
Instalação::
|
|
4
|
+
|
|
5
|
+
pip install pyvizion
|
|
6
|
+
|
|
7
|
+
O ``Bot`` escolhe o motor sozinho. Sem WebDriver é a tela; com Chrome
|
|
8
|
+
é a página. Informe recorte, palavra ou os dois::
|
|
9
|
+
|
|
10
|
+
from vizion import Bot
|
|
11
|
+
|
|
12
|
+
bot = Bot()
|
|
13
|
+
bot.click(image="ok.png", timeout=10)
|
|
14
|
+
bot.click(text="Salvar", sendtext="{enter}")
|
|
15
|
+
bot.click(anchor="linha.png", target="editar.png")
|
|
16
|
+
bot.keyboard("Ctrl+S")
|
|
17
|
+
|
|
18
|
+
API dos motores (``find_and_click`` tenta DOM, depois imagem, depois OCR)::
|
|
19
|
+
|
|
20
|
+
from selenium import webdriver
|
|
21
|
+
from vizion import Vizion, VizionConfig, doctor
|
|
22
|
+
|
|
23
|
+
pagina = Vizion.web(webdriver.Chrome())
|
|
24
|
+
pagina.get("https://intranet")
|
|
25
|
+
pagina.find_and_click(by="id", value="user", template="user.png", text="Usuário")
|
|
26
|
+
|
|
27
|
+
tela = Vizion.desktop()
|
|
28
|
+
tela.click_image("ok.png")
|
|
29
|
+
pagina = tela.open_browser("https://intranet")
|
|
30
|
+
|
|
31
|
+
``help(VizionDriver.find_and_click)`` e ``print(doctor())`` no REPL.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
from __future__ import annotations
|
|
35
|
+
|
|
36
|
+
from importlib.metadata import PackageNotFoundError, version
|
|
37
|
+
from typing import Any
|
|
38
|
+
|
|
39
|
+
from vizion.bot import Bot
|
|
40
|
+
from vizion.core.config import DEFAULT_STRATEGIES, DESKTOP_STRATEGIES, VizionConfig
|
|
41
|
+
from vizion.core.doctor import doctor
|
|
42
|
+
from vizion.core.driver import VizionDriver
|
|
43
|
+
from vizion.core.element import VizionElement
|
|
44
|
+
from vizion.core.exceptions import (
|
|
45
|
+
VizionConfigError,
|
|
46
|
+
VizionCoordinateError,
|
|
47
|
+
VizionElementNotFoundException,
|
|
48
|
+
VizionError,
|
|
49
|
+
VizionImageError,
|
|
50
|
+
VizionOCRError,
|
|
51
|
+
VizionTimeoutError,
|
|
52
|
+
)
|
|
53
|
+
from vizion.core.tasks import Task
|
|
54
|
+
from vizion.core.types import BoundingBox, MatchResult, Point, ViewportMetrics
|
|
55
|
+
from vizion.desktop import VizionDesktop
|
|
56
|
+
from vizion.ocr.engine import OCREngine
|
|
57
|
+
from vizion.vision.matcher import TemplateMatcher
|
|
58
|
+
from vizion.web import VizionWeb
|
|
59
|
+
|
|
60
|
+
try:
|
|
61
|
+
__version__ = version("vizion")
|
|
62
|
+
except PackageNotFoundError: # pragma: no cover - árvore local sem instalação
|
|
63
|
+
__version__ = "0.3.0"
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class Vizion:
|
|
67
|
+
"""Abre o motor web ou o de desktop.
|
|
68
|
+
|
|
69
|
+
:meth:`web` envolve um ``WebDriver``. :meth:`desktop` captura a tela.
|
|
70
|
+
Os dois respondem a ``find_and_click``. :meth:`bot` é o vocabulário
|
|
71
|
+
curto (``click``, ``wait``, ``keyboard``).
|
|
72
|
+
|
|
73
|
+
Examples
|
|
74
|
+
--------
|
|
75
|
+
>>> from selenium import webdriver
|
|
76
|
+
>>> from vizion import Vizion
|
|
77
|
+
>>> pagina = Vizion.web(webdriver.Chrome())
|
|
78
|
+
>>> pagina.get("https://example.com")
|
|
79
|
+
>>> pagina.click_text("More information")
|
|
80
|
+
>>> tela = Vizion.bot()
|
|
81
|
+
>>> tela.click(image="ok.png", timeout=8)
|
|
82
|
+
"""
|
|
83
|
+
|
|
84
|
+
@staticmethod
|
|
85
|
+
def web(driver: Any, **kwargs: Any) -> VizionDriver:
|
|
86
|
+
"""Envolve um Selenium WebDriver no motor híbrido de browser.
|
|
87
|
+
|
|
88
|
+
Parameters
|
|
89
|
+
----------
|
|
90
|
+
driver :
|
|
91
|
+
Instância já criada (``webdriver.Chrome()``, Firefox, Edge…).
|
|
92
|
+
config :
|
|
93
|
+
:class:`~vizion.core.config.VizionConfig` opcional.
|
|
94
|
+
matcher, ocr, catalog :
|
|
95
|
+
Substitutos injetáveis (testes ou motores customizados).
|
|
96
|
+
|
|
97
|
+
Returns
|
|
98
|
+
-------
|
|
99
|
+
VizionDriver
|
|
100
|
+
Proxy do WebDriver: ``web.current_url`` continua funcionando.
|
|
101
|
+
|
|
102
|
+
Examples
|
|
103
|
+
--------
|
|
104
|
+
>>> from selenium import webdriver
|
|
105
|
+
>>> from selenium.webdriver.common.by import By
|
|
106
|
+
>>> from vizion import Vizion
|
|
107
|
+
>>> bot = Vizion.web(webdriver.Chrome())
|
|
108
|
+
>>> bot.get("https://example.com")
|
|
109
|
+
>>> bot.find_and_click(by=By.TAG_NAME, value="a", text="More")
|
|
110
|
+
"""
|
|
111
|
+
return VizionDriver(driver, **kwargs)
|
|
112
|
+
|
|
113
|
+
@staticmethod
|
|
114
|
+
def desktop(**kwargs: Any) -> VizionDesktop:
|
|
115
|
+
"""Abre o motor de desktop (captura de tela + mouse/teclado).
|
|
116
|
+
|
|
117
|
+
Parameters
|
|
118
|
+
----------
|
|
119
|
+
config :
|
|
120
|
+
:class:`~vizion.core.config.VizionConfig`. No desktop as
|
|
121
|
+
estratégias DOM são ignoradas automaticamente.
|
|
122
|
+
grab, controller :
|
|
123
|
+
Injeção para testes (não usa mouse/tela reais).
|
|
124
|
+
catalog :
|
|
125
|
+
:class:`~vizion.core.catalog.ImageCatalog` compartilhado.
|
|
126
|
+
|
|
127
|
+
Examples
|
|
128
|
+
--------
|
|
129
|
+
>>> from vizion import Vizion, VizionConfig
|
|
130
|
+
>>> bot = Vizion.desktop(config=VizionConfig(show_overlay=True))
|
|
131
|
+
>>> bot.register_image("ok", "assets/ok.png")
|
|
132
|
+
>>> bot.start_session()
|
|
133
|
+
>>> bot.click_image("ok", backtrack=True)
|
|
134
|
+
>>> print(bot.end_session())
|
|
135
|
+
"""
|
|
136
|
+
return VizionDesktop(**kwargs)
|
|
137
|
+
|
|
138
|
+
@staticmethod
|
|
139
|
+
def bot(driver: Any | None = None, **kwargs: Any) -> Bot:
|
|
140
|
+
"""Automação com vocabulário mínimo (timeout, image, âncora, alvo).
|
|
141
|
+
|
|
142
|
+
Sem ``driver`` → desktop. Com WebDriver → browser. Sessão e
|
|
143
|
+
backtrack ligam sozinhos.
|
|
144
|
+
|
|
145
|
+
>>> bot = Vizion.bot()
|
|
146
|
+
>>> bot.click(image="salvar.png", timeout=10)
|
|
147
|
+
>>> bot.click(anchor="aviso.png", target="ok.png")
|
|
148
|
+
"""
|
|
149
|
+
return Bot(driver, **kwargs)
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
__all__ = [
|
|
153
|
+
"DEFAULT_STRATEGIES",
|
|
154
|
+
"DESKTOP_STRATEGIES",
|
|
155
|
+
"Bot",
|
|
156
|
+
"BoundingBox",
|
|
157
|
+
"MatchResult",
|
|
158
|
+
"OCREngine",
|
|
159
|
+
"Point",
|
|
160
|
+
"Task",
|
|
161
|
+
"TemplateMatcher",
|
|
162
|
+
"ViewportMetrics",
|
|
163
|
+
"Vizion",
|
|
164
|
+
"VizionConfig",
|
|
165
|
+
"VizionConfigError",
|
|
166
|
+
"VizionCoordinateError",
|
|
167
|
+
"VizionDesktop",
|
|
168
|
+
"VizionDriver",
|
|
169
|
+
"VizionElement",
|
|
170
|
+
"VizionElementNotFoundException",
|
|
171
|
+
"VizionError",
|
|
172
|
+
"VizionImageError",
|
|
173
|
+
"VizionOCRError",
|
|
174
|
+
"VizionTimeoutError",
|
|
175
|
+
"VizionWeb",
|
|
176
|
+
"__version__",
|
|
177
|
+
"doctor",
|
|
178
|
+
]
|