onedrive/api_v5.py
def request( self, url, method='get', data=None, files=None,
				raw=False, raw_all=False, headers=dict(), raise_for=dict(), session=None ):
		'''Make synchronous HTTP request.
			Can be overidden to use different http module (e.g. urllib2, twisted, etc).'''
		try: import requests # import here to avoid dependency on the module
		except ImportError as exc:
			exc.args = ( 'Unable to find/import "requests" module.'
				' Please make sure that it is installed, e.g. by running "pip install requests" command.'
				'\nFor more info, visit: http://docs.python-requests.org/en/latest/user/install/',)
			raise exc

		if not self._requests_setup_done:
			patched_session = self._requests_setup(
				requests, **(self.request_adapter_settings or dict()) )
			if patched_session is not None: self._requests_session = patched_session

		if session is None:
			session = getattr(self, '_requests_session', None)
			if not session: session = self._requests_session = requests.session()
		elif not session: session = requests

		method = method.lower()
		kwz = (self._requests_base_keywords or dict()).copy()
		kwz.update(self.request_extra_keywords or dict())
		kwz, func = dict(), ft.partial(session.request, method.upper(), **kwz)
		kwz_headers = (self.request_base_headers or dict()).copy()
		kwz_headers.update(headers)
		if data is not None:
			if method in ['post', 'put']:
				if all(hasattr(data, k) for k in ['seek', 'read']):
					# Force chunked encoding for files, as uploads hang otherwise
					# See https://github.com/mk-fg/python-onedrive/issues/30 for details
					data.seek(0)
					kwz['data'] = iter(ft.partial(data.read, 200 * 2**10), b'')
				else: kwz['data'] = data
			else:
				kwz['data'] = json.dumps(data)
				kwz_headers.setdefault('Content-Type', 'application/json')
		if files is not None:
			# requests-2+ doesn't seem to add default content-type header
			for k, file_tuple in files.iteritems():
				if len(file_tuple) == 2: files[k] = tuple(file_tuple) + ('application/octet-stream',)
				# Rewind is necessary because request can be repeated due to auth failure
				file_tuple[1].seek(0)
			kwz['files'] = files
		if kwz_headers: kwz['headers'] = kwz_headers

		code = res = None
		try:
			res = func(url, **kwz)
			# log.debug('Response headers: %s', res.headers)
			code = res.status_code
			if code == requests.codes.no_content: return
			if code != requests.codes.ok: res.raise_for_status()
		except requests.RequestException as err:
			message = b'{0} [type: {1}, repr: {0!r}]'.format(err, type(err))
			if (res and getattr(res, 'text', None)) is not None: # "res" with non-200 code can be falsy
				message = res.text
				try: message = json.loads(message)
				except: message = '{}: {!r}'.format(str(err), message)[:300]
				else:
					msg_err, msg_data = message.pop('error', None), message
					if msg_err:
						message = '{}: {}'.format(msg_err.get('code', err), msg_err.get('message', msg_err))
						if msg_data: message = '{} (data: {})'.format(message, msg_data)
			raise raise_for.get(code, ProtocolError)(code, message)
		if raw: res = res.content
		elif raw_all: res = code, dict(res.headers.items()), res.content
		else: res = json.loads(res.text)
		return res
def request( self, url, method='get', data=None, files=None,
				raw=False, raw_all=False, headers=dict(), raise_for=dict(), session=None ):
		'''Make synchronous HTTP request.
			Can be overidden to use different http module (e.g. urllib2, twisted, etc).'''
		try: import requests # import here to avoid dependency on the module
		except ImportError as exc:
			exc.args = ( 'Unable to find/import "requests" module.'
				' Please make sure that it is installed, e.g. by running "pip install requests" command.'
				'\nFor more info, visit: http://docs.python-requests.org/en/latest/user/install/',)
			raise exc

		if not self._requests_setup_done:
			patched_session = self._requests_setup(
				requests, **(self.request_adapter_settings or dict()) )
			if patched_session is not None: self._requests_session = patched_session

		if session is None:
			session = getattr(self, '_requests_session', None)
			if not session: session = self._requests_session = requests.session()
		elif not session: session = requests

		method = method.lower()
		kwz = (self._requests_base_keywords or dict()).copy()
		kwz.update(self.request_extra_keywords or dict())
		kwz, func = dict(), ft.partial(session.request, method.upper(), **kwz)
		kwz_headers = (self.request_base_headers or dict()).copy()
		kwz_headers.update(headers)
		if data is not None:
			if method in ['post', 'put']:
				if all(hasattr(data, k) for k in ['seek', 'read']):
					# Force chunked encoding for files, as uploads hang otherwise
					# See https://github.com/mk-fg/python-onedrive/issues/30 for details
					data.seek(0)
					kwz['data'] = iter(ft.partial(data.read, 200 * 2**10), b'')
				else: kwz['data'] = data
			else:
				kwz['data'] = json.dumps(data)
				kwz_headers.setdefault('Content-Type', 'application/json')
		if files is not None:
			# requests-2+ doesn't seem to add default content-type header
			for k, file_tuple in files.iteritems():
				if len(file_tuple) == 2: files[k] = tuple(file_tuple) + ('application/octet-stream',)
				# Rewind is necessary because request can be repeated due to auth failure
				file_tuple[1].seek(0)
			kwz['files'] = files
		if kwz_headers: kwz['headers'] = kwz_headers

		code = res = None
		try:
			res = func(url, **kwz)
			# log.debug('Response headers: %s', res.headers)
			code = res.status_code
			if code == requests.codes.no_content: return
			if code != requests.codes.ok: res.raise_for_status()
		except requests.RequestException as err:
			message = b'{0} [type: {1}, repr: {0!r}]'.format(err, type(err))
			if (res and getattr(res, 'text', None)) is not None: # "res" with non-200 code can be falsy
				message = res.text
				try: message = json.loads(message)
				except: message = '{}: {!r}'.format(str(err), message)[:300]
				else:
					msg_err, msg_data = message.pop('error', None), message
					if msg_err:
						message = '{}: {}'.format(msg_err.get('code', err), msg_err.get('message', msg_err))
						if msg_data: message = '{} (data: {})'.format(message, msg_data)
			raise raise_for.get(code, ProtocolError)(code, message)
		if raw: res = res.content
		elif raw_all: res = code, dict(res.headers.items()), res.content
		else: res = json.loads(res.text)
		return res
Make synchronous HTTP request.
			Can be overidden to use different http module (e.g. urllib2, twisted, etc).