o
    gq                     @   s.  d Z ddlmZ dZddlZddlZddlZddlZddlmZm	Z	m
Z
mZmZmZmZmZmZmZmZmZ ddlmZ ddlmZ ddlmZ dd	lmZmZ ddlZd
dlmZ d
dl m!Z! d
dl"m#Z# d
dl$m%Z% d
dl&m'Z' d
dl(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z. e/e0Z1G dd dZ2G dd dZ3dS )z1Core classes and exceptions for Simple-Salesforce    )datetimez59.0N)AnyCallableDictIOIteratorListMappingMutableMappingOptionalTupleUnioncast)OrderedDict)partial)Path)urljoinurlparse   )SFBulkHandler)SFBulk2Handler)SalesforceGeneralError)SalesforceLogin)SfdcMetadataApi)HeadersPerAppUsageProxiesUsagedate_to_iso8601exception_handlerc                *       s  e Zd ZdZdZeZdddddddedddddddddefdee	 dee	 dee	 dee	 dee	 dee	 d	ee	 d
ee	 dee
 deej dee	 dee	 dee	 dee	 dee	 dee	 deee	gef  deeeeeef  gef  f$ddZedefddZdaddZdaddZdedee fdd Zdee fd!d"Zd#e	deeed$f f fd%d&Zd'e	de	dee fd(d)Z		*dbd+e	d,eee	ef  d-e	dedee f
d.d/Z 		*dbd+e	d,eee	ef  d-e	dee fd0d1Z!d2e	defd3d4Z"d2e	defd5d6Z#dedefd7d8Z$	9dcd:e	d;ededefd<d=Z%	9	9ddd>e	d?ed;ededef
d@dAZ&	9dcd:e	d;edede'e fdBdCZ(	9dcd:e	d;ededee	ef fdDdEZ)	*	dedFe	d-e	dGeee	ef  dedef
dHdIZ*	*	dedFe	d-e	dGeee	ef  dedef
dJdKZ+	L	M	Ndfd-e	dOe	d#e	dPe,dQe,dedej-fdRdSZ.e/dTe	de0e	ee1e2f f fdUdVZ3dWee	e4e5 f dXededee	ee	 f fdYdZZ6d[e	dedee	eee	e7e	e	f f  f fd\d]Z8d^ej-defd_d`Z9  Z:S )g
SalesforcezSalesforce Instance
    An instance of Salesforce is a handy way to wrap a Salesforce session
    for easy use of the Salesforce REST API.
    Nusernamepasswordsecurity_token
session_idinstanceinstance_urlorganizationIdversionproxiessession	client_iddomainconsumer_keyconsumer_secretprivatekey_file
privatekeyparse_floatobject_pairs_hookc                 C   s*  |du rd}|| _ || _|
pt | _| jj| _d| _|	dur/|
s)|	 | j_| _ntd|	 t	dd |||fD rUd| _
tt| j|||| j | j|| jd	| _|   nt	dd ||p]|fD rd	| _
tt|| _|durt|j| _t|j}|d
vr|  jd| 7  _ntt|| _|   nt	dd |||fD rd| _
tt| j|||| j | j|| jd	| _|   ntt	dd ||||fD rd| _
tt| j||||| j| jd| _|   nOt	dd |||p|fD rd| _
tt| j|||||| j| jd	| _|   n't	dd |||fD r*d| _
tt| j||| j| jd| _|   ntdd| j d| _dd| j dd| _d| j d| j  d| _d| j d | _d| j d!| j  d| _d| j d| j  d"| _d| j d#| j  d| _| j d$| _d| j d%| _i | _ || _!|| _"d| _#dS )&ae  Initialize the instance with the given parameters.
        Available kwargs
        Password Authentication:
        * username -- the Salesforce username to use for authentication
        * password -- the password for the username
        * security_token -- the security token for the username
        * domain -- The domain to using for connecting to Salesforce. Use
                    common domains, such as 'login' or 'test', or
                    Salesforce My domain. If not used, will default to
                    'login'.

        OAuth 2.0 Connected App Token Authentication:
        * consumer_key -- the consumer key generated for the user
        * consumer_secret -- the consumer secret generated for the user

        OAuth 2.0 JWT Bearer Token Authentication:
        * consumer_key -- the consumer key generated for the user

        Then either
        * privatekey_file -- the path to the private key file used
                             for signing the JWT token
        OR
        * privatekey -- the private key to use
                         for signing the JWT token

        Direct Session and Instance Access:

        * session_id -- Access token for this session

        Then either
        * instance -- Domain of your Salesforce instance, i.e.
          `na1.salesforce.com`
        OR
        * instance_url -- Full URL of your instance i.e.
          `https://na1.salesforce.com

        Universal Kwargs:
        * version -- the version of the Salesforce API to use, for example
                     `29.0`
        * proxies -- the optional map of scheme to proxy server
        * session -- Custom requests session, created in calling code. This
                     enables the use of requests Session features not otherwise
                     exposed by simple_salesforce.
        * parse_float -- Function to parse float values with. Is passed along to
                         https://docs.python.org/3/library/json.html#json.load
        * object_pairs_hook -- Function to parse ordered list of pairs in json.
                               To use python 'dict' change it to None or dict.
        NloginzFProxies must be defined on custom session object, ignoring proxies: %sc                 s       | ]}|d uV  qd S N .0argr6   r6   N/home/ubuntu/webapp/venv/lib/python3.10/site-packages/simple_salesforce/api.py	<genexpr>       z&Salesforce.__init__.<locals>.<genexpr>r"   )r*   r!   r"   r#   
sf_versionr)   r+   r,   c                 s   r4   r5   r6   r7   r6   r6   r:   r;      r<   direct)Ni  :c                 s   r4   r5   r6   r7   r6   r6   r:   r;      r<   ipfilter)r*   r!   r"   r'   r=   r)   r+   r,   c                 s   r4   r5   r6   r7   r6   r6   r:   r;      r<   )r*   r!   r"   r-   r.   r)   r,   c                 s   r4   r5   r6   r7   r6   r6   r:   r;      r<   z
jwt-bearer)r*   r!   r&   r-   r/   r0   r)   r,   c                 s   r4   r5   r6   r7   r6   r6   r:   r;      r<   zclient-credentials)r*   r-   r.   r)   r,   z;You must provide login information or an instance and tokenhttps://z.salesforce.comapplication/jsonBearer 1Content-TypeAuthorizationzX-PrettyPrint/services/data/v/z/services/apexrest/z/services/async/z/jobs/z/services/Soap/m/ztooling/z/services/oauth2/)$r=   r,   requestsSessionr*   r)   _salesforce_login_partialloggerwarningall	auth_typer   r   _refresh_sessionr   strr$   r   hostnamesf_instanceport_generate_headers	TypeError	auth_siteheadersbase_urlapex_urlbulk_url	bulk2_urlmetadata_urltooling_url
oauth2_url	api_usage_parse_float_object_pairs_hook_mdapi)selfr!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   r2   rU   r6   r6   r:   __init__)   s  H














zSalesforce.__init__returnc                 C   s.   | j st| j| j| j| j| j| jd| _ | j S )z3Utility to interact with metadata api functionality)r*   r$   r%   r^   api_versionrY   )rd   r   r*   r$   rT   r^   r=   rY   re   r6   r6   r:   mdapi  s   zSalesforce.mdapic                 C   s   dd| j  dd| _dS )z7Utility to generate headers when refreshing the sessionrB   rC   rD   rE   N)r$   rY   ri   r6   r6   r:   rV   $  s   zSalesforce._generate_headersc                 C   s.   | j du r	td|   \| _| _|   dS )z+Utility to refresh the session when expiredNzRThe simple_salesforce session can not refreshed if a session id has been provided.)rL   RuntimeErrorr$   rT   rV   ri   r6   r6   r:   rQ   ,  s   
zSalesforce._refresh_sessionkwargsc                 K   s@   | j d }| jd|fddi|}| |}t|dkrdS |S )zDescribes all available objects
        Arguments:
        * keyword arguments supported by requests.request (e.g. json, timeout)
        sobjectsGETnamedescriber   NrZ   _call_salesforceparse_result_to_jsonlen)re   rl   urlresultjson_resultr6   r6   r:   rp   6  s   

zSalesforce.describec                 C   s0   d}| j r| ddddigd d}|S )z9After connection returns is the organization in a sandboxNz*SELECT IsSandbox FROM Organization LIMIT 1records	IsSandboxr   )r$   	query_allget)re   
is_sandboxr6   r6   r:   r|   J  s   zSalesforce.is_sandboxro   SFTypec              
      sv   | drt |S |dkrt| j| j| j| jS |dkr)t| j| j	| j| jS t
|| j| j| j| j| j| | jdS )a  Returns an `SFType` instance for the given Salesforce object type
        (given in `name`).
        The magic part of the SalesforceAPI, this function translates
        calls such as `salesforce_api_instance.Lead.metadata()` into fully
        constituted `SFType` instances to make a nice Python API wrapper
        for the REST API.
        Arguments:
        * name -- the name of a Salesforce object type, e.g. Lead or Contact
        __bulkbulk2)r=   r)   r*   
salesforcer2   )
startswithsuper__getattr__r   r$   r\   r)   r*   r   r]   r}   rT   r=   rc   )re   ro   	__class__r6   r:   r   Y  s0   
zSalesforce.__getattr__userc                 C   sd   | j  d| d}d|i}| jd|t|d}|jdkrdS |jdkr-t||jd	|j| |S )
a#  Sets the password of a user
        salesforce dev documentation link:
        https://www.salesforce.com/us/developer/docs/api_rest/Content
        /dome_sobject_user_password.htm
        Arguments:
        * user: the userID of the user to set
        * password: the new password
        zsobjects/User/z	/passwordNewPasswordPOST)data   N   User)rZ   rr   jsondumpsstatus_coder   contentrs   )re   r   r"   ru   paramsrv   r6   r6   r:   set_password  s    


zSalesforce.set_passwordrn   pathr   methodc                 K   sB   | j | }| j||f||d|}| |}t|dkrdS |S )al  Allows you to make a direct REST call if you know the path

        Arguments:
        * path: The path of the request
            Example: sobjects/User/ABC123/password'
        * params: dict of parameters to pass to the path
        * method: HTTP request method, default GET
        * other arguments supported by requests.request (e.g. json, timeout)
        ro   r   r   Nrq   )re   r   r   r   rl   ru   rv   rw   r6   r6   r:   restful  s   

zSalesforce.restfulc                 C   s^   | j | }| j||||d}|jd}|dur!d|v r!| |nd}|r-t|dkr-dS |S )ap  Allows you to make a request to OAuth endpoints if you know the path

        Arguments:

        * path: The path of the request
            Example: /services/oauth2/token'
        * params: dict of parameters to pass to the path
        * method: HTTP request method, default GET
        * other arguments supported by requests.request (e.g. json, timeout)
        r   rF   Nr   r   )r`   rr   rY   r{   rs   rt   )re   r   r   r   ru   rv   content_typerw   r6   r6   r:   oauth2  s   

zSalesforce.oauth2searchc                 C   sB   | j d }d|i}| jd|d|d}| |}t|dkrdS |S )zReturns the result of a Salesforce search as a dict decoded from
        the Salesforce response JSON payload.
        Arguments:
        * search -- the fully formatted SOSL search string, e.g.
                    `FIND {Waldo}`
        zsearch/qrn   r   r   r   Nrq   )re   r   ru   r   rv   rw   r6   r6   r:   r     s   
	
zSalesforce.searchc                 C   s   d| d}|  |S )aJ  Returns the result of a Salesforce search as a dict decoded from
        the Salesforce response JSON payload.
        Arguments:
        * search -- the non-SOSL search string, e.g. `Waldo`. This search
                    string will be wrapped to read `FIND {Waldo}` before being
                    sent to Salesforce
        zFIND {})r   )re   r   search_stringr6   r6   r:   quick_search  s   

zSalesforce.quick_searchc                 K   s:   | j d }| jd|fi |}|jdkrt| | |S )zWReturn the result of a Salesforce request to list Organization
        limits.
        zlimits/rn   r   )rZ   rr   r   r   rs   )re   rl   ru   rv   r6   r6   r:   limits  s   


zSalesforce.limitsFqueryinclude_deletedc                 K   s>   | j |rdnd }d|i}| jd|fd|d|}| |S )a^  Return the result of a Salesforce SOQL query as a dict decoded from
        the Salesforce response JSON payload.
        Arguments:
        * query -- the SOQL query to send to Salesforce, e.g.
                   SELECT Id FROM Lead WHERE Email = "waldo@somewhere.com"
        * include_deleted -- True if deleted records should be included
        z	queryAll/zquery/r   rn   r   r   )rZ   rr   rs   )re   r   r   rl   ru   r   rv   r6   r6   r:   r   #  s   
zSalesforce.querynext_records_identifieridentifier_is_urlc                 K   sX   |rd| j  | }n|rdnd}| j | d| }| jd|fddi|}| |S )aj  Retrieves more results from a query that returned more results
        than the batch maximum. Returns a dict decoded from the Salesforce
        response JSON payload.
        Arguments:
        * next_records_identifier -- either the Id of the next Salesforce
                                     object in the result, or a URL to the
                                     next record in the result.
        * identifier_is_url -- True if `next_records_identifier` should be
                               treated as a URL, False if
                               `next_records_identifier` should be treated as
                               an Id.
        * include_deleted -- True if the `next_records_identifier` refers to a
                             query that includes deleted records. Only used if
                             `identifier_is_url` is False
        rA   queryAllr   rI   rn   ro   
query_more)rT   rZ   rr   rs   )re   r   r   r   rl   ru   endpointrv   r6   r6   r:   r   >  s   
zSalesforce.query_morec                 k   sR    | j |fd|i|}	 |d E dH  |d s&| j|d fddi|}ndS q)a;  This is a lazy alternative to `query_all` - it does not construct
        the whole result set into one container, but returns objects from each
        page it retrieves from the API.
        Since `query_all` has always been eagerly executed, we reimplemented it
        using `query_all_iter`, only materializing the returned iterator to
        maintain backwards compatibility.
        The one big difference from `query_all` (apart from being lazy) is that
        we don't return a dictionary with `totalSize` and `done` here,
        we only return the records in an iterator.
        Arguments
        * query -- the SOQL query to send to Salesforce, e.g.
                   SELECT Id FROM Lead WHERE Email = "waldo@somewhere.com"
        * include_deleted -- True if the query should include deleted records.
        r   Trx   NdonenextRecordsUrlr   )r   r   )re   r   r   rl   rv   r6   r6   r:   query_all_iterb  s    
zSalesforce.query_all_iterc                 K   s.   | j |fd|i|}t|}|t|ddS )a  Returns the full set of results for the `query`. This is a
        convenience
        wrapper around `query(...)` and `query_more(...)`.
        The returned dict is the decoded JSON payload from the final call to
        Salesforce, but with the `totalSize` field representing the full
        number of results retrieved and the `records` list representing the
        full list of records retrieved.
        Arguments
        * query -- the SOQL query to send to Salesforce, e.g.
                   SELECT Id FROM Lead WHERE Email = "waldo@somewhere.com"
        * include_deleted -- True if the query should include deleted records.
        r   T)rx   	totalSizer   )r   listrt   )re   r   r   rl   rx   all_recordsr6   r6   r:   rz     s   
zSalesforce.query_allactionr   c                 K   `   |dur	t |nd}| j|| j| fd|d|}z|  }W |S  ty/   |j}Y |S w )aM  Makes an HTTP request to an TOOLING REST endpoint
        Arguments:
        * action -- The REST endpoint for the request.
        * method -- HTTP method for the request (default GET)
        * data -- A dict of parameters to send in a POST / PUT request
        * kwargs -- Additional kwargs to pass to `requests.request`
        Ntoolingexecutero   r   )r   r   rr   r_   	Exceptiontextre   r   r   r   rl   	json_datarv   response_contentr6   r6   r:   r     "   
zSalesforce.toolingexecutec                 K   r   )aJ  Makes an HTTP request to an APEX REST endpoint
        Arguments:
        * action -- The REST endpoint for the request.
        * method -- HTTP method for the request (default GET)
        * data -- A dict of parameters to send in a POST / PUT request
        * kwargs -- Additional kwargs to pass to `requests.request`
        N	apexecuter   )r   r   rr   r[   r   r   r   r6   r6   r:   r     r   zSalesforce.apexecute r      ru   retriesmax_retriesc                 K   s   | j  }|di }|| | jj||fd|i|}	| jdurR|	jdkrR|	 d }
|
d dkrR| 	  |d7 }||krEt
|	|d | j|||fd	|i|S |	jd
kr]t
|	|d |	j d}|rk| || _|	S )zkUtility method for performing HTTP call to Salesforce.
        Returns a `requests.result` object.
        rY   N  r   	errorCodeINVALID_SESSION_IDr   ro   r   ,  Sforce-Limit-Info)rY   copypopupdater*   requestrL   r   r   rQ   r   rr   r{   parse_api_usagera   )re   r   ru   ro   r   r   rl   rY   additional_headersrv   error_detailssforce_limit_infor6   r6   r:   rr     sP   




zSalesforce._call_salesforcer   c                 C   s   i }t d| }d}t || }|r*| r*| }tt|d t|d d|d< |rG| rG| }tt|d t|d |d d|d	< |S )
aF  parse API usage and limits out of the Sforce-Limit-Info header
        Arguments:
        * sforce_limit_info: The value of response header 'Sforce-Limit-Info'
            Example 1: 'api-usage=18/5000'
            Example 2: 'api-usage=25/5000;
                per-app-api-usage=17/250(appName=sample-connected-app)'
        z)[^-]?api-usage=(?P<used>\d+)/(?P<tot>\d+)z>.+per-app-api-usage=(?P<u>\d+)/(?P<t>\d+)\(appName=(?P<n>.+)\)r   r   )usedtotalz	api-usage   )r   r   ro   zper-app-api-usage)rematchgroupsr   intr   )r   rv   ra   pauper_app_api_usager   r6   r6   r:   r     s*   



zSalesforce.parse_api_usagezipfilesandboxc                 K   s(   | j j||fi |\}}||d}|S )a  Deploy using the Salesforce Metadata API. Wrapper for
        SfdcMetaDataApi.deploy(...).
        Arguments:
        * zipfile: a .zip archive to deploy to an org, given as (
        "path/to/zipfile.zip")
        * options: salesforce DeployOptions in .json format.
            (https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta
            /api_meta/meta_deploy.htm)

        Returns a process id and state for this deployment.
        )asyncIdstate)rj   deploy)re   r   r   rl   r   r   rv   r6   r6   r:   r   @  s   
zSalesforce.deployr   c                 K   s.   | j j|fi |\}}}}||||d}|S )a;  Check on the progress of a file-based deployment via Salesforce
        Metadata API.
        Wrapper for SfdcMetaDataApi.check_deploy_status(...).
        Arguments:
        * asyncId: deployment async process ID, returned by Salesforce.deploy()
        Returns status of the deployment the asyncId given.
        )r   state_detaildeployment_detailunit_test_detail)rj   check_deploy_status)re   r   rl   r   r   r   r   resultsr6   r6   r:   checkDeployStatus\  s   
zSalesforce.checkDeployStatusrv   c                 C      |j | j| jdS z""Parse json from a Response object)r2   r1   r   rc   rb   re   rv   r6   r6   r:   rs   t     zSalesforce.parse_result_to_json)rg   N)Nrn   )F)FF)rn   N)r   r   r   );__name__
__module____qualname____doc__rb   r   rc   DEFAULT_API_VERSIONr   rR   r   rJ   rK   r   r   r   r   rf   propertyr   rj   rV   rQ   rp   boolr|   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rz   r   r   r   Responserr   staticmethodr
   r   r   r   r   bytesr   r	   r   rs   __classcell__r6   r6   r   r:   r        s   	

 o



-
'
#





'
'

!
#
$
6%

r    c                   @   s&  e Zd ZdZdZeZeddddefdededede	e de	e
 de	ej d	e	e d
e	eegef  deeeeef  gef fddZedefddZ	dIde	e defddZ	dIde	e defddZ	dIdede	e defddZ	dIdede	e dedefddZ	dIdedede	e dedef
ddZ	dId eeef de	e defd!d"Z	#	dJded eeef d$ede	e def
d%d&Z	#	dJded eeef d$ede	e def
d'd(Z	#	dJded$ede	e de e!ej"f fd)d*Z#	dId+e$d,e$de	e defd-d.Z%	dId+e$d,e$de	e defd/d0Z&	1	2dKd3ed4ed5e!d6e!dedej"fd7d8Z'd9ej"d:ede e!ej"f fd;d<Z(d=ej"defd>d?Z)	@	dLdAedBede	e dedej"f
dCdDZ*	@		#dMdedAedBede	e d$edede e!ej"f fdEdFZ+	@		dNdedBed e	e de	e dede,fdGdHZ-dS )Or}   z*An interface to a specific type of SObjectNobject_namer$   rT   r=   r)   r*   r   r1   r2   c
           
      C   s|   |du r|du rt d|| _|| _|| _|pt | _|| _|	| _|s,|dur,|| j_	i | _
d| d| d| d| _dS )a  Initialize the instance with the given parameters.
        Arguments:
        * object_name -- the name of the type of SObject this represents,
                         e.g. `Lead` or `Contact`
        * session_id -- the session ID for authenticating to Salesforce
        * sf_instance -- the domain of the instance of Salesforce to use
        * sf_version -- the version of the Salesforce API to use
        * proxies -- the optional map of scheme to proxy server
        * session -- Custom requests session, created in calling code. This
                     enables the use of requests Session features not otherwise
                     exposed by simple_salesforce.
        * parse_float -- Function to parse float values with. Is passed along to
                         https://docs.python.org/3/library/json.html#json.load
        * object_pairs_hook -- Function to parse ordered list of pairs in json.
                               To use python 'dict' change it to None or dict.
        NzNThe argument session_id or salesforce must be specified to instanciate SFType.rA   rH   z
/sobjects/rI   )rk   _session_idr   ro   rJ   rK   r*   rb   rc   r)   ra   rZ   )
re   r   r$   rT   r=   r)   r*   r   r1   r2   r6   r6   r:   rf     s"   "zSFType.__init__rg   c                 C   s   | j dur	| j jS | jS )zHelper to return the session idN)r   r$   r   ri   r6   r6   r:   r$     s   
zSFType.session_idrY   c                 C   s   | j d| j|d}| |S )zReturns the result of a GET to `.../{object_name}/` as a dict
        decoded from the JSON payload returned by Salesforce.
        Arguments:
        * headers -- a dict with additional request headers.
        rn   )rY   )rr   rZ   rs   re   rY   rv   r6   r6   r:   metadata  s
   
zSFType.metadatac                 C   s"   | j dt| jd|d}| |S )zReturns the result of a GET to `.../{object_name}/describe` as a
        dict decoded from the JSON payload returned by Salesforce.
        Arguments:
        * headers -- a dict with additional request headers.
        rn   rp   r   ru   rY   rr   r   rZ   rs   r   r6   r6   r:   rp     s   
zSFType.describe	record_idc                 C   s,   d| }| j dt| j||d}| |S )aT  Returns the layout of the object
        Returns the result of a GET to
        `.../{object_name}/describe/layouts/<recordid>` as a dict decoded from
        the JSON payload returned by Salesforce.
        Arguments:
        * record_id -- the Id of the SObject to get
        * headers -- a dict with additional request headers.
        zdescribe/layouts/rn   r   r   )re   r   rY   custom_url_partrv   r6   r6   r:   describe_layout  s   

zSFType.describe_layoutrl   c                 K   s*   | j ddt| j||d|}| |S )a  Returns the result of a GET to `.../{object_name}/{record_id}` as a
        dict decoded from the JSON payload returned by Salesforce.
        Arguments:
        * record_id -- the Id of the SObject to get
        * headers -- a dict with additional request headers.
        rn   r   Nr6   r   )re   r   rY   rl   rv   r6   r6   r:   r{     s   

z
SFType.getcustom_id_field	custom_idc                 K   s8   t | j| d| }| jdd||d|}| |S )a  Return an ``SFType`` by custom ID
        Returns the result of a GET to
        `.../{object_name}/{custom_id_field}/{custom_id}` as a dict decoded
        from the JSON payload returned by Salesforce.
        Arguments:
        * custom_id_field -- the API name of a custom field that was defined
                             as an External ID
        * custom_id - the External ID value of the SObject to get
        * headers -- a dict with additional request headers.
        rI   rn   r   Nr6   )r   rZ   rr   rs   )re   r   r   rY   rl   
custom_urlrv   r6   r6   r:   get_by_custom_id  s   
zSFType.get_by_custom_idr   c                 C   s$   | j d| jt||d}| |S )af  Creates a new SObject using a POST to `.../{object_name}/`.
        Returns a dict decoded from the JSON payload returned by Salesforce.
        Arguments:
        * data -- a dict of the data to create the SObject from. It will be
                  JSON-encoded before being transmitted.
        * headers -- a dict with additional request headers.
        r   r   ru   r   rY   )rr   rZ   r   r   rs   )re   r   rY   rv   r6   r6   r:   create(  s   
zSFType.createFraw_responsec                 C   ,   | j dt| j|t||d}| ||S )a  Creates or updates an SObject using a PATCH to
        `.../{object_name}/{record_id}`.
        If `raw_response` is false (the default), returns the status code
        returned by Salesforce. Otherwise, return the `requests.Response`
        object.
        Arguments:
        * record_id -- an identifier for the SObject as described in the
                       Salesforce documentation
        * data -- a dict of the data to create or update the SObject from. It
                  will be JSON-encoded before being transmitted.
        * raw_response -- a boolean indicating whether to return the response
                          directly, instead of the status code.
        * headers -- a dict with additional request headers.
        PATCHr   rr   r   rZ   r   r   _raw_responsere   r   r   r   rY   rv   r6   r6   r:   upsert<  s   zSFType.upsertc                 C   r   )a  Updates an SObject using a PATCH to
        `.../{object_name}/{record_id}`.
        If `raw_response` is false (the default), returns the status code
        returned by Salesforce. Otherwise, return the `requests.Response`
        object.
        Arguments:
        * record_id -- the Id of the SObject to update
        * data -- a dict of the data to update the SObject from. It will be
                  JSON-encoded before being transmitted.
        * raw_response -- a boolean indicating whether to return the response
                          directly, instead of the status code.
        * headers -- a dict with additional request headers.
        r   r   r   r  r6   r6   r:   r   ]  s   zSFType.updatec                 C   s$   | j dt| j||d}| ||S )a  Deletes an SObject using a DELETE to
        `.../{object_name}/{record_id}`.
        If `raw_response` is false (the default), returns the status code
        returned by Salesforce. Otherwise, return the `requests.Response`
        object.
        Arguments:
        * record_id -- the Id of the SObject to delete
        * raw_response -- a boolean indicating whether to return the response
                          directly, instead of the status code.
        * headers -- a dict with additional request headers.
        DELETEr   )rr   r   rZ   r  )re   r   r   rY   rv   r6   r6   r:   delete}  s   zSFType.deletestartendc                 C   :   t | jdt| dt| }| jd||d}| |S )a~  Gets a list of deleted records
        Use the SObject Get Deleted resource to get a list of deleted records
        for the specified object.
        .../deleted/?start=2013-05-05T00:00:00+00:00&end=2013-05-10T00:00:00
        +00:00
        * start -- start datetime object
        * end -- end datetime object
        * headers -- a dict with additional request headers.
        zdeleted/?start=&end=rn   r   r   rZ   r   rr   rs   re   r  r  rY   ru   rv   r6   r6   r:   deleted     
zSFType.deletedc                 C   r  )a  Gets a list of updated records
        Use the SObject Get Updated resource to get a list of updated
        (modified or added) records for the specified object.
         .../updated/?start=2014-03-20T00:00:00+00:00&end=2014-03-22T00:00:00
         +00:00
        * start -- start datetime object
        * end -- end datetime object
        * headers -- a dict with additional request headers.
        zupdated/?start=r	  rn   r   r
  r  r6   r6   r:   updated  r  zSFType.updatedr   r   r   ru   r   r   c                 K   s   dd| j  dd}|di }||pi  | jj||fd|i|}| jr[| jjdur[|jdkr[| d }	|	d	 d
kr[| j	  |d7 }||krQt
|| jd | j||fi |S |jdkrft
|| j |jd}
|
rtt|
| _|S )zlUtility method for performing HTTP call to Salesforce.

        Returns a `requests.result` object.
        rB   rC   rD   rE   rY   Nr   r   r   r   r   r   r   r   )r$   r   r   r*   r   r   rL   r   r   rQ   r   ro   rr   rY   r{   r    r   ra   )re   r   ru   r   r   rl   rY   r   rv   r   r   r6   r6   r:   rr     sN   


zSFType._call_salesforceresponse	body_flagc                 C   s   |s|j S |S )zUtility method for processing the response and returning either the
        status code or the response object.

        Returns either an `int` or a `requests.Response` object.
        )r   )re   r  r  r6   r6   r:   r    s   
zSFType._raw_responserv   c                 C   r   r   r   r   r6   r6   r:   rs     r   zSFType.parse_result_to_jsonBody	file_pathbase64_fieldc                 K   sB   i }t t|  }|||< | jdd| j||d|}|S )z(Upload base64 encoded file to Salesforcer   )r   ru   rY   r   Nr6   )base64	b64encoder   
read_bytesdecoderr   rZ   )re   r  r  rY   rl   r   bodyrv   r6   r6   r:   upload_base64  s   zSFType.upload_base64c           
      K   sP   i }t t|  }|||< | jddt| j|||d|}	| |	|S )z,Updated base64 image from file to Salesforcer   )r   ru   r   rY   Nr6   )	r  r  r   r  r  rr   r   rZ   r  )
re   r   r  r  rY   r   rl   r   r  rv   r6   r6   r:   update_base641  s   
	zSFType.update_base64c                 K   s2   | j ddt| j| d| ||d|}|jS )zReturns binary stream of base64 object at specific path.

        Arguments:

        * path: The path of the request
            Example: sobjects/Attachment/ABC123/Body
                     sobjects/ContentVersion/ABC123/VersionData
        rn   rI   r   Nr6   )rr   r   rZ   r   )re   r   r  r   rY   rl   rv   r6   r6   r:   
get_base64K  s   
zSFType.get_base64r5   )FN)r   r   )r  N)r  NF)r  NN).r   r   r   r   rb   r   rc   r   rR   r   r   rJ   rK   r    r   r   r   r   rf   r   r$   r   r   rp   r   r{   r   r   r   r   r  r   r   r   r   r  r   r  r  rr   r  rs   r  r  r   r  r6   r6   r6   r:   r}   }  s   	

8








%

#
 


7



r}   )4r   r   r   r  r   loggingr   typingr   r   r   r   r   r   r	   r
   r   r   r   r   collectionsr   	functoolsr   pathlibr   urllib.parser   r   rJ   r   r   r   r   
exceptionsr   r3   r   r   r   utilr   r   r   r   r   r   	getLoggerr   rM   r    r}   r6   r6   r6   r:   <module>   s8    8 
      c