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
|
import re
HTTP_STATUS_CODES = {
100: "Continue",
101: "Switching Protocols",
102: "Processing",
200: "OK",
201: "Created",
202: "Accepted",
203: "Non Authoritative Information",
204: "No Content",
205: "Reset Content",
206: "Partial Content",
207: "Multi Status",
226: "IM Used", # see RFC 3229
300: "Multiple Choices",
301: "Moved Permanently",
302: "Found",
303: "See Other",
304: "Not Modified",
305: "Use Proxy",
307: "Temporary Redirect",
308: "Permanent Redirect",
400: "Bad Request",
401: "Unauthorized",
402: "Payment Required", # unused
403: "Forbidden",
404: "Not Found",
405: "Method Not Allowed",
406: "Not Acceptable",
407: "Proxy Authentication Required",
408: "Request Timeout",
409: "Conflict",
410: "Gone",
411: "Length Required",
412: "Precondition Failed",
413: "Request Entity Too Large",
414: "Request URI Too Long",
415: "Unsupported Media Type",
416: "Requested Range Not Satisfiable",
417: "Expectation Failed",
418: "I'm a teapot", # see RFC 2324
421: "Misdirected Request", # see RFC 7540
422: "Unprocessable Entity",
423: "Locked",
424: "Failed Dependency",
426: "Upgrade Required",
428: "Precondition Required", # see RFC 6585
429: "Too Many Requests",
431: "Request Header Fields Too Large",
449: "Retry With", # proprietary MS extension
451: "Unavailable For Legal Reasons",
500: "Internal Server Error",
501: "Not Implemented",
502: "Bad Gateway",
503: "Service Unavailable",
504: "Gateway Timeout",
505: "HTTP Version Not Supported",
507: "Insufficient Storage",
510: "Not Extended",
}
SUCCESS_CODE = 200
BAD_REQUEST_CODE = 400
NOT_FOUND_CODE = 404
METHOD_NOT_ALLOWED_CODE = 405
def render_template(path, **kwargs):
with open(path, encoding='utf-8') as f:
template = f.read()
for key in kwargs:
template = template.replace(f'%%{key}%%', kwargs[key])
return template
def parse_query(query):
parsed_query = {'expression': {}, 'condition': {}}
pattern = re.compile(r'(expression|condition)(\d+)_(key|value)')
for key, (value,) in query.items():
match = pattern.fullmatch(key)
if match is not None:
index = int(match.group(2))
if index not in parsed_query[match.group(1)]:
parsed_query[match.group(1)][index] = {}
parsed_query[match.group(1)][index][match.group(3)] = value
expressions = []
for expression in parsed_query['expression'].values():
expressions.append('`{}`="{}"'.format(
expression['key'], expression['value']
))
expressions = ','.join(expressions)
conditions = []
for condition in parsed_query['condition'].values():
conditions.append('`{}`="{}"'.format(
condition['key'], condition['value']
))
conditions = ' AND '.join(conditions)
return {'expressions': expressions, 'conditions': conditions}
|