88from functools import partial
99from logging import getLogger
1010
11+ from boxsdk .exception import BoxException
1112from .box_request import BoxRequest as _BoxRequest
1213from .box_response import BoxResponse as _BoxResponse
13- from ..config import API , Client
14+ from ..config import API , Client , Proxy
1415from ..exception import BoxAPIException
1516from ..network .default_network import DefaultNetwork
1617from ..util .json import is_json_response
@@ -35,6 +36,7 @@ def __init__(
3536 default_network_request_kwargs = None ,
3637 api_config = None ,
3738 client_config = None ,
39+ proxy_config = None ,
3840 ):
3941 """
4042 :param network_layer:
@@ -64,11 +66,16 @@ def __init__(
6466 Object containing client information, including user agent string.
6567 :type client_config:
6668 :class:`Client`
69+ :param proxy_config:
70+ Object containing proxy information.
71+ :type proxy_config:
72+ :class:`Proxy` or None
6773 """
6874 if translator is None :
6975 translator = Translator (extend_default_translator = True , new_child = True )
7076 self ._api_config = api_config or API ()
7177 self ._client_config = client_config or Client ()
78+ self ._proxy_config = proxy_config or Proxy ()
7279 super (Session , self ).__init__ ()
7380 self ._network_layer = network_layer or DefaultNetwork ()
7481 self ._default_headers = {
@@ -184,6 +191,14 @@ def client_config(self):
184191 """
185192 return self ._client_config
186193
194+ @property
195+ def proxy_config (self ):
196+ """
197+
198+ :rtype: :class:`Proxy`
199+ """
200+ return self ._proxy_config
201+
187202 def get_url (self , endpoint , * args ):
188203 """
189204 Return the URL for the given Box API endpoint.
@@ -211,6 +226,7 @@ def get_constructor_kwargs(self):
211226 default_network_request_kwargs = self ._default_network_request_kwargs .copy (),
212227 api_config = self ._api_config ,
213228 client_config = self ._client_config ,
229+ proxy_config = self ._proxy_config ,
214230 default_headers = self ._default_headers .copy (),
215231 )
216232
@@ -425,6 +441,34 @@ def _get_retry_request_callable(self, network_response, attempt_number, request)
425441 def _get_request_headers (self ):
426442 return self ._default_headers .copy ()
427443
444+ def _prepare_proxy (self ):
445+ """
446+ Prepares basic authenticated and unauthenticated proxies for requests.
447+
448+ :return:
449+ A prepared proxy dict to send along with the request. None if incorrect parameters were passed.
450+ :rtype:
451+ `dict` or None
452+ """
453+ proxy = {}
454+ proxy_string = ''
455+ if self ._proxy_config .URL is None :
456+ return None
457+ if self ._proxy_config .AUTH and {'user' , 'password' } <= set (self ._proxy_config .AUTH ):
458+ host = self ._proxy_config .URL
459+ address = host .split ('//' )[1 ]
460+ proxy_string = 'http://{0}:{1}@{2}' .format (self ._proxy_config .AUTH .get ('user' , None ),
461+ self ._proxy_config .AUTH .get ('password' , None ),
462+ address )
463+ elif self ._proxy_config .AUTH is None :
464+ proxy_string = self ._proxy_config .URL
465+ else :
466+ raise BoxException ("The proxy auth dict you provided does not match pattern {'user': 'example_user', 'password': 'example_password'}" )
467+ proxy ['http' ] = proxy_string
468+ proxy ['https' ] = proxy ['http' ]
469+
470+ return proxy
471+
428472 def _send_request (self , request , ** kwargs ):
429473 """
430474 Make a request to the Box API.
@@ -443,6 +487,9 @@ def _send_request(self, request, **kwargs):
443487 files , file_stream_positions = kwargs .get ('files' ), kwargs .pop ('file_stream_positions' )
444488 request_kwargs = self ._default_network_request_kwargs .copy ()
445489 request_kwargs .update (kwargs )
490+ proxy_dict = self ._prepare_proxy ()
491+ if proxy_dict is not None :
492+ request_kwargs .update ({'proxies' : proxy_dict })
446493 if files and file_stream_positions :
447494 for name , position in file_stream_positions .items ():
448495 files [name ][1 ].seek (position )
0 commit comments