Skip to content

Commit 46a28ee

Browse files
update pre-commit and use ruff for linting/formating (#105)
* update pre-commit and use ruff for linting/formating * use python 3.11 for lint * try pydantic 1. --------- Co-authored-by: Jonathan Healy <jonathan.d.healy@gmail.com>
1 parent fcf4935 commit 46a28ee

File tree

17 files changed

+169
-183
lines changed

17 files changed

+169
-183
lines changed

.github/workflows/cicd.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727
cache-dependency-path: setup.py
2828

2929
- name: Lint code
30-
if: ${{ matrix.python-version == 3.8 }}
30+
if: ${{ matrix.python-version == 3.11 }}
3131
run: |
3232
python -m pip install pre-commit
3333
pre-commit run --all-files

.pre-commit-config.yaml

Lines changed: 14 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,24 @@
11
repos:
22
- repo: https://github.com/PyCQA/isort
3-
rev: 5.12.0
3+
rev: 5.13.2
44
hooks:
55
- id: isort
66
language_version: python
77

8-
- repo: https://github.com/psf/black
9-
rev: 22.12.0
8+
- repo: https://github.com/astral-sh/ruff-pre-commit
9+
rev: v0.3.5
1010
hooks:
11-
- id: black
12-
args: ["--safe"]
13-
language_version: python
14-
15-
- repo: https://github.com/pycqa/flake8
16-
rev: 6.0.0
17-
hooks:
18-
- id: flake8
19-
language_version: python
20-
args: [
21-
# E501 let black handle all line length decisions
22-
# W503 black conflicts with "line break before operator" rule
23-
# E203 black conflicts with "whitespace before ':'" rule
24-
"--ignore=E501,W503,E203,C901",
25-
]
26-
- repo: https://github.com/chewse/pre-commit-mirrors-pydocstyle
27-
# 2.1.1
28-
rev: v2.1.1
29-
hooks:
30-
- id: pydocstyle
31-
language_version: python
32-
exclude: ".*(test|scripts).*"
33-
args:
34-
[
35-
# Check for docstring presence only
36-
"--select=D1",
37-
]
38-
# Don't require docstrings for tests
39-
# '--match=(?!test).*\.py']
40-
# -
41-
# repo: https://github.com/pre-commit/mirrors-mypy
42-
# rev: v0.770
43-
# hooks:
44-
# - id: mypy
45-
# language_version: python3.8
46-
# args: [--no-strict-optional, --ignore-missing-imports]
11+
- id: ruff
12+
args: ["--fix"]
13+
- id: ruff-format
4714

48-
- repo: https://github.com/PyCQA/pydocstyle
49-
rev: 6.3.0
15+
- repo: https://github.com/pre-commit/mirrors-mypy
16+
rev: v1.9.0
5017
hooks:
51-
- id: pydocstyle
18+
- id: mypy
5219
language_version: python
53-
exclude: ".*(test|scripts).*"
54-
#args: [
55-
# Don't require docstrings for tests
56-
#'--match=(?!test|scripts).*\.py',
57-
#]
20+
exclude: tests/.*
21+
additional_dependencies:
22+
- types-requests
23+
- types-attrs
24+
- pydantic~=1.10

pyproject.toml

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,28 @@
1-
[flake8]
2-
ignore = "D203"
3-
exclude = [".git", "__pycache__", "docs/source/conf.py", "build", "dist"]
4-
max-complexity = 12
5-
max-line-length = 90
6-
71
[tool.isort]
82
profile = "black"
93
known_first_party = "stac_fastapi.pgstac"
104
known_third_party = ["rasterio", "stac-pydantic", "sqlalchemy", "geoalchemy2", "fastapi", "stac_fastapi"]
115
sections = ["FUTURE", "STDLIB", "THIRDPARTY", "FIRSTPARTY", "LOCALFOLDER"]
6+
7+
[tool.mypy]
8+
ignore_missing_imports = true
9+
namespace_packages = true
10+
explicit_package_bases = true
11+
exclude = ["tests", ".venv"]
12+
13+
[tool.ruff]
14+
line-length = 90
15+
16+
[tool.ruff.lint]
17+
select = [
18+
"C",
19+
"E",
20+
"F",
21+
"W",
22+
"B",
23+
]
24+
ignore = [
25+
"E203", # line too long, handled by black
26+
"E501", # do not perform function calls in argument defaults
27+
"B028", # No explicit `stacklevel` keyword argument found
28+
]

scripts/ingest_joplin.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""Ingest sample data during docker-compose"""
2+
23
import json
34
import sys
45
from pathlib import Path

setup.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,5 @@
6464
install_requires=install_requires,
6565
tests_require=extra_reqs["dev"],
6666
extras_require=extra_reqs,
67-
entry_points={
68-
"console_scripts": ["stac-fastapi-pgstac=stac_fastapi.pgstac.app:run"]
69-
},
67+
entry_points={"console_scripts": ["stac-fastapi-pgstac=stac_fastapi.pgstac.app:run"]},
7068
)

stac_fastapi/pgstac/app.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,7 @@
4646

4747
if enabled_extensions := os.getenv("ENABLED_EXTENSIONS"):
4848
extensions = [
49-
extensions_map[extension_name]
50-
for extension_name in enabled_extensions.split(",")
49+
extensions_map[extension_name] for extension_name in enabled_extensions.split(",")
5150
]
5251
else:
5352
extensions = list(extensions_map.values())
@@ -57,7 +56,7 @@
5756
api = StacApi(
5857
settings=settings,
5958
extensions=extensions,
60-
client=CoreCrudClient(post_request_model=post_request_model),
59+
client=CoreCrudClient(post_request_model=post_request_model), # type: ignore
6160
response_class=ORJSONResponse,
6261
search_get_request_model=create_get_request_model(extensions),
6362
search_post_request_model=post_request_model,
@@ -90,8 +89,8 @@ def run():
9089
reload=settings.reload,
9190
root_path=os.getenv("UVICORN_ROOT_PATH", ""),
9291
)
93-
except ImportError:
94-
raise RuntimeError("Uvicorn must be installed in order to use command")
92+
except ImportError as e:
93+
raise RuntimeError("Uvicorn must be installed in order to use command") from e
9594

9695

9796
if __name__ == "__main__":

stac_fastapi/pgstac/core.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""Item crud client."""
2+
23
import re
34
from typing import Any, Dict, List, Optional, Union
45
from urllib.parse import unquote_plus, urljoin
@@ -136,7 +137,7 @@ async def _get_base_item(
136137

137138
return item
138139

139-
async def _search_base(
140+
async def _search_base( # noqa: C901
140141
self,
141142
search_request: PgstacSearch,
142143
request: Request,
@@ -172,10 +173,10 @@ async def _search_base(
172173
req=search_request_json,
173174
)
174175
items = await conn.fetchval(q, *p)
175-
except InvalidDatetimeFormatError:
176+
except InvalidDatetimeFormatError as e:
176177
raise InvalidQueryParameter(
177178
f"Datetime parameter {search_request.datetime} is invalid."
178-
)
179+
) from e
179180

180181
next: Optional[str] = items.pop("next", None)
181182
prev: Optional[str] = items.pop("prev", None)
@@ -207,8 +208,8 @@ async def _add_item_links(
207208
and all([collection_id, item_id])
208209
):
209210
feature["links"] = await ItemLinks(
210-
collection_id=collection_id,
211-
item_id=item_id,
211+
collection_id=collection_id, # type: ignore
212+
item_id=item_id, # type: ignore
212213
request=request,
213214
).get_links(extra_links=feature.get("links"))
214215

@@ -255,7 +256,7 @@ async def item_collection(
255256
bbox: Optional[BBox] = None,
256257
datetime: Optional[DateTimeType] = None,
257258
limit: Optional[int] = None,
258-
token: str = None,
259+
token: Optional[str] = None,
259260
**kwargs,
260261
) -> ItemCollection:
261262
"""Get all items from a specific collection.
@@ -340,7 +341,7 @@ async def post_search(
340341
item_collection = await self._search_base(search_request, request=request)
341342
return ItemCollection(**item_collection)
342343

343-
async def get_search(
344+
async def get_search( # noqa: C901
344345
self,
345346
request: Request,
346347
collections: Optional[List[str]] = None,
@@ -432,5 +433,6 @@ async def get_search(
432433
except ValidationError as e:
433434
raise HTTPException(
434435
status_code=400, detail=f"Invalid parameters provided {e}"
435-
)
436+
) from e
437+
436438
return await self.post_search(search_request, request=request)

stac_fastapi/pgstac/db.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,16 @@
22

33
import json
44
from contextlib import asynccontextmanager, contextmanager
5-
from typing import AsyncIterator, Callable, Dict, Generator, Literal, Union
5+
from typing import (
6+
AsyncIterator,
7+
Callable,
8+
Dict,
9+
Generator,
10+
List,
11+
Literal,
12+
Optional,
13+
Union,
14+
)
615

716
import attr
817
import orjson
@@ -36,14 +45,17 @@ async def con_init(conn):
3645
ConnectionGetter = Callable[[Request, Literal["r", "w"]], AsyncIterator[Connection]]
3746

3847

39-
async def connect_to_db(app: FastAPI, get_conn: ConnectionGetter = None) -> None:
48+
async def connect_to_db(
49+
app: FastAPI, get_conn: Optional[ConnectionGetter] = None
50+
) -> None:
4051
"""Create connection pools & connection retriever on application."""
4152
settings = app.state.settings
4253
if app.state.settings.testing:
4354
readpool = writepool = settings.testing_connection_string
4455
else:
4556
readpool = settings.reader_connection_string
4657
writepool = settings.writer_connection_string
58+
4759
db = DB()
4860
app.state.readpool = await db.create_pool(readpool, settings)
4961
app.state.writepool = await db.create_pool(writepool, settings)
@@ -62,15 +74,13 @@ async def get_connection(
6274
readwrite: Literal["r", "w"] = "r",
6375
) -> AsyncIterator[Connection]:
6476
"""Retrieve connection from database conection pool."""
65-
pool = (
66-
request.app.state.writepool if readwrite == "w" else request.app.state.readpool
67-
)
77+
pool = request.app.state.writepool if readwrite == "w" else request.app.state.readpool
6878
with translate_pgstac_errors():
6979
async with pool.acquire() as conn:
7080
yield conn
7181

7282

73-
async def dbfunc(conn: Connection, func: str, arg: Union[str, Dict]):
83+
async def dbfunc(conn: Connection, func: str, arg: Union[str, Dict, List]):
7484
"""Wrap PLPGSQL Functions.
7585
7686
Keyword arguments:

stac_fastapi/pgstac/extensions/filter.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""Get Queryables."""
2+
23
from typing import Any, Optional
34

45
from buildpg import render

0 commit comments

Comments
 (0)