55import typing
66from collections .abc import Mapping , Sequence
77
8+ from httpware ._internal .auth import AuthValue , _normalize_auth
89from httpware ._internal .chain import compose
910from httpware .config import ClientConfig , Limits , Timeout
1011from httpware .decoders import ResponseDecoder
@@ -52,6 +53,8 @@ class AsyncClient:
5253 _transport : Transport
5354 _dispatch : Next
5455 _owns_transport : bool
56+ _user_middleware : tuple [Middleware , ...]
57+ _auth : AuthValue
5558
5659 def __init__ (
5760 self ,
@@ -64,12 +67,19 @@ def __init__(
6467 transport : Transport | None = None ,
6568 decoder : ResponseDecoder | None = None ,
6669 middleware : Sequence [Middleware ] | None = None ,
70+ auth : AuthValue = None ,
6771 ) -> None :
6872 normalized_timeout = _normalize_timeout (timeout )
6973 resolved_limits = limits or Limits ()
7074 resolved_transport : Transport = transport or Httpx2Transport (limits = resolved_limits , timeout = normalized_timeout )
7175 resolved_decoder = decoder or PydanticDecoder ()
72- resolved_middleware = tuple (middleware ) if middleware is not None else ()
76+ resolved_user_middleware : tuple [Middleware , ...] = tuple (middleware ) if middleware is not None else ()
77+ resolved_auth_middleware = _normalize_auth (auth )
78+ composed_middleware : tuple [Middleware , ...] = (
79+ resolved_user_middleware
80+ if resolved_auth_middleware is None
81+ else (* resolved_user_middleware , resolved_auth_middleware )
82+ )
7383
7484 self ._config = ClientConfig (
7585 base_url = base_url ,
@@ -78,11 +88,13 @@ def __init__(
7888 timeout = normalized_timeout ,
7989 limits = resolved_limits ,
8090 decoder = resolved_decoder ,
81- middleware = resolved_middleware ,
91+ middleware = composed_middleware ,
8292 )
8393 self ._transport = resolved_transport
84- self ._dispatch = compose (resolved_middleware , resolved_transport )
94+ self ._dispatch = compose (composed_middleware , resolved_transport )
8595 self ._owns_transport = True
96+ self ._user_middleware = resolved_user_middleware
97+ self ._auth = auth
8698
8799 @classmethod
88100 def from_url (cls , base_url : str , ** kwargs : object ) -> "AsyncClient" :
@@ -582,6 +594,7 @@ def with_options(
582594 timeout : Timeout | float | None = _UNSET ,
583595 decoder : ResponseDecoder | None = _UNSET ,
584596 middleware : Sequence [Middleware ] | None = _UNSET ,
597+ auth : AuthValue | object = _UNSET ,
585598 ) -> "AsyncClient" :
586599 """Return a new AsyncClient sharing the same transport with overridden config.
587600
@@ -603,18 +616,44 @@ def with_options(
603616 changes ["timeout" ] = _normalize_timeout (timeout )
604617 if decoder is not _UNSET :
605618 changes ["decoder" ] = decoder or PydanticDecoder ()
619+
620+ new_user_middleware = self ._user_middleware
606621 if middleware is not _UNSET :
607- changes ["middleware" ] = tuple (middleware ) if middleware is not None else ()
622+ new_user_middleware = tuple (middleware ) if middleware is not None else ()
623+
624+ new_auth : AuthValue = self ._auth
625+ if auth is not _UNSET :
626+ new_auth = auth # ty: ignore[invalid-assignment]
627+
628+ new_auth_middleware = _normalize_auth (new_auth )
629+ new_composed : tuple [Middleware , ...] = (
630+ new_user_middleware if new_auth_middleware is None else (* new_user_middleware , new_auth_middleware )
631+ )
632+ changes ["middleware" ] = new_composed
608633
609634 new_config = dataclasses .replace (self ._config , ** changes )
610- return AsyncClient ._from_view (new_config , self ._transport )
635+ return AsyncClient ._from_view (
636+ new_config ,
637+ self ._transport ,
638+ user_middleware = new_user_middleware ,
639+ auth = new_auth ,
640+ )
611641
612642 @classmethod
613- def _from_view (cls , config : ClientConfig , transport : Transport ) -> "AsyncClient" :
643+ def _from_view (
644+ cls ,
645+ config : ClientConfig ,
646+ transport : Transport ,
647+ * ,
648+ user_middleware : tuple [Middleware , ...],
649+ auth : AuthValue ,
650+ ) -> "AsyncClient" :
614651 """Construct a view sharing an existing transport. Bypasses __init__."""
615652 client = cls .__new__ (cls )
616653 client ._config = config # noqa: SLF001
617654 client ._transport = transport # noqa: SLF001
618655 client ._dispatch = compose (config .middleware , transport ) # noqa: SLF001
619656 client ._owns_transport = False # noqa: SLF001
657+ client ._user_middleware = user_middleware # noqa: SLF001
658+ client ._auth = auth # noqa: SLF001
620659 return client
0 commit comments