Exemplo n.º 1
0
    def get(
        self,
        endpoint: str,
        team: Optional[str] = None,
        retry: bool = False,
        raw: bool = False,
        debug: bool = False,
    ):
        """Get something from the server trough HTTP

        Parameters
        ----------
        endpoint : str
            Recipient of the HTTP operation
        retry : bool
            Retry to perform the operation. Set to False on recursive calls.
        raw : bool
            Flag for returning raw response
        debug : bool
            Debugging flag. In this case failed requests get printed

        Returns
        -------
        dict
        Dictionary which contains the server response

        Raises
        ------
        NotFound
            Resource not found
        Unauthorized
            Action is not authorized
        """
        response = requests.get(urljoin(self.url, endpoint),
                                headers=self._get_headers(team))

        if response.status_code == 401:
            raise Unauthorized()
        if response.status_code == 404:
            raise NotFound(urljoin(self.url, endpoint))
        if response.status_code != 200 and retry:
            if debug:
                print(
                    f"Client get request response ({response.json()}) with unexpected status "
                    f"({response.status_code}). "
                    f"Client: ({self})"
                    f"Request: (endpoint={endpoint})")
            time.sleep(10)
            return self.get(endpoint=endpoint, retry=False)
        if raw:
            return response
        else:
            return self._decode_response(response, debug)
Exemplo n.º 2
0
    def _raise_if_known_error(self, response: Response, endpoint: str) -> None:

        if response.status_code == 401:
            raise Unauthorized()

        if response.status_code == 404:
            raise NotFound(urljoin(self.url, endpoint))

        if self._has_json_response(response):
            body = response.json()
            is_name_taken: Optional[bool] = None
            if isinstance(body, Dict):
                is_name_taken = body.get(
                    "errors", {}).get("name") == ["has already been taken"]

            if response.status_code == 422:
                if is_name_taken:
                    raise NameTaken
                raise ValidationError(body)

        if response.status_code == 429:
            error_code: Optional[str] = None
            try:
                error_code = response.json()["errors"]["code"]
            except:
                pass

            if error_code == "INSUFFICIENT_REMAINING_STORAGE":
                raise InsufficientStorage()
Exemplo n.º 3
0
    def _delete(
        self,
        endpoint: str,
        payload: Optional[Dict[Any, Any]] = None,
        team_slug: Optional[str] = None,
        retry: bool = False,
    ) -> Union[Dict[str, Any], List[Dict[str, Any]]]:
        if payload is None:
            payload = {}

        response: requests.Response = requests.delete(
            urljoin(self.url, endpoint),
            json=payload,
            headers=self._get_headers(team_slug))

        self.log.debug(
            f"Client DELETE request response ({self._get_response_debug_text(response)}) with unexpected status "
            f"({response.status_code}). "
            f"Client: ({self})"
            f"Request: (endpoint={endpoint})")

        self._raise_if_known_error(response, endpoint)

        if not response.ok and retry:
            time.sleep(10)
            return self._delete(endpoint, payload=payload, retry=False)

        response.raise_for_status()

        return self._decode_response(response)
Exemplo n.º 4
0
    def _put_raw(self,
                 endpoint: str,
                 payload: Dict[str, Any],
                 team_slug: Optional[str] = None,
                 retry: bool = False) -> Response:
        response: requests.Response = requests.put(
            urljoin(self.url, endpoint),
            json=payload,
            headers=self._get_headers(team_slug))

        self.log.debug(
            f"Client PUT request got response ({self._get_response_debug_text(response)}) with status "
            f"({response.status_code}). "
            f"Client: ({self})"
            f"Request: (endpoint={endpoint}, payload={payload})")

        self._raise_if_known_error(response, endpoint)

        if not response.ok and retry:
            time.sleep(10)
            return self._put_raw(endpoint, payload=payload, retry=False)

        response.raise_for_status()

        return response
Exemplo n.º 5
0
    def post(
        self,
        endpoint: str,
        payload: Optional[Dict] = None,
        team: Optional[str] = None,
        retry: bool = False,
        error_handlers: Optional[list] = None,
        debug: bool = False,
    ):
        """Post something new on the server trough HTTP

        Parameters
        ----------
        endpoint : str
            Recipient of the HTTP operation
        payload : dict
            What you want to put on the server (typically json encoded)
        retry : bool
            Retry to perform the operation. Set to False on recursive calls.
        refresh : bool
            Flag for use the refresh token instead
        debug : bool
            Debugging flag. In this case failed requests get printed

        Returns
        -------
        dict
        Dictionary which contains the server response
        """
        if payload is None:
            payload = {}
        if error_handlers is None:
            error_handlers = []
        response = requests.post(urljoin(self.url, endpoint),
                                 json=payload,
                                 headers=self._get_headers(team))
        if response.status_code == 401:
            raise Unauthorized()

        if response.status_code != 200:
            for error_handler in error_handlers:
                error_handler(response.status_code, response.json())

            if debug:
                print(
                    f"Client get request response ({response.json()}) with unexpected status "
                    f"({response.status_code}). "
                    f"Client: ({self})"
                    f"Request: (endpoint={endpoint}, payload={payload})")
            if retry:
                time.sleep(10)
                return self.post(endpoint, payload=payload, retry=False)

        return self._decode_response(response, debug)
Exemplo n.º 6
0
    def put(
        self,
        endpoint: str,
        payload: Dict,
        team: Optional[str] = None,
        retry: bool = False,
        debug: bool = False,
    ):
        """Put something on the server trough HTTP

        Parameters
        ----------
        endpoint : str
            Recipient of the HTTP operation
        payload : dict
            What you want to put on the server (typically json encoded)
        retry : bool
            Retry to perform the operation. Set to False on recursive calls.
        debug : bool
            Debugging flag. In this case failed requests get printed

        Returns
        -------
        dict
        Dictionary which contains the server response
        """
        response = requests.put(urljoin(self.url, endpoint),
                                json=payload,
                                headers=self._get_headers(team))

        if response.status_code == 401:
            raise Unauthorized()

        if response.status_code == 429:
            error_code = response.json()["errors"]["code"]
            if error_code == "INSUFFICIENT_REMAINING_STORAGE":
                raise InsufficientStorage()

        if response.status_code != 200 and retry:
            if debug:
                print(
                    f"Client get request response ({response.json()}) with unexpected status "
                    f"({response.status_code}). "
                    f"Client: ({self})"
                    f"Request: (endpoint={endpoint}, payload={payload})")
            time.sleep(10)
            return self.put(endpoint, payload=payload, retry=False)

        return self._decode_response(response, debug)
Exemplo n.º 7
0
    def from_api_key(cls,
                     api_key: str,
                     datasets_dir: Optional[Path] = None) -> "Client":
        """
        Factory method to create a client given an API key.

        Parameters
        ----------
        api_key: str
            API key to use to authenticate the client
        datasets_dir : Optional[Path]
            String where the client should be initialized from (aka the root path). Defaults to None.

        Returns
        -------
        Client
            The initialized client.
        """
        if not datasets_dir:
            datasets_dir = Path.home() / ".darwin" / "datasets"

        headers: Dict[str, str] = {
            "Content-Type": "application/json",
            "Authorization": f"ApiKey {api_key}"
        }
        api_url: str = Client.default_api_url()
        response: requests.Response = requests.get(urljoin(
            api_url, "/users/token_info"),
                                                   headers=headers)

        if not response.ok:
            raise InvalidLogin()

        data: Dict[str, Any] = response.json()
        team: str = data["selected_team"]["slug"]

        config: Config = Config(path=None)
        config.set_team(team=team,
                        api_key=api_key,
                        datasets_dir=str(datasets_dir))
        config.set_global(api_endpoint=api_url,
                          base_url=Client.default_base_url())

        return cls(config=config, default_team=team)
Exemplo n.º 8
0
    def from_api_key(cls, api_key: str, datasets_dir: Optional[Path] = None):
        """Factory method to create a client given an API key

        Parameters
        ----------
        api_key: str
            API key to use to authenticate the client
        datasets_dir : str
            String where the client should be initialized from (aka the root path)

        Returns
        -------
        Client
            The inited client
        """
        if datasets_dir is None:
            datasets_dir = Path.home() / ".darwin" / "datasets"
        headers = {
            "Content-Type": "application/json",
            "Authorization": f"ApiKey {api_key}"
        }
        api_url = Client.default_api_url()
        response = requests.get(urljoin(api_url, "/users/token_info"),
                                headers=headers)

        if response.status_code != 200:
            raise InvalidLogin()
        data = response.json()
        team_id = data["selected_team"]["id"]
        team = [
            team["slug"] for team in data["teams"] if team["id"] == team_id
        ][0]

        config = Config(path=None)
        config.set_team(team=team,
                        api_key=api_key,
                        datasets_dir=str(datasets_dir))
        config.set_global(api_endpoint=api_url,
                          base_url=Client.default_base_url())

        return cls(config=config, default_team=team)
Exemplo n.º 9
0
    def _get_raw(self,
                 endpoint: str,
                 team_slug: Optional[str] = None,
                 retry: bool = False) -> Response:
        response: Response = requests.get(urljoin(self.url, endpoint),
                                          headers=self._get_headers(team_slug))

        self.log.debug(
            f"Client GET request response ({self._get_response_debug_text(response)}) with status "
            f"({response.status_code}). "
            f"Client: ({self})"
            f"Request: (endpoint={endpoint})")

        self._raise_if_known_error(response, endpoint)

        if not response.ok and retry:
            time.sleep(10)
            return self._get_raw(endpoint=endpoint, retry=False)

        response.raise_for_status()

        return response
Exemplo n.º 10
0
 def remote_path(self) -> Path:
     """Returns an URL specifying the location of the remote dataset"""
     return Path(
         urljoin(self.client.base_url, f"/datasets/{self.dataset_id}"))
Exemplo n.º 11
0
 def workview_url_for_item(self, item):
     return urljoin(
         self.client.base_url,
         f"/workview?dataset={self.dataset_id}&image={item.seq}")
Exemplo n.º 12
0
 def it_strips_correctly():
     assert (urljoin("http://www.darwin.v7labs.com/", "/users/token_info")
             == "http://www.darwin.v7labs.com/users/token_info")
Exemplo n.º 13
0
 def it_returns_an_url():
     assert urljoin("api", "teams") == "api/teams"