Skip to content

Add type hints for router methods meta kwargs#18

Draft
flapili wants to merge 1 commit into
mr-fatalyst:masterfrom
flapili:feature/type-meta-kwargs
Draft

Add type hints for router methods meta kwargs#18
flapili wants to merge 1 commit into
mr-fatalyst:masterfrom
flapili:feature/type-meta-kwargs

Conversation

@flapili

@flapili flapili commented Jun 18, 2026

Copy link
Copy Markdown

Pull Request

Thanks for contributing to FastOpenAPI!
Before submitting, please make sure you've read CONTRIBUTING.md.


What’s Included?

  • New feature
  • Bug fix
  • Documentation improvement
  • Refactor / internal change

Describe your changes:
Adding type hint to document usage of router's methods like get/post/... to help autocompletion, does not change runtime behavior

For now the code is draft, contains TODOs and I was not sure where I should put the Meta class so in the meantime, I nested it in the router 👀


How Was It Tested?

For now only checking autocompletion & docstring work in editor (I noticed that Ty lsp does not handle fields docstrings in typedDict yet(?) but pylance do work)


Anything Else?

Optional:

  • Any TODOs or follow-up items?
  • Where Meta should be located?
  • check sys.version_info to import Unpack & NotRequired for 3.11 & 3.12 respectivly ?
  • Known limitations or trade-offs?
  • Anything you'd like reviewers to focus on?
  • I'm not sure about how to word docstrings properly

@mr-fatalyst

Copy link
Copy Markdown
Owner

Hi @flapili, thanks for the PR! The direction is good and I would like to take it. I just shipped py.typed, and **meta is the last untyped part of the public API, so typed kwargs fit well here. A few things need to change before this can be merged.

1. The TypedDict must cover every supported key.
Unpack[TypedDict] makes the kwargs a closed set: any keyword not listed becomes a type error for every user who runs a type checker. The library currently reads these keys from meta:

  • response_model: Any
  • status_code: int
  • summary: str
  • description: str
  • deprecated: bool
  • tags: list[str]
  • operation_id: str
  • security: list[dict[str, list[str]]]
  • responses: dict[int, Any]
  • response_errors: list[int]

With the current draft, valid code like tags=["items"] or operation_id="listItems" would be flagged as an error.

2. response_model should be Any, not Type[BaseModel].
Valid values include list[Item], plain dict, and primitives like int or str. Type[BaseModel] would reject all of those.

3. mypy strict must stay green.
CI now runs mypy --strict on the package, and the draft would fail it in two places:

  • meta["method"] = method inside _create_route_decorator writes a key that is not declared in the TypedDict. Either declare method: NotRequired[str] (marked as internal in its docstring) or keep the internal parameter typed as a plain dict.
  • The return annotations on get/post/etc. were dropped. Strict mode requires them, please keep them.

4. Location and name.
Please move the class to module level in fastopenapi/core/router.py, next to RouteInfo, and name it RouteMeta (Meta is too generic). It should also be importable by users so they can annotate their own helper functions.

5. Imports: no sys.version_info checks needed.
Import Unpack and NotRequired from typing_extensions unconditionally and add typing-extensions to the dependencies in pyproject.toml. Pydantic already depends on it, so it is present in every user environment anyway and adds no real weight.

6. Please rebase on current master.
core/router.py changed quite a bit recently, so the diff is based on an outdated revision and will conflict.

On the field docstrings: the wording approach is fine. Some language servers do not show TypedDict field docstrings yet, but Pylance does, and that covers most users.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants