Search code examples
pythonxmlfunctioniteratorapi-design

How to iterate through XML values to make XML API call with iterative values?


I am working on a project to extract data via this API (http://www.yourmembership.com/company/api-reference/). The API requires that the calls be made via XML. I have successfully been able to make calls and retrieve data back via HTTP response object using the 'requests' library in python.

My question is I want to develop a function that will iterate through IDs from one API call and plug them into another function which will make iterative API calls to get more data back about each ID.

For example the script I have now gives me a dump of all event IDs:

import requests

xml ="""

<?xml version="1.0" encoding="UTF-8"?>
<YourMembership>
   <Version>2.25</Version>
   <ApiKey></ApiKey>
   <CallID>008</CallID>
   <></>
   <SaPasscode></SaPasscode>
   <Call Method = "Sa.Events.All.GetIDs">
       <StartDate>2017/01/1</StartDate>
       <EndDate>2017/12/31</EndDate>
   </Call>
</YourMembership>
"""


headers = {'Content-Type': 'application/x-www-form-urlencoded'}
r = requests.post('https://api.yourmembership.com', data=xml,headers=headers)
print(r.text)

The response looks like this(no child objects)for 'print(r.text)':

<EventID>12345</EventID>
<EventID>67890</EventID>
<EventID>24680</EventID>
<EventID>13579</EventID>
<EventID>08642</EventID>

How can I take these event_IDs and iterate through the response object and plug them into this function below(function is not complete, rough draft) and get info for each event_ID by making iterative XML API calls by somehow plugging values for the field ?

import requests
def xml_event_info():
xml ="""

<?xml version="1.0" encoding="UTF-8"?>
<YourMembership>
   <Version>2.25</Version>
   <ApiKey>xxx-xxx</ApiKey>
   <CallID>001</CallID>
   <></>
   <SaPasscode>xxxx</SaPasscode>
   <Call Method = "Sa.Events.Event.Get">
       <EventID>12345</EventID>
   </Call>
</YourMembership>
"""


headers = {'Content-Type': 'application/x-www-form-urlencoded'}
r = requests.post('https://api.yourmembership.com', data=xml,headers=headers)
print(r.text)

Thank you in advance, please let me know if my question does not make sense.

EDIT:

<YourMembership_Response>
<ErrCode>0</ErrCode>
<ExtendedErrorInfo></ExtendedErrorInfo>
<Sa.Events.All.GetIDs>
<EventID>98765</EventID>
</Sa.Events.All.GetIDs>
</YourMembership_Response>

Solution

  • Consider interfacing Python's built-in etree to parse the YM_Response and extract the EventID text as seen in example:

    import xml.etree.ElementTree as et
    
    txt="""
    <YourMembership_Response>
        <ErrCode>0</ErrCode>
        <ExtendedErrorInfo></ExtendedErrorInfo>
        <Sa.Events.All.GetIDs>
            <EventID>98765</EventID>
        </Sa.Events.All.GetIDs>
    </YourMembership_Response>
    """
    
    dom = et.fromstring(txt)
    
    for i in dom.iterfind('.//EventID'):    
        print(i.text)   
    # 98765
    

    Altogether, iteratively call your method passing Event IDs as a parameter that is then string formatted to XML string. See curly brace inside XML string and then .format in the requests line:

    import requests
    import xml.etree.ElementTree as et
    
    def xml_event_info(eventID):       
        xml ='''        
        <?xml version="1.0" encoding="UTF-8"?>
        <YourMembership>
           <Version>2.25</Version>
           <ApiKey>xxx-xxx</ApiKey>
           <CallID>001</CallID>
           <></>
           <SaPasscode>xxxx</SaPasscode>
           <Call Method = "Sa.Events.Event.Get">
               <EventID>{}</EventID>
           </Call>
        </YourMembership>        
        '''        
        headers = {'Content-Type': 'application/x-www-form-urlencoded'}
        r = requests.post('https://api.yourmembership.com', 
                          data=xml.format(eventID), headers=headers)        
        print(r.text)      
    
    
    xml ='''    
    <?xml version="1.0" encoding="UTF-8"?>
    <YourMembership>
       <Version>2.25</Version>
       <ApiKey>xxxxx</ApiKey>
       <CallID>008</CallID>
       <></>
       <SaPasscode>xxxx</SaPasscode>
       <Call Method = "Sa.Events.All.GetIDs">
           <StartDate>2017/01/1</StartDate>
           <EndDate>2017/12/31</EndDate>
       </Call>
    </YourMembership>
    '''        
    headers = {'Content-Type': 'application/x-www-form-urlencoded'}
    r = requests.post('https://api.yourmembership.com', data=xml, headers=headers)
    
    # BUILD XML TREE OBJECT    
    dom = et.fromstring(r.text)
    
    # PARSE EVENT ID TEXT AND PASS INTO FUNCTION
    for i in dom.iterfind('.//EventID'):    
        xml_event_info(i.text)