1
1
import re
2
2
from typing import Any , Dict , Union
3
3
4
+ from gotrue .types import AuthChangeEvent
4
5
from httpx import Timeout
5
6
from postgrest import SyncFilterRequestBuilder , SyncPostgrestClient , SyncRequestBuilder
6
7
from postgrest .constants import DEFAULT_POSTGREST_CLIENT_TIMEOUT
@@ -59,6 +60,7 @@ def __init__(
59
60
self .supabase_url = supabase_url
60
61
self .supabase_key = supabase_key
61
62
options .headers .update (self ._get_auth_headers ())
63
+ self .options = options
62
64
self .rest_url = f"{ supabase_url } /rest/v1"
63
65
self .realtime_url = f"{ supabase_url } /realtime/v1" .replace ("http" , "ws" )
64
66
self .auth_url = f"{ supabase_url } /auth/v1"
@@ -77,16 +79,9 @@ def __init__(
77
79
# supabase_key=self.supabase_key,
78
80
# )
79
81
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 )
90
85
91
86
def functions (self ) -> FunctionsClient :
92
87
return FunctionsClient (self .functions_url , self ._get_auth_headers ())
@@ -125,6 +120,30 @@ def rpc(self, fn: str, params: Dict[Any, Any]) -> SyncFilterRequestBuilder:
125
120
"""
126
121
return self .postgrest .rpc (fn , params )
127
122
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
+
128
147
# async def remove_subscription_helper(resolve):
129
148
# try:
130
149
# await self._close_subscription(subscription)
@@ -185,17 +204,14 @@ def _init_supabase_auth_client(
185
204
@staticmethod
186
205
def _init_postgrest_client (
187
206
rest_url : str ,
188
- supabase_key : str ,
189
207
headers : Dict [str , str ],
190
208
schema : str ,
191
209
timeout : Union [int , float , Timeout ] = DEFAULT_POSTGREST_CLIENT_TIMEOUT ,
192
210
) -> SyncPostgrestClient :
193
211
"""Private helper for creating an instance of the Postgrest client."""
194
- client = SyncPostgrestClient (
212
+ return SyncPostgrestClient (
195
213
rest_url , headers = headers , schema = schema , timeout = timeout
196
214
)
197
- client .auth (token = supabase_key )
198
- return client
199
215
200
216
def _get_auth_headers (self ) -> Dict [str , str ]:
201
217
"""Helper method to get auth headers."""
@@ -205,6 +221,21 @@ def _get_auth_headers(self) -> Dict[str, str]:
205
221
"Authorization" : f"Bearer { self .supabase_key } " ,
206
222
}
207
223
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
+
208
239
209
240
def create_client (
210
241
supabase_url : str ,
0 commit comments