def _convert_files(files): """Files can be passed in a variety of formats: * {'file': open("bla.f")} * {'file': (name, open("bla.f"))} * {'file': (name, content-type, open("bla.f"))} * Anything that has iteritems method, e.g. MultiDict: MultiDict([(name, open()), (name, open())] Our goal is to standardize it to unified form of: * [(param, (file name, content type, producer))] """ if hasattr(files, "iteritems"): files = files.iteritems() for param, val in files: file_name, content_type, fobj = (None, None, None) if isinstance(val, tuple): if len(val) == 2: file_name, fobj = val elif len(val) == 3: file_name, content_type, fobj = val else: fobj = val if hasattr(fobj, "name"): file_name = path.basename(fobj.name) if not content_type: content_type = _guess_content_type(file_name) yield (param, (file_name, content_type, IBodyProducer(fobj)))
def requestReceived(method, url, version, headers, body): self.assertIsInstance(method, bytes) self.assertIsInstance(url, urlparse.ParseResult) self.assertIsInstance(version, bytes) self.assertIsInstance(headers, Headers) self.assertTrue(IBodyProducer.providedBy(body)) self.receivedRequest = (method, url, version, headers, body)
def _convert_files(files): """Files can be passed in a variety of formats: * {'file': open("bla.f")} * {'file': (name, open("bla.f"))} * {'file': (name, content-type, open("bla.f"))} * Anything that has iteritems method, e.g. MultiDict: MultiDict([(name, open()), (name, open())] Our goal is to standardize it to unified form of: * [(param, (file name, content type, producer))] """ if hasattr(files, "iteritems"): files = files.iteritems() elif hasattr(files, "items"): files = files.items() for param, val in files: file_name, content_type, fobj = (None, None, None) if isinstance(val, tuple): if len(val) == 2: file_name, fobj = val elif len(val) == 3: file_name, content_type, fobj = val else: # NB: This is TypeError for backward compatibility. This case # used to fall through to `IBodyProducer`, below, which raised # TypeError about being unable to coerce None. raise TypeError( ("`files` argument must be a sequence of tuples of" " (file_name, file_obj) or" " (file_name, content_type, file_obj)," " but the {!r} tuple has length {}: {!r}").format( param, len(val), val), ) else: fobj = val if hasattr(fobj, "name"): file_name = FilePath(fobj.name).basename() if not content_type: content_type = _guess_content_type(file_name) # XXX: Shouldn't this call self._data_to_body_producer? yield (param, (file_name, content_type, IBodyProducer(fobj)))
def request(self, method, uri, headers=None, bodyProducer=None): # type: (bytes, bytes, Optional[Headers], Optional[IBodyProducer]) -> Deferred[IResponse] # noqa if not isinstance(method, bytes): raise TypeError("method must be bytes, not {!r} of type {}".format( method, type(method))) if not isinstance(uri, bytes): raise TypeError("uri must be bytes, not {!r} of type {}".format( uri, type(uri))) if headers is not None and not isinstance(headers, Headers): raise TypeError("headers must be {}, not {!r} of type {}".format( type(Headers), headers, type(headers))) if bodyProducer is not None and not IBodyProducer.providedBy( bodyProducer): raise TypeError(( "bodyProducer must implement IBodyProducer, but {!r} does not." " Is the implementation marked with @implementer(IBodyProducer)?" ).format(bodyProducer)) d = Deferred() record = RequestRecord(method, uri, headers, bodyProducer, d) self._callback(record) return d
def assertRequest(self, agent, method, url, headers, body): call = self.agent.request.mock_calls[-1][1] self.assertEqual(call[0], method) self.assertEqual(call[1], url) self.assertEqual(call[2], headers) if not body: #self.assertEqual(call[3], body) return bodyProducer = call[3] self.assertTrue(IBodyProducer.providedBy(bodyProducer)) output = StringIO() consumer = FileConsumer(output) def _check_body(_): self.assertEqual(output.getvalue(), body) d = bodyProducer.startProducing(consumer) d.addCallback(_check_body) return d
def request(self, method, url, **kwargs): method = method.upper() # Join parameters provided in the URL # and the ones passed as argument. params = kwargs.get('params') if params: url = _combine_query_params(url, params) # Convert headers dictionary to # twisted raw headers format. headers = kwargs.get('headers') if headers: if isinstance(headers, dict): h = Headers({}) for k, v in headers.iteritems(): if isinstance(v, str): h.addRawHeader(k, v) else: h.setRawHeaders(k, v) headers = h else: headers = Headers({}) # Here we choose a right producer # based on the parameters passed in. bodyProducer = None data = kwargs.get('data') files = kwargs.get('files') if files: # If the files keyword is present we will issue a # multipart/form-data request as it suits better for cases # with files and/or large objects. files = list(_convert_files(files)) boundary = uuid.uuid4() headers.setRawHeaders( 'content-type', [ 'multipart/form-data; boundary=%s' % (boundary,)]) if data: data = _convert_params(data) else: data = [] bodyProducer = multipart.MultiPartProducer( data + files, boundary=boundary) elif data: # Otherwise stick to x-www-form-urlencoded format # as it's generally faster for smaller requests. if isinstance(data, (dict, list, tuple)): headers.setRawHeaders( 'content-type', ['application/x-www-form-urlencoded']) data = urlencode(data, doseq=True) bodyProducer = IBodyProducer(data) cookies = kwargs.get('cookies', {}) if not isinstance(cookies, CookieJar): cookies = cookiejar_from_dict(cookies) cookies = merge_cookies(self._cookiejar, cookies) wrapped_agent = CookieAgent(self._agent, cookies) if kwargs.get('allow_redirects', True): wrapped_agent = RedirectAgent(wrapped_agent) wrapped_agent = ContentDecoderAgent(wrapped_agent, [('gzip', GzipDecoder)]) auth = kwargs.get('auth') if auth: wrapped_agent = add_auth(wrapped_agent, auth) d = wrapped_agent.request( method, url, headers=headers, bodyProducer=bodyProducer) timeout = kwargs.get('timeout') if timeout: delayedCall = default_reactor(kwargs.get('reactor')).callLater( timeout, d.cancel) def gotResult(result): if delayedCall.active(): delayedCall.cancel() return result d.addBoth(gotResult) if not kwargs.get('unbuffered', False): d.addCallback(_BufferedResponse) return d.addCallback(_Response, cookies)