Skip to content

Commit

Permalink
Use Ruff and pyproject.toml (#191)
Browse files Browse the repository at this point in the history
* Use Ruff and pyproject.toml

Replace isort and Flake8 with ruff, and move black and pytest config to pyproject.toml.

* Add a pre-commit action

* Use pre-commit.ci but disable fixes

* Use pre-commit to format pyproject.toml

* Ruff fixes
  • Loading branch information
abkfenris authored May 11, 2023
1 parent 3358bce commit 9bb549e
Show file tree
Hide file tree
Showing 11 changed files with 118 additions and 76 deletions.
4 changes: 2 additions & 2 deletions .binder/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
print(client.cluster)
print(client.cluster.dashboard_link)

ds = xr.tutorial.open_dataset('air_temperature', chunks=dict(lat=5, lon=5), decode_cf=False)
ds = xr.tutorial.open_dataset('air_temperature', chunks={'lat': 5, 'lon': 5}, decode_cf=False)
print(ds)

for k, da in ds.variables.items():
for _k, da in ds.variables.items():
da.encoding['compressor'] = None

app = ds.rest.app
Expand Down
28 changes: 14 additions & 14 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ repos:
- id: check-yaml
- id: double-quote-string-fixer

- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: "v0.0.265"
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix]

- repo: https://github.com/executablebooks/mdformat
rev: 0.7.16
hooks:
Expand All @@ -27,20 +33,6 @@ repos:
rev: 23.3.0
hooks:
- id: black
args: ["--line-length", "100", "--skip-string-normalization"]

- repo: https://github.com/PyCQA/flake8
rev: 6.0.0
hooks:
- id: flake8
- repo: https://github.com/asottile/seed-isort-config
rev: v2.2.0
hooks:
- id: seed-isort-config
- repo: https://github.com/PyCQA/isort
rev: 5.12.0
hooks:
- id: isort

- repo: https://github.com/pre-commit/mirrors-prettier
rev: v3.0.0-alpha.6
Expand All @@ -49,3 +41,11 @@ repos:
language_version: system
exclude_types:
- markdown # managed by mdformat

- repo: https://github.com/tox-dev/pyproject-fmt
rev: "0.9.0"
hooks:
- id: pyproject-fmt

ci:
autofix_prs: false
4 changes: 4 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ Publish Xarray Datasets via a REST API.
.. image:: https://codecov.io/gh/xarray-contrib/xpublish/branch/main/graph/badge.svg
:target: https://codecov.io/gh/xarray-contrib/xpublish

.. image:: https://results.pre-commit.ci/badge/github/xpublish-community/xpublish/main.svg
:target: https://results.pre-commit.ci/latest/github/xpublish-community/xpublish/main
:alt: pre-commit.ci status

**Serverside: Publish a Xarray Dataset through a rest API**

.. code-block:: python
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def get_mean(var_name: str, dataset=Depends(deps.dataset)):

ds = xr.tutorial.open_dataset(
'air_temperature',
chunks=dict(lat=5, lon=5),
chunks={'lat': 5, 'lon': 5},
)

rest = SingleDatasetRest(ds)
Expand Down
2 changes: 1 addition & 1 deletion docs/source/getting-started/tutorial/dataset-router.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

ds = xr.tutorial.open_dataset(
'air_temperature',
chunks=dict(lat=5, lon=5),
chunks={'lat': 5, 'lon': 5},
)

myrouter = APIRouter()
Expand Down
61 changes: 61 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@

[tool.black]
line-length = 100
skip-string-normalization = true

[tool.pytest.ini_options]
log_cli = true
log_level = "INFO"
addopts = "--cov=./ --cov-report=xml --verbose"

[tool.ruff]
select = [
"B", # flake8-bugbear
"C",
"E", # pycodestyle
"F", # Pyflakes
"I", # isort
"W", # pycodestyle
# "T4",
"B9",
]
ignore = [
# "E203",
# "E266",
"E501",
# "W503",
"E722",
"E402",
"C901",
]
line-length = 100

[tool.ruff.mccabe]
# Unlike Flake8, default to a complexity level of 10.
max-complexity = 18

[tool.ruff.isort]
combine-as-imports = true
known-first-party = ["xpublish"]
known-third-party = [
"cachey",
"dask",
"fastapi",
"numcodecs",
"numpy",
"pandas",
"pkg_resources",
"pluggy",
"pydantic",
"pytest",
"setuptools",
"sphinx_autosummary_accessors",
"starlette",
"uvicorn",
"xarray",
"zarr",
]

[tool.ruff.flake8-bugbear]
# Allow fastapi.Depends and other dependency injection style function arguments
extend-immutable-calls = ["fastapi.Depends", "fastapi.Query"]
26 changes: 0 additions & 26 deletions setup.cfg

This file was deleted.

36 changes: 18 additions & 18 deletions tests/test_rest_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@

@pytest.fixture(scope='function')
def airtemp_rest(airtemp_ds):
app_kws = dict(
title='My Dataset',
description='Dataset Description',
version='1.0.0',
openapi_url='/dataset.json',
docs_url='/data-docs',
)
app_kws = {
'title': 'My Dataset',
'description': 'Dataset Description',
'version': '1.0.0',
'openapi_url': '/dataset.json',
'docs_url': '/data-docs',
}

return SingleDatasetRest(airtemp_ds, app_kws=app_kws)

Expand Down Expand Up @@ -115,13 +115,13 @@ def test_init_cache_kws(airtemp_ds):
def test_init_app_kws(airtemp_ds):
rest = Rest(
{'airtemp': airtemp_ds},
app_kws=dict(
title='My Dataset',
description='Dataset Description',
version='1.0.0',
openapi_url='/dataset.json',
docs_url='/data-docs',
),
app_kws={
'title': 'My Dataset',
'description': 'Dataset Description',
'version': '1.0.0',
'openapi_url': '/dataset.json',
'docs_url': '/data-docs',
},
)

assert rest.app.title == 'My Dataset'
Expand Down Expand Up @@ -353,8 +353,8 @@ def test_rest_accessor(airtemp_ds):

def test_rest_accessor_kws(airtemp_ds):
airtemp_ds.rest(
app_kws=dict(docs_url='/data-docs'),
cache_kws=dict(available_bytes=1e9),
app_kws={'docs_url': '/data-docs'},
cache_kws={'available_bytes': 1e9},
)

assert airtemp_ds.rest.cache.available_bytes == 1e9
Expand Down Expand Up @@ -414,14 +414,14 @@ def test_single_dataset_openapi_override(airtemp_rest):


def test_serve(airtemp_rest, mocker):
kwargs = dict(host='0.0.0.0', log_level='debug', port=9000)
kwargs = {'host': '0.0.0.0', 'log_level': 'debug', 'port': 9000}
mocker.patch('uvicorn.run')
airtemp_rest.serve(**kwargs)
uvicorn.run.assert_called_once_with(airtemp_rest.app, **kwargs)


def test_accessor_serve(airtemp_ds, mocker):
kwargs = dict(host='0.0.0.0', log_level='debug', port=9000)
kwargs = {'host': '0.0.0.0', 'log_level': 'debug', 'port': 9000}
mocker.patch('uvicorn.run')
airtemp_ds.rest.serve(**kwargs)
uvicorn.run.assert_called_once_with(airtemp_ds.rest.app, **kwargs)
2 changes: 1 addition & 1 deletion xpublish/routers/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
from .common import dataset_collection_router
from .common import dataset_collection_router # noqa: F401
27 changes: 15 additions & 12 deletions xpublish/utils/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def normalize_datasets(datasets) -> Dict[str, xr.Dataset]:
if isinstance(datasets, xr.Dataset):
return {}
elif isinstance(datasets, Mapping):
if not all([isinstance(obj, xr.Dataset) for obj in datasets.values()]):
if not all(isinstance(obj, xr.Dataset) for obj in datasets.values()):
raise TypeError(error_msg)
return {str(k): ds.assign_attrs({DATASET_ID_ATTR_KEY: k}) for k, ds in datasets.items()}
else:
Expand Down Expand Up @@ -97,14 +97,14 @@ def openapi(self):
if self._app.openapi_schema:
return self._app.openapi_schema

kwargs = dict(
title=self._app.title,
version=self._app.version,
description=self._app.description,
routes=self._app.routes,
tags=self._app.openapi_tags,
servers=self._app.servers,
)
kwargs = {
'title': self._app.title,
'version': self._app.version,
'description': self._app.description,
'routes': self._app.routes,
'tags': self._app.openapi_tags,
'servers': self._app.servers,
}

openapi_schema = get_openapi(**kwargs)

Expand All @@ -124,9 +124,12 @@ def openapi(self):

class JSONResponse(StarletteJSONResponse):
def __init__(self, *args, **kwargs):
self._render_kwargs = dict(
ensure_ascii=True, allow_nan=True, indent=None, separators=(',', ':')
)
self._render_kwargs = {
'ensure_ascii': True,
'allow_nan': True,
'indent': None,
'separators': (',', ':'),
}
self._render_kwargs.update(kwargs.pop('render_kwargs', {}))
super().__init__(*args, **kwargs)

Expand Down
2 changes: 1 addition & 1 deletion xpublish/utils/zarr.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def _extract_dataarray_coords(da, zattrs):
nondim_coords = set(da.coords) - set(da.dims)

if len(nondim_coords) > 0 and da.name not in nondim_coords:
coords = ' '.join(sorted(list(nondim_coords)))
coords = ' '.join(sorted(nondim_coords))
zattrs['coordinates'] = encode_zarr_attr_value(coords)
return zattrs

Expand Down

0 comments on commit 9bb549e

Please sign in to comment.