Skip to content

Commit b73ae9e

Browse files
add type checking (#842)
1 parent 8f85454 commit b73ae9e

File tree

12 files changed

+59
-45
lines changed

12 files changed

+59
-45
lines changed

.pre-commit-config.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,13 @@ repos:
55
- id: ruff
66
args: [--fix, --exit-non-zero-on-fix]
77
- id: ruff-format
8+
9+
- repo: https://github.com/pre-commit/mirrors-mypy
10+
rev: v1.15.0
11+
hooks:
12+
- id: mypy
13+
language_version: python
14+
exclude: tests/.*
15+
additional_dependencies:
16+
- types-attrs
17+
- pydantic

pyproject.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ section-order = ["future", "standard-library", "third-party", "first-party", "lo
2323
[tool.ruff.format]
2424
quote-style = "double"
2525

26+
[tool.mypy]
27+
ignore_missing_imports = true
28+
namespace_packages = true
29+
explicit_package_bases = true
30+
exclude = ["tests", ".venv"]
31+
2632
[tool.bumpversion]
2733
current_version = "5.2.1"
2834
parse = """(?x)

stac_fastapi/api/stac_fastapi/api/app.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ class StacApi:
110110
),
111111
takes_self=True,
112112
),
113-
converter=update_openapi,
113+
converter=update_openapi, # type: ignore
114114
)
115115
router: APIRouter = attr.ib(default=attr.Factory(APIRouter))
116116
search_get_request_model: Type[BaseSearchGetRequest] = attr.ib(

stac_fastapi/api/stac_fastapi/api/models.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ def create_request_model(
5656
for model in models:
5757
for k, field_info in model.model_fields.items():
5858
fields[k] = (field_info.annotation, field_info)
59-
return create_model(model_name, **fields, __base__=base_model)
59+
60+
return create_model(model_name, **fields, __base__=base_model) # type: ignore
6061

6162
raise TypeError("Mixed Request Model types. Check extension request types.")
6263

@@ -121,7 +122,7 @@ class ItemCollectionUri(APIRequest, DatetimeMixin):
121122
description="Limits the number of results that are included in each page of the response (capped to 10_000)." # noqa: E501
122123
),
123124
] = attr.ib(default=10)
124-
bbox: Optional[BBox] = attr.ib(default=None, converter=_bbox_converter)
125+
bbox: Optional[BBox] = attr.ib(default=None, converter=_bbox_converter) # type: ignore
125126
datetime: DateTimeQueryType = attr.ib(default=None, validator=_validate_datetime)
126127

127128

stac_fastapi/api/stac_fastapi/api/py.typed

Whitespace-only changes.

stac_fastapi/api/stac_fastapi/api/routes.py

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import copy
44
import functools
55
import inspect
6-
from typing import Any, Callable, Dict, List, Optional, Type, TypedDict, Union
6+
from typing import Any, Awaitable, Callable, Dict, List, Optional, Type, TypedDict, Union
77

88
from fastapi import Depends, FastAPI, params
99
from fastapi.datastructures import DefaultPlaceholder
@@ -39,7 +39,7 @@ async def run(*args, **kwargs):
3939
def create_async_endpoint(
4040
func: Callable,
4141
request_model: Union[Type[APIRequest], Type[BaseModel], Dict],
42-
):
42+
) -> Callable[[Any, Any], Awaitable[Any]]:
4343
"""Wrap a function in a coroutine which may be used to create a FastAPI endpoint.
4444
4545
Synchronous functions are executed asynchronously using a background thread.
@@ -48,32 +48,28 @@ def create_async_endpoint(
4848
if not inspect.iscoroutinefunction(func):
4949
func = sync_to_async(func)
5050

51-
if issubclass(request_model, APIRequest):
51+
_endpoint: Callable[[Any, Any], Awaitable[Any]]
5252

53-
async def _endpoint(
54-
request: Request,
55-
request_data: request_model = Depends(), # type:ignore
56-
):
53+
if isinstance(request_model, dict):
54+
55+
async def _endpoint(request: Request, request_data: Dict[str, Any]):
56+
"""Endpoint."""
57+
return _wrap_response(await func(request_data, request=request))
58+
59+
elif issubclass(request_model, APIRequest):
60+
61+
async def _endpoint(request: Request, request_data=Depends(request_model)):
5762
"""Endpoint."""
5863
return _wrap_response(await func(request=request, **request_data.kwargs()))
5964

6065
elif issubclass(request_model, BaseModel):
6166

62-
async def _endpoint(
63-
request: Request,
64-
request_data: request_model, # type:ignore
65-
):
67+
async def _endpoint(request: Request, request_data: request_model): # type: ignore
6668
"""Endpoint."""
6769
return _wrap_response(await func(request_data, request=request))
6870

6971
else:
70-
71-
async def _endpoint(
72-
request: Request,
73-
request_data: Dict[str, Any], # type:ignore
74-
):
75-
"""Endpoint."""
76-
return _wrap_response(await func(request_data, request=request))
72+
raise ValueError(f"Unsupported type for request model {type(request_model)}")
7773

7874
return _endpoint
7975

stac_fastapi/extensions/stac_fastapi/extensions/core/collection_search/client.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import attr
66

7-
from stac_fastapi.types import stac
7+
from stac_fastapi.types.stac import ItemCollection
88

99
from .request import BaseCollectionSearchPostRequest
1010

@@ -18,7 +18,7 @@ async def post_all_collections(
1818
self,
1919
search_request: BaseCollectionSearchPostRequest,
2020
**kwargs,
21-
) -> stac.ItemCollection:
21+
) -> ItemCollection:
2222
"""Get all available collections.
2323
2424
Called with `POST /collections`.
@@ -37,7 +37,7 @@ class BaseCollectionSearchClient(abc.ABC):
3737
@abc.abstractmethod
3838
def post_all_collections(
3939
self, search_request: BaseCollectionSearchPostRequest, **kwargs
40-
) -> stac.ItemCollection:
40+
) -> ItemCollection:
4141
"""Get all available collections.
4242
4343
Called with `POST /collections`.

stac_fastapi/extensions/stac_fastapi/extensions/core/collection_search/collection_search.py

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,13 @@ class CollectionSearchExtension(ApiExtension):
4747
the extension
4848
"""
4949

50-
GET: BaseCollectionSearchGetRequest = attr.ib(default=BaseCollectionSearchGetRequest)
51-
POST = None
50+
GET: BaseCollectionSearchGetRequest = attr.ib(default=BaseCollectionSearchGetRequest) # type: ignore
51+
POST = attr.ib(init=False)
5252

5353
conformance_classes: List[str] = attr.ib(
5454
default=[
55-
CollectionSearchConformanceClasses.COLLECTIONSEARCH,
56-
CollectionSearchConformanceClasses.BASIS,
55+
CollectionSearchConformanceClasses.COLLECTIONSEARCH.value,
56+
CollectionSearchConformanceClasses.BASIS.value,
5757
]
5858
)
5959
schema_href: Optional[str] = attr.ib(default=None)
@@ -73,13 +73,14 @@ def register(self, app: FastAPI) -> None:
7373
def from_extensions(
7474
cls,
7575
extensions: List[ApiExtension],
76+
*,
7677
schema_href: Optional[str] = None,
7778
) -> "CollectionSearchExtension":
7879
"""Create CollectionSearchExtension object from extensions."""
7980

8081
conformance_classes = [
81-
CollectionSearchConformanceClasses.COLLECTIONSEARCH,
82-
CollectionSearchConformanceClasses.BASIS,
82+
CollectionSearchConformanceClasses.COLLECTIONSEARCH.value,
83+
CollectionSearchConformanceClasses.BASIS.value,
8384
]
8485
for ext in extensions:
8586
conformance_classes.extend(ext.conformance_classes)
@@ -119,15 +120,15 @@ class CollectionSearchPostExtension(CollectionSearchExtension):
119120
settings: ApiSettings = attr.ib()
120121
conformance_classes: List[str] = attr.ib(
121122
default=[
122-
CollectionSearchConformanceClasses.COLLECTIONSEARCH,
123-
CollectionSearchConformanceClasses.BASIS,
123+
CollectionSearchConformanceClasses.COLLECTIONSEARCH.value,
124+
CollectionSearchConformanceClasses.BASIS.value,
124125
]
125126
)
126127
schema_href: Optional[str] = attr.ib(default=None)
127128
router: APIRouter = attr.ib(factory=APIRouter)
128129

129-
GET: BaseCollectionSearchGetRequest = attr.ib(default=BaseCollectionSearchGetRequest)
130-
POST: BaseCollectionSearchPostRequest = attr.ib(
130+
GET: BaseCollectionSearchGetRequest = attr.ib(default=BaseCollectionSearchGetRequest) # type: ignore
131+
POST: BaseCollectionSearchPostRequest = attr.ib( # type: ignore
131132
default=BaseCollectionSearchPostRequest
132133
)
133134

@@ -163,19 +164,19 @@ def register(self, app: FastAPI) -> None:
163164
app.include_router(self.router)
164165

165166
@classmethod
166-
def from_extensions(
167+
def from_extensions( # type: ignore
167168
cls,
168169
extensions: List[ApiExtension],
169170
*,
171+
schema_href: Optional[str] = None,
170172
client: Union[AsyncBaseCollectionSearchClient, BaseCollectionSearchClient],
171173
settings: ApiSettings,
172-
schema_href: Optional[str] = None,
173174
router: Optional[APIRouter] = None,
174175
) -> "CollectionSearchPostExtension":
175176
"""Create CollectionSearchPostExtension object from extensions."""
176177
conformance_classes = [
177-
CollectionSearchConformanceClasses.COLLECTIONSEARCH,
178-
CollectionSearchConformanceClasses.BASIS,
178+
CollectionSearchConformanceClasses.COLLECTIONSEARCH.value,
179+
CollectionSearchConformanceClasses.BASIS.value,
179180
]
180181
for ext in extensions:
181182
conformance_classes.extend(ext.conformance_classes)

stac_fastapi/extensions/stac_fastapi/extensions/core/collection_search/request.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
class BaseCollectionSearchGetRequest(APIRequest, DatetimeMixin):
2525
"""Basics additional Collection-Search parameters for the GET request."""
2626

27-
bbox: Optional[BBox] = attr.ib(default=None, converter=_bbox_converter)
27+
bbox: Optional[BBox] = attr.ib(default=None, converter=_bbox_converter) # type: ignore
2828
datetime: DateTimeQueryType = attr.ib(default=None, validator=_validate_datetime)
2929
limit: Annotated[
3030
Optional[Limit],

stac_fastapi/extensions/stac_fastapi/extensions/py.typed

Whitespace-only changes.

0 commit comments

Comments
 (0)