Example #1
0
class TransportTestcases(unittest.TestCase):
    def setUp(self):
        self.requester = API_Requests_Wrapper(
            url='https://woo.test:8888/',
            api='wp-json',
            api_version='wp/v2'
        )

    def test_api_url(self):
        self.assertEqual(
            'https://woo.test:8888/wp-json',
            self.requester.api_url
        )

    def test_endpoint_url(self):
        self.assertEqual(
            'https://woo.test:8888/wp-json/wp/v2/posts',
            self.requester.endpoint_url('posts')
        )

    def test_request(self):

        @all_requests
        def woo_test_mock(*args, **kwargs):
            """ URL Mock """
            return {'status_code': 200,
                    'content': b'OK'}

        with HTTMock(woo_test_mock):
            # call requests
            response = self.requester.request("GET", "https://woo.test:8888/wp-json/wp/v2/posts")
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.request.url, 'https://woo.test:8888/wp-json/wp/v2/posts')
Example #2
0
    def __init__(self, url, consumer_key, consumer_secret, **kwargs):
        self.logger = logging.getLogger(__name__)
        self.requester = API_Requests_Wrapper(url=url, **kwargs)

        auth_kwargs = dict(
            requester=self.requester,
            consumer_key=consumer_key,
            consumer_secret=consumer_secret,
        )
        auth_kwargs.update(kwargs)

        auth_class = OAuth
        if kwargs.get('basic_auth'):
            auth_class = BasicAuth
        elif kwargs.get('oauth1a_3leg'):
            auth_class = OAuth_3Leg
        elif kwargs.get('no_auth'):
            auth_class = NoAuth

        if (kwargs.get('version', '').startswith('wc')
                and kwargs.get('oauth1a_3leg')):
            self.logger.warn(
                "WooCommerce JSON Api does not seem to support 3leg")

        self.auth = auth_class(**auth_kwargs)
Example #3
0
class API(object):
    """ API Class """
    def __init__(self, url, consumer_key, consumer_secret, **kwargs):
        self.logger = logging.getLogger(__name__)
        self.requester = API_Requests_Wrapper(url=url, **kwargs)

        auth_kwargs = dict(
            requester=self.requester,
            consumer_key=consumer_key,
            consumer_secret=consumer_secret,
        )
        auth_kwargs.update(kwargs)

        auth_class = OAuth
        if kwargs.get('basic_auth'):
            auth_class = BasicAuth
        elif kwargs.get('oauth1a_3leg'):
            auth_class = OAuth_3Leg

        if kwargs.get('version',
                      '').startswith('wc') and kwargs.get('oauth1a_3leg'):
            self.logger.warn(
                "WooCommerce JSON Api does not seem to support 3leg")

        self.auth = auth_class(**auth_kwargs)

    @property
    def url(self):
        return self.requester.url

    @property
    def timeout(self):
        return self.requester.timeout

    @property
    def namespace(self):
        return self.requester.api

    @property
    def version(self):
        return self.requester.api_version

    @property
    def verify_ssl(self):
        return self.requester.verify_ssl

    @property
    def is_ssl(self):
        return self.requester.is_ssl

    @property
    def consumer_key(self):
        return self.auth.consumer_key

    @property
    def consumer_secret(self):
        return self.auth.consumer_secret

    @property
    def callback(self):
        return self.auth.callback

    def request_post_mortem(self, response=None):
        """
        Attempt to diagnose what went wrong in a request
        """

        reason = None
        remedy = None

        response_json = {}
        try:
            response_json = response.json()
        except ValueError:
            pass

        # import pudb; pudb.set_trace()

        request_body = {}
        request_url = ""
        if hasattr(response, 'request'):
            if hasattr(response.request, 'url'):
                request_url = response.request.url
            if hasattr(response.request, 'body'):
                request_body = response.request.body

        if isinstance(response_json, dict) and ('code' in response_json
                                                or 'message' in response_json):
            reason = u" - ".join([
                str(response_json.get(key)) for key in ['code', 'message', 'data'] \
                if key in response_json
            ])

            if 'code' == 'rest_user_invalid_email':
                remedy = "Try checking the email %s doesn't already exist" % \
                request_body.get('email')

            elif 'code' == 'json_oauth1_consumer_mismatch':
                remedy = "Try deleting the cached credentials at %s" % \
                self.auth.creds_store

            elif 'code' == 'woocommerce_rest_cannot_view':
                if not self.auth.query_string_auth:
                    remedy = "Try enabling query_string_auth"
                else:
                    remedy = (
                        "This error is super generic and can be caused by just "
                        "about anything. Here are some things to try: \n"
                        " - Check that the account which as assigned to your "
                        "oAuth creds has the correct access level\n"
                        " - Enable logging and check for error messages in "
                        "wp-content and wp-content/uploads/wc-logs\n"
                        " - Check that your query string parameters are valid\n"
                        " - Make sure your server is not messing with authentication headers\n"
                        " - Try a different endpoint\n"
                        " - Try enabling HTTPS and using basic authentication\n"
                    )

        response_headers = {}
        if hasattr(response, 'headers'):
            response_headers = response.headers

        if not reason:
            requester_api_url = self.requester.api_url
            if hasattr(response, 'links') and response.links:
                links = response.links
                first_link_key = list(links)[0]
                header_api_url = links[first_link_key].get('url', '')
                if header_api_url:
                    header_api_url = StrUtils.eviscerate(header_api_url, '/')

                if header_api_url and requester_api_url\
                and header_api_url != requester_api_url:
                    reason = "hostname mismatch. %s != %s" % (
                        header_api_url, requester_api_url)
                    header_url = StrUtils.eviscerate(header_api_url, '/')
                    header_url = StrUtils.eviscerate(header_url,
                                                     self.requester.api)
                    header_url = StrUtils.eviscerate(header_url, '/')
                    remedy = "try changing url to %s" % header_url

        msg = "API call to %s returned \nCODE: %s\nRESPONSE:%s \nHEADERS: %s\nREQ_BODY:%s" % (
            request_url, str(
                response.status_code), UrlUtils.beautify_response(response),
            str(response_headers), str(request_body)[:1000])
        if reason:
            msg += "\nBecause of %s" % reason
        if remedy:
            msg += "\n%s" % remedy
        raise UserWarning(msg)

    def __request(self, method, endpoint, data, **kwargs):
        """ Do requests """

        endpoint_url = self.requester.endpoint_url(endpoint)
        endpoint_url = self.auth.get_auth_url(endpoint_url, method, **kwargs)
        auth = self.auth.get_auth()

        content_type = kwargs.get('headers', {}).get('content-type',
                                                     'application/json')

        if data is not None and content_type.startswith('application/json'):
            data = jsonencode(data, ensure_ascii=False).encode('utf-8')

        response = self.requester.request(method=method,
                                          url=endpoint_url,
                                          auth=auth,
                                          data=data,
                                          **kwargs)

        if response.status_code not in [200, 201, 202]:
            self.request_post_mortem(response)

        return response

    # TODO add kwargs option for headers

    def get(self, endpoint, **kwargs):
        """ Get requests """
        return self.__request("GET", endpoint, None, **kwargs)

    def post(self, endpoint, data, **kwargs):
        """ POST requests """
        return self.__request("POST", endpoint, data, **kwargs)

    def put(self, endpoint, data, **kwargs):
        """ PUT requests """
        return self.__request("PUT", endpoint, data, **kwargs)

    def delete(self, endpoint, **kwargs):
        """ DELETE requests """
        return self.__request("DELETE", endpoint, None, **kwargs)

    def options(self, endpoint, **kwargs):
        """ OPTIONS requests """
        return self.__request("OPTIONS", endpoint, None, **kwargs)
Example #4
0
 def setUp(self):
     self.requester = API_Requests_Wrapper(
         url='https://woo.test:8888/',
         api='wp-json',
         api_version='wp/v2'
     )