Skip to content

Instantly share code, notes, and snippets.

@av1m
Last active September 19, 2021 02:19
Show Gist options
  • Save av1m/6986f6644e643174edf217fdee1dd50b to your computer and use it in GitHub Desktop.
Save av1m/6986f6644e643174edf217fdee1dd50b to your computer and use it in GitHub Desktop.
Create pydantic model from meraki openapi
""" Create pydantic model from meraki openapi specifications
OpenAPI specification is available at: https://github.com/meraki/openapi
Requirements for this script:
- requests
- datamodel-code-generator
Command to run this script:
- python3 generate_schema.py
Author:
- @av1m
"""
import requests
from pathlib import Path
from tempfile import TemporaryDirectory
from datamodel_code_generator import InputFileType, generate
import json
import re
from copy import deepcopy
def camel_to_snake(name): # https://stackoverflow.com/a/1176023/11120444
name_copy = deepcopy(name)
name_copy = re.sub("(.)([A-Z][a-z]+)", r"\1_\2", name_copy)
return re.sub("([a-z0-9])([A-Z])", r"\1_\2", name_copy).lower()
# Retrieve the meraki openapi specifications
specs = requests.get(
"https://raw.githubusercontent.com/meraki/openapi/master/openapi/spec2.json"
).json()
submodules = []
for path in specs.get("paths"):
spec = specs.get("paths").get(path)
for method in spec:
operation_id = spec.get(method).get("operationId")
filename = camel_to_snake(operation_id) + "_" + method
classname = operation_id + method.upper()
responses = spec.get(method).get("responses")
submodules.append(f"from {filename}.py import {classname}\n")
if len(responses) != 1:
raise Exception(str(responses))
# actually, there is always a unique response
status_code = list(responses.keys())[0]
if "examples" not in responses.get(status_code):
print(f"Can't gather the example for {method.upper()} {operation_id}")
continue
json_response = responses.get(status_code)["examples"]["application/json"]
json_schema = json.dumps(json_response)
schemas_directory = Path("./schemas/")
schemas_directory.mkdir(parents=True, exist_ok=True)
output = Path(schemas_directory / (filename + ".py"))
generate(
json_schema,
input_file_type=InputFileType.Json,
input_filename=filename + ".json",
class_name=classname,
output=output,
snake_case_field=True,
)
# print(output.read_text())
with open("./schemas/__init__.py", "w") as out:
out.writelines(submodules)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment