From 2406d02336e3d1bf77aeba31e25b7934d4236bc3 Mon Sep 17 00:00:00 2001 From: Bear-03 <64696287+Bear-03@users.noreply.github.com> Date: Wed, 4 Nov 2026 12:36:14 +0100 Subject: [PATCH 1/2] [Authlib] Improve starlette integrations --- stubs/Authlib/@tests/stubtest_allowlist.txt | 1 - stubs/Authlib/METADATA.toml | 2 +- .../starlette_client/__init__.pyi | 17 ++++++--- .../integrations/starlette_client/apps.pyi | 35 ++++++++++--------- 4 files changed, 33 insertions(+), 22 deletions(-) diff --git a/stubs/Authlib/@tests/stubtest_allowlist.txt b/stubs/Authlib/@tests/stubtest_allowlist.txt index 1cad504d5e7e..afe7d20305f3 100644 --- a/stubs/Authlib/@tests/stubtest_allowlist.txt +++ b/stubs/Authlib/@tests/stubtest_allowlist.txt @@ -43,4 +43,3 @@ authlib.oidc.core.grants.implicit.OpenIDImplicitGrant.validate_consent_request # Exclude integrations dirs # Failed to import, getting ModuleNotFoundError for third-party libs: authlib.integrations.sqla_oauth2.* -authlib.integrations.starlette_client.* diff --git a/stubs/Authlib/METADATA.toml b/stubs/Authlib/METADATA.toml index 2a74c8f3e5c1..5a87ffbbc384 100644 --- a/stubs/Authlib/METADATA.toml +++ b/stubs/Authlib/METADATA.toml @@ -2,7 +2,7 @@ version = "1.8.0" upstream-repository = "https://github.com/authlib/authlib" dependencies = ["cryptography"] # Requires a version of flask with a `py.typed` file -optional-dependencies = ["django-stubs", "Flask>=2.0.0", "httpx2", "requests", "types-oauthlib"] +optional-dependencies = ["django-stubs", "Flask>=2.0.0", "httpx2", "requests", "starlette", "types-oauthlib"] [tool.stubtest] mypy-plugins = ["mypy_django_plugin.main"] diff --git a/stubs/Authlib/authlib/integrations/starlette_client/__init__.pyi b/stubs/Authlib/authlib/integrations/starlette_client/__init__.pyi index ea654f6f55bd..1432f72e2281 100644 --- a/stubs/Authlib/authlib/integrations/starlette_client/__init__.pyi +++ b/stubs/Authlib/authlib/integrations/starlette_client/__init__.pyi @@ -1,14 +1,23 @@ -from _typeshed import Incomplete +from typing import TypeVar, overload -from ..base_client import BaseOAuth, OAuthError as OAuthError +from starlette.config import Config + +from ..base_client import BaseApp, BaseOAuth, OAuthError as OAuthError from .apps import StarletteOAuth1App as StarletteOAuth1App, StarletteOAuth2App as StarletteOAuth2App from .integration import StarletteIntegration as StarletteIntegration +_AppT = TypeVar("_AppT", bound=BaseApp) + class OAuth(BaseOAuth): oauth1_client_cls = StarletteOAuth1App oauth2_client_cls = StarletteOAuth2App framework_integration_cls = StarletteIntegration - config: Incomplete - def __init__(self, config=None, cache=None, fetch_token=None, update_token=None) -> None: ... + config: Config | None + def __init__(self, config: Config | None = None, cache=None, fetch_token=None, update_token=None) -> None: ... + + @overload + def register(self, name: str, overwrite: bool = False, *, client_cls: type[_AppT], **kwargs) -> _AppT: ... + @overload + def register(self, name: str, overwrite: bool = False, **kwargs): ... __all__ = ["OAuth", "OAuthError", "StarletteIntegration", "StarletteOAuth1App", "StarletteOAuth2App"] diff --git a/stubs/Authlib/authlib/integrations/starlette_client/apps.pyi b/stubs/Authlib/authlib/integrations/starlette_client/apps.pyi index 47b6267c4430..3fda629024c3 100644 --- a/stubs/Authlib/authlib/integrations/starlette_client/apps.pyi +++ b/stubs/Authlib/authlib/integrations/starlette_client/apps.pyi @@ -1,33 +1,36 @@ from _typeshed import Incomplete -from typing import TypeAlias +from typing import Any +from starlette.datastructures import URL +from starlette.requests import Request +from starlette.responses import RedirectResponse + +from ...oauth2.rfc6749.wrappers import OAuth2Token from ..base_client import BaseApp from ..base_client.async_app import AsyncOAuth1Mixin, AsyncOAuth2Mixin from ..base_client.async_openid import AsyncOpenIDMixin from ..httpx_client import AsyncOAuth1Client, AsyncOAuth2Client -_RedirectResponse: TypeAlias = Incomplete # actual type is starlette.responses.RedirectResponse - class StarletteAppMixin: - async def save_authorize_data(self, request, **kwargs) -> None: ... - async def authorize_redirect(self, request, redirect_uri=None, **kwargs) -> _RedirectResponse: ... + async def save_authorize_data(self, request: Request, **kwargs) -> None: ... + async def authorize_redirect(self, request: Request, redirect_uri: str | URL | None = None, **kwargs) -> RedirectResponse: ... class StarletteOAuth1App(StarletteAppMixin, AsyncOAuth1Mixin, BaseApp): client_cls = AsyncOAuth1Client - async def authorize_access_token(self, request, **kwargs): ... + async def authorize_access_token(self, request: Request, **kwargs) -> dict[Incomplete, Incomplete]: ... class StarletteOAuth2App(StarletteAppMixin, AsyncOAuth2Mixin, AsyncOpenIDMixin, BaseApp): client_cls = AsyncOAuth2Client async def logout_redirect( self, - request, - post_logout_redirect_uri=None, - id_token_hint=None, + request: Request, + post_logout_redirect_uri: str | URL | None = None, + id_token_hint: str | None = None, *, - state=None, - client_id=None, - logout_hint=None, - ui_locales=None, - ) -> _RedirectResponse: ... - async def validate_logout_response(self, request): ... - async def authorize_access_token(self, request, **kwargs): ... + state: str | None = None, + client_id: str | None = None, + logout_hint: str | None = None, + ui_locales: str | None = None, + ) -> RedirectResponse: ... + async def validate_logout_response(self, request: Request) -> dict[str, Any]: ... + async def authorize_access_token(self, request: Request, **kwargs) -> OAuth2Token: ... From 2ee6f5e48bfc3da67beb4d02bdfabf3b1d79279a Mon Sep 17 00:00:00 2001 From: Bear-03 <64696287+Bear-03@users.noreply.github.com> Date: Wed, 4 Nov 2026 21:11:54 +0100 Subject: [PATCH 2/2] Type OAuth1 access token as dict[str, Any] --- stubs/Authlib/authlib/integrations/starlette_client/apps.pyi | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/stubs/Authlib/authlib/integrations/starlette_client/apps.pyi b/stubs/Authlib/authlib/integrations/starlette_client/apps.pyi index 3fda629024c3..2114647cbf4a 100644 --- a/stubs/Authlib/authlib/integrations/starlette_client/apps.pyi +++ b/stubs/Authlib/authlib/integrations/starlette_client/apps.pyi @@ -1,4 +1,3 @@ -from _typeshed import Incomplete from typing import Any from starlette.datastructures import URL @@ -17,7 +16,7 @@ class StarletteAppMixin: class StarletteOAuth1App(StarletteAppMixin, AsyncOAuth1Mixin, BaseApp): client_cls = AsyncOAuth1Client - async def authorize_access_token(self, request: Request, **kwargs) -> dict[Incomplete, Incomplete]: ... + async def authorize_access_token(self, request: Request, **kwargs) -> dict[str, Any]: ... class StarletteOAuth2App(StarletteAppMixin, AsyncOAuth2Mixin, AsyncOpenIDMixin, BaseApp): client_cls = AsyncOAuth2Client