diff --git a/.flake8 b/.flake8 deleted file mode 100644 index b851f0e..0000000 --- a/.flake8 +++ /dev/null @@ -1,5 +0,0 @@ -[flake8] -ignore = E501,W503,E203 -exclude = .git,__pycache__,docs/source/conf.py,old,build,dist -max-complexity = 14 -max-line-length = 90 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bbe0b8c..739c625 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,19 +8,24 @@ on: - '*' pull_request: env: - LATEST_PY_VERSION: '3.10' + LATEST_PY_VERSION: '3.12' 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@v2 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} @@ -52,34 +57,38 @@ jobs: runs-on: ubuntu-latest if: startsWith(github.event.ref, 'refs/tags') || github.event_name == 'release' steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Set up Python - uses: actions/setup-python@v1 + uses: actions/setup-python@v5 with: python-version: ${{ env.LATEST_PY_VERSION }} - name: Install dependencies run: | python -m pip install --upgrade pip - python -m pip install flit - python -m pip install . + python -m pip install hatch + python -m hatch build - name: Set tag version id: tag - # https://stackoverflow.com/questions/58177786/get-the-current-pushed-tag-in-github-actions - run: echo ::set-output name=tag::${GITHUB_REF#refs/*/} + run: | + echo "version=${GITHUB_REF#refs/*/}" + echo "version=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT - name: Set module version id: module - # https://stackoverflow.com/questions/58177786/get-the-current-pushed-tag-in-github-actions - run: echo ::set-output name=version::$(python -c 'from importlib.metadata import version; print(version("rio_viz"))') + run: | + hatch --quiet version + echo "version=$(hatch --quiet version)" >> $GITHUB_OUTPUT - name: Build and publish - if: steps.tag.outputs.tag == steps.module.outputs.version + if: ${{ steps.tag.outputs.version }} == ${{ steps.module.outputs.version}} env: - FLIT_USERNAME: ${{ secrets.PYPI_USERNAME }} - FLIT_PASSWORD: ${{ secrets.PYPI_PASSWORD }} - run: flit publish + HATCH_INDEX_USER: ${{ secrets.PYPI_USERNAME }} + HATCH_INDEX_AUTH: ${{ secrets.PYPI_PASSWORD }} + run: | + python -m hatch publish + publish-docker: needs: [tests] @@ -104,8 +113,9 @@ jobs: - name: Set tag version id: tag - # https://stackoverflow.com/questions/58177786/get-the-current-pushed-tag-in-github-actions - run: echo ::set-output name=tag::${GITHUB_REF#refs/*/} + run: | + echo "version=${GITHUB_REF#refs/*/}" + echo "version=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT # Push `latest` when commiting to main - name: Build and push diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1726693..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: v1.3.0 + rev: v1.9.0 hooks: - id: mypy language_version: python diff --git a/CHANGES.md b/CHANGES.md index f026aff..cc44495 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,10 @@ +# 0.12.2 (2024-04-24) + +* update titiler dependency to `>=0.16,<0.19` +* add python 3.12 official support +* change code formatter to `ruff-format` +* switch to Hatch + # 0.12.1 (2024-01-12) * fix invalid nodata overwriting diff --git a/pyproject.toml b/pyproject.toml index 0439af7..c9fcd4a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,13 +15,14 @@ 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"] dependencies = [ "braceexpand", "rio-cogeo>=5.0", - "titiler.core>=0.16.0,<0.17", + "titiler.core>=0.16.0,<0.19", "starlette-cramjam>=0.3,<0.4", "uvicorn", "server-thread>=0.2.0", @@ -48,19 +49,25 @@ Source = "https://github.com/developmentseed/rio-viz" viz = "rio_viz.scripts.cli:viz" [build-system] -requires = ["flit>=3.2,<4"] -build-backend = "flit_core.buildapi" +requires = ["hatchling"] +build-backend = "hatchling.build" -[tool.flit.module] -name = "rio_viz" +[tool.hatch.version] +path = "rio_viz/__init__.py" -[tool.flit.sdist] +[tool.hatch.build.targets.sdist] exclude = [ - "tests/", - "docs/", - ".github/", - "CHANGES.md", - "CONTRIBUTING.md", + "/tests", + ".ruff_cache/", + "examples/", + ".github", + ".history", + ".bumpversion.cfg", + ".gitignore", + "Dockerfile", + ".pre-commit-config.yaml", + "CHANGES.md", + "CONTRIBUTING.md", ] [tool.isort] @@ -74,10 +81,14 @@ default_section = "THIRDPARTY" no_strict_optional = true [tool.ruff] +line-length = 90 + +[tool.ruff.lint] select = [ "D1", # pydocstyle errors "E", # pycodestyle errors "W", # pycodestyle warnings + "F", # flake8 "C", # flake8-comprehensions "B", # flake8-bugbear ] @@ -85,4 +96,8 @@ ignore = [ "E501", # line too long, handled by black "B008", # do not perform function calls in argument defaults "B905", # ignore zip() without an explicit strict= parameter, only support with python >3.10 + "B028", ] + +[tool.ruff.lint.mccabe] +max-complexity = 12 diff --git a/rio_viz/app.py b/rio_viz/app.py index dafa64b..e7bfd4f 100644 --- a/rio_viz/app.py +++ b/rio_viz/app.py @@ -1,6 +1,5 @@ """rio_viz app.""" -import pathlib import urllib.parse from typing import Any, Dict, List, Literal, Optional, Tuple, Type, Union @@ -68,9 +67,9 @@ class viz: """Creates a very minimal slippy map tile server using fastAPI + Uvicorn.""" src_path: str = attr.ib() - reader: Union[ - Type[BaseReader], Type[MultiBandReader], Type[MultiBaseReader] - ] = attr.ib(default=Reader) + reader: Union[Type[BaseReader], Type[MultiBandReader], Type[MultiBaseReader]] = ( + attr.ib(default=Reader) + ) app: FastAPI = attr.ib(default=attr.Factory(FastAPI)) @@ -616,9 +615,7 @@ def tilejson( with self.reader(self.src_path) as src_dst: # type: ignore bounds = ( - self.bounds - if self.bounds is not None - else src_dst.geographic_bounds + self.bounds if self.bounds is not None else src_dst.geographic_bounds ) minzoom = self.minzoom if self.minzoom is not None else src_dst.minzoom maxzoom = self.maxzoom if self.maxzoom is not None else src_dst.maxzoom @@ -678,9 +675,7 @@ def wmts( with self.reader(self.src_path) as src_dst: # type: ignore bounds = ( - self.bounds - if self.bounds is not None - else src_dst.geographic_bounds + self.bounds if self.bounds is not None else src_dst.geographic_bounds ) minzoom = self.minzoom if self.minzoom is not None else src_dst.minzoom maxzoom = self.maxzoom if self.maxzoom is not None else src_dst.maxzoom @@ -699,9 +694,9 @@ def wmts( tileMatrix.append(tm) return templates.TemplateResponse( - "wmts.xml", - { - "request": request, + request, + name="wmts.xml", + context={ "tiles_endpoint": tiles_endpoint, "bounds": bounds, "tileMatrix": tileMatrix, @@ -738,9 +733,9 @@ def map_viewer( tilejson_url += f"?{request.query_params}" return templates.TemplateResponse( + request, name="map.html", context={ - "request": request, "tilejson_endpoint": tilejson_url, }, media_type="text/html", @@ -768,9 +763,9 @@ def viewer(request: Request): name = "assets.html" return templates.TemplateResponse( + request, name=name, context={ - "request": request, "tilejson_endpoint": str(request.url_for("tilejson")), "stats_endpoint": str(request.url_for("statistics")), "info_endpoint": str(request.url_for("info")), diff --git a/rio_viz/io/mosaic.py b/rio_viz/io/mosaic.py index ed2752d..d88e33b 100644 --- a/rio_viz/io/mosaic.py +++ b/rio_viz/io/mosaic.py @@ -101,9 +101,9 @@ def point( def _reader(asset: str, lon: float, lat: float, **kwargs) -> PointData: return self.datasets[asset].point(lon, lat, **kwargs) - return mosaic_point_reader( - mosaic_assets, _reader, lon, lat, threads=0, **kwargs - )[0] + return mosaic_point_reader(mosaic_assets, _reader, lon, lat, threads=0, **kwargs)[ + 0 + ] def info(self) -> Info: """info."""