Skip to content

Commit 0af4610

Browse files
update type informations (#869)
* update type informations * update changelog * run mypy
1 parent cc9370e commit 0af4610

File tree

22 files changed

+108
-66
lines changed

22 files changed

+108
-66
lines changed

.github/workflows/cicd.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ jobs:
3535
if: ${{ matrix.python-version == env.LATEST_PY_VERSION }}
3636
run: |
3737
uv run pre-commit run --all-files
38+
uv run --with mypy --with types-attrs mypy -p stac_fastapi
3839
3940
- name: Run tests
4041
run: uv run pytest -svvv

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ repos:
77
- id: ruff-format
88

99
- repo: https://github.com/pre-commit/mirrors-mypy
10-
rev: v1.15.0
10+
rev: v1.19.0
1111
hooks:
1212
- id: mypy
1313
language_version: python

CHANGES.md

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

33
## [Unreleased]
44

5+
## [6.1.3] - 2025-12-09
6+
7+
### Fixed
8+
9+
- fixed type hints
10+
511
## [6.1.2] - 2025-12-09
612

713
### Fixed

stac_fastapi/api/stac_fastapi/api/errors.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ def request_validation_exception_handler(
9393
status_code=status.HTTP_400_BAD_REQUEST,
9494
)
9595

96+
# TODO: Argument 2 to "add_exception_handler" of "Starlette" has incompatible type
9697
app.add_exception_handler(
97-
RequestValidationError, request_validation_exception_handler
98+
RequestValidationError,
99+
request_validation_exception_handler, # type: ignore
98100
)

stac_fastapi/api/stac_fastapi/api/middleware.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ def _get_forwarded_url_parts(self, scope: Scope) -> Tuple[str, str, str]:
8686
proto = scope.get("scheme", "http")
8787
header_host = self._get_header_value_by_name(scope, "host")
8888
if header_host is None:
89-
domain, port = scope.get("server")
89+
domain, port = scope["server"]
9090
else:
9191
header_host_parts = header_host.split(":")
9292
if len(header_host_parts) == 2:

stac_fastapi/api/stac_fastapi/api/models.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,19 @@
2424
import orjson # noqa
2525
from fastapi.responses import ORJSONResponse as JSONResponse
2626
except ImportError: # pragma: nocover
27-
from starlette.responses import JSONResponse
27+
from starlette.responses import JSONResponse # type: ignore
2828

2929

3030
def create_request_model(
3131
model_name="SearchGetRequest",
3232
base_model: Union[Type[BaseModel], Type[APIRequest]] = BaseSearchGetRequest,
3333
extensions: Optional[List[ApiExtension]] = None,
3434
mixins: Optional[Union[List[Type[BaseModel]], List[Type[APIRequest]]]] = None,
35-
request_type: Optional[str] = "GET",
35+
request_type: str = "GET",
3636
) -> Union[Type[BaseModel], Type[APIRequest]]:
3737
"""Create a pydantic model for validating request bodies."""
3838
fields = {}
39-
extension_models = []
39+
extension_models: List[Union[Type[BaseModel], Type[APIRequest]]] = []
4040

4141
# Check extensions for additional parameters to search
4242
for extension in extensions or []:
@@ -54,7 +54,7 @@ def create_request_model(
5454
# Handle POST requests
5555
elif all([issubclass(m, BaseModel) for m in models]):
5656
for model in models:
57-
for k, field_info in model.model_fields.items():
57+
for k, field_info in model.model_fields.items(): # type: ignore
5858
fields[k] = (field_info.annotation, field_info)
5959

6060
return create_model(model_name, **fields, __base__=base_model) # type: ignore
@@ -64,11 +64,10 @@ def create_request_model(
6464

6565
def create_get_request_model(
6666
extensions: Optional[List[ApiExtension]],
67-
base_model: BaseSearchGetRequest = BaseSearchGetRequest,
67+
base_model: Type[BaseSearchGetRequest] = BaseSearchGetRequest,
6868
) -> Type[APIRequest]:
6969
"""Wrap create_request_model to create the GET request model."""
70-
71-
return create_request_model(
70+
return create_request_model( # type: ignore
7271
"SearchGetRequest",
7372
base_model=base_model,
7473
extensions=extensions,
@@ -78,10 +77,10 @@ def create_get_request_model(
7877

7978
def create_post_request_model(
8079
extensions: Optional[List[ApiExtension]],
81-
base_model: BaseSearchPostRequest = BaseSearchPostRequest,
80+
base_model: Type[BaseSearchPostRequest] = BaseSearchPostRequest,
8281
) -> Type[BaseModel]:
8382
"""Wrap create_request_model to create the POST request model."""
84-
return create_request_model(
83+
return create_request_model( # type: ignore
8584
"SearchPostRequest",
8685
base_model=base_model,
8786
extensions=extensions,

stac_fastapi/api/stac_fastapi/api/openapi.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,11 @@ def update_openapi(app: FastAPI) -> FastAPI:
1414
content-type response header.
1515
"""
1616
# Find the route for the openapi_url in the app
17+
# TODO: Type info is Route, while it shoukd maybe be APIRoute? Check FastAPI source.
1718
openapi_route: Route = next(
18-
route for route in app.router.routes if route.path == app.openapi_url
19+
route
20+
for route in app.router.routes
21+
if route.path == app.openapi_url # type: ignore
1922
)
2023
# Store the old endpoint function so we can call it from the patched function
2124
old_endpoint = openapi_route.endpoint

stac_fastapi/api/stac_fastapi/api/routes.py

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
from starlette.routing import BaseRoute, Match
1717
from starlette.status import HTTP_204_NO_CONTENT
1818

19-
from stac_fastapi.api.models import APIRequest
19+
from stac_fastapi.types.search import APIRequest
2020

2121

2222
def _wrap_response(resp: Any) -> Any:
@@ -58,7 +58,7 @@ async def _endpoint(request: Request, request_data: Dict[str, Any]):
5858

5959
elif issubclass(request_model, APIRequest):
6060

61-
async def _endpoint(request: Request, request_data=Depends(request_model)):
61+
async def _endpoint(request: Request, request_data=Depends(request_model)): # type: ignore
6262
"""Endpoint."""
6363
return _wrap_response(await func(request=request, **request_data.kwargs()))
6464

@@ -100,10 +100,14 @@ def add_route_dependencies(
100100
_scope = copy.deepcopy(scope)
101101
for route in routes:
102102
if scope["path"] == "*":
103-
_scope["path"] = route.path
103+
# NOTE: ignore type, because BaseRoute has no "path" attribute
104+
# but APIRoute does.
105+
_scope["path"] = route.path # type: ignore
104106

107+
# NOTE: ignore type, because BaseRoute has no "method" attribute
108+
# but APIRoute does.
105109
if scope["method"] == "*":
106-
_scope["method"] = list(route.methods)[0]
110+
_scope["method"] = list(route.methods)[0] # type: ignore
107111

108112
match, _ = route.matches({"type": "http", **_scope})
109113
if match != Match.FULL:
@@ -119,7 +123,10 @@ def add_route_dependencies(
119123
route.dependant.dependencies.insert(
120124
0,
121125
get_parameterless_sub_dependant(
122-
depends=depends, path=route.path_format
126+
# NOTE: ignore type, because BaseRoute has no "path_format"
127+
# attribute but APIRoute does.
128+
depends=depends,
129+
path=route.path_format, # type: ignore
123130
),
124131
)
125132

@@ -128,7 +135,9 @@ def add_route_dependencies(
128135
# app.include_router(router))
129136
# https://github.com/tiangolo/fastapi/blob/58ab733f19846b4875c5b79bfb1f4d1cb7f4823f/fastapi/applications.py#L337-L360
130137
# https://github.com/tiangolo/fastapi/blob/58ab733f19846b4875c5b79bfb1f4d1cb7f4823f/fastapi/routing.py#L677-L678
131-
route.dependencies.extend(dependencies)
138+
# NOTE: ignore type, because BaseRoute has no "dependencies" attribute
139+
# but APIRoute does.
140+
route.dependencies.extend(dependencies) # type: ignore
132141

133142

134143
def add_direct_response(app: FastAPI) -> None:

stac_fastapi/extensions/stac_fastapi/extensions/core/aggregation/aggregation.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
"""Aggregation Extension."""
22
from enum import Enum
3-
from typing import List, Union
3+
from typing import List, Type, Union
44

55
import attr
66
from fastapi import APIRouter, FastAPI
7+
from pydantic import BaseModel
78

89
from stac_fastapi.api.models import CollectionUri, EmptyRequest
910
from stac_fastapi.api.routes import create_async_endpoint
1011
from stac_fastapi.types.extension import ApiExtension
12+
from stac_fastapi.types.search import APIRequest
1113

1214
from .client import AsyncBaseAggregationClient, BaseAggregationClient
1315
from .request import AggregationExtensionGetRequest, AggregationExtensionPostRequest
@@ -50,8 +52,8 @@ class AggregationExtension(ApiExtension):
5052
conformance_classes: Conformance classes provided by the extension
5153
"""
5254

53-
GET = AggregationExtensionGetRequest
54-
POST = AggregationExtensionPostRequest
55+
GET: Type[APIRequest] = AggregationExtensionGetRequest
56+
POST: Type[BaseModel] = AggregationExtensionPostRequest
5557

5658
client: Union[AsyncBaseAggregationClient, BaseAggregationClient] = attr.ib(
5759
factory=BaseAggregationClient

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

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
"""Collection-Search extension."""
22

33
from enum import Enum
4-
from typing import List, Optional, Union
4+
from typing import List, Optional, Type, Union
55

66
import attr
77
from fastapi import APIRouter, FastAPI
8+
from pydantic import BaseModel
89
from stac_pydantic.api.collections import Collections
910
from stac_pydantic.shared import MimeTypes
1011

1112
from stac_fastapi.api.models import GeoJSONResponse, create_request_model
1213
from stac_fastapi.api.routes import create_async_endpoint
1314
from stac_fastapi.types.config import ApiSettings
1415
from stac_fastapi.types.extension import ApiExtension
16+
from stac_fastapi.types.search import APIRequest
1517

1618
from .client import AsyncBaseCollectionSearchClient, BaseCollectionSearchClient
1719
from .request import BaseCollectionSearchGetRequest, BaseCollectionSearchPostRequest
@@ -47,8 +49,8 @@ class CollectionSearchExtension(ApiExtension):
4749
the extension
4850
"""
4951

50-
GET: BaseCollectionSearchGetRequest = attr.ib(default=BaseCollectionSearchGetRequest) # type: ignore
51-
POST = attr.ib(init=False)
52+
GET: Type[APIRequest] = attr.ib(default=BaseCollectionSearchGetRequest)
53+
POST: Optional[Type[BaseModel]] = attr.ib(init=False)
5254

5355
conformance_classes: List[str] = attr.ib(
5456
default=[
@@ -93,7 +95,7 @@ def from_extensions(
9395
)
9496

9597
return cls(
96-
GET=get_request_model,
98+
GET=get_request_model, # type: ignore
9799
conformance_classes=conformance_classes,
98100
schema_href=schema_href,
99101
)
@@ -127,10 +129,8 @@ class CollectionSearchPostExtension(CollectionSearchExtension):
127129
schema_href: Optional[str] = attr.ib(default=None)
128130
router: APIRouter = attr.ib(factory=APIRouter)
129131

130-
GET: BaseCollectionSearchGetRequest = attr.ib(default=BaseCollectionSearchGetRequest) # type: ignore
131-
POST: BaseCollectionSearchPostRequest = attr.ib( # type: ignore
132-
default=BaseCollectionSearchPostRequest
133-
)
132+
GET: Type[APIRequest] = attr.ib(default=BaseCollectionSearchGetRequest)
133+
POST: Type[BaseModel] = attr.ib(default=BaseCollectionSearchPostRequest)
134134

135135
def register(self, app: FastAPI) -> None:
136136
"""Register the extension with a FastAPI application.
@@ -198,8 +198,8 @@ def from_extensions( # type: ignore
198198
return cls(
199199
client=client,
200200
settings=settings,
201-
GET=get_request_model,
202-
POST=post_request_model,
201+
GET=get_request_model, # type: ignore
202+
POST=post_request_model, # type: ignore
203203
conformance_classes=conformance_classes,
204204
router=router or APIRouter(),
205205
schema_href=schema_href,

0 commit comments

Comments
 (0)