Beispiel #1
0
    def _supported_httpmethods(cls, webmethodnames):

        """The HTTP methods that should be supported by this service

        .. note::
            This does not return the same result as calling
            :meth:`_natural_httpmethod` on each of the given *webmethodnames*.
            Some allowed web methods imply support for more than their
            naturally corresponding HTTP method.

        :param webmethodnames:
            The names of the supported web methods.
        :type webmethodnames: ~[:obj:`str`]

        :rtype: {:obj:`str`}

        """

        httpmethods = {cls._natural_httpmethod(methodname)
                       for methodname in webmethodnames}

        # CAVEAT: expose HTTP POST as a means to submit long arguments to web
        #   methods whose HTTP implementations do not reliably support message
        #   bodies
        if any(not _http.method_defines_body_semantics(method)
               for method in httpmethods):
            httpmethods.add('POST')

        if 'GET' in httpmethods:
            httpmethods.add('HEAD')

        return httpmethods
Beispiel #2
0
    def _request_webmethodname(cls, httpmethod, path, query):

        if httpmethod == 'HEAD':
            return 'get'

        # CAVEAT: examine the query string to convert HTTP POST to calls to
        #   corresponding web method names whose HTTP implementations do not
        #   reliably support message bodies
        if httpmethod == 'POST':
            query_method_pattern = r'^{}(&|$)'
            for name in (cls._webmethodname(httpmethod)
                         for httpmethod in _http.METHODS
                         if not _http.method_defines_body_semantics
                                    (httpmethod)):
                if _re.match(query_method_pattern.format(name), query):
                    return name

        return httpmethod.lower()
Beispiel #3
0
    def _request_body_args_prims_frombody(self, body, mediatype, httpmethod):

        # CAVEAT: handle the request body only for HTTP methods that define
        #   semantics for the body.  :rfc:`2616#section-4.3` recommends to
        #   ignore message bodies for methods that do not specify semantics for
        #   entity bodies
        if not _http.method_defines_body_semantics(httpmethod):
            return {}

        try:
            mediatype_name, _, _ = mediatype.partition(';')
            meth = self._request_body_args_prims_frombody_meth_by_mediatype\
                    [mediatype_name]
        except KeyError:
            supported_mediatypes = \
                self._request_body_args_prims_frombody_func_by_mediatype.keys()
            raise ValueError('unsupported body media type {!r}: expecting one'
                              ' of {}'
                              .format(mediatype, supported_mediatypes))
        return meth(self, body)
Beispiel #4
0
    def __init__(self,
                 method,
                 uri,
                 args=None,
                 argtypes=None,
                 args_as=None,
                 accept_mediaranges=('application/json', '*/*; q=0.01'),
                 auth=None,
                 authtype='basic',
                 origin=None,
                 headers=None,
                 **kwargs):

        method_kwargs = {}

        headers = _odict(headers or ())
        method_kwargs['headers'] = headers
        if origin is not None:
            headers['Origin'] = origin
        headers.setdefault('Accept', ', '.join(accept_mediaranges))

        if args:
            if argtypes:
                untyped_args = [arg for arg in args if arg not in argtypes]
            else:
                untyped_args = args.keys()
            if untyped_args:
                raise ValueError('missing type specifications for request'
                                  ' arguments {}'.format(untyped_args))

            if args_as is None:
                if _http.method_defines_body_semantics(method.upper()):
                    args_as = 'body'
                else:
                    args_as = 'query'

            if args_as == 'query':
                args_json = {name: argtypes[name](value).json()
                             for name, value in args.items()}
                method_kwargs['params'] = args_json

            elif args_as == 'body':
                args_webobjects = {name: argtypes[name](value)
                                   for name, value in args.items()}
                body = _webtypes.json_dumps(args_webobjects)
                method_kwargs['data'] = body

                headers['Content-Type'] = 'application/json'

            elif args_as == 'body_urlencoded':
                args_json = {name: argtypes[name](value).json()
                             for name, value in args.items()}
                body = _urlencode(args_json)
                method_kwargs['data'] = body

                headers['Content-Type'] = 'application/x-www-form-urlencoded'

            else:
                raise ValueError('invalid argument mechanism {!r}; expected'
                                  ' one of {}'
                                  .format(args_as,
                                          ('query', 'body',
                                           'body_urlencoded')))

        if auth is not None:
            try:
                auth_class = _requests_auth_classmap[authtype]
            except KeyError:
                raise ValueError('invalid authentication type {!r}; expected'
                                  ' one of {}'
                                  .format(authtype, ('basic', 'digest')))
            method_kwargs['auth'] = auth_class(*auth)

        method_kwargs.update(kwargs)

        super(WebRequest, self).__init__(method, uri, **method_kwargs)