diff options
Diffstat (limited to 'jb/managers/gr_api.py')
| -rw-r--r-- | jb/managers/gr_api.py | 59 |
1 files changed, 54 insertions, 5 deletions
diff --git a/jb/managers/gr_api.py b/jb/managers/gr_api.py index 8ffeaf0..a31f7da 100644 --- a/jb/managers/gr_api.py +++ b/jb/managers/gr_api.py @@ -1,16 +1,23 @@ """Client for General Research's product-user API.""" +import logging from typing import Any import requests from jb.models.auth import User +logger = logging.getLogger(__name__) + class GRApiError(RuntimeError): """The General Research API could not satisfy a request.""" +class GRApiNotFoundError(GRApiError): + """The requested General Research API resource does not exist.""" + + class GRApiManager: def __init__( self, @@ -40,6 +47,14 @@ class GRApiManager: response = self.session.request(method, url, timeout=self.timeout, **kwargs) response.raise_for_status() return response + except requests.HTTPError as exc: + if exc.response is not None and exc.response.status_code == 404: + raise GRApiNotFoundError( + f"General Research API resource not found: {method} {url}" + ) from exc + raise GRApiError( + f"General Research API request failed: {method} {url}" + ) from exc except requests.RequestException as exc: raise GRApiError( f"General Research API request failed: {method} {url}" @@ -101,12 +116,46 @@ class GRApiManager: ).json() return self.get_user(user.product_user_id) - def transition_product_user_id(self, user: User, amt_worker_id: str) -> User: + def transition_user_from_amt(self, user: User, amt_worker_id: str) -> User: """This should only be called once upon transition from an AMT account to a General Research account.""" url = f"{self.base_url}/{self.product_id}/user/{amt_worker_id}/" - res = self._request( - "PATCH", url, json={"product_user_id": user.product_user_id} - ) + try: + self._request( + "PATCH", url, json={"product_user_id": user.product_user_id} + ) + except GRApiNotFoundError as exc: + raise ValueError(f"User {amt_worker_id} does not exist") from exc + except GRApiError as exc: + http_error = exc.__cause__ + response = ( + http_error.response + if isinstance(http_error, requests.HTTPError) + else None + ) + if response is not None and response.status_code == 400: + try: + detail = response.json().get("detail") + except (ValueError, AttributeError): + detail = None + if detail == "Unable to update User": + raise ValueError( + "unable to update user, probably another user already " + "exists with this email" + ) from exc + raise self.set_user_email(user) - return self.get_user(user.product_user_id) + transitioned_user = self.get_user(user.product_user_id) + logger.warning( + "Transitioned product user from AMT worker %s to %s with email %s", + amt_worker_id, + transitioned_user.product_user_id, + transitioned_user.email, + extra={ + "event": "transition_user_from_amt", + "amt_worker_id": amt_worker_id, + "product_user_id": transitioned_user.product_user_id, + "email": str(transitioned_user.email), + }, + ) + return transitioned_user |
