Skip to content

Commit

Permalink
Add parse_response method to custom pydantic base model
Browse files Browse the repository at this point in the history
  • Loading branch information
Dani Reinón committed Nov 14, 2021
1 parent eaeae46 commit cb4624d
Show file tree
Hide file tree
Showing 13 changed files with 169 additions and 117 deletions.
44 changes: 28 additions & 16 deletions gotrue/_async/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,17 @@

from typing import Any, Dict, Optional, Union

from ..helpers import encode_uri_component, parse_response, parse_session_or_user
from ..helpers import encode_uri_component, check_response
from ..http_clients import AsyncClient
from ..types import CookieOptions, LinkType, Provider, Session, User, UserAttributes
from ..types import (
CookieOptions,
LinkType,
Provider,
Session,
User,
UserAttributes,
determine_session_or_user_model_from_response,
)


class AsyncGoTrueAPI:
Expand Down Expand Up @@ -70,7 +78,8 @@ async def sign_up_with_email(
data = {"email": email, "password": password, "data": data}
url = f"{self.url}/signup{query_string}"
response = await self.http_client.post(url, json=data, headers=headers)
return parse_response(response, parse_session_or_user)
SessionOrUserModel = determine_session_or_user_model_from_response(response)
return SessionOrUserModel.parse_response(response)

async def sign_in_with_email(
self,
Expand Down Expand Up @@ -108,7 +117,7 @@ async def sign_in_with_email(
data = {"email": email, "password": password}
url = f"{self.url}/token{query_string}"
response = await self.http_client.post(url, json=data, headers=headers)
return parse_response(response, Session.parse_obj)
return Session.parse_response(response)

async def sign_up_with_phone(
self,
Expand Down Expand Up @@ -143,7 +152,8 @@ async def sign_up_with_phone(
data = {"phone": phone, "password": password, "data": data}
url = f"{self.url}/signup"
response = await self.http_client.post(url, json=data, headers=headers)
return parse_response(response, parse_session_or_user)
SessionOrUserModel = determine_session_or_user_model_from_response(response)
return SessionOrUserModel.parse_response(response)

async def sign_in_with_phone(
self,
Expand Down Expand Up @@ -175,7 +185,7 @@ async def sign_in_with_phone(
data = {"phone": phone, "password": password}
url = f"{self.url}/token{query_string}"
response = await self.http_client.post(url, json=data, headers=headers)
return parse_response(response, Session.parse_obj)
return Session.parse_response(response)

async def send_magic_link_email(
self,
Expand Down Expand Up @@ -205,7 +215,7 @@ async def send_magic_link_email(
data = {"email": email}
url = f"{self.url}/magiclink{query_string}"
response = await self.http_client.post(url, json=data, headers=headers)
return parse_response(response, lambda _: None)
return check_response(response)

async def send_mobile_otp(self, *, phone: str) -> None:
"""Sends a mobile OTP via SMS. Will register the account if it doesn't already exist
Expand All @@ -224,7 +234,7 @@ async def send_mobile_otp(self, *, phone: str) -> None:
data = {"phone": phone}
url = f"{self.url}/otp"
response = await self.http_client.post(url, json=data, headers=headers)
return parse_response(response, lambda _: None)
return check_response(response)

async def verify_mobile_otp(
self,
Expand Down Expand Up @@ -266,7 +276,8 @@ async def verify_mobile_otp(
data["redirect_to"] = redirect_to_encoded
url = f"{self.url}/verify"
response = await self.http_client.post(url, json=data, headers=headers)
return parse_response(response, parse_session_or_user)
SessionOrUserModel = determine_session_or_user_model_from_response(response)
return SessionOrUserModel.parse_response(response)

async def invite_user_by_email(
self,
Expand Down Expand Up @@ -304,7 +315,7 @@ async def invite_user_by_email(
data = {"email": email, "data": data}
url = f"{self.url}/invite{query_string}"
response = await self.http_client.post(url, json=data, headers=headers)
return parse_response(response, User.parse_obj)
return User.parse_response(response)

async def reset_password_for_email(
self,
Expand Down Expand Up @@ -334,7 +345,7 @@ async def reset_password_for_email(
data = {"email": email}
url = f"{self.url}/recover{query_string}"
response = await self.http_client.post(url, json=data, headers=headers)
return parse_response(response, lambda _: None)
return check_response(response)

def _create_request_headers(self, *, jwt: str) -> Dict[str, str]:
"""Create temporary object.
Expand Down Expand Up @@ -426,7 +437,7 @@ async def get_user(self, *, jwt: str) -> User:
headers = self._create_request_headers(jwt=jwt)
url = f"{self.url}/user"
response = await self.http_client.get(url, headers=headers)
return parse_response(response, User.parse_obj)
return User.parse_response(response)

async def update_user(
self,
Expand Down Expand Up @@ -458,7 +469,7 @@ async def update_user(
data = attributes.dict()
url = f"{self.url}/user"
response = await self.http_client.put(url, json=data, headers=headers)
return parse_response(response, User.parse_obj)
return User.parse_response(response)

async def delete_user(self, *, uid: str, jwt: str) -> User:
"""Delete a user. Requires a `service_role` key.
Expand Down Expand Up @@ -486,7 +497,7 @@ async def delete_user(self, *, uid: str, jwt: str) -> User:
headers = self._create_request_headers(jwt=jwt)
url = f"{self.url}/admin/users/${uid}"
response = await self.http_client.delete(url, headers=headers)
return parse_response(response, User.parse_obj)
return User.parse_response(response)

async def refresh_access_token(self, *, refresh_token: str) -> Session:
"""Generates a new JWT.
Expand All @@ -511,7 +522,7 @@ async def refresh_access_token(self, *, refresh_token: str) -> Session:
data = {"refresh_token": refresh_token}
url = f"{self.url}/token{query_string}"
response = await self.http_client.post(url, json=data, headers=headers)
return parse_response(response, Session.parse_obj)
return Session.parse_response(response)

async def generate_link(
self,
Expand Down Expand Up @@ -562,7 +573,8 @@ async def generate_link(
data["redirect_to"] = redirect_to_encoded
url = f"{self.url}/admin/generate_link"
response = await self.http_client.post(url, json=data, headers=headers)
return parse_response(response, parse_session_or_user)
SessionOrUserModel = determine_session_or_user_model_from_response(response)
return SessionOrUserModel.parse_response(response)

async def set_auth_cookie(self, *, req, res):
"""Stub for parity with JS api."""
Expand Down
2 changes: 1 addition & 1 deletion gotrue/_async/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

from ..constants import COOKIE_OPTIONS, DEFAULT_HEADERS, GOTRUE_URL, STORAGE_KEY
from ..types import (
APIError,
AuthChangeEvent,
CookieOptions,
Provider,
Expand All @@ -19,6 +18,7 @@
User,
UserAttributes,
)
from ..exceptions import APIError
from .api import AsyncGoTrueAPI
from .storage import AsyncMemoryStorage, AsyncSupportedStorage

Expand Down
44 changes: 28 additions & 16 deletions gotrue/_sync/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,17 @@

from typing import Any, Dict, Optional, Union

from ..helpers import encode_uri_component, parse_response, parse_session_or_user
from ..helpers import encode_uri_component, check_response
from ..http_clients import SyncClient
from ..types import CookieOptions, LinkType, Provider, Session, User, UserAttributes
from ..types import (
CookieOptions,
LinkType,
Provider,
Session,
User,
UserAttributes,
determine_session_or_user_model_from_response,
)


class SyncGoTrueAPI:
Expand Down Expand Up @@ -70,7 +78,8 @@ def sign_up_with_email(
data = {"email": email, "password": password, "data": data}
url = f"{self.url}/signup{query_string}"
response = self.http_client.post(url, json=data, headers=headers)
return parse_response(response, parse_session_or_user)
SessionOrUserModel = determine_session_or_user_model_from_response(response)
return SessionOrUserModel.parse_response(response)

def sign_in_with_email(
self,
Expand Down Expand Up @@ -108,7 +117,7 @@ def sign_in_with_email(
data = {"email": email, "password": password}
url = f"{self.url}/token{query_string}"
response = self.http_client.post(url, json=data, headers=headers)
return parse_response(response, Session.parse_obj)
return Session.parse_response(response)

def sign_up_with_phone(
self,
Expand Down Expand Up @@ -143,7 +152,8 @@ def sign_up_with_phone(
data = {"phone": phone, "password": password, "data": data}
url = f"{self.url}/signup"
response = self.http_client.post(url, json=data, headers=headers)
return parse_response(response, parse_session_or_user)
SessionOrUserModel = determine_session_or_user_model_from_response(response)
return SessionOrUserModel.parse_response(response)

def sign_in_with_phone(
self,
Expand Down Expand Up @@ -175,7 +185,7 @@ def sign_in_with_phone(
data = {"phone": phone, "password": password}
url = f"{self.url}/token{query_string}"
response = self.http_client.post(url, json=data, headers=headers)
return parse_response(response, Session.parse_obj)
return Session.parse_response(response)

def send_magic_link_email(
self,
Expand Down Expand Up @@ -205,7 +215,7 @@ def send_magic_link_email(
data = {"email": email}
url = f"{self.url}/magiclink{query_string}"
response = self.http_client.post(url, json=data, headers=headers)
return parse_response(response, lambda _: None)
return check_response(response)

def send_mobile_otp(self, *, phone: str) -> None:
"""Sends a mobile OTP via SMS. Will register the account if it doesn't already exist
Expand All @@ -224,7 +234,7 @@ def send_mobile_otp(self, *, phone: str) -> None:
data = {"phone": phone}
url = f"{self.url}/otp"
response = self.http_client.post(url, json=data, headers=headers)
return parse_response(response, lambda _: None)
return check_response(response)

def verify_mobile_otp(
self,
Expand Down Expand Up @@ -266,7 +276,8 @@ def verify_mobile_otp(
data["redirect_to"] = redirect_to_encoded
url = f"{self.url}/verify"
response = self.http_client.post(url, json=data, headers=headers)
return parse_response(response, parse_session_or_user)
SessionOrUserModel = determine_session_or_user_model_from_response(response)
return SessionOrUserModel.parse_response(response)

def invite_user_by_email(
self,
Expand Down Expand Up @@ -304,7 +315,7 @@ def invite_user_by_email(
data = {"email": email, "data": data}
url = f"{self.url}/invite{query_string}"
response = self.http_client.post(url, json=data, headers=headers)
return parse_response(response, User.parse_obj)
return User.parse_response(response)

def reset_password_for_email(
self,
Expand Down Expand Up @@ -334,7 +345,7 @@ def reset_password_for_email(
data = {"email": email}
url = f"{self.url}/recover{query_string}"
response = self.http_client.post(url, json=data, headers=headers)
return parse_response(response, lambda _: None)
return check_response(response)

def _create_request_headers(self, *, jwt: str) -> Dict[str, str]:
"""Create temporary object.
Expand Down Expand Up @@ -426,7 +437,7 @@ def get_user(self, *, jwt: str) -> User:
headers = self._create_request_headers(jwt=jwt)
url = f"{self.url}/user"
response = self.http_client.get(url, headers=headers)
return parse_response(response, User.parse_obj)
return User.parse_response(response)

def update_user(
self,
Expand Down Expand Up @@ -458,7 +469,7 @@ def update_user(
data = attributes.dict()
url = f"{self.url}/user"
response = self.http_client.put(url, json=data, headers=headers)
return parse_response(response, User.parse_obj)
return User.parse_response(response)

def delete_user(self, *, uid: str, jwt: str) -> User:
"""Delete a user. Requires a `service_role` key.
Expand Down Expand Up @@ -486,7 +497,7 @@ def delete_user(self, *, uid: str, jwt: str) -> User:
headers = self._create_request_headers(jwt=jwt)
url = f"{self.url}/admin/users/${uid}"
response = self.http_client.delete(url, headers=headers)
return parse_response(response, User.parse_obj)
return User.parse_response(response)

def refresh_access_token(self, *, refresh_token: str) -> Session:
"""Generates a new JWT.
Expand All @@ -511,7 +522,7 @@ def refresh_access_token(self, *, refresh_token: str) -> Session:
data = {"refresh_token": refresh_token}
url = f"{self.url}/token{query_string}"
response = self.http_client.post(url, json=data, headers=headers)
return parse_response(response, Session.parse_obj)
return Session.parse_response(response)

def generate_link(
self,
Expand Down Expand Up @@ -562,7 +573,8 @@ def generate_link(
data["redirect_to"] = redirect_to_encoded
url = f"{self.url}/admin/generate_link"
response = self.http_client.post(url, json=data, headers=headers)
return parse_response(response, parse_session_or_user)
SessionOrUserModel = determine_session_or_user_model_from_response(response)
return SessionOrUserModel.parse_response(response)

def set_auth_cookie(self, *, req, res):
"""Stub for parity with JS api."""
Expand Down
14 changes: 10 additions & 4 deletions gotrue/_sync/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

from ..constants import COOKIE_OPTIONS, DEFAULT_HEADERS, GOTRUE_URL, STORAGE_KEY
from ..types import (
APIError,
AuthChangeEvent,
CookieOptions,
Provider,
Expand All @@ -19,6 +18,7 @@
User,
UserAttributes,
)
from ..exceptions import APIError
from .api import SyncGoTrueAPI
from .storage import SyncMemoryStorage, SyncSupportedStorage

Expand Down Expand Up @@ -377,7 +377,9 @@ def set_auth(self, *, access_token: str) -> Session:
self._save_session(session=session)
return session

def get_session_from_url(self, *, url: str, store_session: bool = False) -> Session:
def get_session_from_url(
self, *, url: str, store_session: bool = False
) -> Session:
"""Gets the session data from a URL string.
Parameters
Expand Down Expand Up @@ -569,13 +571,17 @@ def _recover_and_refresh(self) -> None:
self._save_session(session=session)
self._notify_all_subscribers(event=AuthChangeEvent.SIGNED_IN)

def _call_refresh_token(self, *, refresh_token: Optional[str] = None) -> Session:
def _call_refresh_token(
self, *, refresh_token: Optional[str] = None
) -> Session:
if refresh_token is None:
if self.current_session:
refresh_token = self.current_session.refresh_token
else:
raise ValueError("No current session and refresh_token not supplied.")
response = self.api.refresh_access_token(refresh_token=cast(str, refresh_token))
response = self.api.refresh_access_token(
refresh_token=cast(str, refresh_token)
)
self._save_session(session=response)
self._notify_all_subscribers(event=AuthChangeEvent.SIGNED_IN)
return response
Expand Down

0 comments on commit cb4624d

Please sign in to comment.