Skip to content

Commit e1d1520

Browse files
committed
Map types
1 parent eaa91d1 commit e1d1520

1 file changed

Lines changed: 26 additions & 4 deletions

File tree

src/odin/contrib/json_schema/__init__.py

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""JSON schema support for Odin."""
22
import json
3-
from typing import Any, Dict, Final, Sequence, TextIO, Type
3+
from typing import Any, Dict, Final, List, Sequence, TextIO, Type, Union
44

55
import odin
66
from odin.registration import get_child_resources
@@ -13,8 +13,11 @@
1313
class JSONSchema:
1414
"""JSON Schema representation of an Odin resource."""
1515

16-
def __init__(self, resource: Type[ResourceBase]):
16+
def __init__(
17+
self, resource: Type[ResourceBase], *, require_type_field: bool = True
18+
):
1719
self.resource = resource
20+
self.require_type_field = require_type_field
1821

1922
self.defs = {}
2023

@@ -44,7 +47,8 @@ def _resource_to_schema(self, meta: ResourceOptions) -> Dict[str, Any]:
4447
def _required_fields(self, meta: ResourceOptions) -> Sequence[str]:
4548
"""Get a list of required fields."""
4649
required = [field.name for field in meta.fields if not field.null]
47-
required.append(meta.type_field)
50+
if self.require_type_field:
51+
required.append(meta.type_field)
4852
return required
4953

5054
def _fields_to_properties(self, meta: ResourceOptions) -> Dict[str, Any]:
@@ -61,14 +65,32 @@ def _field_to_schema(self, field: odin.Field) -> Dict[str, Any]:
6165
return self._composite_field_to_schema(field)
6266

6367
schema = {
64-
"type": "string",
68+
"type": self._field_type(field),
6569
"description": field.doc_text or "",
6670
}
6771
if field.choices:
6872
schema["enum"] = tuple(str(value) for value in field.choice_values)
6973

7074
return schema
7175

76+
def _field_type(self, field: odin.Field) -> Union[str, List[str]]:
77+
"""Get the type of a field."""
78+
79+
if isinstance(field, odin.ListField):
80+
type_name = "array"
81+
elif isinstance(field, odin.IntegerField):
82+
type_name = "integer"
83+
elif isinstance(field, odin.FloatField):
84+
type_name = "number"
85+
elif isinstance(field, odin.BooleanField):
86+
type_name = "boolean"
87+
elif isinstance(field, odin.DictField):
88+
type_name = "object"
89+
else:
90+
type_name = "string"
91+
92+
return [type_name, "null"] if field.null else type_name
93+
7294
def _composite_field_to_schema(self, field: odin.CompositeField) -> Dict[str, Any]:
7395
"""Convert a composite field to a JSON schema."""
7496

0 commit comments

Comments
 (0)