jmcarp / jmcarp/flask-apispec

Parameter schema object doesn't get linked to definition

Open
#62 4 comments 4 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
652
Forks
151
PR merge metrics
No merged PRs in 30d

Description

When I use a marshmallow schema object in parameters, it doesn't linked to definitions automatically. This is causing problems when I use `swagger-codegen`, because all the parameter objects are of `Body` class (thus I have `Body`, `Body1`, `Body2`, etc.), instead of the real schema class they are defined.

Here's the code snippet to reproduce the issue:

```python
from flask_script import Manager

from flask import Flask, make_response
from flask_restful import Api
from flask_apispec import FlaskApiSpec, MethodResource, use_kwargs, marshal_with

from marshmallow import fields, Schema

app = Flask(__name__)
api = Api(app)

class PetSchema(Schema):
class Meta:
fields = ('name',)

name = fields.String()

class PetResource(MethodResource):

@marshal_with(PetSchema)
def get(self, pet_id):
return {
'name': 'Jerry'
}

@use_kwargs(PetSchema)
@marshal_with(PetSchema, code=201)
def post(self, **kwargs):
return {
'name': 'Jerry'
}

api.add_resource(PetResource, '/pet/')

docs = FlaskApiSpec(app)
docs.spec.definition('PetSchema', schema=PetSchema)
docs.register(PetResource)

manager = Manager(app)

if __name__ == '__main__':
manager.run()
```

By running `python app.py runserver` and going to `localhost:5000/swagger`, I get the following Swagger JSON:

```json
{
"definitions": {
"PetSchema": {
"properties": {
"name": {
"type": "string"
}
},
"type": "object"
}
},
"info": {
"title": "flask-apispec",
"version": "v1"
},
"parameters": {},
"paths": {
"/pet/{pet_id}": {
"get": {
"parameters": [
{
"in": "path",
"name": "pet_id",
"required": true,
"type": "string"
}
],
"responses": {
"default": {
"description": "",
"schema": {
"$ref": "#/definitions/PetSchema"
}
}
}
},
"post": {
"parameters": [
{
"in": "body",
"name": "body",
"required": false,
"schema": {
"properties": {
"name": {
"type": "string"
}
},
"type": "object"
}
},
{
"in": "path",
"name": "pet_id",
"required": true,
"type": "string"
}
],
"responses": {
"201": {
"description": "",
"schema": {
"$ref": "#/definitions/PetSchema"
}
}
}
}
}
},
"swagger": "2.0",
"tags": []
}
```

One can see that while `"$ref": "#/definitions/PetSchema"` is correctly placed in `responses`, in `parameters` however, it's broken down. This causes `swagger-codegen` to fail to recognize the schema class, and use class `Body` in the generated code, which is a problem when the app have several routes with schema in parameters.

Is this an issue in `apispec` or `flask-apispec`? Any feedback would be much appreciated!

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with the provided FlaskApiSpec reproduction, especially use_kwargs(PetSchema), docs.spec.definition('PetSchema', schema=PetSchema), and the generated /swagger JSON. Trace how the POST body parameter is generated and compare it with the response reference. Done means the parameter points to the registered PetSchema definition and swagger-codegen recognizes the schema class.

Written by the indexing model from the issue text.

Assessment

Tech stack
flask, python
Domain
api, backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.