Skip to content

Add RFC6570 Uri Template Support #3

Merged
merged 14 commits into from Apr 10, 2012

3 participants

@kyleconroy

First go at Issue #2. The code isn't too clean, but I have all examples for the RFC6570 spec passing. I'd love to hear what people think. Usage looks like.

URI.from_template("http://example.com/{var}", var="value")
@kyleconroy

Cleaned up the code and added more test cases.

@mwhooker
Python Libs member
mwhooker commented Apr 8, 2012

This looks really awesome. Thanks for the patch.

I don't have too much time to look at it today, but two things stand out: I think the template logic should go in another file, and I don't see an implementation for IRI. The RFC has this to say

Although the URI syntax is used for the result, the template string
is allowed to contain the broader set of characters that can be found
in Internationalized Resource Identifier (IRI) references [RFC3987].
Therefore, a URI Template is also an IRI template, and the result of
template processing can be transformed to an IRI by following the
process defined in Section 3.2 of [RFC3987].

so this should be implementable in "ResourceIdentifier", with IRI and URI handling conversion.

I know we're really low on documentation right now, so it might not be apparent how all the classes are supposed to work, so if you have any questions I can try to answer them later.

@kyleconroy

@mwhooker The template code has been moved into template.py.

I'm a little unsure how to properly handle encodings and conversion for URIs and IRIs. I have two very small tests that are passing, but I'm sure my encoding support is incorrect. Any pointers on correctly handling the differences would be great.

@glyphobet
Python Libs member

Wow, thanks. I think this looks great and should be merged.

The only problem I see is that dictionary keys that are not strs make it blow up:

>>> from uricore import template
>>> template.uri_template(u'{?gro\xdf}', **{u'gro\xdf':u'great',})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "uricore/template.py", line 116, in uri_template
    return re.sub(r"{(.*?)}", template_expansion, template)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/re.py", line 151, in sub
    return _compile(pattern, flags).sub(repl, string, count)
  File "uricore/template.py", line 109, in template_expansion
    uri = [_format_mapping(operator, item) for item in params]
  File "uricore/template.py", line 29, in _format_mapping
    return "{}{}{}".format(k, mid, v)
UnicodeEncodeError: 'ascii' codec can't encode character u'\xdf' in position 3: ordinal not in range(128)

I think this should definitely be supported, as Python programs tend to suffer from unicode/str confusion.

Non-basestring keys are also a problem... I could imagine someone wanting to generate a query string like ?1=foo&2=bar:

>>>template.uri_template(u'{?1}', **{1:u'great',})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: uri_template() keywords must be strings

This would be harder to fix and I'm not sure it follows the spec, or if it's clear what to do in all cases (call repr on every non-basestring key, or what?).

@mwhooker mwhooker merged commit 9dd9704 into core:master Apr 10, 2012
@mwhooker
Python Libs member

@glyphobet added your use cases to tests.

@kyleconroy

@mwhooker @glyphobet Thanks guys, the unicode fix looks perfect

@glyphobet
Python Libs member

No problem. But it only fixes one of the two problems. @mwhooker's test is still failing: http://travis-ci.org/#!/core/uricore/jobs/1062021

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.