diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3c99d8c..17248cc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,19 +9,24 @@ on: - '*' pull_request: env: - LATEST_PY_VERSION: '3.10' + LATEST_PY_VERSION: '3.11' jobs: tests: runs-on: ubuntu-latest strategy: matrix: - python-version: ['3.8', '3.9', '3.10', '3.11'] + python-version: + - '3.8' + - '3.9' + - '3.10' + - '3.11' + - '3.12' steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} @@ -53,9 +58,9 @@ jobs: runs-on: ubuntu-latest if: startsWith(github.event.ref, 'refs/tags') || github.event_name == 'release' steps: - - uses: actions/checkout@v3 - - name: Set up Python - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 + - name: Set up Python ${{ env.LATEST_PY_VERSION }} + uses: actions/setup-python@v5 with: python-version: ${{ env.LATEST_PY_VERSION }} @@ -94,7 +99,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Set up QEMU uses: docker/setup-qemu-action@v1 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2147fac..fd657db 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,26 +4,21 @@ repos: hooks: - id: validate-pyproject - - repo: https://github.com/psf/black - rev: 22.12.0 - hooks: - - id: black - language_version: python - - repo: https://github.com/PyCQA/isort - rev: 5.12.0 + rev: 5.13.2 hooks: - id: isort language_version: python - - repo: https://github.com/charliermarsh/ruff-pre-commit - rev: v0.0.238 + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.3.5 hooks: - id: ruff args: ["--fix"] + - id: ruff-format - repo: https://github.com/pre-commit/mirrors-mypy - rev: v0.991 + rev: v1.9.0 hooks: - id: mypy language_version: python diff --git a/CHANGES.md b/CHANGES.md index c9b29a3..ab31ac4 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,7 @@ +## 0.12.1 (2024-04-18) + +* fix GET range parsing +* add python 3.12 official support ## 0.12.0 (2024-01-24) diff --git a/pyproject.toml b/pyproject.toml index 0b01bf0..8f1e9d0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,6 +16,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Topic :: Scientific/Engineering :: GIS", ] dynamic = ["version", "readme"] @@ -92,6 +93,9 @@ default_section = "THIRDPARTY" no_strict_optional = true [tool.ruff] +line-length = 90 + +[tool.ruff.lint] select = [ "D1", # pydocstyle errors "E", # pycodestyle errors @@ -105,3 +109,6 @@ ignore = [ "B008", # do not perform function calls in argument defaults "B905", # ignore zip() without an explicit strict= parameter, only support with python >3.10 ] + +[tool.ruff.lint.mccabe] +max-complexity = 14 diff --git a/tests/test_viz.py b/tests/test_viz.py index 2335a87..b39b766 100644 --- a/tests/test_viz.py +++ b/tests/test_viz.py @@ -1,6 +1,5 @@ """Tests for tilebench.""" - from starlette.testclient import TestClient from tilebench.viz import TileDebug diff --git a/tilebench/__init__.py b/tilebench/__init__.py index 4d01fb6..f73773d 100644 --- a/tilebench/__init__.py +++ b/tilebench/__init__.py @@ -28,16 +28,14 @@ def parse_logs(logs: List[str]) -> Dict[str, Any]: } # GET - all_get_requests = len( - [line for line in logs if "CURL_INFO_HEADER_OUT: GET" in line] - ) + all_get_requests = len([line for line in logs if "CURL_INFO_HEADER_OUT: GET" in line]) get_requests = [line for line in logs if ": Downloading" in line] get_values = [ - map(int, get.split(" Downloading ")[1].split(" ")[0].split("-")) + list(map(int, get.split(" Downloading ")[1].split(" ")[0].split("-"))) for get in get_requests ] - get_values_str = [get.split(" ")[4] for get in get_requests] + get_values_str = [f"{start}-{end}" for (start, end) in get_values] data_transfer = sum([j - i + 1 for i, j in get_values]) get_summary = { diff --git a/tilebench/middleware.py b/tilebench/middleware.py index 2562477..3238769 100644 --- a/tilebench/middleware.py +++ b/tilebench/middleware.py @@ -55,9 +55,9 @@ async def dispatch(self, request: Request, call_next): ranges_results = "ranges; values={}".format( "|".join(results["GET"]["ranges"]) ) - response.headers[ - "VSI-Stats" - ] = f"{head_results}, {get_results}, {ranges_results}" + response.headers["VSI-Stats"] = ( + f"{head_results}, {get_results}, {ranges_results}" + ) return response diff --git a/tilebench/scripts/cli.py b/tilebench/scripts/cli.py index 341f09e..674e338 100644 --- a/tilebench/scripts/cli.py +++ b/tilebench/scripts/cli.py @@ -88,7 +88,7 @@ def profile( module, classname = reader.rsplit(".", 1) reader = getattr(importlib.import_module(module), classname) # noqa if not issubclass(reader, (BaseReader, MultiBandReader, MultiBaseReader)): - warnings.warn(f"Invalid reader type: {type(reader)}") + warnings.warn(f"Invalid reader type: {type(reader)}", stacklevel=1) Reader = reader or COGReader @@ -159,7 +159,7 @@ def get_zooms(input, reader, tms): module, classname = reader.rsplit(".", 1) reader = getattr(importlib.import_module(module), classname) # noqa if not issubclass(reader, (BaseReader, MultiBandReader, MultiBaseReader)): - warnings.warn(f"Invalid reader type: {type(reader)}") + warnings.warn(f"Invalid reader type: {type(reader)}", stacklevel=1) Reader = reader or COGReader @@ -191,7 +191,7 @@ def random(input, zoom, reader, tms): module, classname = reader.rsplit(".", 1) reader = getattr(importlib.import_module(module), classname) # noqa if not issubclass(reader, (BaseReader, MultiBandReader, MultiBaseReader)): - warnings.warn(f"Invalid reader type: {type(reader)}") + warnings.warn(f"Invalid reader type: {type(reader)}", stacklevel=1) Reader = reader or COGReader @@ -253,7 +253,7 @@ def viz(src_path, port, host, server_only, reader, config): module, classname = reader.rsplit(".", 1) reader = getattr(importlib.import_module(module), classname) # noqa if not issubclass(reader, (BaseReader)): - warnings.warn(f"Invalid reader type: {type(reader)}") + warnings.warn(f"Invalid reader type: {type(reader)}", stacklevel=1) Reader = reader or COGReader diff --git a/tilebench/viz.py b/tilebench/viz.py index dae7eb2..ccd5a29 100644 --- a/tilebench/viz.py +++ b/tilebench/viz.py @@ -224,16 +224,14 @@ def _read_tile(src_path: str, x: int, y: int, z: int): head_results = "head;count={count}".format(**stats["HEAD"]) get_results = "get;count={count};size={bytes}".format(**stats["GET"]) - ranges_results = "ranges; values={}".format( - "|".join(stats["GET"]["ranges"]) + ranges_results = "ranges; values={}".format("|".join(stats["GET"]["ranges"])) + response.headers["VSI-Stats"] = ( + f"{head_results}, {get_results}, {ranges_results}" ) - response.headers[ - "VSI-Stats" - ] = f"{head_results}, {get_results}, {ranges_results}" - response.headers[ - "server-timing" - ] = f"dataread; dur={round(t.elapsed * 1000, 2)}" + response.headers["server-timing"] = ( + f"dataread; dur={round(t.elapsed * 1000, 2)}" + ) return "OK" @self.router.get(