...
This commit is contained in:
55
_archive/openrpc/model/__init__.py
Normal file
55
_archive/openrpc/model/__init__.py
Normal file
@@ -0,0 +1,55 @@
|
||||
import json
|
||||
|
||||
import yaml # type: ignore
|
||||
|
||||
from heroserver.openrpc.model.openrpc_spec import OpenRPCSpec
|
||||
|
||||
# def decode_openrpc(yaml_string: str) -> dict:
|
||||
# # TODO:
|
||||
# pass
|
||||
|
||||
|
||||
# def encode_openrpc(openrpc_object: dict) -> str:
|
||||
# # TODO:
|
||||
# pass
|
||||
|
||||
|
||||
def decode_openrpc_yaml(yaml_string: str) -> OpenRPCSpec:
|
||||
# Parse YAML string into a Python dict and then convert it into an OpenRPCObject using Pydantic
|
||||
data = yaml.safe_load(yaml_string)
|
||||
return OpenRPCSpec.load(data)
|
||||
|
||||
|
||||
def encode_openrpc_yaml(openrpc_object: OpenRPCSpec) -> str:
|
||||
# Convert the OpenRPCObject instance to a dictionary and then dump it to a YAML string
|
||||
return yaml.dump(openrpc_object.__dict__, sort_keys=False, allow_unicode=True)
|
||||
|
||||
|
||||
def decode_openrpc_json(json_string: str) -> OpenRPCSpec:
|
||||
d = json.loads(json_string)
|
||||
return OpenRPCSpec.load(d)
|
||||
|
||||
|
||||
def encode_openrpc_json(openrpc_object: OpenRPCSpec) -> str:
|
||||
# Convert the OpenRPCObject instance to a dictionary and then dump it to a JSON string
|
||||
return json.dumps(openrpc_object, indent=4)
|
||||
|
||||
|
||||
# check that the dict is well formatted
|
||||
def check(openrpc_spec: dict) -> bool:
|
||||
# todo, try to load the dict in openrpc object
|
||||
json_spec = json.dumps(openrpc_spec)
|
||||
try:
|
||||
decode_openrpc_json(json_spec)
|
||||
except:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from heroserver.openrpc.parser.cleaner import load
|
||||
from heroserver.openrpc.parser.parser import parser
|
||||
|
||||
openrpc_spec = parser(load("/root/code/git.threefold.info/projectmycelium/hero_server/lib/openrpclib/parser/examples"))
|
||||
|
||||
print(check(openrpc_spec))
|
329
_archive/openrpc/model/common.py
Normal file
329
_archive/openrpc/model/common.py
Normal file
@@ -0,0 +1,329 @@
|
||||
from typing import Any, Dict, List, Optional, Union
|
||||
|
||||
|
||||
class ReferenceObject:
|
||||
def __init__(self, ref: str = ""):
|
||||
self.ref = ref
|
||||
|
||||
@classmethod
|
||||
def load(cls, data: Dict[str, Any]) -> "ReferenceObject":
|
||||
return cls(ref=data.get("$ref", ""))
|
||||
|
||||
|
||||
class SchemaObject:
|
||||
def __init__(
|
||||
self,
|
||||
title: Optional[str] = None,
|
||||
multipleOf: Optional[float] = None,
|
||||
maximum: Optional[float] = None,
|
||||
exclusiveMaximum: Optional[bool] = None,
|
||||
minimum: Optional[float] = None,
|
||||
exclusiveMinimum: Optional[bool] = None,
|
||||
maxLength: Optional[int] = None,
|
||||
minLength: Optional[int] = None,
|
||||
pattern: Optional[str] = None,
|
||||
maxItems: Optional[int] = None,
|
||||
minItems: Optional[int] = None,
|
||||
uniqueItems: Optional[bool] = None,
|
||||
maxProperties: Optional[int] = None,
|
||||
minProperties: Optional[int] = None,
|
||||
required: Optional[List[str]] = None,
|
||||
enum: Optional[List[Any]] = None,
|
||||
type: Optional[str] = None,
|
||||
allOf: Optional[List[Union["SchemaObject", ReferenceObject]]] = None,
|
||||
oneOf: Optional[List[Union["SchemaObject", ReferenceObject]]] = None,
|
||||
anyOf: Optional[List[Union["SchemaObject", ReferenceObject]]] = None,
|
||||
not_: Optional[Union["SchemaObject", ReferenceObject]] = None,
|
||||
items: Optional[
|
||||
Union[
|
||||
"SchemaObject",
|
||||
ReferenceObject,
|
||||
List[Union["SchemaObject", ReferenceObject]],
|
||||
]
|
||||
] = None,
|
||||
properties: Optional[Dict[str, Union["SchemaObject", ReferenceObject]]] = None,
|
||||
additionalProperties: Optional[Union[bool, "SchemaObject"]] = None,
|
||||
description: Optional[str] = None,
|
||||
format: Optional[str] = None,
|
||||
default: Optional[Any] = None,
|
||||
xtags: Optional[List[str]] = None,
|
||||
example: Optional[str] = None,
|
||||
):
|
||||
self.title = title
|
||||
self.multipleOf = multipleOf
|
||||
self.maximum = maximum
|
||||
self.exclusiveMaximum = exclusiveMaximum
|
||||
self.minimum = minimum
|
||||
self.exclusiveMinimum = exclusiveMinimum
|
||||
self.maxLength = maxLength
|
||||
self.minLength = minLength
|
||||
self.pattern = pattern
|
||||
self.maxItems = maxItems
|
||||
self.minItems = minItems
|
||||
self.uniqueItems = uniqueItems
|
||||
self.maxProperties = maxProperties
|
||||
self.minProperties = minProperties
|
||||
self.required = required
|
||||
self.enum = enum
|
||||
self.type = type
|
||||
self.allOf = allOf
|
||||
self.oneOf = oneOf
|
||||
self.anyOf = anyOf
|
||||
self.not_ = not_
|
||||
self.items = items
|
||||
self.properties = properties
|
||||
self.additionalProperties = additionalProperties
|
||||
self.description = description
|
||||
self.format = format
|
||||
self.default = default
|
||||
self.xtags = xtags
|
||||
self.example = example
|
||||
|
||||
@classmethod
|
||||
def load(cls, data: Dict[str, Any]) -> "SchemaObject":
|
||||
return cls(
|
||||
title=data.get("title"),
|
||||
multipleOf=data.get("multipleOf"),
|
||||
maximum=data.get("maximum"),
|
||||
exclusiveMaximum=data.get("exclusiveMaximum"),
|
||||
minimum=data.get("minimum"),
|
||||
exclusiveMinimum=data.get("exclusiveMinimum"),
|
||||
maxLength=data.get("maxLength"),
|
||||
minLength=data.get("minLength"),
|
||||
pattern=data.get("pattern"),
|
||||
maxItems=data.get("maxItems"),
|
||||
minItems=data.get("minItems"),
|
||||
uniqueItems=data.get("uniqueItems"),
|
||||
maxProperties=data.get("maxProperties"),
|
||||
minProperties=data.get("minProperties"),
|
||||
required=data.get("required"),
|
||||
enum=data.get("enum"),
|
||||
type=data.get("type"),
|
||||
allOf=(
|
||||
[
|
||||
(
|
||||
ReferenceObject.load(item)
|
||||
if "$ref" in item
|
||||
else SchemaObject.load(item)
|
||||
)
|
||||
for item in data.get("allOf", [])
|
||||
]
|
||||
if "allOf" in data
|
||||
else None
|
||||
),
|
||||
oneOf=(
|
||||
[
|
||||
(
|
||||
ReferenceObject.load(item)
|
||||
if "$ref" in item
|
||||
else SchemaObject.load(item)
|
||||
)
|
||||
for item in data.get("oneOf", [])
|
||||
]
|
||||
if "oneOf" in data
|
||||
else None
|
||||
),
|
||||
anyOf=(
|
||||
[
|
||||
(
|
||||
ReferenceObject.load(item)
|
||||
if "$ref" in item
|
||||
else SchemaObject.load(item)
|
||||
)
|
||||
for item in data.get("anyOf", [])
|
||||
]
|
||||
if "anyOf" in data
|
||||
else None
|
||||
),
|
||||
not_=(
|
||||
(
|
||||
ReferenceObject.load(data)
|
||||
if "$ref" in data
|
||||
else SchemaObject.load(data)
|
||||
)
|
||||
if "not" in data
|
||||
else None
|
||||
),
|
||||
items=(
|
||||
(
|
||||
ReferenceObject.load(data["items"])
|
||||
if "$ref" in data["items"]
|
||||
else SchemaObject.load(data["items"])
|
||||
)
|
||||
if isinstance(data.get("items"), dict)
|
||||
else (
|
||||
[
|
||||
(
|
||||
ReferenceObject.load(item)
|
||||
if "$ref" in item
|
||||
else SchemaObject.load(item)
|
||||
)
|
||||
for item in data.get("items", [])
|
||||
]
|
||||
if "items" in data
|
||||
else None
|
||||
)
|
||||
),
|
||||
properties=(
|
||||
{
|
||||
k: (
|
||||
ReferenceObject.load(v) if "$ref" in v else SchemaObject.load(v)
|
||||
)
|
||||
for k, v in data.get("properties", {}).items()
|
||||
}
|
||||
if "properties" in data
|
||||
else None
|
||||
),
|
||||
additionalProperties=(
|
||||
SchemaObject.load(data["additionalProperties"])
|
||||
if isinstance(data.get("additionalProperties"), dict)
|
||||
else data.get("additionalProperties")
|
||||
),
|
||||
description=data.get("description"),
|
||||
format=data.get("format"),
|
||||
default=data.get("default"),
|
||||
xtags=data.get("x-tags"),
|
||||
example=data.get("example"),
|
||||
)
|
||||
|
||||
|
||||
class ContentDescriptorObject:
|
||||
def __init__(
|
||||
self,
|
||||
name: str,
|
||||
schema: Union[SchemaObject, ReferenceObject],
|
||||
summary: Optional[str] = None,
|
||||
description: Optional[str] = None,
|
||||
required: Optional[bool] = None,
|
||||
deprecated: Optional[bool] = None,
|
||||
):
|
||||
self.name = name
|
||||
self.summary = summary
|
||||
self.description = description
|
||||
self.required = required
|
||||
self.schema = schema
|
||||
self.deprecated = deprecated
|
||||
|
||||
@classmethod
|
||||
def load(cls, data: Dict[str, Any]) -> "ContentDescriptorObject":
|
||||
return cls(
|
||||
name=data["name"],
|
||||
summary=data.get("summary"),
|
||||
description=data.get("description"),
|
||||
required=data.get("required"),
|
||||
schema=(
|
||||
ReferenceObject.load(data["schema"])
|
||||
if "$ref" in data["schema"]
|
||||
else SchemaObject.load(data["schema"])
|
||||
),
|
||||
deprecated=data.get("deprecated"),
|
||||
)
|
||||
|
||||
|
||||
class ExternalDocumentationObject:
|
||||
def __init__(self, url: str, description: Optional[str] = None):
|
||||
self.description = description
|
||||
self.url = url
|
||||
|
||||
@classmethod
|
||||
def load(cls, data: Dict[str, Any]) -> "ExternalDocumentationObject":
|
||||
return cls(description=data.get("description"), url=data["url"])
|
||||
|
||||
|
||||
class ExampleObject:
|
||||
def __init__(
|
||||
self,
|
||||
name: str,
|
||||
summary: Optional[str] = None,
|
||||
description: Optional[str] = None,
|
||||
value: Optional[Any] = None,
|
||||
externalValue: Optional[str] = None,
|
||||
):
|
||||
self.name = name
|
||||
self.summary = summary
|
||||
self.description = description
|
||||
self.value = value
|
||||
self.externalValue = externalValue
|
||||
|
||||
@classmethod
|
||||
def load(cls, data: Dict[str, Any]) -> "ExampleObject":
|
||||
return cls(
|
||||
name=data["name"],
|
||||
summary=data.get("summary"),
|
||||
description=data.get("description"),
|
||||
value=data.get("value"),
|
||||
externalValue=data.get("externalValue"),
|
||||
)
|
||||
|
||||
|
||||
class ErrorObject:
|
||||
def __init__(self, code: int, message: str, data: Optional[Any] = None):
|
||||
self.code = code
|
||||
self.message = message
|
||||
self.data = data
|
||||
|
||||
@classmethod
|
||||
def load(cls, data: Dict[str, Any]) -> "ErrorObject":
|
||||
return cls(code=data["code"], message=data["message"], data=data.get("data"))
|
||||
|
||||
|
||||
class ExamplePairingObject:
|
||||
def __init__(
|
||||
self,
|
||||
name: str,
|
||||
result: Union[ExampleObject, ReferenceObject],
|
||||
params: List[ExampleObject],
|
||||
description: Optional[str] = None,
|
||||
summary: Optional[str] = None,
|
||||
):
|
||||
self.name = name
|
||||
self.description = description
|
||||
self.summary = summary
|
||||
self.params = params
|
||||
self.result = result
|
||||
|
||||
def get_x() -> Union[str, int]:
|
||||
a = [1, 2, 3]
|
||||
b = ["a", "b", "c"]
|
||||
z = Union()
|
||||
|
||||
@classmethod
|
||||
def load(cls, data: Dict[str, Any]) -> "ExamplePairingObject":
|
||||
return cls(
|
||||
name=data["name"],
|
||||
description=data.get("description"),
|
||||
summary=data.get("summary"),
|
||||
params=[ExampleObject.load(item) for item in data["params"]],
|
||||
result=(
|
||||
ExampleObject.load(data["result"])
|
||||
if isinstance(data["result"], dict) and "value" in data["result"]
|
||||
else ReferenceObject.load(data["result"])
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class TagObject:
|
||||
def __init__(
|
||||
self,
|
||||
name: str,
|
||||
summary: Optional[str] = None,
|
||||
description: Optional[str] = None,
|
||||
externalDocs: Optional[ExternalDocumentationObject] = None,
|
||||
):
|
||||
self.name = name
|
||||
self.summary = summary
|
||||
self.description = description
|
||||
self.externalDocs = externalDocs
|
||||
|
||||
@classmethod
|
||||
def load(cls, data: Dict[str, Any]) -> "TagObject":
|
||||
return cls(
|
||||
name=data["name"],
|
||||
summary=data.get("summary"),
|
||||
description=data.get("description"),
|
||||
externalDocs=(
|
||||
ExternalDocumentationObject.load(data["externalDocs"])
|
||||
if "externalDocs" in data
|
||||
else None
|
||||
),
|
||||
)
|
44
_archive/openrpc/model/components.py
Normal file
44
_archive/openrpc/model/components.py
Normal file
@@ -0,0 +1,44 @@
|
||||
from typing import Any, Dict, Union
|
||||
|
||||
from heroserver.openrpc.model.common import (
|
||||
ContentDescriptorObject,
|
||||
ErrorObject,
|
||||
ExampleObject,
|
||||
ExamplePairingObject,
|
||||
ReferenceObject,
|
||||
SchemaObject,
|
||||
TagObject,
|
||||
)
|
||||
from heroserver.openrpc.model.server import LinkObject
|
||||
|
||||
|
||||
class ComponentsObject:
|
||||
def __init__(
|
||||
self,
|
||||
contentDescriptors: Dict[str, ContentDescriptorObject],
|
||||
schemas: Dict[str, Union[SchemaObject, ReferenceObject]],
|
||||
examples: Dict[str, ExampleObject],
|
||||
links: Dict[str, LinkObject],
|
||||
errors: Dict[str, ErrorObject],
|
||||
examplePairingObjects: Dict[str, ExamplePairingObject],
|
||||
tags: Dict[str, TagObject],
|
||||
):
|
||||
self.contentDescriptors = contentDescriptors
|
||||
self.schemas = schemas
|
||||
self.examples = examples
|
||||
self.links = links
|
||||
self.errors = errors
|
||||
self.examplePairingObjects = examplePairingObjects
|
||||
self.tags = tags
|
||||
|
||||
@classmethod
|
||||
def load(cls, data: Dict[str, Any]) -> "ComponentsObject":
|
||||
return cls(
|
||||
contentDescriptors={k: ContentDescriptorObject.load(v) for k, v in data.get("contentDescriptors", {}).items()},
|
||||
schemas={k: ReferenceObject.load(v) if "$ref" in v else SchemaObject.load(v) for k, v in data.get("schemas", {}).items()},
|
||||
examples={k: ExampleObject.load(v) for k, v in data.get("examples", {}).items()},
|
||||
links={k: LinkObject.load(v) for k, v in data.get("links", {}).items()},
|
||||
errors={k: ErrorObject.load(v) for k, v in data.get("errors", {}).items()},
|
||||
examplePairingObjects={k: ExamplePairingObject.load(v) for k, v in data.get("examplePairingObjects", {}).items()},
|
||||
tags={k: TagObject.load(v) for k, v in data.get("tags", {}).items()},
|
||||
)
|
56
_archive/openrpc/model/info.py
Normal file
56
_archive/openrpc/model/info.py
Normal file
@@ -0,0 +1,56 @@
|
||||
from typing import Any, Dict, Optional
|
||||
|
||||
|
||||
class ContactObject:
|
||||
def __init__(
|
||||
self,
|
||||
name: Optional[str] = None,
|
||||
url: Optional[str] = None,
|
||||
email: Optional[str] = None,
|
||||
):
|
||||
self.name = name
|
||||
self.url = url
|
||||
self.email = email
|
||||
|
||||
@classmethod
|
||||
def load(cls, data: Dict[str, Any]) -> "ContactObject":
|
||||
return cls(name=data.get("name"), url=data.get("url"), email=data.get("email"))
|
||||
|
||||
|
||||
class LicenseObject:
|
||||
def __init__(self, name: str, url: Optional[str] = None):
|
||||
self.name = name
|
||||
self.url = url
|
||||
|
||||
@classmethod
|
||||
def load(cls, data: Dict[str, Any]) -> "LicenseObject":
|
||||
return cls(name=data["name"], url=data.get("url"))
|
||||
|
||||
|
||||
class InfoObject:
|
||||
def __init__(
|
||||
self,
|
||||
title: str,
|
||||
version: str,
|
||||
description: Optional[str] = None,
|
||||
termsOfService: Optional[str] = None,
|
||||
contact: Optional[ContactObject] = None,
|
||||
license: Optional[LicenseObject] = None,
|
||||
):
|
||||
self.title = title
|
||||
self.description = description
|
||||
self.termsOfService = termsOfService
|
||||
self.contact = contact
|
||||
self.license = license
|
||||
self.version = version
|
||||
|
||||
@classmethod
|
||||
def load(cls, data: Dict[str, Any]) -> "InfoObject":
|
||||
return cls(
|
||||
title=data["title"],
|
||||
description=data.get("description"),
|
||||
termsOfService=data.get("termsOfService"),
|
||||
contact=ContactObject.load(data["contact"]) if "contact" in data else None,
|
||||
license=LicenseObject.load(data["license"]) if "license" in data else None,
|
||||
version=data["version"],
|
||||
)
|
91
_archive/openrpc/model/methods.py
Normal file
91
_archive/openrpc/model/methods.py
Normal file
@@ -0,0 +1,91 @@
|
||||
from typing import Any, Dict, List, Optional, Union
|
||||
|
||||
from heroserver.openrpc.model.common import (
|
||||
ContentDescriptorObject,
|
||||
ErrorObject,
|
||||
ExamplePairingObject,
|
||||
ExternalDocumentationObject,
|
||||
ReferenceObject,
|
||||
TagObject,
|
||||
)
|
||||
from heroserver.openrpc.model.server import LinkObject, ServerObject
|
||||
|
||||
|
||||
class MethodObject:
|
||||
def __init__(
|
||||
self,
|
||||
name: str,
|
||||
params: List[Union[ContentDescriptorObject, ReferenceObject]],
|
||||
result: Union[ContentDescriptorObject, ReferenceObject, None],
|
||||
tags: Optional[List[Union[TagObject, ReferenceObject]]] = None,
|
||||
summary: Optional[str] = None,
|
||||
description: Optional[str] = None,
|
||||
externalDocs: Optional[ExternalDocumentationObject] = None,
|
||||
deprecated: Optional[bool] = None,
|
||||
servers: Optional[List[ServerObject]] = None,
|
||||
errors: Optional[List[Union[ErrorObject, ReferenceObject]]] = None,
|
||||
links: Optional[List[Union[LinkObject, ReferenceObject]]] = None,
|
||||
paramStructure: Optional[str] = None,
|
||||
examples: Optional[List[ExamplePairingObject]] = None,
|
||||
):
|
||||
self.name = name
|
||||
self.tags = tags
|
||||
self.summary = summary
|
||||
self.description = description
|
||||
self.externalDocs = externalDocs
|
||||
self.params = params
|
||||
self.result = result
|
||||
self.deprecated = deprecated
|
||||
self.servers = servers
|
||||
self.errors = errors
|
||||
self.links = links
|
||||
self.paramStructure = paramStructure
|
||||
self.examples = examples
|
||||
|
||||
@classmethod
|
||||
def load(cls, data: Dict[str, Any]) -> "MethodObject":
|
||||
return cls(
|
||||
name=data["name"],
|
||||
tags=(
|
||||
[
|
||||
(TagObject.load(item) if isinstance(item, dict) and "name" in item else ReferenceObject.load(item))
|
||||
for item in data.get("tags", [])
|
||||
]
|
||||
if "tags" in data
|
||||
else None
|
||||
),
|
||||
summary=data.get("summary"),
|
||||
description=data.get("description"),
|
||||
externalDocs=(ExternalDocumentationObject.load(data["externalDocs"]) if "externalDocs" in data else None),
|
||||
params=[
|
||||
(ContentDescriptorObject.load(item) if isinstance(item, dict) and "name" in item else ReferenceObject.load(item))
|
||||
for item in data["params"]
|
||||
],
|
||||
result=(
|
||||
ContentDescriptorObject.load(data["result"])
|
||||
if isinstance(data["result"], dict) and "name" in data["result"]
|
||||
else ReferenceObject.load(data["result"])
|
||||
if "result" in data
|
||||
else None
|
||||
),
|
||||
deprecated=data.get("deprecated"),
|
||||
servers=([ServerObject.load(item) for item in data.get("servers", [])] if "servers" in data else None),
|
||||
errors=(
|
||||
[
|
||||
(ErrorObject.load(item) if isinstance(item, dict) and "code" in item else ReferenceObject.load(item))
|
||||
for item in data.get("errors", [])
|
||||
]
|
||||
if "errors" in data
|
||||
else None
|
||||
),
|
||||
links=(
|
||||
[
|
||||
(LinkObject.load(item) if isinstance(item, dict) and "name" in item else ReferenceObject.load(item))
|
||||
for item in data.get("links", [])
|
||||
]
|
||||
if "links" in data
|
||||
else None
|
||||
),
|
||||
paramStructure=data.get("paramStructure"),
|
||||
examples=([ExamplePairingObject.load(item) for item in data.get("examples", [])] if "examples" in data else None),
|
||||
)
|
98
_archive/openrpc/model/openrpc_spec.py
Normal file
98
_archive/openrpc/model/openrpc_spec.py
Normal file
@@ -0,0 +1,98 @@
|
||||
from typing import Any, Dict, List, Optional, Union
|
||||
|
||||
from heroserver.openrpc.model.common import (
|
||||
ContentDescriptorObject,
|
||||
ExternalDocumentationObject,
|
||||
ReferenceObject,
|
||||
SchemaObject,
|
||||
)
|
||||
from heroserver.openrpc.model.components import ComponentsObject
|
||||
from heroserver.openrpc.model.info import InfoObject
|
||||
from heroserver.openrpc.model.methods import MethodObject
|
||||
from heroserver.openrpc.model.server import ServerObject
|
||||
|
||||
ROOT_OBJ_DEF = "!!define.root_object"
|
||||
|
||||
|
||||
class OpenRPCSpec:
|
||||
def __init__(
|
||||
self,
|
||||
openrpc: str,
|
||||
info: InfoObject,
|
||||
methods: List[MethodObject],
|
||||
servers: Optional[List[ServerObject]] = None,
|
||||
components: Optional[ComponentsObject] = None,
|
||||
externalDocs: Optional[ExternalDocumentationObject] = None,
|
||||
spec_extensions: Optional[Dict[str, Any]] = None,
|
||||
):
|
||||
self.openrpc = openrpc
|
||||
self.info = info
|
||||
self.servers = servers
|
||||
self.methods = methods
|
||||
self.components = components
|
||||
self.externalDocs = externalDocs
|
||||
self.spec_extensions = spec_extensions
|
||||
|
||||
@classmethod
|
||||
def load(cls, data: Dict[str, Any]) -> "OpenRPCSpec":
|
||||
return cls(
|
||||
openrpc=data["openrpc"],
|
||||
info=InfoObject.load(data["info"]),
|
||||
servers=([ServerObject.load(item) for item in data.get("servers", [])] if "servers" in data else None),
|
||||
methods=[MethodObject.load(item) for item in data["methods"]],
|
||||
components=(ComponentsObject.load(data["components"]) if "components" in data else None),
|
||||
externalDocs=(ExternalDocumentationObject.load(data["externalDocs"]) if "externalDocs" in data else None),
|
||||
spec_extensions=data.get("spec_extensions"),
|
||||
)
|
||||
|
||||
def ref_to_schema(self, ref: str) -> Union[SchemaObject, ContentDescriptorObject]:
|
||||
if not ref.startswith("#/"):
|
||||
raise Exception(f"invalid ref: {ref}")
|
||||
|
||||
l = ref.split("/")[1:]
|
||||
obj = self
|
||||
for item in l:
|
||||
# TODO: find root cause of RO_
|
||||
if item.startswith("RO_"):
|
||||
item = item[3:]
|
||||
|
||||
if isinstance(obj, Dict):
|
||||
print("obj contents: ", obj)
|
||||
print("Trying to access key: ", item)
|
||||
obj = obj[item]
|
||||
else:
|
||||
obj = obj.__dict__[item]
|
||||
|
||||
if not isinstance(obj, SchemaObject) and not isinstance(obj, ContentDescriptorObject):
|
||||
raise Exception(f"ref to unsupported type: {ref}")
|
||||
|
||||
return obj
|
||||
|
||||
def get_root_objects(self) -> Dict[str, SchemaObject]:
|
||||
if not self.components:
|
||||
return {}
|
||||
|
||||
objs: Dict[str, SchemaObject] = {}
|
||||
base_ref = ["components", "schemas"]
|
||||
for name, scheme in self.components.schemas.items():
|
||||
if scheme.xtags and "rootobject" in scheme.xtags:
|
||||
objs["/".join(base_ref + [name.lower()])] = scheme
|
||||
|
||||
return objs
|
||||
|
||||
def set_root_objects(self, refs: List[str]):
|
||||
for ref in refs:
|
||||
obj = self.ref_to_schema(ref)
|
||||
if isinstance(obj, ContentDescriptorObject):
|
||||
obj = obj.schema
|
||||
if isinstance(obj, ReferenceObject):
|
||||
self.set_root_objects([obj.ref])
|
||||
continue
|
||||
|
||||
if not obj.description:
|
||||
obj.description = ROOT_OBJ_DEF
|
||||
else:
|
||||
obj.description += f";{ROOT_OBJ_DEF}"
|
||||
|
||||
|
||||
# Note that classes that refer to themselves or each other are handled using string literals in annotations to avoid forward reference issues. Python 3.7+ supports this feature with the use of 'from __future__ import annotations'.
|
84
_archive/openrpc/model/server.py
Normal file
84
_archive/openrpc/model/server.py
Normal file
@@ -0,0 +1,84 @@
|
||||
from typing import Any, Dict, List, Optional, Union
|
||||
|
||||
|
||||
class ServerVariableObject:
|
||||
def __init__(
|
||||
self,
|
||||
default: str,
|
||||
enum: Optional[List[str]] = None,
|
||||
description: Optional[str] = None,
|
||||
):
|
||||
self.enum = enum
|
||||
self.default = default
|
||||
self.description = description
|
||||
|
||||
@classmethod
|
||||
def load(cls, data: Dict[str, Any]) -> "ServerVariableObject":
|
||||
return cls(
|
||||
enum=data.get("enum"),
|
||||
default=data["default"],
|
||||
description=data.get("description"),
|
||||
)
|
||||
|
||||
|
||||
class ServerObject:
|
||||
def __init__(
|
||||
self,
|
||||
name: str,
|
||||
url: str,
|
||||
summary: Optional[str] = None,
|
||||
description: Optional[str] = None,
|
||||
variables: Optional[Dict[str, ServerVariableObject]] = None,
|
||||
):
|
||||
self.name = name
|
||||
self.url = url
|
||||
self.summary = summary
|
||||
self.description = description
|
||||
self.variables = variables
|
||||
|
||||
@classmethod
|
||||
def load(cls, data: Dict[str, Any]) -> "ServerObject":
|
||||
variables = (
|
||||
{
|
||||
k: ServerVariableObject.load(v)
|
||||
for k, v in data.get("variables", {}).items()
|
||||
}
|
||||
if "variables" in data
|
||||
else None
|
||||
)
|
||||
return cls(
|
||||
name=data["name"],
|
||||
url=data["url"],
|
||||
summary=data.get("summary"),
|
||||
description=data.get("description"),
|
||||
variables=variables,
|
||||
)
|
||||
|
||||
|
||||
class LinkObject:
|
||||
def __init__(
|
||||
self,
|
||||
name: str,
|
||||
method: str,
|
||||
params: Dict[str, Any],
|
||||
description: Optional[str] = None,
|
||||
summary: Optional[str] = None,
|
||||
server: Optional[ServerObject] = None,
|
||||
):
|
||||
self.name = name
|
||||
self.description = description
|
||||
self.summary = summary
|
||||
self.method = method
|
||||
self.params = params
|
||||
self.server = server
|
||||
|
||||
@classmethod
|
||||
def load(cls, data: Dict[str, Any]) -> "LinkObject":
|
||||
return cls(
|
||||
name=data["name"],
|
||||
description=data.get("description"),
|
||||
summary=data.get("summary"),
|
||||
method=data["method"],
|
||||
params=data["params"],
|
||||
server=ServerObject.load(data["server"]) if "server" in data else None,
|
||||
)
|
Reference in New Issue
Block a user