Skip to content

Commit e067646

Browse files
committed
Readme for Python multiapi helper
1 parent 36406da commit e067646

File tree

1 file changed

+122
-0
lines changed

1 file changed

+122
-0
lines changed

scripts/multi_api_readme_help.py

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
import json
2+
import logging
3+
from pathlib import Path
4+
import sys
5+
6+
7+
_LOGGER = logging.getLogger(__name__)
8+
9+
_TAG_PREFIX = """### Tag: package-{api_version}-only
10+
11+
These settings apply only when `--tag=package-{api_version}-only` is specified on the command line.
12+
13+
```yaml $(tag) == 'package-{api_version}-only'
14+
input-file:"""
15+
_TAG_SUFFIX = "```\n\n"
16+
17+
_BATCH_PREFIX = """```yaml $(python) && $(multiapi)
18+
batch:"""
19+
_BATCH_SUFFIX = "```\n\n"
20+
21+
_PY_NAMESPACE = """### Tag: package-{api_version}-only and python
22+
23+
These settings apply only when `--tag=package-{api_version}-only --python` is specified on the command line.
24+
Please also specify `--python-sdks-folder=<path to the root directory of your azure-sdk-for-python clone>`.
25+
26+
``` yaml $(tag) == 'package-{api_version}-only' && $(python)
27+
python:
28+
namespace: $(python-base-namespace).{ns}
29+
output-folder: $(python-sdks-folder)/$(python-base-folder)/{ns}
30+
```
31+
"""
32+
33+
def get_api_versions(root):
34+
35+
api_versions = {}
36+
prefixes_per_path = {}
37+
38+
rp_folders = root.glob("Microsoft.*")
39+
for rp_folder in rp_folders:
40+
_LOGGER.info(f"Parsing folder {rp_folder}")
41+
for preview_stable in rp_folder.iterdir():
42+
_LOGGER.info(f"Currently in {preview_stable}")
43+
for api_version in preview_stable.iterdir():
44+
_LOGGER.info(f"Currently in {api_version}")
45+
for swagger in api_version.glob("*.json"):
46+
prefixes_per_path[swagger] = parse_swagger(swagger)
47+
api_versions.setdefault(api_version.name, []).append(swagger.relative_to(root).as_posix())
48+
49+
# Try to detect when it's problematic. That's tough, the following logic is definitely
50+
# not handling all the touch parts yet...
51+
52+
# 1- If a file declare several prefixes, let's warning
53+
for swagger_path, prefixed_used in prefixes_per_path.items():
54+
if len(prefixed_used) == 1:
55+
_LOGGER.info(f"File {swagger_path} uses only one prefix: {prefixed_used}")
56+
else:
57+
_LOGGER.warn(f"File {swagger_path} uses several prefixes: {prefixed_used}")
58+
59+
60+
# Let's print
61+
print_tags(api_versions)
62+
print_batch(api_versions)
63+
print_python_namespace(api_versions)
64+
65+
def print_tags(api_versions):
66+
for api_version in sorted(api_versions.keys(), reverse=True):
67+
swagger_files = api_versions[api_version]
68+
print(_TAG_PREFIX.format(api_version=api_version))
69+
for swagger_file in swagger_files:
70+
print("- {}".format(swagger_file))
71+
print(_TAG_SUFFIX)
72+
73+
74+
def print_batch(api_versions):
75+
print(_BATCH_PREFIX)
76+
for api_version in sorted(api_versions.keys(), reverse=True):
77+
print(f" - tag: package-{api_version}-only")
78+
print(_BATCH_SUFFIX)
79+
80+
def print_python_namespace(api_versions):
81+
for api_version in sorted(api_versions.keys(), reverse=True):
82+
swagger_files = api_versions[api_version]
83+
print(_PY_NAMESPACE.format(
84+
api_version=api_version,
85+
ns="v"+api_version.replace("-", "_"))
86+
)
87+
88+
def parse_swagger(swagger_path):
89+
_LOGGER.info(f"Parsing {swagger_path}")
90+
with swagger_path.open() as swagger:
91+
parsed_swagger = json.load(swagger)
92+
93+
api_version = parsed_swagger["info"]["version"]
94+
95+
operations = operation_finder(parsed_swagger)
96+
97+
prefixed_used = {op.split("_")[0] for op in operations if "_" in op}
98+
return prefixed_used
99+
100+
def operation_finder(swagger_root):
101+
result = set()
102+
for key, node in swagger_root.items():
103+
if key == "definitions": # Skipping some node
104+
return result
105+
if key == "operationId":
106+
result.add(node)
107+
# Can skip it now, only one operationId per node
108+
return result
109+
if isinstance(node, dict):
110+
result |= operation_finder(node)
111+
return result
112+
113+
114+
if __name__ == "__main__":
115+
logging.basicConfig(level=logging.DEBUG if "--debug" in sys.argv else logging.WARNING)
116+
117+
root = Path(__file__).parent
118+
119+
root = Path(sys.argv[1]).relative_to(root)
120+
121+
_LOGGER.info(f"My root: {root}")
122+
get_api_versions(root)

0 commit comments

Comments
 (0)