forked from WebexCommunity/WebexPythonSDK
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgenerate.py
More file actions
171 lines (139 loc) · 5.09 KB
/
Copy pathgenerate.py
File metadata and controls
171 lines (139 loc) · 5.09 KB
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
import os
import yaml
import argparse
from jinja2 import Environment, FileSystemLoader
from utils import get_additional_parameters
from exceptions import MissingKeyError
def render_prop_mixin(
env: Environment,
name: str,
properties: list,
base_name: str,
template_name: str = "mixins.py",
path_prefix: str = "../webexteamssdk/models/mixins/",
) -> str:
"""Renders a simple property mixin for the SDK based on the
information provided in the descriptor file.
Args:
env(Environment): The jinja environment to render under. Defines
the templates that will be used.
name(str): The name of our endpoint. Will be turned into the class
name as {name}SimplePropertyMixin.
properties(list): List of property extracted from the list.properties
key in the descriptor file.
base_name(str): Base name of the descriptor file. Used to generate
the filenames.
template_name(str): Name of the template to use. Default: mixins.py
path_prefix(str): Path to the mixins folder.
Default: ../webexteamssdk/models/mixins/
Returns:
str: Path to the generated
"""
# Render template based on loaded properties
tmpl = env.get_template(template_name)
out = tmpl.render(name=name, properties=properties)
target_path = os.path.join(path_prefix, f"{base_name}.py")
with open(target_path, "w") as fh:
fh.writelines(out)
return target_path
def render_api_class(
env: Environment,
descr: dict,
base_name: str,
template_name: str = "api.py",
path_prefix: str = "../webexteamssdk/api/",
) -> str:
"""Renders an API class based on the properties described in
the descr file.
Args:
env(Environment): The jinja environment to render under. Defines
the templates that will be used.
descr(dict): Descriptor parsed from the yaml file defining the
properties of the endpoint and target api model.
base_name(str): Base name of the descriptor file. Used to generate
the filenames.
template_name(str): Name of the template to use. Default: api.py
path_prefix(str): Path to the target api folder that the output will
we placed in. Default: ../webexteamssdk/api/
Returns:
str: The path to the generated api class
"""
create_parameters = get_additional_parameters(descr, "create")
update_parameters = get_additional_parameters(descr, "update")
additional_code = descr.get("additional_code", None)
# Render template
tpl = env.get_template(template_name)
out = tpl.render(
name=descr['name'],
endpoint=descr['endpoint'],
object_type=descr['object_type'],
url_parameters=descr['url_parameters'],
query_parameters=descr['query_parameters'],
create_parameters=create_parameters,
update_parameters=update_parameters,
methods=descr['methods'],
additional_code=additional_code,
)
target_path = os.path.join(path_prefix, f"{base_name}.py")
with open(target_path, "w") as fh:
fh.writelines(out)
return target_path
def main():
# Setup arg parser
parser = argparse.ArgumentParser(
description="Generate new endpoints for the SDK"
)
parser.add_argument(
"-d",
"--descriptor",
help="Path to the descriptor .yaml file",
type=str,
required=True,
)
parser.add_argument(
"-t",
"--template_dir",
help="Path to the templates directory",
type=str,
default="templates",
required=False,
)
args = parser.parse_args()
# Setup jinja environment and load information from description file
env = Environment(loader=FileSystemLoader(args.template_dir))
descr_file = args.descriptor
base_name = os.path.splitext(os.path.basename(descr_file))[0]
descr = yaml.safe_load(open(descr_file))
# Check that all required keys are present
required_keys = [
"name",
"list.properties",
"endpoint",
"object_type",
"query_parameters",
"methods",
]
for key in required_keys:
# Check all keys - subkeys (i.e. d['list']['properties']
# can be passed in dot notation, so list.properties)
keys = key.split(".")
d = descr
for sub_key in keys:
if sub_key not in d.keys():
raise MissingKeyError(f"Missing required key '{key}'")
else:
d = d.get(sub_key)
# Add empty url_parameters key if there are no URL parameters defined
if 'url_parameters' not in descr.keys():
descr['url_parameters'] = []
mixin_path = render_prop_mixin(
env=env,
name=descr["name"],
properties=descr["list"]["properties"],
base_name=base_name,
)
print(f"Rendered mixin for {descr['name']} to {mixin_path}")
api_path = render_api_class(env=env, descr=descr, base_name=base_name)
print(f"Rendered api class for {descr['name']} to {api_path}")
if __name__ == "__main__":
main()