flasgger / flasgger

Easy OpenAPI specs and Swagger UI for your Flask API
http://flasgger.pythonanywhere.com/
MIT License
3.62k stars 525 forks source link

[RESOLVED] Definitions cause infinite loop loading Swagger UI #53

Closed stevencox closed 7 years ago

stevencox commented 7 years ago

Hi folks, great work. When I include a "definition" in my swagger spec, which otherwise works, I get this error:

127.0.0.1 - - [20/Mar/2017 22:00:17] "GET /specs HTTP/1.1" 200 -
127.0.0.1 - - [20/Mar/2017 22:00:17] "GET /v1/spec HTTP/1.1" 500 -
Traceback (most recent call last):
  File "/Users/scox/dev/exposures/venv/lib/python3.6/site-packages/flask/app.py", line 1994, in __call__
    return self.wsgi_app(environ, start_response)
  File "/Users/scox/dev/exposures/venv/lib/python3.6/site-packages/flask/app.py", line 1985, in wsgi_app
    response = self.handle_exception(e)
  File "/Users/scox/dev/exposures/venv/lib/python3.6/site-packages/flask/app.py", line 1540, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/Users/scox/dev/exposures/venv/lib/python3.6/site-packages/flask/_compat.py", line 33, in reraise
    raise value
  File "/Users/scox/dev/exposures/venv/lib/python3.6/site-packages/flask/app.py", line 1982, in wsgi_app
    response = self.full_dispatch_request()
  File "/Users/scox/dev/exposures/venv/lib/python3.6/site-packages/flask/app.py", line 1614, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/Users/scox/dev/exposures/venv/lib/python3.6/site-packages/flask/app.py", line 1517, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/Users/scox/dev/exposures/venv/lib/python3.6/site-packages/flask/_compat.py", line 33, in reraise
    raise value
  File "/Users/scox/dev/exposures/venv/lib/python3.6/site-packages/flask/app.py", line 1612, in full_dispatch_request
    rv = self.dispatch_request()
  File "/Users/scox/dev/exposures/venv/lib/python3.6/site-packages/flask/app.py", line 1598, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/Users/scox/dev/exposures/venv/lib/python3.6/site-packages/flask/views.py", line 84, in view
    return self.dispatch_request(*args, **kwargs)
  File "/Users/scox/dev/exposures/venv/lib/python3.6/site-packages/flask/views.py", line 149, in dispatch_request
    return meth(*args, **kwargs)
  File "/Users/scox/dev/exposures/venv/lib/python3.6/site-packages/flasgger/base.py", line 267, in get
    verb=verb)
  File "/Users/scox/dev/exposures/venv/lib/python3.6/site-packages/flasgger/base.py", line 123, in _extract_definitions
    schema = item.get("schema")
AttributeError: 'str' object has no attribute 'get'

I'm using an external yaml file for a single operation so I could see how a definition might not be in the correct context for that file. So I looked for an example using definitions in this repo but didn't see any. What am I doing wrong?

rochacbruno commented 7 years ago

Can you share your YAML?

Looks like you defined something as string when should be a dict

stevencox commented 7 years ago

@rochacbruno, the YAML is pasted below. It's also available in the Swagger editor like this if that's helpful:

What I'd really like to do is use the spec as a whole like it is below, including for validation. Is that an option? i.e. instead of splitting it up into separate operations.

swagger: '2.0'
info:
  contact:
    responsibleDeveloper: Data Translator Green Team
    url: www.renci.org
    email: help@renci.org
    responsibleOrganization: Data Translator Green Team
  title: Exposure API
  description: API for environmental exposure models for NIH Data Translator program
  termsOfService: None Available
  version: 0.0.1
host: renci.org
basePath: /DataTranslatorExposures/api
schemes:
  - http
paths:
  '/exposureValue/{exposure}':
    get:
      description: >-
        Retrieve the computed exposure value for a given environmental exposure
        factor, time period, and set of locations
      operationId: getExposureValue
      responses:
        '200':
          description: successful operation
          schema:
            type: array
            items:
              $ref: '#/definitions/Exposures'
      parameters:
        - name: exposure
          in: path
          description: 'The name of the exposure factor (currently limited to pm25, ozone).'
          required: true
          type: string
        - name: stime
          in: query
          description: >-
            The starting date to obtain exposures for (example 1985-04-12 is
            April 12th 1985). Currently time of day is ignored.
          required: true
          type: string
        - name: etime
          in: query
          description: >-
            The ending date to obtain exposures for (example 1985-04-13 is April
            13th 1985). Currently time of day is ignored.
          required: true
          type: string
        - name: loc
          in: query
          description: >-
            A description of the location(s) to retrieve the exposure for.
            Locaton may be a single geocoordinate (example
            '35.720278,-79.176389') or a semicomma separated list of
            geocoord:dayhours giving the start and ending hours on specific days
            of the week at that location (example
            '35.720278,-79.176389,Sa0813;35.720278,-79.176389,other') indicates
            Saturdays from 8am to 1pm is at one location and all other times are
            at another location. Hours should be in 24 hours time using 2
            digits, days of the week should be the first two characters of the
            day.If the day of the week does not appear then the time periods
            apply to all days (example
            '35.720278,-79.176389,0614,35.731944,-78.852778,1424') gives two
            time periods for all days. If hours do not appear then the time
            period applies to all hours of the day (example
            '35.720278,-79.176389,Sa,35.731944,-78.852778,Su').
          required: true
          type: string
        - name: tres
          in: query
          description: >-
            The temporal resolution to use for results, should be one of 'hour'
            or 'day'. Default is 'day'
          required: false
          type: string
        - name: tstat
          in: query
          description: >-
            The statistic to use for results, should be one of 'max', 'mean', or
            'median'. Default is 'max'
          required: false
          type: string
      summary: Get exposure value for a given environmental factor
      produces:
        - application/json
  '/exposureScore/{exposure}':
    get:
      description: >-
        Retrieve the computed exposure score for a given environmental exposure
        factor, time period, and set of locations
      operationId: getExposureScore
      responses:
        '200':
          description: successful operation
          schema:
            type: array
            items:
              $ref: '#/definitions/Exposures'
      parameters:
        - name: exposure
          in: path
          description: 'The name of the exposure factor (currently limited to pm25, ozone).'
          required: true
          type: string
        - name: stime
          in: query
          description: >-
            The starting date to obtain exposures for (example 1985-04-12 is
            April 12th 1985). Currently time of day is ignored.
          required: true
          type: string
        - name: etime
          in: query
          description: >-
            The ending date to obtain exposures for (example 1985-04-13 is April
            13th 1985). Currently time of day is ignored.
          required: true
          type: string
        - name: loc
          in: query
          description: >-
            A description of the location(s) to retrieve the exposure for.
            Locaton may be a single geocoordinate (example
            '35.720278,-79.176389') or a semicomma separated list of
            geocoord:dayhours giving the start and ending hours on specific days
            of the week at that location (example
            '35.720278,-79.176389,Sa0813;35.720278,-79.176389,other') indicates
            Saturdays from 8am to 1pm is at one location and all other times are
            at another location. Hours should be in 24 hours time using 2
            digits, days of the week should be the first two characters of the
            day.If the day of the week does not appear then the time periods
            apply to all days (example
            '35.720278,-79.176389,0614,35.731944,-78.852778,1424') gives two
            time periods for all days. If hours do not appear then the time
            period applies to all hours of the day (example
            '35.720278,-79.176389,Sa,35.731944,-78.852778,Su').
          required: true
          type: string
        - name: tres
          in: query
          description: >-
            The temporal resolution to use for results, should be one of 'hour'
            or 'day'. Default is 'day'
          required: false
          type: string
        - name: tscore
          in: query
          description: >-
            The exposure score type to return. The accepted values vary by
            exposure factor. For pm25 values are '7dayrisk', '14dayrisk' (NOT
            COMPLETE)
          required: false
          type: string
      summary: Get exposure score for a given environmental factor
      produces:
        - application/json
definitions:
  Exposures:
    type: object
    properties:
      values:
        $ref: '#/definitions/Exposure'
  Exposure:
    type: object
    properties:
      stime:
        type: string
        format: dateTime
        example: starting time for the given measure
      value:
        type: string
        example: numerical or categorical depending upon type of value being requested
      etime:
        type: string
        format: dateTime
        example: ending time for the given measure
stevencox commented 7 years ago

Here's the repo. I've split the entire spec above into this and changed the operation definition to include a schema to take advantage of flasgger as follows:

Get environmental exposure value operation
---
swagger: '2.0'
info:
  title: Exposure API
  description: API for environmental exposure models for NIH Data Translator program
  contact:
    responsibleOrganization: Data Translator Green Team
    responsibleDeveloper: Data Translator Green Team
    email: help@renci.org
    url: www.renci.org
  termsOfService: None Available
  version: 0.0.1
host: exposures.renci.org
basePath: /api
schemes:
  - [ "http", "https" ]
tags:
  - Exposure
operationId: getExposureScore
parameters:
  - name: body
    in: body
    required: true
    schema:
      id : exposureScoreRequestSchema
      required:
        - exposure
        - stime
        - etime
        - loc
      properties:
        exposure:
          description: 'The name of the exposure factor (currently limited to pm25, ozone).'
          required: [ "true" ]
          default: pm25
          type: string
        stime:
          description: >-
            The starting date to obtain exposures for (example 1985-04-12 is
            April 12th 1985). Currently time of day is ignored.
          required: [ "true" ]
          default: '1985-04-12'
          type: string
        etime:
          description: >-
            The ending date to obtain exposures for (example 1985-04-13 is April
            13th 1985). Currently time of day is ignored.
          default: '1985-04-12'
          required: [ "true" ]
          type: string
        loc:
          description: >-
            A description of the location(s) to retrieve the exposure for.
            Locaton may be a single geocoordinate (example
            '35.720278,-79.176389') or a semicomma separated list of
            geocoord:dayhours giving the start and ending hours on specific days
            of the week at that location (example
            '35.720278,-79.176389,Sa0813;35.720278,-79.176389,other') indicates
            Saturdays from 8am to 1pm is at one location and all other times are
            at another location. Hours should be in 24 hours time using 2
            digits, days of the week should be the first two characters of the
            day.If the day of the week does not appear then the time periods
            apply to all days (example
            '35.720278,-79.176389,0614,35.731944,-78.852778,1424') gives two
            time periods for all days. If hours do not appear then the time
            period applies to all hours of the day (example
            '35.720278,-79.176389,Sa,35.731944,-78.852778,Su').
          required: [ "true" ]
          default: '35.720278,-79.176389,Sa,35.731944,-78.852778,Su'
          type: string
        tres:
          description: >-
            The temporal resolution to use for results, should be one of 'hour'
            or 'day'. Default is 'day'
          required: [ "false" ]
          type: string
        tscore:
          description: >-
            The exposure score type to return. The accepted values vary by
            exposure factor. For pm25 values are '7dayrisk', '14dayrisk' (NOT
            COMPLETE)
          required: [ "false" ]
          type: string
produces:
  - application/json
summary: Get exposure score for a given environmental factor
description: >-
  Retrieve the computed exposure score for a given environmental exposure
  factor, time period, and set of locations
responses:
  '200':
    description: successful operation
    schema:
      items:
        $ref: '#/definitions/Exposures'
        type: array
definitions:
  Exposures:
    type: object
    properties:
      values:
        $ref: '#/definitions/Exposure'
  Exposure:
    type: object
    properties:
      stime:
        type: string
        format: dateTime
        example: starting time for the given measure
      value:
        type: string
        example: numerical or categorical depending upon type of value being requested
      etime:
        type: string
        format: dateTime
        example: ending time for the given measure

On the face of it, it doesn't seem like definitions really belong at the same level as an operation. It works great without that part. Anyway, any guidance is appreciated.

rochacbruno commented 7 years ago

I will try to reproduce your problem.

rochacbruno commented 7 years ago

@stevencox sent https://github.com/stevencox/exposures/pull/1