Replace openapi-core deprecated interface
openapi-core==0.23.0 dropped deprecated interface breaking us. The change itself is small, but not backwards compatible and uncovers quite some issues. relates-to: https://review.opendev.org/c/openstack/manila/+/982081 relates-to: https://review.opendev.org/c/openstack/cinder/+/982079 Closes-Bug: #2145963 Change-Id: Ifcf90af5bfbeebca3a8728a71b30b09d6cd4ede5 Signed-off-by: Artem Goncharov <artem.goncharov@gmail.com>
This commit is contained in:
@@ -17,7 +17,7 @@ from typing import Any
|
||||
|
||||
import jsonref
|
||||
import yaml
|
||||
from openapi_core import Spec
|
||||
from openapi_core import OpenAPI
|
||||
from pydantic import BaseModel
|
||||
|
||||
VERSION_RE = re.compile(r"^[Vv]([0-9]+)(\.([0-9]+))?$")
|
||||
@@ -124,7 +124,8 @@ def get_openapi_spec(path: str | Path):
|
||||
"""Load OpenAPI spec from a file"""
|
||||
with open(path) as fp:
|
||||
spec_data = jsonref.replace_refs(yaml.safe_load(fp), proxies=False)
|
||||
return Spec.from_dict(spec_data)
|
||||
return spec_data
|
||||
# return OpenAPI.from_dict(spec_data)
|
||||
|
||||
|
||||
def find_openapi_operation(spec, operationId: str):
|
||||
|
||||
@@ -14,8 +14,6 @@ from typing import Any
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
|
||||
# from openapi_core import Spec
|
||||
|
||||
|
||||
class TypeSchema(BaseModel):
|
||||
# TODO(gtema): enums are re-shuffled on every serialization
|
||||
|
||||
@@ -16,27 +16,28 @@ import datetime
|
||||
import enum
|
||||
import importlib
|
||||
import inspect
|
||||
import jsonref
|
||||
import logging
|
||||
import re
|
||||
from collections.abc import Callable
|
||||
from pathlib import Path
|
||||
from typing import Any, Literal
|
||||
from collections.abc import Callable
|
||||
import re
|
||||
|
||||
from codegenerator import common
|
||||
from codegenerator.common.schema import ParameterSchema
|
||||
from codegenerator.common.schema import PathSchema
|
||||
from codegenerator.common.schema import SpecSchema
|
||||
from codegenerator.common.schema import TypeSchema
|
||||
from codegenerator.metadata import MetadataGenerator
|
||||
from codegenerator import model
|
||||
from codegenerator.openapi.utils import rst_to_md
|
||||
from openapi_core import Spec
|
||||
import jsonref
|
||||
from openapi_core import OpenAPI
|
||||
from openapi_spec_validator import validate
|
||||
from ruamel.yaml.scalarstring import LiteralScalarString
|
||||
from ruamel.yaml import YAML
|
||||
from ruamel.yaml.scalarstring import LiteralScalarString
|
||||
from wsme import types as wtypes
|
||||
|
||||
from codegenerator import common, model
|
||||
from codegenerator.common.schema import (
|
||||
ParameterSchema,
|
||||
PathSchema,
|
||||
SpecSchema,
|
||||
TypeSchema,
|
||||
)
|
||||
from codegenerator.metadata import MetadataGenerator
|
||||
from codegenerator.openapi.utils import rst_to_md
|
||||
|
||||
VERSION_RE = re.compile(r"[Vv][0-9\.]*")
|
||||
|
||||
@@ -223,12 +224,10 @@ class OpenStackServerSourceBase:
|
||||
model_data = openapi_spec.model_dump(
|
||||
exclude_none=True, exclude_defaults=True, by_alias=True
|
||||
)
|
||||
Spec.from_dict(model_data)
|
||||
OpenAPI.from_dict(model_data)
|
||||
validate(model_data)
|
||||
|
||||
openapi_spec = Spec.from_dict(
|
||||
jsonref.replace_refs(model_data, proxies=False)
|
||||
)
|
||||
openapi_spec = jsonref.replace_refs(model_data, proxies=False)
|
||||
|
||||
# Build the metadata as if we would do this normally
|
||||
metadata = MetadataGenerator.build_metadata(
|
||||
@@ -1202,6 +1201,8 @@ class OpenStackServerSourceBase:
|
||||
|
||||
if isinstance(schema, dict):
|
||||
# Forcibly convert to TypeSchema
|
||||
if isinstance(schema.get("type"), tuple):
|
||||
schema["type"] = list(schema["type"])
|
||||
schema = TypeSchema(**schema)
|
||||
properties = getattr(schema, "properties", None)
|
||||
if properties:
|
||||
@@ -1216,6 +1217,17 @@ class OpenStackServerSourceBase:
|
||||
|
||||
for k, v in properties.items():
|
||||
typ = v.get("type")
|
||||
if isinstance(typ, tuple):
|
||||
# A very dirty hack. In cinder a type is defined as tuple.
|
||||
# Before
|
||||
# https://review.opendev.org/c/openstack/cinder/+/982079 is
|
||||
# merged we need to tweak the schema.
|
||||
typ = list(typ)
|
||||
v["type"] = typ
|
||||
if v.get("enum") and isinstance(v["enum"], tuple):
|
||||
# Hack for the manila bug
|
||||
# https://review.opendev.org/c/openstack/manila/+/982081
|
||||
v["enum"] = list(v["enum"])
|
||||
if typ == "object":
|
||||
schema.properties[k] = self._sanitize_schema(v)
|
||||
if typ == "array":
|
||||
@@ -1635,16 +1647,41 @@ def _convert_wsme_to_jsonschema(body_spec):
|
||||
res["enum"] = list(values)
|
||||
# elif hasattr(body_spec, "__name__") and body_spec.__name__ == "bool":
|
||||
elif wtypes.isdict(body_spec):
|
||||
# The value may be a custom wrapper. In this case (when no
|
||||
# conversion is possible just fallback to the {}
|
||||
try:
|
||||
value_type = _convert_wsme_to_jsonschema(body_spec.value_type)
|
||||
except RuntimeError:
|
||||
value_type = {}
|
||||
res = {
|
||||
"type": "object",
|
||||
"additionalProperties": _convert_wsme_to_jsonschema(
|
||||
body_spec.value_type
|
||||
),
|
||||
"additionalProperties": value_type,
|
||||
# _convert_wsme_to_jsonschema(
|
||||
# body_spec.value_type
|
||||
# ),
|
||||
}
|
||||
elif wtypes.isusertype(body_spec):
|
||||
if hasattr(body_spec, "types"):
|
||||
# Multitype like magnum defines
|
||||
type_defs = getattr(body_spec, "types")
|
||||
res_types: list[str] = []
|
||||
for typ in type_defs:
|
||||
if typ is str:
|
||||
res_types.append("string")
|
||||
elif typ is float:
|
||||
res_types.append("number")
|
||||
elif typ is int:
|
||||
res_types.append("integer")
|
||||
elif typ is bool:
|
||||
res_types.append("boolean")
|
||||
else:
|
||||
raise RuntimeError(f"Unsupported multitype entity {typ}")
|
||||
res = {"type": res_types}
|
||||
return res
|
||||
|
||||
basetype = body_spec.basetype
|
||||
name = body_spec.name
|
||||
if basetype is str:
|
||||
if basetype is str and name:
|
||||
res = {"type": "string", "format": name}
|
||||
else:
|
||||
raise RuntimeError(f"Unsupported basetype {basetype}")
|
||||
|
||||
@@ -23,6 +23,7 @@ from codegenerator.common import (
|
||||
BasePrimitiveType,
|
||||
)
|
||||
from codegenerator.common import rust as common_rust
|
||||
from codegenerator.model import OneOfType, PrimitiveType
|
||||
|
||||
BASIC_FIELDS = [
|
||||
"id",
|
||||
@@ -581,7 +582,18 @@ class RequestTypeManager(common_rust.TypeManager):
|
||||
)
|
||||
):
|
||||
dict_type_model = self._get_adt_by_reference(field.data_type)
|
||||
simplified_data_type = JsonValue()
|
||||
simplified_data_type = None
|
||||
if isinstance(dict_type_model.value_type, OneOfType):
|
||||
if all(
|
||||
isinstance(item, PrimitiveType)
|
||||
for item in dict_type_model.value_type.kinds
|
||||
):
|
||||
# When all of the enum types are primitives just use the
|
||||
# plain string and deser it into the enum later in the
|
||||
# cli-sdk setter.
|
||||
simplified_data_type = String()
|
||||
if not simplified_data_type:
|
||||
simplified_data_type = JsonValue()
|
||||
simplified_data_type.original_data_type = (
|
||||
field_data_type.value_type
|
||||
)
|
||||
|
||||
@@ -335,6 +335,13 @@ Some({{ val }})
|
||||
.into_iter(),
|
||||
);
|
||||
|
||||
{%- elif param.data_type.value_type.__class__.__name__ == "String" and original_type.__class__.__name__ == "Enum" %}
|
||||
{# in magnum labels_XXX is a dict with the multitype value. In SDK this maps to Enum which we need to deser into #}
|
||||
let mut data: Vec<(String, {{ sdk_mod_path[-1] }}::{{ original_type.name }})> = Vec::new();
|
||||
for (k, v) in {{ val_var }}.iter() {
|
||||
data.push((k.clone(), serde_json::from_str(&v)?));
|
||||
}
|
||||
{{ dst_var }}.{{ param.remote_name }}(data.into_iter());
|
||||
{%- elif param.data_type.value_type.__class__.__name__ == "Option" %}
|
||||
{{ dst_var }}.{{ param.remote_name }}({{ val_var | replace("&", "") }}.iter().cloned().map(|(k, v)| (k, v.map(Into::into))));
|
||||
{%- elif param.data_type.value_type.__class__.__name__ == "JsonValue" and original_type.__class__.__name__ == "ArrayInput" %}
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ dynamic = ["version"]
|
||||
dependencies = [
|
||||
"Jinja2>=3.0", # BSD
|
||||
"jsonref>=1.0", # MIT
|
||||
"openapi_core>=0.17", # BSD
|
||||
"openapi_core>=0.19", # BSD
|
||||
"pydantic>=2.6", # MIT
|
||||
"ruamel.yaml>=0.18", # MIT
|
||||
"jsonschema>=4.19", # MIT
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
Jinja2>=3.0 # BSD
|
||||
jsonref>=1.0 # MIT
|
||||
openapi_core>=0.17 # BSD
|
||||
openapi_core>=0.19.0 # BSD
|
||||
pydantic>=2.6 # MIT
|
||||
ruamel.yaml>=0.18 # MIT
|
||||
jsonschema>=4.19 # MIT
|
||||
|
||||
Reference in New Issue
Block a user