<s> from __future__ import absolute_import , unicode_literals <EOL> import logging <EOL> import os . path <EOL> import urllib <EOL> import urlparse <EOL> from xml . etree import ElementTree <EOL> import pytz <EOL> import requests <EOL> import wrapt <EOL> from requests_oauthlib import OAuth2Session <EOL> from . exceptions import ( <EOL> SalesforceRestException , <EOL> AuthenticationMissingException , <EOL> InvalidSessionException , <EOL> get_exception , <EOL> ) <EOL> logger = logging . getLogger ( __name__ ) <EOL> @ wrapt . decorator <EOL> def auth_required ( wrapped , instance , args , kwargs ) : <EOL> if getattr ( instance . session , '<STR_LIT>' , None ) is None : <EOL> raise AuthenticationMissingException ( ) <EOL> return wrapped ( * args , ** kwargs ) <EOL> METHOD_STATUS_CODES = { <EOL> '<STR_LIT:GET>' : ( <NUM_LIT:200> , <NUM_LIT> ) , <EOL> '<STR_LIT:POST>' : ( <NUM_LIT> , <NUM_LIT> ) , <EOL> '<STR_LIT>' : ( <NUM_LIT> , <NUM_LIT> , <NUM_LIT> ) , <EOL> '<STR_LIT>' : ( <NUM_LIT:200> , <NUM_LIT> ) , <EOL> } <EOL> class SalesforceRestClientBase ( object ) : <EOL> RESPONSE_FORMAT_JSON = '<STR_LIT>' <EOL> RESPONSE_FORMAT_XML = '<STR_LIT>' <EOL> @ property <EOL> def version ( self ) : <EOL> raise NotImplementedError ( '<STR_LIT>' ) <EOL> def __init__ ( self , client_id , client_secret , domain , user_id = None , <EOL> access_token = None , refresh_token = None , token_updater = None , <EOL> response_format = RESPONSE_FORMAT_JSON ) : <EOL> '''<STR_LIT>''' <EOL> self . domain = domain <EOL> self . user_id = user_id <EOL> self . response_format = response_format <EOL> if access_token : <EOL> token = { <EOL> '<STR_LIT>' : access_token , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> } <EOL> if refresh_token : <EOL> token [ '<STR_LIT>' ] = refresh_token <EOL> auto_refresh_url = '<STR_LIT>' <EOL> auto_refresh_kwargs = { <EOL> '<STR_LIT>' : client_id , <EOL> '<STR_LIT>' : client_secret , <EOL> } <EOL> else : <EOL> auto_refresh_url = None <EOL> auto_refresh_kwargs = None <EOL> self . session = OAuth2Session ( client_id , token = token , <EOL> auto_refresh_url = auto_refresh_url , <EOL> auto_refresh_kwargs = auto_refresh_kwargs , <EOL> token_updater = token_updater ) <EOL> else : <EOL> session = requests . Session ( ) <EOL> self . session . headers [ '<STR_LIT>' ] = '<STR_LIT>' . format ( <EOL> response_format <EOL> ) <EOL> def _url ( self , path , params = None , versioned = True ) : <EOL> path_parts = [ '<STR_LIT>' ] <EOL> if versioned : <EOL> path_parts . append ( '<STR_LIT>' . format ( self . version ) ) <EOL> path_parts . append ( path ) <EOL> url = urlparse . urljoin ( '<STR_LIT>' . format ( self . domain ) , <EOL> os . path . join ( * path_parts ) ) <EOL> if params : <EOL> url += '<STR_LIT>' . format ( urllib . urlencode ( params ) ) <EOL> return url <EOL> def _extract_response ( self , response ) : <EOL> error_code = error_message = content = None <EOL> if self . response_format == SalesforceRestClientBase . RESPONSE_FORMAT_JSON : <EOL> if response . text : <EOL> content = response . json ( ) <EOL> if <NUM_LIT> <= response . status_code < <NUM_LIT> : <EOL> error = content [ <NUM_LIT:0> ] <EOL> error_code = error [ '<STR_LIT>' ] <EOL> error_message = error [ '<STR_LIT:message>' ] <EOL> elif self . response_format == SalesforceRestClientBase . RESPONSE_FORMAT_XML : <EOL> content = ElementTree . fromstring ( response . text . encode ( '<STR_LIT:utf-8>' ) ) <EOL> if <NUM_LIT> <= response . status_code < <NUM_LIT> : <EOL> error = content . getchildren ( ) [ <NUM_LIT:0> ] <EOL> error_code , error_message = [ e . text . decode ( '<STR_LIT:utf-8>' ) for e in error ] <EOL> if response . status_code in METHOD_STATUS_CODES [ response . request . method ] : <EOL> return content <EOL> elif error_code or error_message : <EOL> raise get_exception ( response . status_code , <EOL> error_code , <EOL> error_message ) <EOL> else : <EOL> raise SalesforceRestException ( response . status_code , <EOL> response . text ) <EOL> def _format_datetime ( self , value ) : <EOL> return value . astimezone ( pytz . utc ) . strftime ( '<STR_LIT>' ) <EOL> def _refresh_token ( self ) : <EOL> if self . session . token . get ( '<STR_LIT>' ) : <EOL> token = self . session . refresh_token ( <EOL> self . session . auto_refresh_url , <EOL> ) <EOL> if self . session . token_updater : <EOL> self . session . token_updater ( token ) <EOL> return token <EOL> def _call ( self , url , method = '<STR_LIT>' , body = None , headers = None ) : <EOL> logger . debug ( url ) <EOL> response = getattr ( self . session , method ) ( url , data = body , <EOL> headers = headers ) <EOL> try : <EOL> return self . _extract_response ( response ) <EOL> except InvalidSessionException as e : <EOL> if self . _refresh_token ( ) : <EOL> response = getattr ( self . session , method ) ( url , data = body , <EOL> headers = headers ) <EOL> return self . _extract_response ( response ) <EOL> raise <EOL> def call ( self , path , method = '<STR_LIT>' , params = None , body = None , headers = None , <EOL> versioned = True ) : <EOL> url = self . _url ( path , params = params , versioned = versioned ) <EOL> return self . _call ( url , method = method , body = body , headers = headers ) <EOL> def versions ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . call ( '<STR_LIT>' , versioned = False ) <EOL> @ staticmethod <EOL> def validate_field ( value , field , new_record = True ) : <EOL> """<STR_LIT>""" <EOL> errors = [ ] <EOL> if new_record : <EOL> if not field [ '<STR_LIT>' ] and value is not None : <EOL> errors . append ( '<STR_LIT>' ) <EOL> else : <EOL> if not field [ '<STR_LIT>' ] and value is not None : <EOL> errors . append ( '<STR_LIT>' ) <EOL> if value is not None and field . get ( '<STR_LIT>' ) : <EOL> values = [ i [ '<STR_LIT:value>' ] <EOL> for i in field [ '<STR_LIT>' ] if i [ '<STR_LIT>' ] ] <EOL> if value not in values : <EOL> errors . append ( '<STR_LIT>' ) <EOL> if ( new_record and value is None and not field [ '<STR_LIT>' ] and <EOL> not field [ '<STR_LIT>' ] and field [ '<STR_LIT:type>' ] != '<STR_LIT>' ) : <EOL> errors . append ( '<STR_LIT>' ) <EOL> return errors <EOL> @ staticmethod <EOL> def validate_object ( data , object_description , new_record = True ) : <EOL> """<STR_LIT>""" <EOL> errors = { } <EOL> field_map = { f [ '<STR_LIT:name>' ] : f for f in object_description [ '<STR_LIT>' ] } <EOL> for field_name , field in field_map . items ( ) : <EOL> field_errors = SalesforceRestClientBase . validate_field ( <EOL> data . get ( field_name ) , field , new_record = new_record ) <EOL> if field_errors : <EOL> errors [ field_name ] = field_errors <EOL> for field_name in set ( data . keys ( ) ) - set ( field_map . keys ( ) ) : <EOL> errors [ field_name ] = [ '<STR_LIT>' ] <EOL> return not errors , errors </s>
