系列: ocpp
python
160 行
· 更新於 2025-10-10
schema_to_dataclass.py
ocpp/homework/ocpp_many/scripts/schema_to_dataclass.py
#!/usr/bin/env python
import json
import re
import sys
from pathlib import Path
map_schema_type_to_python = {
"object": "Dict",
"array": "List",
"integer": "int",
"string": "str",
"number": "int",
"boolean": "bool",
"any": "Any",
}
def create_dataclass(name):
return dataclass(name)
def create_attribute(name, type, required):
name = re.sub("([a-z0-9])([A-Z])", r"\1_\2", name).lower()
type = map_schema_type_to_python[type]
return attribute(name, type, required)
class dataclass:
def __init__(self, name):
self.name = name
self.attrs = []
def add_attr(self, attr):
self.attrs.append(attr)
def __str__(self):
output = f"@dataclass\nclass {self.name}Payload:\n"
if len(self.attrs) == 0:
return output + " pass\n"
optional_attrs = ""
for attr in self.attrs:
if attr.required:
output += str(attr)
else:
optional_attrs += str(attr)
return output + optional_attrs
class attribute:
def __init__(self, name, type, required):
self.name = name
self.type = type
self.required = required
def __str__(self):
name = self.name
if not re.match("^[a-zA-Z_]", self.name):
name = "_" + self.name
definition = f" {name}: {self.type}"
if self.required is True:
definition += "\n"
else:
definition += " = None\n"
return definition
def __repr__(self):
return f"<{self.name}, {self.type}, {self.required}> "
calls = []
call_results = []
def parse_schema(schema):
with open(schema, "r") as f:
schema = json.loads(f.read())
name = schema["$id"].split(":")[-1]
call = False
call_result = False
if name.endswith("Request"):
call = True
name = name[: -len("Request")]
elif name.endswith("Response"):
call_result = True
name = name[: -len("Response")]
dc = create_dataclass(name)
try:
properties = schema["properties"]
except KeyError:
if call:
calls.append(dc)
elif call_result:
call_results.append(dc)
return
for property, definition in properties.items():
if property == "customData":
continue
required = True
try:
required = property in schema["required"]
except KeyError:
required = False
try:
type = definition["type"]
except KeyError:
try:
ref = definition["$ref"].split("/")[-1]
type = schema["definitions"][ref]["type"]
except KeyError:
if definition == {}:
type = "any"
attr = create_attribute(property, type, required)
dc.add_attr(attr)
if call:
calls.append(dc)
elif call_result:
call_results.append(dc)
if __name__ == "__main__":
if len(sys.argv) != 2:
print("Pass path to folder with schemas")
sys.exit(-1)
p = Path(sys.argv[1])
schemas = list(p.glob("*.json"))
for schema in schemas:
parse_schema(schema)
with open("call.py", "wb+") as f:
f.write(b"from typing import Any, Dict, List\n")
f.write(b"from dataclasses import dataclass, field, Optional\n")
for call in sorted(calls, key=lambda call: call.name):
f.write(b"\n\n")
f.write(str(call).encode("utf-8"))
with open("call_result.py", "wb+") as f:
f.write(b"from typing import Any, Dict, List\n")
f.write(b"from dataclasses import dataclass, field\n")
for call in sorted(call_results, key=lambda call: call.name):
f.write(b"\n\n")
f.write(str(call).encode("utf-8"))
相關文章
ocpp
python
更新於 2026-02-03
central_system.py
central_system.py — python source code from the ocpp learning materials (ocpp/homework/central_system.py).
閱讀文章 →
ocpp
python
更新於 2026-02-03
charge_point.py
charge_point.py — python source code from the ocpp learning materials (ocpp/homework/ocpp/charge_point.py).
閱讀文章 →
ocpp
python
更新於 2026-02-03
exceptions.py
exceptions.py — python source code from the ocpp learning materials (ocpp/homework/ocpp/exceptions.py).
閱讀文章 →
ocpp
python
更新於 2026-02-03
messages.py
messages.py — python source code from the ocpp learning materials (ocpp/homework/ocpp/messages.py).
閱讀文章 →
ocpp
python
更新於 2026-02-03
routing.py
routing.py — python source code from the ocpp learning materials (ocpp/homework/ocpp/routing.py).
閱讀文章 →
ocpp
python
更新於 2026-02-03
__init__.py
__init__.py — python source code from the ocpp learning materials (ocpp/homework/ocpp/v16/__init__.py).
閱讀文章 →