예제 #1
0
파일: utils.py 프로젝트: akx/stackspy
def merge_setting_safe(request_setting, session_setting, dict_class=OrderedDict):
	merged_setting = dict_class(to_key_val_list(session_setting or ()))
	merged_setting.update(to_key_val_list(request_setting or ()))
	for (k, v) in (request_setting or {}).items():
		if v is None:
			del merged_setting[k]
	return merged_setting
예제 #2
0
파일: models.py 프로젝트: uibiv/demo
    def prepare_body(self, data, files, json=None):
        """Prepares the given HTTP body data."""
        if not files:
            super().prepare_body(data, files, json)
            if self.body and not isinstance(self.body, bytes):
                self.body = StreamBody(self.body)
            return

        fields = []
        for key, value in to_key_val_list(data or {}):
            fields.append(Field(key, content=value))
        for (k, v) in to_key_val_list(files or {}):
            # support for explicit filename
            ft = None
            fh = None
            if isinstance(v, (tuple, list)):
                if len(v) == 2:
                    fn, fp = v
                elif len(v) == 3:
                    fn, fp, ft = v
                else:
                    fn, fp, ft, fh = v
            else:
                fn = None
                fp = v

            if isinstance(fp, (str, bytes, bytearray)):
                content = fp
                fp = None
            else:
                content = None

            fields.append(
                Field(
                    k,
                    filename=fn,
                    file=fp,
                    content=content,
                    content_type=ft,
                    headers=fh,
                )
            )

        self.body = MultipartBody(fields)
        self.headers.setdefault('Content-Type', self.body.content_type)
        self.prepare_content_length(self.body)
예제 #3
0
    def _merge_retain_none(request_setting,
                           session_setting,
                           dict_class=OrderedDict):

        if session_setting is None:
            return request_setting

        if request_setting is None:
            return session_setting

        # Bypass if not a dictionary (e.g. verify)
        if not (isinstance(session_setting, Mapping)
                and isinstance(request_setting, Mapping)):
            return request_setting

        merged_setting = dict_class(to_key_val_list(session_setting))
        merged_setting.update(to_key_val_list(request_setting))

        return merged_setting
예제 #4
0
 def _build_query(self, query_params):
     result = []
     for k, vs in to_key_val_list(query_params):
         if isinstance(vs, basestring) or not hasattr(vs, '__iter__'):
             vs = [vs]
         for v in vs:
             if v is not None:
                 result.append(
                     (k.encode('utf-8') if isinstance(k, str) else k,
                         v.encode('utf-8') if isinstance(v, str) else v)
                 )
     return urlencode(result, doseq=True)
    def _create_operation_request(endpoint,
                                  operation=None,
                                  method="POST",
                                  data=None,
                                  files=None):
        """
        Creates an operation request against a given ArcGIS Server endpoint.

        :param endpoint: The endpoint on which to perform the operation.
        :type base_url: str or object implementing agsadmin._endpoint_base

        :param operation: The operation to perform. If None, the endpoint metadata is returned.
        :type operation: str

        :param method: Overrides the HTTP verb to use on the request, default is POST but some operations
                       accept/require GET
        :type method: str
        """

        files = to_key_val_list(files or {})

        # data may come in as an object containing other complex objects types (e.g. strings, lists), these should be
        # encoded to JSON strings
        if not data == None:
            encoded_data = {}
            for key, value in iteritems(data):
                if isinstance(value, collections.Mapping):
                    encoded_data[key] = json.dumps(value)
                elif isinstance(value, list):
                    encoded_data[key] = json.dumps(value)
                else:
                    encoded_data[key] = value
            data = encoded_data

            # determine if we need to take any data paramaters and send them as files
            if "thumbnail" in data and not data["thumbnail"] is None:
                thumbnail_path = data["thumbnail"]
                files.append(
                    ("thumbnail", (os.path.basename(thumbnail_path),
                                   open(thumbnail_path, "rb"),
                                   mimetypes.guess_type(thumbnail_path,
                                                        False)[0])))
                del data["thumbnail"]

        return Request(method,
                       "{endpoint}/{operation}".format(
                           endpoint=endpoint._url_full if isinstance(
                               endpoint, EndpointBase) else endpoint,
                           operation=operation if operation else ""),
                       data=data,
                       files=files if len(files) > 0 else None)
    def _create_operation_request(endpoint, operation=None, method="POST", data=None, files=None):
        """
        Creates an operation request against a given ArcGIS Server endpoint.

        :param endpoint: The endpoint on which to perform the operation.
        :type base_url: str or object implementing agsadmin._endpoint_base

        :param operation: The operation to perform. If None, the endpoint metadata is returned.
        :type operation: str

        :param method: Overrides the HTTP verb to use on the request, default is POST but some operations
                       accept/require GET
        :type method: str
        """

        files = to_key_val_list(files or {})

        # data may come in as an object containing other complex objects types (e.g. strings, lists), these should be
        # encoded to JSON strings
        if not data == None:
            encoded_data = {}
            for key, value in iteritems(data):
                if isinstance(value, collections.Mapping):
                    encoded_data[key] = json.dumps(value)
                elif isinstance(value, list):
                    encoded_data[key] = json.dumps(value)
                else:
                    encoded_data[key] = value
            data = encoded_data

            # determine if we need to take any data paramaters and send them as files
            if "thumbnail" in data and not data["thumbnail"] is None:
                thumbnail_path = data["thumbnail"]
                files.append(("thumbnail", (os.path.basename(thumbnail_path), open(thumbnail_path, "rb"),
                                            mimetypes.guess_type(thumbnail_path, False)[0])))
                del data["thumbnail"]

        return Request(
            method,
            "{endpoint}/{operation}".format(
                endpoint=endpoint._url_full if isinstance(endpoint, EndpointBase) else endpoint,
                operation=operation if operation else ""),
            data=data,
            files=files if len(files) > 0 else None)
예제 #7
0
def encode_http_params(data):
    """
    Encode HTTP parameters to URL query string

    :param data: data as text or tuple/list
    :type data: str or bytes or tuple or list
    :return: str -- encoded data
    """
    if isinstance(data, (str, bytes)):
        return urlencode(data)
    elif hasattr(data, '__iter__'):
        result = []
        for k, vs in to_key_val_list(data):
            if vs is not None:
                result.append(
                    (k.encode('utf-8') if isinstance(k, str) else k,
                     vs.encode('utf-8') if isinstance(vs, str) else vs))
        return urlencode(result, doseq=True)
    else:
        raise ValueError('Invalid argument')
예제 #8
0
    def _apply_options(self, kwargs):
        kwargs['timeout'] = self.timeout

        if self.auth is not None:
            kwargs['auth'] = self.auth

        # fix space quoting for query string: '%20' instead of '+'
        params = kwargs.get('params')
        if params and hasattr(params, '__iter__'):
            result = []
            for k, vs in to_key_val_list(params):
                if isinstance(vs, basestring) or not hasattr(vs, '__iter__'):
                    vs = [vs]
                for v in vs:
                    if v is not None:
                        result.append(
                            (k.encode('utf-8') if isinstance(k, str) else k,
                             v.encode('utf-8') if isinstance(v, str) else v))

            kwargs['params'] = urlencode(result, doseq=True, quote_via=quote)
예제 #9
0
    def send_request(self, req):
        '''
        returns requests.Response object

        raise
        '''
        # requests gotcha: even if send through the session, request.prepare()
        # does not get merged with the session's attributes, so we have to call
        # session.prepare_request(...)

        # merge params with the api key
        req.params = to_key_val_list(req.params) + [('key', self.api_key)]
        prepared_req = self._session.prepare_request(req)
        logger.debug('req.params {} prepare_req {}'.format(req.params, prepared_req))
        res = self._session.send(prepared_req)
        if res.status_code != 200:
            # CrowdFlower responds with a '202 Accepted' when we request a bulk
            # download which has not yet been generated, which means we simply
            # have to wait and try again
            raise CrowdFlowerError(req, res)
        return res
예제 #10
0
    def send_request(self, req):
        '''
        returns requests.Response object

        raise
        '''
        # requests gotcha: even if send through the session, request.prepare()
        # does not get merged with the session's attributes, so we have to call
        # session.prepare_request(...)

        # merge params with the api key
        req.params = to_key_val_list(req.params) + [('key', self.api_key)]
        prepared_req = self._session.prepare_request(req)
        logger.debug('Request params: {}'.format(req.params))

        res = self._session.send(prepared_req)
        if res.status_code != 200:
            # CrowdFlower responds with a '202 Accepted' when we request a bulk
            # download which has not yet been generated, which means we simply
            # have to wait and try again
            raise CrowdFlowerError(req, res)
        return res
예제 #11
0
파일: test_utils.py 프로젝트: ctomiao2/vim
 def test_invalid(self):
     with pytest.raises(ValueError):
         to_key_val_list('string')
예제 #12
0
파일: test_utils.py 프로젝트: ctomiao2/vim
 def test_valid(self, value, expected):
     assert to_key_val_list(value) == expected
예제 #13
0
 def test_invalid(self):
     with pytest.raises(ValueError):
         to_key_val_list('string')
예제 #14
0
 def test_valid(self, value, expected):
     assert to_key_val_list(value) == expected
예제 #15
0
def _prepare_files(files):
    if files is not None:
        files = [_prepare_file(k, v) for k, v in to_key_val_list(files)]
    return files