78 lines
2.7 KiB
Python
78 lines
2.7 KiB
Python
from typing import Dict, List, Optional, Union
|
|
from urllib.parse import urlparse
|
|
|
|
from heroserver.openrpc.generator.code.lang_code_generator import LangCodeGenerator
|
|
from heroserver.openrpc.generator.model.model_generator import ModelGenerator
|
|
|
|
from heroserver.openrpc.model.common import (
|
|
ContentDescriptorObject,
|
|
ReferenceObject,
|
|
)
|
|
from heroserver.openrpc.model.openrpc_spec import OpenRPCSpec
|
|
|
|
|
|
class ClientGenerator:
|
|
def __init__(
|
|
self,
|
|
spec: OpenRPCSpec,
|
|
lang_code_generator: LangCodeGenerator,
|
|
output_file: str,
|
|
) -> None:
|
|
self.spec = spec
|
|
self.model_generator = ModelGenerator(spec, lang_code_generator)
|
|
self.lang_code_generator = lang_code_generator
|
|
self.output_file = output_file
|
|
|
|
def generate_client(self):
|
|
code_pre = self.lang_code_generator.generate_imports()
|
|
code_models = self.model_generator.generate_models()
|
|
code_methods = self.generate_methods()
|
|
|
|
# Write the generated code to a file
|
|
with open(self.output_file, "w") as file:
|
|
file.write(code_pre)
|
|
file.write("\n")
|
|
file.write(code_models)
|
|
file.write("\n")
|
|
file.write(code_methods)
|
|
|
|
print(f"Generated API code has been written to {self.output_file}")
|
|
|
|
def generate_methods(self):
|
|
servers = self.spec.servers
|
|
base_url = "http://localhost:8000"
|
|
if servers:
|
|
base_url = servers[0].url
|
|
|
|
url = urlparse(base_url)
|
|
methods = []
|
|
for method_spec in self.spec.methods:
|
|
params: Dict[str, str] = {}
|
|
for param in method_spec.params:
|
|
params[param.name] = self.model_generator.jsonschema_to_type(
|
|
["methods", method_spec.name, "params", param.name],
|
|
param.schema,
|
|
)
|
|
|
|
return_type = self.method_result_return_type(["methods", method_spec.name, "result"], method_spec.result)
|
|
methods.append(self.lang_code_generator.generate_method(method_spec, url, params, return_type))
|
|
|
|
return "\n\n".join(methods)
|
|
|
|
def method_result_return_type(
|
|
self,
|
|
path: List[str],
|
|
method_result: Optional[Union[ContentDescriptorObject, ReferenceObject]],
|
|
) -> str:
|
|
if not method_result:
|
|
type_name = ""
|
|
|
|
if isinstance(method_result, ContentDescriptorObject):
|
|
schema = method_result.schema
|
|
type_name = self.model_generator.jsonschema_to_type(path, schema)
|
|
|
|
elif isinstance(method_result, ReferenceObject):
|
|
type_name = self.model_generator.jsonschema_to_type(path, method_result)
|
|
|
|
return type_name
|