Skip to content

Commit 7744d00

Browse files
authored
Merge pull request #179 from vgalin/develop
html2image v2.0.6
2 parents 26efbcb + bb761f5 commit 7744d00

File tree

11 files changed

+170
-77
lines changed

11 files changed

+170
-77
lines changed

.github/workflows/main.yml

Lines changed: 64 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,82 @@
11
name: CI
2+
23
on: [push, pull_request]
3-
# pull_request:
4-
# branches:
5-
# - main
6-
# - develop
7-
# - 'releases/**'
8-
# push:
9-
# branches:
10-
# - main
11-
# - develop
12-
# - 'v**' # temporary
13-
4+
145
jobs:
156
ci:
167
strategy:
178
fail-fast: false
189
matrix:
19-
python-version: [3.6, 3.7, 3.8, 3.9, "3.10"]
20-
poetry-version: [1.1.4]
21-
os: [ubuntu-18.04, macos-latest, windows-latest]
10+
# UV requires Python 3.8+ to run, but it can manage environments for older Python versions.
11+
# actions/setup-python handles installing the target Python for the job.
12+
python-version: ["3.6", "3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.12"]
13+
os: [ubuntu-latest, macos-latest, windows-latest]
2214
runs-on: ${{ matrix.os }}
2315
steps:
24-
- uses: actions/checkout@v2
25-
- uses: actions/setup-python@v2
16+
- name: Checkout repository
17+
uses: actions/checkout@v4
18+
19+
- name: Set up Python
20+
uses: actions/setup-python@v5
2621
with:
2722
python-version: ${{ matrix.python-version }}
28-
- name: Python Poetry Action
29-
uses: abatilo/actions-poetry@v2.1.0
23+
24+
- name: Set up UV
25+
uses: astral-sh/setup-uv@v1 # official action for UV
3026
with:
31-
poetry-version: ${{ matrix.poetry-version }}
27+
# Optional: Pin to a specific UV version for more deterministic builds
28+
# version: "0.1.20" # Example version, check latest if pinning
29+
enable-cache: true # Optional: enable UV caching for faster builds
30+
3231
- name: Install dependencies
3332
run: |
34-
python -m pip install --upgrade pip
35-
pip install flake8 pytest
36-
pip install -r requirements.txt
37-
pip install -r requirements-test.txt
33+
# Use --system to install into the Python environment set up by actions/setup-python.
34+
uv pip install --system -e .[test,lint]
35+
shell: bash
36+
3837
- name: Flake8 linting
3938
run: |
40-
# stop the build if there are Python syntax errors or undefined names
4139
python -m flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
42-
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
4340
python -m flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
44-
- name: Run python -m pytest
45-
run: |
46-
python -m pytest
41+
shell: bash
42+
43+
- name: Run PyTest
44+
run: python -m pytest
45+
shell: bash
46+
47+
publish:
48+
name: Build and publish to PyPI
49+
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
50+
runs-on: ubuntu-latest
51+
environment:
52+
name: pypi
53+
url: https://pypi.org/p/html2image
54+
permissions:
55+
id-token: write
56+
57+
steps:
58+
- name: Checkout repository
59+
uses: actions/checkout@v4
60+
61+
- name: Set up Python
62+
uses: actions/setup-python@v5
63+
with:
64+
python-version: '3.12' # Use a recent Python for build tools
65+
66+
- name: Set up UV
67+
uses: astral-sh/setup-uv@v1
68+
with:
69+
enable-cache: true
70+
71+
- name: Install build dependencies
72+
# Ensure 'build' is listed in your pyproject.toml [project.optional-dependencies.dev]
73+
# or install it explicitly here.
74+
run: uv pip install --system build
75+
shell: bash
76+
77+
- name: Build package
78+
run: python -m build # This will use hatchling as defined in pyproject.toml
79+
shell: bash
80+
81+
- name: Publish package to PyPI
82+
uses: pypa/gh-action-pypi-publish@release/v1

.gitignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,5 +132,5 @@ dmypy.json
132132
.vscode/
133133
tests_output/
134134

135-
# .lock file not relevant for libraries
136-
poetry.lock
135+
# uv
136+
uv.lock

README.md

Lines changed: 48 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,17 @@ For more information about headless modes :
4141
- (Firefox) [https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Headless_mode](https://web.archive.org/web/20210604151145/https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Headless_mode)
4242

4343
## Installation
44-
HTML2Image is published on PyPI and can be installed through pip:
44+
HTML2Image is published on PyPI and can be installed through `pip`:
4545

4646
```console
4747
pip install --upgrade html2image
4848
```
4949

50+
Or with `uv`:
51+
```console
52+
uv pip install html2image
53+
```
54+
5055
In addition to this package, at least one of the following browsers **must** be installed on your machine :
5156
- Google Chrome (Windows, MacOS)
5257
- Chromium Browser (Linux)
@@ -317,15 +322,6 @@ You can load and execute a python script to use the package, or simply use the C
317322

318323
On top of that, you can also use [volumes](https://docs.docker.com/storage/volumes/) to bind a container directory to your local machine directory, allowing you to retrieve the generated images, or even load some resources (HTML, CSS or Python files).
319324

320-
## Testing
321-
322-
Only basic testing is available at the moment. To run tests, install the requirements (Pillow) and run PyTest at the root of the project:
323-
``` console
324-
pip install -r requirements-test.txt
325-
python -m pytest
326-
```
327-
328-
329325
## FAQ
330326

331327
- Can I automatically take a full page screenshot?
@@ -339,11 +335,52 @@ python -m pytest
339335

340336
- Can I make a cookie modal disappear?
341337
**Yes and no**. **No**, because there is no options to do it magically and [extensions are not supported in headless Chrome](https://bugs.chromium.org/p/chromium/issues/detail?id=706008#c5) (The [`I don't care about cookies`](https://www.i-dont-care-about-cookies.eu/) extension would have been useful in this case). **Yes**, because you can make any element of a page disappear by retrieving its source code, modifying it as you wish, and finally screenshotting the modified source code.
338+
339+
340+
## Contributing and Local Development
341+
342+
If you want to contribute to `html2image` or run tests locally, follow these steps:
343+
344+
1. **Clone the repository:**
345+
```bash
346+
git clone https://github.com/vgalin/html2image.git
347+
cd html2image
348+
```
349+
350+
2. **Install [uv](https://github.com/astral-sh/uv)** by following the installation instructions on the `uv` GitHub page.
351+
352+
3. **Create and activate a virtual environment:**
353+
```bash
354+
uv venv
355+
source .venv/bin/activate # On Linux/macOS
356+
# .\.venv\Scripts\Activate.ps1 # On Windows PowerShell
357+
# .\.venv\Scripts\activate.bat # On Windows CMD
358+
```
359+
360+
4. **Install dependencies (including development tools):**
361+
```bash
362+
uv pip install -e .[dev]
363+
```
364+
This installs the package in editable mode along with all dependencies needed for testing and linting.
365+
366+
### Running Tests
367+
Only basic testing is available at the moment.
368+
To run the test suite:
369+
```console
370+
pytest
371+
```
372+
Or, using `uv`'s runner:
373+
```console
374+
uv run pytest
375+
```
376+
377+
378+
342379
## TODO List
343380
- A nice CLI (currently in a WIP state).
344381
- Support for other browsers, such as Firefox, once their screenshot feature becomes operational.
345382
- PDF generation?
346-
- Contributing, issue templates, pull request template, code of conduct.
383+
- Issue templates, pull request template, code of conduct.
347384
348385
---
349386

html2image/browsers/chrome.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ class ChromeHeadless(ChromiumHeadless):
185185
+ You can also keep the original behavior to backward compatibility by setting this to `None`.
186186
"""
187187

188-
def __init__(self, executable=None, flags=None, print_command=False, disable_logging=False, use_new_headless=False,):
188+
def __init__(self, executable=None, flags=None, print_command=False, disable_logging=False, use_new_headless=None,):
189189
super().__init__(executable=executable, flags=flags, print_command=print_command, disable_logging=disable_logging, use_new_headless=use_new_headless)
190190

191191
@property

html2image/browsers/chrome_cdp.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ def ws(self):
6161
if not self._ws:
6262
print(f'----------- http://localhost:{self.cdp_port}/json/version')
6363
r = requests.get(f'http://localhost:{self.cdp_port}/json') # TODO use page websocket instead of browser one
64-
print(f'{r.json()=}')
64+
print(f'{r.json()}')
6565
print(f'Using ws url= {r.json()[0]["webSocketDebuggerUrl"]}')
6666
self._ws = create_connection(r.json()[0]['webSocketDebuggerUrl'])
6767
print('Successfully connected to ws.')
@@ -75,7 +75,7 @@ def _id(self):
7575
def cdp_send(self, method, **params):
7676
"""
7777
"""
78-
print(f'cdp_send: {method=} {params=}')
78+
print(f'cdp_send: {method} {params}')
7979
return self.ws.send(
8080
json.dumps({
8181
'id': self._id,
@@ -107,7 +107,7 @@ def screenshot(
107107
while True:
108108
message = json.loads(self.ws.recv())
109109
method = message.get('method')
110-
print(f'{method=}')
110+
print(f'{method}')
111111
if method == 'Page.loadEventFired':
112112
break
113113

@@ -159,11 +159,11 @@ def get_page_infos(self):
159159

160160
while True:
161161
message = json.loads(self.ws.recv())
162-
print(f'{message=}')
162+
print(f'{message}')
163163
if 'result' in message and 'layoutViewport' in message['result']:
164164
return message['result']
165165

166-
def print_pdf():
166+
def print_pdf(self):
167167
# TODO : Page.printToPDF
168168
pass
169169

html2image/browsers/chromium.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class ChromiumHeadless(Browser):
2626
+ You can also keep the original behavior to backward compatibility by setting this to `None`.
2727
"""
2828

29-
def __init__(self, executable=None, flags=None, print_command=False, disable_logging=False, use_new_headless=False,):
29+
def __init__(self, executable=None, flags=None, print_command=False, disable_logging=False, use_new_headless=None,):
3030
self.executable = executable
3131
if not flags:
3232
self.flags = [

html2image/browsers/edge.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ class EdgeHeadless(ChromiumHeadless):
165165
+ You can also keep the original behavior to backward compatibility by setting this to `None`.
166166
"""
167167

168-
def __init__(self, executable=None, flags=None, print_command=False, disable_logging=False, use_new_headless=False,):
168+
def __init__(self, executable=None, flags=None, print_command=False, disable_logging=False, use_new_headless=None,):
169169
super().__init__(executable=executable, flags=flags, print_command=print_command, disable_logging=disable_logging, use_new_headless=use_new_headless)
170170

171171
@property

html2image/html2image.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,7 @@ def _prepare_html_string(html_body, css_style_string):
408408
prepared_html = f"""\
409409
<html>
410410
<head>
411+
<meta charset="UTF-8">
411412
<style>
412413
{css_style_string}
413414
</style>

pyproject.toml

Lines changed: 47 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,64 @@
1-
[tool.poetry]
1+
[project]
22
name = "html2image"
3-
version = "2.0.5"
3+
version = "2.0.6" # todo take a look at dynamic versionning (e.g., hatch-vcs)
44
description = "Package acting as a wrapper around the headless mode of existing web browsers to generate images from URLs and from HTML+CSS strings or files."
5-
authors = ["vgalin"]
6-
license = "MIT"
7-
8-
# Added
5+
authors = [
6+
{ name = "vgalin" }
7+
]
8+
license = { file = "LICENSE" }
99
readme = "README.md"
10-
homepage = "https://github.com/vgalin/html2image"
11-
repository = "https://github.com/vgalin/html2image"
10+
1211
keywords = ["html", "css", "screenshot", "image", "chrome", "html to image", "css to image", "chromium-browser", "chromium"]
1312
classifiers = [
1413
"Development Status :: 5 - Production/Stable",
14+
"License :: OSI Approved :: MIT License",
1515
"Programming Language :: Python :: 3 :: Only",
16-
"Operating System :: Microsoft",
17-
"Operating System :: Unix",
16+
"Programming Language :: Python :: 3.6",
17+
"Programming Language :: Python :: 3.7",
18+
"Programming Language :: Python :: 3.8",
19+
"Programming Language :: Python :: 3.9",
20+
"Programming Language :: Python :: 3.10",
21+
"Programming Language :: Python :: 3.11",
22+
"Programming Language :: Python :: 3.12",
23+
"Programming Language :: Python :: 3.13",
24+
"Operating System :: Microsoft :: Windows",
25+
"Operating System :: POSIX :: Linux",
1826
"Operating System :: MacOS",
1927
"Topic :: Utilities",
2028
"Topic :: Software Development :: User Interfaces",
2129
"Topic :: Multimedia :: Graphics :: Graphics Conversion",
2230
]
23-
include = [
24-
"LICENSE",
31+
requires-python = ">=3.6"
32+
33+
dependencies = [
34+
"websocket-client~=1.0",
35+
"requests",
2536
]
2637

27-
[tool.poetry.dependencies]
28-
python = "^3.6"
29-
websocket-client = "1.*"
30-
requests = "*"
38+
[project.urls]
39+
Homepage = "https://github.com/vgalin/html2image"
40+
Repository = "https://github.com/vgalin/html2image"
41+
Issues = "https://github.com/vgalin/html2image/issues"
42+
Changelog = "https://github.com/vgalin/html2image/releases"
3143

32-
[tool.poetry.dev-dependencies]
33-
Pillow = "^8.2.0"
44+
[project.optional-dependencies]
45+
test = [
46+
"Pillow>=8.2.0",
47+
"pytest",
48+
]
49+
lint = [
50+
"flake8",
51+
]
52+
dev = [
53+
"html2image[test,lint]",
54+
"build",
55+
"twine",
56+
]
3457

35-
[build-system]
36-
requires = ["poetry>=0.12"]
37-
build-backend = "poetry.masonry.api"
58+
[project.scripts]
59+
hti = "html2image:main"
60+
html2image = "html2image:main"
3861

39-
[tool.poetry.scripts]
40-
hti = 'html2image:main'
41-
html2image = 'html2image:main'
62+
[build-system]
63+
requires = ["hatchling"]
64+
build-backend = "hatchling.build"

requirements-test.txt

Lines changed: 0 additions & 2 deletions
This file was deleted.

0 commit comments

Comments
 (0)