openapi3
openapi3 copied to clipboard
Support for schema anyOf
Based on the specs here:
https://swagger.io/docs/specification/data-models/oneof-anyof-allof-not/
Given
paths:
/pets:
patch:
requestBody:
content:
application/json:
schema:
anyOf:
- $ref: '#/components/schemas/PetByAge'
- $ref: '#/components/schemas/PetByType'
responses:
'200':
description: Updated
components:
schemas:
PetByAge:
type: object
properties:
age:
type: integer
nickname:
type: string
required:
- age
PetByType:
type: object
properties:
pet_type:
type: string
enum: [Cat, Dog]
hunts:
type: boolean
required:
- pet_type
The following JSON response should be valid:
{
"pet_type": "Cat",
"hunts": true
}
{
"nickname": "Fido",
"pet_type": "Dog",
"age": 4
}
@Dorthu would this be hard to implement? I'm trying to dive in to the code base. What do I need to do to in order to make this work?
Hi,
I already implemented this in https://github.com/Dorthu/openapi3/pull/69 - been quite a lot.
import httpx
import json
import pydantic
import pytest
from aiopenapi3 import OpenAPI
DD = """
paths:
/pets:
patch:
requestBody:
content:
application/json:
schema:
anyOf:
- $ref: '#/components/schemas/PetByAge'
- $ref: '#/components/schemas/PetByType'
responses:
'200':
description: Updated
components:
schemas:
PetByAge:
type: object
properties:
age:
type: integer
nickname:
type: string
required:
- age
PetByType:
type: object
properties:
pet_type:
type: string
enum: [Cat, Dog]
hunts:
type: boolean
required:
- pet_type
openapi: "3.1.0"
info:
version: 1.0.0
title: https://github.com/Dorthu/openapi3/issues/101
servers:
- url: /
"""
def test_anyOf(httpx_mock):
api = OpenAPI.loads("http://localhost", DD, httpx.Client)
# create a Request so we can use the Requests "data" property to access the body schema
m = api.createRequest(("/pets", "patch"))
data = json.loads("""{
"pet_type": "Cat",
"hunts": true
}""")
# use the body schema to create a pydantic model to validate the data
data = m.data.get_type().model_validate(data)
# same
data = json.loads("""
{
"nickname": "Fido",
"pet_type": "Dog",
"age": 4
}""")
data = m.data.get_type().model_validate(data)
# fail due to missing property
with pytest.raises(pydantic.ValidationError):
# missing age
data = json.loads("""
{
"nickname": "Frogo",
"pet_type": "Frog"
}""")
data = m.data.get_type().model_validate(data)
data = json.loads("""
{
"nickname": "Frogo",
"pet_type": "Frog",
"age": 4,
"wet": true
}""")
# works as wet is an additionalProperty
data = m.data.get_type().model_validate(data)
# access model via root - due to use of anyOf
assert data.root.model_extra["wet"] is True