-
Notifications
You must be signed in to change notification settings - Fork 11
/
patterns.py
57 lines (46 loc) · 1.66 KB
/
patterns.py
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
import re
import uuid
from datetime import date, datetime
def parse_date(d) -> date:
return datetime.strptime(d, "%Y-%m-%d").date()
def alpha(param: str) -> str:
if not param.isalpha():
raise ValueError(f"Value {param} contains non-alphabetic chracters")
return param
def slug(param: str) -> str:
if not REGEX_TYPES["slug"][1].match(param):
raise ValueError(f"Value {param} does not match the slug format")
return param
def nonemptystr(param: str) -> str:
if not param:
raise ValueError(f"Value {param} is an empty string")
return param
REGEX_PARAM_NAME = re.compile(r"^<([a-zA-Z_][a-zA-Z0-9_]*)(?::(.*))?>$")
# Predefined path parameter types. The value is a tuple consisteing of a
# callable and a compiled regular expression.
# The callable should:
# 1. accept a string input
# 2. cast the string to desired type
# 3. raise ValueError if it cannot
# The regular expression is generally NOT used. Unless the path is forced
# to use regex patterns.
REGEX_TYPES = {
"strorempty": (str, re.compile(r"^[^/]*$")),
"str": (nonemptystr, re.compile(r"^[^/]+$")),
"slug": (slug, re.compile(r"^[a-z0-9]+(?:-[a-z0-9]+)*$")),
"alpha": (alpha, re.compile(r"^[A-Za-z]+$")),
"path": (str, re.compile(r"^[^/]?.*?$")),
"float": (float, re.compile(r"^-?(?:\d+(?:\.\d*)?|\.\d+)$")),
"int": (int, re.compile(r"^-?\d+$")),
"ymd": (
parse_date,
re.compile(r"^([12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01]))$"),
),
"uuid": (
uuid.UUID,
re.compile(
r"^[A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-"
r"[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}$"
),
),
}