11import re
22from typing import Any , Dict , Union
33
4+ from gotrue .types import AuthChangeEvent
45from httpx import Timeout
56from postgrest import SyncFilterRequestBuilder , SyncPostgrestClient , SyncRequestBuilder
67from postgrest .constants import DEFAULT_POSTGREST_CLIENT_TIMEOUT
@@ -59,6 +60,7 @@ def __init__(
5960 self .supabase_url = supabase_url
6061 self .supabase_key = supabase_key
6162 options .headers .update (self ._get_auth_headers ())
63+ self .options = options
6264 self .rest_url = f"{ supabase_url } /rest/v1"
6365 self .realtime_url = f"{ supabase_url } /realtime/v1" .replace ("http" , "ws" )
6466 self .auth_url = f"{ supabase_url } /auth/v1"
@@ -77,16 +79,9 @@ def __init__(
7779 # supabase_key=self.supabase_key,
7880 # )
7981 self .realtime = None
80- self .postgrest = self ._init_postgrest_client (
81- rest_url = self .rest_url ,
82- supabase_key = self .supabase_key ,
83- headers = options .headers ,
84- schema = options .schema ,
85- timeout = options .postgrest_client_timeout ,
86- )
87- self .storage = self ._init_storage_client (
88- self .storage_url , self ._get_auth_headers (), options .storage_client_timeout
89- )
82+ self ._postgrest = None
83+ self ._storage = None
84+ self .auth .on_auth_state_change (self ._listen_to_auth_events )
9085
9186 def functions (self ) -> FunctionsClient :
9287 return FunctionsClient (self .functions_url , self ._get_auth_headers ())
@@ -125,6 +120,30 @@ def rpc(self, fn: str, params: Dict[Any, Any]) -> SyncFilterRequestBuilder:
125120 """
126121 return self .postgrest .rpc (fn , params )
127122
123+ @property
124+ def postgrest (self ):
125+ if self ._postgrest is None :
126+ self .options .headers .update (self ._get_token_header ())
127+ self ._postgrest = self ._init_postgrest_client (
128+ rest_url = self .rest_url ,
129+ headers = self .options .headers ,
130+ schema = self .options .schema ,
131+ timeout = self .options .postgrest_client_timeout ,
132+ )
133+ return self ._postgrest
134+
135+ @property
136+ def storage (self ):
137+ if self ._storage is None :
138+ headers = self ._get_auth_headers ()
139+ headers .update (self ._get_token_header ())
140+ self ._storage = self ._init_storage_client (
141+ storage_url = self .storage_url ,
142+ headers = headers ,
143+ storage_client_timeout = self .options .storage_client_timeout ,
144+ )
145+ return self ._storage
146+
128147 # async def remove_subscription_helper(resolve):
129148 # try:
130149 # await self._close_subscription(subscription)
@@ -185,17 +204,14 @@ def _init_supabase_auth_client(
185204 @staticmethod
186205 def _init_postgrest_client (
187206 rest_url : str ,
188- supabase_key : str ,
189207 headers : Dict [str , str ],
190208 schema : str ,
191209 timeout : Union [int , float , Timeout ] = DEFAULT_POSTGREST_CLIENT_TIMEOUT ,
192210 ) -> SyncPostgrestClient :
193211 """Private helper for creating an instance of the Postgrest client."""
194- client = SyncPostgrestClient (
212+ return SyncPostgrestClient (
195213 rest_url , headers = headers , schema = schema , timeout = timeout
196214 )
197- client .auth (token = supabase_key )
198- return client
199215
200216 def _get_auth_headers (self ) -> Dict [str , str ]:
201217 """Helper method to get auth headers."""
@@ -205,6 +221,21 @@ def _get_auth_headers(self) -> Dict[str, str]:
205221 "Authorization" : f"Bearer { self .supabase_key } " ,
206222 }
207223
224+ def _get_token_header (self ):
225+ try :
226+ access_token = self .auth .get_session ().access_token
227+ except :
228+ access_token = self .supabase_key
229+
230+ return {
231+ "Authorization" : f"Bearer { access_token } " ,
232+ }
233+
234+ def _listen_to_auth_events (self , event : AuthChangeEvent , session ):
235+ # reset postgrest instance on event change
236+ self ._postgrest = None
237+ self ._storage = None
238+
208239
209240def create_client (
210241 supabase_url : str ,
0 commit comments