I am trying to work with an openapi.json, which has been automatically created by FastAPI (version 0.109.0). The openapi version is 3.0.3 and I need to upload it to an app, which does not support schemas that have been defined using anyOf
, allOf
or OneOf
.
The openapi.json looks like this:
{
"openapi": "3.0.3",
"info": {
"title": "SomeTitle",
"description": "SomeDescription",
"version": "1.2.0"
},
"servers": [
{
"url": "http://localhost:8080",
"description": "Local Environment for testing"
},
{
"url": "Productive URL",
"description": "Productive Instance"
}
],
"paths": {
"/api/v1/rag/prepare-index": {
"post": {
"tags": [
"Retrieval Augmented Generation"
],
"summary": "Build Index",
"operationId": "Build_Index",
"security": [
{
"APIKeyHeader": []
}
],
"parameters": [
{
"name": "project_id",
"in": "query",
"required": true,
"schema": {
"type": "string",
"title": "Project Id"
}
},
{
"name": "max_docs",
"in": "query",
"required": true,
"schema": {
"type": "integer",
"title": "Max Docs"
}
},
{
"name": "vector_store",
"in": "query",
"required": false,
"schema": {
"allOf": [
{
"$ref": "#/components/schemas/VectorStores"
}
],
"default": "in_memory",
"title": "Vector Store"
}
}
],
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
"type": "object",
"title": "Response Build Index"
}
}
}
},
"404": {
"description": "Not found"
},
"422": {
"description": "Validation error"
}
}
}
},
...
},
"components":
"schemas": {
...
"VectorStores": {
"type": "string",
"enum": [
"redis",
"in_memory"
],
"title": "VectorStores"
},
...
}
}
}
When uploading, the documentation is shown correctly, but upon trying to finish the import into the app, I am receiving the following error:
Import failed
Please adjust your OpenAPI specification and try again. Reason: Invalid Request Body
/specification/body/paths/~1api~1v1~1rag~1prepare-index/post/parameters/2/schema
must NOT have additional properties
/specification/body/paths/~1api~1v1~1rag~1prepare-index/post/parameters/2/schema/allOf
schema cannot contain anyOf,oneOf,allOf
/specification/body/paths/~1api~1v1~1rag~1prepare-index/post/parameters/2/schema/oneOf
schema cannot contain anyOf,oneOf,allOf
/specification/body/paths/~1api~1v1~1rag~1prepare-index/post/parameters/2/schema
must match exactly one schema in oneOf
/specification/body/paths/~1api~1v1~1rag~1prepare-index/post/parameters/2
must have required property '$ref'
/specification/body/paths/~1api~1v1~1rag~1prepare-index/post/parameters/2
must NOT have additional properties
/specification/body/paths/~1api~1v1~1rag~1prepare-index/post/parameters/2
must match exactly one schema in oneOf
So I tried deleting the allOf
part in the schema of the path parameter vector_store
. Now $ref
is a direct child of schema
property of that parameter. However, it still throws the same error. Also, when deleting the title
and default
properties or providing $ref
on the same level as is_required
did not help. Further, I tried working with the swagger-editor
in order to make it a valid openapi.json, however unfortunately none of that worked out...
What am I missing here?
It looks like the error is coming from the third parameter
definition and the use of allOf
. The error states you cannot have anyOf
, allOf
, or oneOf
.
I also wonder if FastAPI is looking for a requestBody
property because it's a POST
operation. You don't have one defined and it has an error related to that.
Try this...
{
"openapi": "3.0.3",
"info": {
"title": "SomeTitle",
"description": "SomeDescription",
"version": "1.2.0"
},
"servers": [
{
"url": "http://localhost:8080",
"description": "Local Environment for testing"
},
{
"url": "Productive URL",
"description": "Productive Instance"
}
],
"paths": {
"/api/v1/rag/prepare-index": {
"post": {
"tags": [
"Retrieval Augmented Generation"
],
"summary": "Build Index",
"operationId": "Build_Index",
"security": [
{
"APIKeyHeader": []
}
],
"parameters": [
{
"name": "project_id",
"in": "query",
"required": true,
"schema": {
"type": "string",
"title": "Project Id"
}
},
{
"name": "max_docs",
"in": "query",
"required": true,
"schema": {
"type": "integer",
"title": "Max Docs"
}
},
{
"name": "vector_store",
"in": "query",
"required": false,
"schema": {
"$ref": "#/components/schemas/VectorStores"
}
}
],
"requestBody": {
"description": "a request body",
"content": {
"application/json": {
"schema": {
"type": "object"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
"type": "object",
"title": "Response Build Index"
}
}
}
},
"404": {
"description": "Not found"
},
"422": {
"description": "Validation error"
}
}
}
}
},
"components": {
"schemas": {
"VectorStores": {
"type": "string",
"enum": [
"redis",
"in_memory"
],
"title": "VectorStores",
"default": "in_memory"
}
}
}
}
In your original example, you had title
and default
as sibling properties to the allOf
rather than inside the allOf
as a subschema.
How to compose an allOf
to overwrite sibling properties of a $ref
.
{
"parameters": [
{
"name": "test",
"in": "query",
"schema": {
"allOf": [
{
"$ref": "#/components/schemas/test"
},
{
"title": "this is the title I really want!",
"default": "default value over written"
}
]
}
}
],
...
"components": {
"schemas": {
"test": {
"title": "it's a title",
"description": "it's a description",
"type": "string",
"default": "default value"
}
}
}
}