Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

initial commit with xml and an oauth2 token request helper #84

Closed

Conversation

willplaehn
Copy link
Contributor

Hi Filipe (and Vinta Software),

I enjoyed your talk on Wednesday in NYC. I decided to use Tapioca to write a wrapper for the Google Sheets API. In the process, I implemented approaches to issues #78 and #12 (XML and Get Auth Token for Oauth2).

Please review and let me know if this is close to what you had in mind!

Here are some notes on the implementations:

Addition 1, XML:
1. Added an XMLAdapterMixin. I had a little bit of trouble with the response_to_native() method in combination with etree.ElementTree when the API endpoint was returning errors, my solution was to search for 'xml' in the content-type header and return a different response if it wasn't present.

2. I created a custom dictionary format that can be translated into XML so that it's easy for a developer to type when they're exploring an API. For me, typing out an XML string is pretty bad, and typing out a highly nested dictionary representation of XML can be horrible. The format uses pipes to separate node tags from attributes in the dictionary's keys, and the dictionary's values become the text in-between the XML tags.

**How it works:**Translation to XML is handled in two stages. We use the horrible nested dictionary in-between that maps directly onto the etree.ElementTree.Element object.

The "flat dictionary" format:

{'root|attr1="val 1"': {'subroot1|attr1="sub val 1"': 'sub text 1',
                        'subroot2|attr2="sub val 2"': 'sub text 2'}}

Is translated into the "etree element dictionary" format:

 'attrib': {'attr1': 'val 1'},
 'tag': 'root',
 'tail': None,
 'sub_elts': [
     {'text': 'sub text 1',
      'attrib': {'attr1': 'sub val 1'},
      'tag': 'subroot1',
      'tail': None,
      'sub_elts': None},
     {'text': 'sub text 2',
      'attrib': {'attr2': 'sub val 2'},
      'tag': 'subroot2',
      'tail': None,
      'sub_elts': None}
 ]
}

And is finally translated to the following XML bytes string to be handled by Tapioca:

'<root attr1="val 1">
    <subroot1 attr1="sub val 1">
        sub text 1
    </subroot1>
    <subroot2 attr2="sub val 2">
        sub text 2
    </subroot2>
</root>'

As of now, the response format is returned only in the nested-dictionary format. I think the biggest challenge with handling XML via dictionaries in Tapioca is that developers may want to work directly with XML as either input or output (in addition to the other formats), which is not directly supported. Need to think about how to add those capabilities / amend the existing config requirements without making configuration or branching on input overly confusing or error-prone.

Edit: The latest commit f782f1f attempts to address multiple input and output formats through a single interface. The input is branched based on 4 types of input (etree.Element, string representing XML, nested dictionary, and flat dictionary).

Branching code:

def input_branches_to_xml_bytestring(data):
    if type(data) == ElementTree.Element:
        return ElementTree.tostring(data, encoding='utf-8')
    elif type(data) == str:
        return data.encode('utf-8')
    elif type(data) == bytes:
        return data
    elif type(data) == dict:
        if 'tag' in data.keys():
            return etree_elt_dict_to_xml(data)
        else:
            return etree_elt_dict_to_xml(flat_dict_to_etree_elt_dict(data))
    else:
        raise Exception('Format not recognized')

Addition 2, Token Request:
Here, I followed the Requests-OAuthlib tutorial to make a helper for developers to request their tokens from Oauth services. They just plug in the required fields, follow the instructions, and it returns their token at the end. I haven't looked at this with respect to Oauth token request processes other than Google's.

I think this could go nicely into the cookiecutter since it'll be convenient to type parameters into a file / system variable instead of calling it through the console -- see how it's used in the tapioca-gsheets project.

Thanks for reviewing, and let me know if you'd like to discuss these in more detail or change the approach before considering a merge!

@willplaehn
Copy link
Contributor Author

Closing this PR per conversation and review of xmltodict with Filipe. Splitting and opening one for the token requester, and another for XML using xmltodict.

@willplaehn willplaehn closed this Nov 23, 2015
@willplaehn willplaehn deleted the xml_and_oauth2_helper branch November 24, 2015 23:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant