def test_endpoint_wrong_uri(self):
     with self.assertRaises(ValueError):
         ApiRequestArguments(
             endpoint=EndPoint(path="/buzz"),
             content_negotiation="application-json",
             verbosity="normal",
             version="2.0.0",
         )
 def test_endpoint_wrong_start(self):
     with self.assertRaises(ValueError):
         ApiRequestArguments(
             endpoint=EndPoint(path="account"),  # need '/' at the beginning
             content_negotiation="application/json",
             version="2.0.0",
             verbosity="normal",
         )
 def test_content_negotiation_wrong(self):
     with self.assertRaises(ValueError):
         ApiRequestArguments(
             endpoint=EndPoint(path="/account"),
             content_negotiation="application/weird",
             version="2.0.0",
             verbosity="normal",
         )
 def test_verbosity_wrong(self):
     with self.assertRaises(ValueError):
         ApiRequestArguments(
             endpoint=EndPoint(path="/account"),
             verbosity="buzz",  # does not exists
             content_negotiation="application/json",
             version="2.0.0",
         )
 def test_version_wrong(self):
     with self.assertRaises(ValueError):
         ApiRequestArguments(
             endpoint=EndPoint(path="/account"),
             version="3.1.0",  # to high, maybe in the future...
             content_negotiation="application/json",
             verbosity="normal",
         )
 def test_api_arguments(self):
     arguments = ApiRequestArguments(
         endpoint=EndPoint(path="/reports"),
         version="2.0.0",
         verbosity="full",
         content_negotiation="application/x-yaml",
     )
     self.assertEqual(arguments.version, "2.0.0")
     self.assertEqual(arguments.verbosity, "full")
     self.assertEqual(arguments.content_negotiation, "application/x-yaml")
     self.assertEqual(arguments.endpoint.path, "/reports")
    def request(
        self,
        endpoint: str,
        version: str = None,
        verbosity: str = VERBOSITY_NORMAL,
        content_negotiation: str = CONTENT_JSON,
        body: dict = None,
        query_params: dict = None,
    ) -> Response:
        """Generic method to send requests to our API.

        Wrapper on top of ``requests.Session.request`` method adding token encryption
        on headers.
        Every time we call `request` five steps are applied:
          1. Validation of arguments.
          2. Token creation - token depends on the `endpoint` argument and `signature_token`.
          3. Preparation of parameter dictionary. Add token to headers.
          4. Make a request.
          5. Return a response.

        Args:
          endpoint (str): API endpoint.
          version (str): API Version. Optional. Defaults to the latest.
          verbosity (str): `normal`, `quiet` or `full`. Defaults to `normal`.
          content_negotiation (str): `application/json` or `application/x-yaml`. Defaults to `application/json`.
          body (dict): Optional.
          query_params (dict): Optional.

        Returns:
          response (requests.models.Response).

        Examples:
          >>> from mopinion import MopinionClient
          >>> client = MopinionClient(public_key=PUBLICKEY, private_key=PRIVATEKEY)
          >>> response = client.request("/account")
          >>> assert response.json()["_meta"]["code"] == 200
          >>> response = client.request(endpoint="/deployments")
          >>> assert response.json()["_meta"]["code"] == 200
        """

        # validate arguments
        arguments = ApiRequestArguments(
            version=version,
            verbosity=verbosity,
            endpoint=EndPoint(path=endpoint),
            content_negotiation=content_negotiation,
        )

        # create token - token depends on endpoint
        xtoken = self.get_token(endpoint=arguments.endpoint, body=body)

        # prepare params dict (url, method, headers, body, query_params)
        url = f"{settings.BASE_URL}{arguments.endpoint.path}"
        headers = {
            "X-Auth-Token": xtoken,
            "verbosity": arguments.verbosity,
            "Accept": arguments.content_negotiation,
        }
        if arguments.version:
            headers["version"] = arguments.version

        params = {"method": "GET", "url": url, "headers": headers}
        if body:
            params["json"] = body  # add content type 'Application-json'
        if query_params:
            params["params"] = query_params

        # request
        response = self.session.request(**params)
        response.raise_for_status()
        return response