From dee8b02d26410cb4eb32f337a680bfb48005de2c Mon Sep 17 00:00:00 2001 From: Vitor Hideyoshi Date: Sat, 21 Jun 2025 11:46:26 -0300 Subject: [PATCH] Adds Docs for Ref Type --- docs/source/usage.reference.rst | 81 +++++++++++++++++++++++++++++++++ docs/source/usage.rst | 3 +- tests/test_schema_converter.py | 35 ++++++++++++++ 3 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 docs/source/usage.reference.rst diff --git a/docs/source/usage.reference.rst b/docs/source/usage.reference.rst new file mode 100644 index 0000000..33ee6ae --- /dev/null +++ b/docs/source/usage.reference.rst @@ -0,0 +1,81 @@ +Reference Type +=================== + +The Reference type allows you to reference another schema by its `$ref` property. This is useful for reusing schemas across your application. + +The Reference type has no specific properties, it has only the generic properties: + +- default: Default value for the reference. +- description: Description of the reference field. + + +Examples +----------------- + +1. Reference to the Root schema: + +.. code-block:: python + + from jambo import SchemaConverter + + schema = { + "title": "Person", + "type": "object", + "properties": { + "name": {"type": "string"}, + "age": {"type": "integer"}, + "emergency_contact": { + "$ref": "#" + } + }, + "required": ["name"], + } + + Model = SchemaConverter.build(schema) + + obj = Model(name="Alice", age=30, emergency_contact=Model(name="Bob", age=25)) + print(obj) # Output: Person(name='Alice', age=30, emergency_contact=Person(name='Bob', age=25)) + + +2. Reference to a Def Schema: + +.. code-block:: python + + from jambo import SchemaConverter + + schema = { + "title": "Person", + "type": "object", + "properties": { + "name": {"type": "string"}, + "age": {"type": "integer"}, + "address": { + "$ref": "#/$defs/Address" + } + }, + "required": ["name"], + "$defs": { + "Address": { + "type": "object", + "properties": { + "street": {"type": "string"}, + "city": {"type": "string"}, + }, + "required": ["street", "city"], + } + }, + } + + Model = SchemaConverter.build(schema) + + obj = Model(name="Alice", age=30, address={"street": "123 Main St", "city": "Springfield"}) + print(obj) # Output: Person(name='Alice', age=30, address=Address(street='123 Main St', city='Springfield')) + + +.. note:: + + At the moment, Jambo doesn't have a way to expose the class definition :py:class:`Address` defined inside the `$defs` property, + but you can access the model class by using the `Model.__fields__` attribute to get the field definitions, + or by using the `Model.model_fields` property to get a dictionary of field names and their types. + +.. \ No newline at end of file diff --git a/docs/source/usage.rst b/docs/source/usage.rst index b3ba7b9..a86b2f4 100644 --- a/docs/source/usage.rst +++ b/docs/source/usage.rst @@ -41,4 +41,5 @@ For more complex schemas and types see our documentation on usage.numeric usage.bool usage.array - usage.object \ No newline at end of file + usage.object + usage.reference \ No newline at end of file diff --git a/tests/test_schema_converter.py b/tests/test_schema_converter.py index 76c38ec..c8bc96c 100644 --- a/tests/test_schema_converter.py +++ b/tests/test_schema_converter.py @@ -562,3 +562,38 @@ class TestSchemaConverter(TestCase): self.assertIsInstance(obj.emergency_contact, model) self.assertEqual(obj.emergency_contact.name, "Jane") self.assertEqual(obj.emergency_contact.age, 28) + + def test_ref_with_def_another_model(self): + schema = { + "title": "Person", + "type": "object", + "properties": { + "name": {"type": "string"}, + "age": {"type": "integer"}, + "address": {"$ref": "#/$defs/Address"}, + }, + "required": ["name"], + "$defs": { + "Address": { + "type": "object", + "properties": { + "street": {"type": "string"}, + "city": {"type": "string"}, + }, + "required": ["street", "city"], + } + }, + } + + Model = SchemaConverter.build(schema) + + obj = Model( + name="John", + age=30, + address={"street": "123 Main St", "city": "Springfield"}, + ) + + self.assertEqual(obj.name, "John") + self.assertEqual(obj.age, 30) + self.assertEqual(obj.address.street, "123 Main St") + self.assertEqual(obj.address.city, "Springfield")