# this_file: pyproject.toml
#==============================================================================
# BROSH PACKAGE CONFIGURATION
# This pyproject.toml defines the package metadata, dependencies, build system,
# and development environment for the brosh package.
#==============================================================================
#------------------------------------------------------------------------------
# PROJECT METADATA
# Core package information used by PyPI and package managers.
#------------------------------------------------------------------------------
[project]
name = 'brosh'
description = 'Browser screenshot tool using Playwright async API'
readme = 'README.md'
requires-python = '>=3.10'
dynamic = ["version"]
keywords = [
'screenshot',
'browser',
'playwright',
'web',
'capture',
'automation',
'mcp',
]
classifiers = [
'Development Status :: 4 - Beta',
'Programming Language :: Python',
'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: 3.11',
'Programming Language :: Python :: 3.12',
'Programming Language :: Python :: Implementation :: CPython',
'Programming Language :: Python :: Implementation :: PyPy',
'Operating System :: OS Independent',
'License :: OSI Approved :: MIT License',
'Intended Audience :: Developers',
]
dependencies = [
'fire>=0.5.0',
'playwright>=1.40.0',
'pillow>=11.2.1',
'fastmcp>=2.8.0',
'platformdirs>=4.0.0',
'loguru>=0.7.0',
'html2text>=2025.4.15',
'pyoxipng>=9.1.0',
]
# Author information
[[project.authors]]
name = 'Adam Twardoch'
email = 'adam+github@twardoch.com'
# License information
[project.license]
text = 'MIT'
# Project URLs
[project.urls]
Documentation = 'https://github.com/twardoch/brosh#readme'
Issues = 'https://github.com/twardoch/brosh/issues'
Source = 'https://github.com/twardoch/brosh'
#------------------------------------------------------------------------------
# OPTIONAL DEPENDENCIES
# Additional dependencies for optional features, development, and testing.
#------------------------------------------------------------------------------
[project.optional-dependencies]
# Development tools
dev = [
'pre-commit>=4.1.0',
'ruff>=0.9.7',
'mypy>=1.15.0',
'absolufy-imports>=0.3.1',
'pyupgrade>=3.19.1',
'isort>=6.0.1', # Ruff now includes isort functionality, could be removed if using ruff format for imports
'uzpy>=1.0.0', # Keeping for now, though its role is unclear
'uv>=0.2.0',
'autoflake>=2.3.0', # Added autoflake
]
# Binary building tools
binary = [
'pyinstaller>=6.0.0',
'setuptools>=70.0.0',
]
# Testing tools and frameworks
test = [
'pytest>=8.3.4',
'pytest-cov==5.0.0',
'pytest-xdist>=3.6.1',
'pytest-benchmark[histogram]>=5.1.0',
'pytest-asyncio>=1.0.0',
'coverage[toml]>=7.6.12',
]
docs = [
"sphinx<8",
"sphinx-rtd-theme>=3.0.2",
"sphinx-autodoc-typehints<3",
"myst-parser<4",
]
# All optional dependencies combined
all = [
"brosh[dev,test,docs,binary]", # Combined all optional dependencies
]
#------------------------------------------------------------------------------
# COMMAND-LINE SCRIPTS
# Entry points for command-line executables installed with the package.
#------------------------------------------------------------------------------
[project.scripts]
brosh = "brosh.__main__:main"
brosh-mcp = "brosh.mcp:main"
#------------------------------------------------------------------------------
# BUILD SYSTEM CONFIGURATION
# Defines the tools required to build the package and the build backend.
#------------------------------------------------------------------------------
[build-system]
requires = [
'hatchling>=1.27.0',
'hatch-vcs>=0.4.0',
]
build-backend = 'hatchling.build'
#------------------------------------------------------------------------------
# HATCH BUILD CONFIGURATION
# Configures the build process, specifying which packages to include and
# how to handle versioning.
#------------------------------------------------------------------------------
[tool.hatch.build]
include = [
"src/brosh/py.typed",
"src/brosh/data/**/*",
]
exclude = ["**/__pycache__", "**/.pytest_cache", "**/.mypy_cache"]
[tool.hatch.build.targets.wheel]
packages = ["src/brosh"]
reproducible = true
[tool.hatch.metadata]
allow-direct-references = true
# Version control system hook configuration
# Automatically updates the version file from git tags
[tool.hatch.build.hooks.vcs]
version-file = "src/brosh/__version__.py"
# Version source configuration
[tool.hatch.version]
source = 'vcs' # Get version from git tags or other VCS info
#------------------------------------------------------------------------------
# DEVELOPMENT ENVIRONMENTS
[tool.hatch.envs.default]
features = ['dev', 'test', 'all']
dependencies = [
]
# Commands available in the default environment
[tool.hatch.envs.default.scripts]
test = 'pytest {args:tests}'
test-cov = "pytest --cov-report=term-missing --cov-config=pyproject.toml --cov=src/brosh --cov=tests {args:tests}"
type-check = "mypy src/brosh tests"
lint = ["ruff check src/brosh tests", "ruff format --respect-gitignore src/brosh tests"]
fmt = ["ruff format --respect-gitignore src/brosh tests", "ruff check --fix src/brosh tests"]
fix = ["ruff check --fix --unsafe-fixes src/brosh tests", "ruff format --respect-gitignore src/brosh tests"]
polish = [
"pre-commit run --all-files",
"ruff format --respect-gitignore src tests",
"ruff check --fix --unsafe-fixes src tests"
]
[[tool.hatch.envs.all.matrix]]
python = ["3.10", "3.11", "3.12"]
#------------------------------------------------------------------------------
# SPECIALIZED ENVIRONMENTS
# Additional environments for specific development tasks.
#------------------------------------------------------------------------------
[tool.hatch.envs.lint]
detached = true
features = ['dev']
[tool.hatch.envs.lint.scripts]
typing = "mypy --install-types --non-interactive {args:src/brosh tests}"
style = ["ruff check {args:.}", "ruff format --respect-gitignore {args:.}"]
fmt = ["ruff format --respect-gitignore {args:.}", "ruff check --fix {args:.}"]
fix = ["ruff check --fix --unsafe-fixes {args:.}", "ruff format --respect-gitignore {args:.}"]
all = ["style", "typing", "fix"]
[tool.hatch.envs.test]
features = ['test']
[tool.hatch.envs.test.scripts]
test = "python -m pytest -n auto {args:tests}"
test-cov = "python -m pytest -n auto --cov-report=term-missing --cov-config=pyproject.toml --cov=src/brosh --cov=tests {args:tests}"
bench = "python -m pytest -v -p no:briefcase tests/test_benchmark.py --benchmark-only"
bench-save = "python -m pytest -v -p no:briefcase tests/test_benchmark.py --benchmark-only --benchmark-json=benchmark/results.json"
[tool.hatch.envs.docs]
features = ['docs']
[tool.hatch.envs.docs.scripts]
build = "sphinx-build -b html docs/source docs/build"
[tool.hatch.envs.ci]
features = ['test']
[tool.hatch.envs.ci.scripts]
test = "pytest --cov=src/brosh --cov-report=xml"
#------------------------------------------------------------------------------
# CODE QUALITY TOOLS
# Configuration for linting, formatting, and code quality enforcement.
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# PYTEST CONFIGURATION
# Settings for the pytest testing framework.
#------------------------------------------------------------------------------
[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = ["test_*.py", "*_test.py"]
python_classes = ["Test*"]
python_functions = ["test_*"]
addopts = [
"--strict-markers",
"--strict-config",
"--verbose",
"--tb=short",
"--cov=src/brosh",
"--cov-report=term-missing",
"--cov-report=html:htmlcov",
"--cov-report=xml",
"--cov-fail-under=80",
]
markers = [
"slow: marks tests as slow (deselect with '-m \"not slow\"')",
"integration: marks tests as integration tests",
"unit: marks tests as unit tests",
"asyncio: marks tests as async tests",
]
asyncio_mode = "auto"
minversion = "8.0"
filterwarnings = [
"error",
"ignore::UserWarning",
"ignore::DeprecationWarning",
"ignore::PendingDeprecationWarning",
]
#------------------------------------------------------------------------------
# COVERAGE CONFIGURATION
# Settings for code coverage reporting.
#------------------------------------------------------------------------------
[tool.coverage.run]
source = ["src"]
branch = true
parallel = true
omit = [
"*/tests/*",
"*/test_*",
"*/__pycache__/*",
"*/site-packages/*",
"*/.venv/*",
]
[tool.coverage.paths]
source = [
"src/",
"*/site-packages/",
]
[tool.coverage.report]
exclude_lines = [
"pragma: no cover",
"def __repr__",
"if self.debug:",
"if settings.DEBUG",
"raise AssertionError",
"raise NotImplementedError",
"if 0:",
"if __name__ == .__main__.:",
"class .*\\bProtocol\\):",
"@(abc\\.)?abstractmethod",
]
ignore_errors = true
show_missing = true
skip_covered = false
[tool.coverage.html]
directory = "htmlcov"
[tool.coverage.xml]
output = "coverage.xml"
#------------------------------------------------------------------------------
# RUFF CONFIGURATION
# Configuration for Ruff, including linter and formatter settings.
#------------------------------------------------------------------------------
[tool.ruff]
target-version = "py310"
line-length = 120
exclude = [".git", ".venv", "venv", "dist", "build", "_private"]
[tool.ruff.lint]
select = [
'A',
'ARG',
'ASYNC',
'B',
'C',
'DTZ',
'E',
'EM',
'F',
'FBT',
'I',
'ICN',
'ISC',
'LOG',
'N',
'PLC',
'PLE',
'PLR',
'PLW',
'PT',
'PTH',
'PYI',
'RET',
'RSE',
'RUF',
'S',
'SIM',
'T',
'TCH',
'TID',
'UP',
'W',
'YTT',
]
ignore = [
'B027',
'C901',
'FBT003',
'PLR0911',
'PLR0912',
'PLR0913',
'PLR0915',
'PLR1714',
'PLW0603',
'PT013',
'PTH123',
'PYI056',
'S105',
'S106',
'S107',
'S110',
'SIM102',
'ISC001', # Ignore implicit string concatenation, as Ruff formatter handles it
]
unfixable = [
'F401',
]
[tool.ruff.lint.isort]
known-first-party = ['brosh']
[tool.ruff.lint.flake8-tidy-imports]
ban-relative-imports = 'parents'
[tool.ruff.lint.per-file-ignores]
'tests/**/*' = [
'PLR2004',
'S101',
'TID252'
]
# Removed redundant/misplaced dependency-groups table