aboutsummaryrefslogtreecommitdiff
path: root/uritemplate/template.py
blob: c37f45b4f863d2148f816f9132b15e7bae501d76 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
"""

uritemplate.template
====================

This module contains the essential inner workings of uritemplate.

What treasures await you:

- URITemplate class
- URIVariable class

"""
try:
    from urllib import quote
except ImportError:
    # python 3
    from urllib.parse import quote

import re

template_re = re.compile('{([^\}]+)}')


class URITemplate(object):
    """The :class:`URITemplate <URITemplate>` object is the central object to
    uritemplate. This parses the template and will be used to expand it.

    Example::

        from uritemplate import URITemplate
        import requests


        t = URITemplate(
            'https://api.github.com/users/sigmavirus24/gists{/gist_id}'
        )
        uri = t.expand(gist_id=123456)
        resp = requests.get(uri)
        for gist in resp.json():
            print(gist['html_url'])

    """
    def __init__(self, uri):
        self.uri = uri
        self.var_list = [
            URIVariable(m.groups()[0]) for m in template_re.finditer(self.uri)
        ]

    def __repr__(self):
        return 'URITemplate({0})'.format(self.uri)

    def expand(self, *args, **kwargs):
        pass


class URIVariable(object):
    """The :class:`URIVariable <URIVariable>` object validates everything
    underneath the Template object. It validates template expansions and will
    truncate length as decided by the template.
    """

    operators = ('+', '#', '.', '/', ';', '?', '&', '|', '!', '@')
    reserved = ":/?#[]@!$&'()*+,;="

    def __init__(self, var):
        self.original = var
        self.operator = None
        self.safe = '/'
        self.vars = []
        #self.parse()

    def __repr__(self):
        return 'URIVariable({0})'.format(self.original)

    def parse(self):
        if self.original[0] in URIVariable.operators:
            self.operator = self.orig[0]

        if self.operator in URIVariable.operators[:2]:
            self.safe = URIVariable.reserved
            var_list = self.original[1:].split(',')
        else:
            var_list = self.original.split(',')

        self.defaults = {}
        for var in var_list:
            default_val = None
            name = var
            if '=' in var:
                name, default_val = tuple(var.split('=', 1))

            explode = True if name.endswith('*') else False

            prefix_index = name.index(':')
            if prefix_index > 0:
                prefix = int(name[prefix_index + 1:])
                name = name[:prefix_index]

            if default_val:
                self.defaults[name] = default_val

            self.vars.append((name, {'explode': explode, 'prefix': prefix}))

    def expand(self, *args, **kwargs):
        args = [quote(a, self.safe) for a in args]
        kwargs = dict((k, quote(v)) for k, v in kwargs.items())