openapi3
openapi3 copied to clipboard
Failure to parse data after get
I'm using Django rest framework to auto generate a schema for a very simple API, one endpoint listGenes returns a json object which is an array of objects:
[
{
"id": 1,
"name": "gene1"
},
{
"id": 2,
"name": "gene2
}.
]
openapi3 correctly parses the schema and I can access the operations but when I called the listgenes operation, api.call_listGenes(), I get the following traceback:
Traceback (most recent call last):
File "openapi_client.py", line 13, in <module>
gene_list = api.call_listGenes()
File "/Users/dbuchan/.virtualenvs/advanced_web_dev/lib/python3.8/site-packages/openapi3/openapi.py", line 188, in __call__
return self.operation(self.base_url, *args, security=self.security,
File "/Users/dbuchan/.virtualenvs/advanced_web_dev/lib/python3.8/site-packages/openapi3/paths.py", line 287, in request
return expected_media.schema.model(result.json())
File "/Users/dbuchan/.virtualenvs/advanced_web_dev/lib/python3.8/site-packages/openapi3/schemas.py", line 113, in model
return self.get_type()(data, self)
File "/Users/dbuchan/.virtualenvs/advanced_web_dev/lib/python3.8/site-packages/openapi3/schemas.py", line 93, in get_type
'__slots__': self.properties.keys()
AttributeError: 'NoneType' object has no attribute 'keys'
The schema is
openapi: 3.0.2
info:
title: Genedata
version: 1.0.0
description: API for interacting with gene records
servers:
- url: http://127.0.0.1:8080
paths:
/api/gene/{id}/:
get:
operationId: RetrieveGene
description: ''
parameters:
- name: id
in: path
required: true
description: A unique integer value identifying this gene.
schema:
type: string
responses:
'200':
content:
application/json:
schema:
properties:
gene_id:
type: string
maxLength: 256
entity:
type: string
maxLength: 256
start:
type: integer
maximum: 2147483647
minimum: -2147483648
stop:
type: integer
maximum: 2147483647
minimum: -2147483648
sense:
type: string
maxLength: 1
start_codon:
type: string
maxLength: 1
ec:
properties:
id:
type: integer
readOnly: true
ec_name:
type: string
readOnly: true
type: object
sequencing:
properties:
id:
type: integer
readOnly: true
sequencing_factory:
type: string
readOnly: true
factory_location:
type: string
readOnly: true
type: object
required:
- gene_id
- entity
- sense
- ec
- sequencing
description: ''
post:
operationId: CreateGene
description: ''
parameters:
- name: id
in: path
required: true
description: A unique integer value identifying this gene.
schema:
type: string
requestBody:
content:
application/json:
schema: &id001
properties:
gene_id:
type: string
maxLength: 256
entity:
type: string
maxLength: 256
start:
type: integer
maximum: 2147483647
minimum: -2147483648
stop:
type: integer
maximum: 2147483647
minimum: -2147483648
sense:
type: string
maxLength: 1
start_codon:
type: string
maxLength: 1
ec:
properties:
id:
type: integer
readOnly: true
ec_name:
type: string
readOnly: true
type: object
sequencing:
properties:
id:
type: integer
readOnly: true
sequencing_factory:
type: string
readOnly: true
factory_location:
type: string
readOnly: true
type: object
required:
- gene_id
- entity
- sense
- ec
- sequencing
application/x-www-form-urlencoded:
schema: *id001
multipart/form-data:
schema: *id001
responses:
'200':
content:
application/json:
schema:
properties:
gene_id:
type: string
maxLength: 256
entity:
type: string
maxLength: 256
start:
type: integer
maximum: 2147483647
minimum: -2147483648
stop:
type: integer
maximum: 2147483647
minimum: -2147483648
sense:
type: string
maxLength: 1
start_codon:
type: string
maxLength: 1
ec:
properties:
id:
type: integer
readOnly: true
ec_name:
type: string
readOnly: true
type: object
sequencing:
properties:
id:
type: integer
readOnly: true
sequencing_factory:
type: string
readOnly: true
factory_location:
type: string
readOnly: true
type: object
required:
- gene_id
- entity
- sense
- ec
- sequencing
description: ''
put:
operationId: UpdateGene
description: ''
parameters:
- name: id
in: path
required: true
description: A unique integer value identifying this gene.
schema:
type: string
requestBody:
content:
application/json:
schema: &id002
properties:
gene_id:
type: string
maxLength: 256
entity:
type: string
maxLength: 256
start:
type: integer
maximum: 2147483647
minimum: -2147483648
stop:
type: integer
maximum: 2147483647
minimum: -2147483648
sense:
type: string
maxLength: 1
start_codon:
type: string
maxLength: 1
ec:
properties:
id:
type: integer
readOnly: true
ec_name:
type: string
readOnly: true
type: object
sequencing:
properties:
id:
type: integer
readOnly: true
sequencing_factory:
type: string
readOnly: true
factory_location:
type: string
readOnly: true
type: object
required:
- gene_id
- entity
- sense
- ec
- sequencing
application/x-www-form-urlencoded:
schema: *id002
multipart/form-data:
schema: *id002
responses:
'200':
content:
application/json:
schema:
properties:
gene_id:
type: string
maxLength: 256
entity:
type: string
maxLength: 256
start:
type: integer
maximum: 2147483647
minimum: -2147483648
stop:
type: integer
maximum: 2147483647
minimum: -2147483648
sense:
type: string
maxLength: 1
start_codon:
type: string
maxLength: 1
ec:
properties:
id:
type: integer
readOnly: true
ec_name:
type: string
readOnly: true
type: object
sequencing:
properties:
id:
type: integer
readOnly: true
sequencing_factory:
type: string
readOnly: true
factory_location:
type: string
readOnly: true
type: object
required:
- gene_id
- entity
- sense
- ec
- sequencing
description: ''
delete:
operationId: DestroyGene
description: ''
parameters:
- name: id
in: path
required: true
description: A unique integer value identifying this gene.
schema:
type: string
responses:
'204':
description: ''
/api/genes:
get:
operationId: listGenes
description: 'Get a list of genes'
parameters: []
responses:
'200':
content:
application/json:
schema:
type: array
items:
properties:
id:
type: integer
readOnly: true
gene_id:
type: string
maxLength: 256
required:
- gene_id
description: 'Sucesfully returns gene list'
I guess fixed by #55
That looks like it is the issue. I don't have code/system set up to confirm that this is the fix right now though.
Still getting this exact error, not sure what i'd need to include in the schema for this to disappear. The schema was generated using FastAPI.
{
"openapi": "3.0.2",
"info": {
"title": "FastAPI",
"version": "0.1.0"
},
"servers": [
{
"url": "http://localhost:8000",
"description": "Staging environment"
}
],
"paths": {
"/": {
"get": {
"summary": "Root",
"operationId": "root__get",
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {}
}
}
}
}
}
},
"/hello/{name}": {
"get": {
"summary": "Say Hello",
"operationId": "say_hello_hello__name__get",
"parameters": [
{
"required": true,
"schema": {
"title": "Name",
"type": "string"
},
"name": "name",
"in": "path"
}
],
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {}
}
}
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {"$ref": "#/components/schemas/HTTPValidationError"}
}
}
}
}
}
}
},
"components": {
"schemas": {
"HTTPValidationError": {
"title": "HTTPValidationError",
"type": "object",
"properties": {
"detail": {
"title": "Detail",
"type": "array",
"items": {"$ref": "#/components/schemas/ValidationError"}
}
}
},
"ValidationError": {
"title": "ValidationError",
"required": [
"loc",
"msg",
"type"
],
"type": "object",
"properties": {
"loc": {
"title": "Location",
"type": "array",
"items": {"type": "string"}
},
"msg": {
"title": "Message",
"type": "string"
},
"type": {
"title": "Error Type",
"type": "string"
}
}
}
}
}
}
This is unrelated to the array problem.
"schema": {}
Can you post the API signature for root__get and say_hello_hello__name__get?, I think they lack a definition for the response/return value.
I'm hoping you mean the method signature:
from fastapi import FastAPI
app = FastAPI(servers=[{"url": "http://localhost:8000", "description": "Staging environment"}, ])
@app.get("/")
async def root():
return {"message": "Hello World"}
@app.get("/hello/{name}")
async def say_hello(name: str):
return {"message": f"Hello {name}"}
the response/return type is undefined.
define it:
from fastapi import FastAPI, BaseModel
app = FastAPI(servers=[{"url": "http://localhost:8000", "description": "Staging environment"}, ])
class Message(BaseModel):
message:str
@app.get("/", response_model=Message)
async def root():
return Message(message="Hello World")
@app.get("/hello/{name}", responses={200:{"model": Message}})
async def say_hello(name: str):
return Message(message=f"Hello {name}")
untested.