ipfs / pinning-services-api-spec

Standalone, vendor-agnostic Pinning Service API for IPFS ecosystem
https://ipfs.github.io/pinning-services-api-spec/
Creative Commons Zero v1.0 Universal
102 stars 27 forks source link

JS server generation problems #68

Open Gozala opened 4 years ago

Gozala commented 4 years ago

My attempts to generate a server from the current API spec seems to produce invalid results. Below are the steps:

openapi-generator generate -i https://raw.githubusercontent.com/ipfs/pinning-services-api-spec/master/ipfs-pinning-service.yaml -g nodejs-express-server

npm start

 node index.js

{"message":"Express server running","level":"info","service":"user-service","timestamp":"2020-11-19T23:26:26.420Z"}
info: Express server running {"service":"user-service","timestamp":"2020-11-19T23:26:26.420Z"}
openapi.validator: Validating schema
openapi.validator: validation errors [
  {
    "keyword": "required",
    "dataPath": ".paths['/pins']['get'].parameters[7]",
    "schemaPath": "#/definitions/SchemaXORContent/oneOf/0/required",
    "params": {
      "missingProperty": "schema"
    },
    "message": "should have required property 'schema'"
  },
  {
    "keyword": "not",
    "dataPath": ".paths['/pins']['get'].parameters[7]",
    "schemaPath": "#/definitions/SchemaXORContent/oneOf/1/allOf/0/not",
    "params": {},
    "message": "should NOT be valid"
  },
  {
    "keyword": "not",
    "dataPath": ".paths['/pins']['get'].parameters[7]",
    "schemaPath": "#/definitions/SchemaXORContent/oneOf/1/allOf/1/not",
    "params": {},
    "message": "should NOT be valid"
  },
  {
    "keyword": "oneOf",
    "dataPath": ".paths['/pins']['get'].parameters[7]",
    "schemaPath": "#/definitions/SchemaXORContent/oneOf",
    "params": {
      "passingSchemas": null
    },
    "message": "should match exactly one schema in oneOf"
  },
  {
    "keyword": "required",
    "dataPath": ".paths['/pins']['get'].parameters[7]",
    "schemaPath": "#/definitions/Reference/required",
    "params": {
      "missingProperty": "$ref"
    },
    "message": "should have required property '$ref'"
  },
  {
    "keyword": "oneOf",
    "dataPath": ".paths['/pins']['get'].parameters[7]",
    "schemaPath": "#/properties/parameters/items/oneOf",
    "params": {
      "passingSchemas": null
    },
    "message": "should match exactly one schema in oneOf"
  },
  {
    "keyword": "required",
    "dataPath": ".components.parameters['meta']",
    "schemaPath": "#/definitions/Reference/required",
    "params": {
      "missingProperty": "$ref"
    },
    "message": "should have required property '$ref'"
  },
  {
    "keyword": "required",
    "dataPath": ".components.parameters['meta']",
    "schemaPath": "#/definitions/SchemaXORContent/oneOf/0/required",
    "params": {
      "missingProperty": "schema"
    },
    "message": "should have required property 'schema'"
  },
  {
    "keyword": "not",
    "dataPath": ".components.parameters['meta']",
    "schemaPath": "#/definitions/SchemaXORContent/oneOf/1/allOf/0/not",
    "params": {},
    "message": "should NOT be valid"
  },
  {
    "keyword": "not",
    "dataPath": ".components.parameters['meta']",
    "schemaPath": "#/definitions/SchemaXORContent/oneOf/1/allOf/1/not",
    "params": {},
    "message": "should NOT be valid"
  },
  {
    "keyword": "oneOf",
    "dataPath": ".components.parameters['meta']",
    "schemaPath": "#/definitions/SchemaXORContent/oneOf",
    "params": {
      "passingSchemas": null
    },
    "message": "should match exactly one schema in oneOf"
  },
  {
    "keyword": "oneOf",
    "dataPath": ".components.parameters['meta']",
    "schemaPath": "#/properties/parameters/patternProperties/%5E%5Ba-zA-Z0-9%5C.%5C-_%5D%2B%24/oneOf",
    "params": {
      "passingSchemas": null
    },
    "message": "should match exactly one schema in oneOf"
  }
]
Error: openapi.validator: args.apiDoc was invalid.  See the output.
    at OpenAPIFramework.initialize (/Users/gozala/Projects/js-mock-pinning-service/node_modules/express-openapi-validator/dist/framework/index.js:32:23)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
    at async OpenApiSpecLoader.discoverRoutes (/Users/gozala/Projects/js-mock-pinning-service/node_modules/express-openapi-validator/dist/framework/openapi.spec.loader.js:47:39)
Listening on port 3000

I'm bit lost with all the stuff it generated right now, but I'll post updates as I make progress here.

Gozala commented 4 years ago

Pretty gross but I managed to generate a server from https://editor.swagger.io/ which I had to patch here and there to run

Gozala commented 4 years ago

End up switching to https://github.com/isa-group/oas-generator instead.

lidel commented 4 years ago

I'll try to reproduce openapi-generator-cli and fill upstream issue if needed. Our YAML is passing validation on CI (done with github/super-linter), so probably a bug in the nodejs-express-server generator.

lidel commented 4 years ago

@Gozala filled https://github.com/OpenAPITools/openapi-generator/issues/7992 – are you blocked on this, or are we ok with using oas-generator instead?

Gozala commented 4 years ago

No I’m not blocked, had being working with oas-generator produced output. But I should point out that https://editor.swagger.io/ also produced bundle that was complaining about the yml file. And same was true with https://github.com/lukeautry/tsoa as well and bunch of other I tried from https://openapi.tools/#server

So whatever the issue is I think there is something about our schema that causes problems.

While oas works it still produces some odd result specifically request.swaggare.params seem to put everything under field named undefined on POST /pins which makes me wonder if schema is missing a name somewhere which breaks all the other generators.

sailccsa commented 3 years ago

I've got the same error, or at least with paths['/pins']['get'].parameters[7] matching oneOf a provided schema when using the python-flask and python-aiohttp generators.

sailccsa commented 3 years ago

Using openapi-generator-cli >= 4.0.0 the error is moved to actually running the app:

Traceback (most recent call last):
  File "/usr/lib64/python3.9/runpy.py", line 197, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/usr/lib64/python3.9/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/home/gwalters/software/code/ipfs-pinning-service/flask-app/openapi_server/__main__.py", line 19, in <module>
    main()
  File "/home/gwalters/software/code/ipfs-pinning-service/flask-app/openapi_server/__main__.py", line 11, in main
    app.add_api('openapi.yaml',
  File "/home/gwalters/software/code/ipfs-pinning-service/venv/lib/python3.9/site-packages/connexion/apps/flask_app.py", line 57, in add_api
    api = super(FlaskApp, self).add_api(specification, **kwargs)
  File "/home/gwalters/software/code/ipfs-pinning-service/venv/lib/python3.9/site-packages/connexion/apps/abstract.py", line 144, in add_api
    api = self.api_cls(specification,
  File "/home/gwalters/software/code/ipfs-pinning-service/venv/lib/python3.9/site-packages/connexion/apis/abstract.py", line 75, in __init__
    self.specification = Specification.load(specification, arguments=arguments)
  File "/home/gwalters/software/code/ipfs-pinning-service/venv/lib/python3.9/site-packages/connexion/spec.py", line 153, in load
    return cls.from_file(spec, arguments=arguments)
  File "/home/gwalters/software/code/ipfs-pinning-service/venv/lib/python3.9/site-packages/connexion/spec.py", line 107, in from_file
    return cls.from_dict(spec)
  File "/home/gwalters/software/code/ipfs-pinning-service/venv/lib/python3.9/site-packages/connexion/spec.py", line 145, in from_dict
    return OpenAPISpecification(spec)
  File "/home/gwalters/software/code/ipfs-pinning-service/venv/lib/python3.9/site-packages/connexion/spec.py", line 38, in __init__
    self._validate_spec(raw_spec)
  File "/home/gwalters/software/code/ipfs-pinning-service/venv/lib/python3.9/site-packages/connexion/spec.py", line 239, in _validate_spec
    raise InvalidSpecification.create_from(e)
connexion.exceptions.InvalidSpecification: {'description': 'Response used for listing pin objects matching request', 'properties': {'count': {'description': 'The total number of pin objects that exist for passed query filters', 'example': 1, 'format': 'int32', 'minimum': 0, 'type': 'integer'}, 'results': {'description': 'An array of PinStatus results', 'items': {'$ref': '#/components/schemas/PinStatus'}, 'maxItems': 1000, 'minItems': 0, 'type': 'array', 'uniqueItems': True}}, 'required': ['count', 'results'], 'type': 'object'} is not valid under any of the given schemas

Failed validating 'oneOf' in schema['properties']['paths']['patternProperties']['^\\/']['patternProperties']['^(get|put|post|delete|options|head|patch|trace)$']['properties']['responses']['patternProperties']['^[1-5](?:\\d{2}|XX)$']:
    {'oneOf': [{'$ref': '#/definitions/Response'},
               {'$ref': '#/definitions/Reference'}]}

On instance['paths']['/pins']['get']['responses']['200']:
    {'$ref': '#/components/schemas/PinResults', 'x-scope': ['']}

Using lesser versions the generator doesn't run successfully.

Here's an easy way to reproduce the issue:

openapi-generator-cli version-manager set 3.3.4
openapi-generator-cli generate -i https://github.com/ipfs/pinning-services-api-spec/raw/main/ipfs-pinning-service.yaml -g python-flask -o flask-app
[main] INFO  o.o.c.ignore.CodegenIgnoreProcessor - No .openapi-generator-ignore file found.
[main] INFO  o.o.c.l.PythonFlaskConnexionServerCodegen - Environment variable PYTHON_POST_PROCESS_FILE not defined so the Python code may not be properly formatted. To define it, try 'export PYTHON_POST_PROCESS_FILE="/usr/local/bin/yapf -i"' (Linux/Mac)
[main] INFO  o.o.c.l.PythonFlaskConnexionServerCodegen - NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).
[main] WARN  o.o.codegen.DefaultCodegen - Empty operationId found for path: GET /pins. Renamed to auto-generated operationId: pinsGET
[main] WARN  o.o.codegen.DefaultCodegen - Empty operationId found for path: POST /pins. Renamed to auto-generated operationId: pinsPOST
[main] WARN  o.o.codegen.DefaultCodegen - Empty operationId found for path: GET /pins/{requestid}. Renamed to auto-generated operationId: pinsRequestidGET
[main] WARN  o.o.codegen.DefaultCodegen - Empty operationId found for path: POST /pins/{requestid}. Renamed to auto-generated operationId: pinsRequestidPOST
[main] WARN  o.o.codegen.DefaultCodegen - Empty operationId found for path: DELETE /pins/{requestid}. Renamed to auto-generated operationId: pinsRequestidDELETE
[main] INFO  o.o.codegen.DefaultGenerator - Model Delegates not generated since it's an alias to array (without property)
[main] INFO  o.o.codegen.DefaultGenerator - Model Origins not generated since it's an alias to array (without property)
[main] INFO  o.o.codegen.DefaultGenerator - Model PinMeta not generated since it's an alias to map (without property)
[main] INFO  o.o.codegen.DefaultGenerator - Model StatusInfo not generated since it's an alias to map (without property)
[main] INFO  o.o.codegen.AbstractGenerator - writing file /home/gwalters/software/code/ipfs-pinning-service/flask-app/openapi_server/models/failure.py
[main] INFO  o.o.codegen.AbstractGenerator - writing file /home/gwalters/software/code/ipfs-pinning-service/flask-app/openapi_server/models/failure_error.py
[main] INFO  o.o.codegen.AbstractGenerator - writing file /home/gwalters/software/code/ipfs-pinning-service/flask-app/openapi_server/models/pin.py
[main] INFO  o.o.codegen.AbstractGenerator - writing file /home/gwalters/software/code/ipfs-pinning-service/flask-app/openapi_server/models/pin_results.py
[main] INFO  o.o.codegen.AbstractGenerator - writing file /home/gwalters/software/code/ipfs-pinning-service/flask-app/openapi_server/models/pin_status.py
[main] INFO  o.o.codegen.AbstractGenerator - writing file /home/gwalters/software/code/ipfs-pinning-service/flask-app/openapi_server/models/status.py
[main] INFO  o.o.codegen.AbstractGenerator - writing file /home/gwalters/software/code/ipfs-pinning-service/flask-app/openapi_server/models/text_matching_strategy.py
[main] ERROR o.o.codegen.DefaultCodegen - ERROR! Not handling  class QueryParameter {
    class Parameter {
        name: meta
        in: null
        description: Return pin objects that match specified metadata keys passed as a string representation of a JSON object; when implementing a client library, make sure the parameter is URL-encoded to ensure safe transport
        required: false
        deprecated: null
        allowEmptyValue: null
        style: form
        explode: true
        allowReserved: null
        schema: null
        examples: null
        example: null
        content: class Content {
            {application/json=class MediaType {
                schema: class Schema {
                    title: null
                    multipleOf: null
                    maximum: null
                    exclusiveMaximum: null
                    minimum: null
                    exclusiveMinimum: null
                    maxLength: null
                    minLength: null
                    pattern: null
                    maxItems: null
                    minItems: null
                    uniqueItems: null
                    maxProperties: null
                    minProperties: null
                    required: null
                    type: null
                    not: null
                    properties: null
                    additionalProperties: null
                    description: null
                    format: null
                    $ref: #/components/schemas/PinMeta
                    nullable: null
                    readOnly: null
                    writeOnly: null
                    example: null
                    externalDocs: null
                    deprecated: null
                    discriminator: null
                    xml: null
                }
                examples: null
                example: null
                encoding: null
            }}
        }
        $ref: null
    }
    in: query
} as Body Parameter at the moment
[main] ERROR o.o.codegen.DefaultCodegen - ERROR! Not handling  class QueryParameter {
    class Parameter {
        name: meta
        in: null
        description: Return pin objects that match specified metadata keys passed as a string representation of a JSON object; when implementing a client library, make sure the parameter is URL-encoded to ensure safe transport
        required: false
        deprecated: null
        allowEmptyValue: null
        style: form
        explode: true
        allowReserved: null
        schema: null
        examples: null
        example: null
        content: class Content {
            {application/json=class MediaType {
                schema: class Schema {
                    title: null
                    multipleOf: null
                    maximum: null
                    exclusiveMaximum: null
                    minimum: null
                    exclusiveMinimum: null
                    maxLength: null
                    minLength: null
                    pattern: null
                    maxItems: null
                    minItems: null
                    uniqueItems: null
                    maxProperties: null
                    minProperties: null
                    required: null
                    type: null
                    not: null
                    properties: null
                    additionalProperties: null
                    description: null
                    format: null
                    $ref: #/components/schemas/PinMeta
                    nullable: null
                    readOnly: null
                    writeOnly: null
                    example: null
                    externalDocs: null
                    deprecated: null
                    discriminator: null
                    xml: null
                }
                examples: null
                example: null
                encoding: null
            }}
        }
        $ref: null
    }
    in: query
} as Body Parameter at the moment
[main] WARN  o.o.codegen.DefaultCodegen - Parameter name not defined properly. Default to UNKNOWN_PARAMETER_NAME
[main] INFO  o.o.codegen.AbstractGenerator - writing file /home/gwalters/software/code/ipfs-pinning-service/flask-app/openapi_server/controllers/pins_controller.py
[main] INFO  o.o.codegen.AbstractGenerator - writing file /home/gwalters/software/code/ipfs-pinning-service/flask-app/openapi_server/test/test_pins_controller.py
[main] INFO  o.o.codegen.AbstractGenerator - writing file /home/gwalters/software/code/ipfs-pinning-service/flask-app/README.md
[main] INFO  o.o.codegen.AbstractGenerator - writing file /home/gwalters/software/code/ipfs-pinning-service/flask-app/setup.py
[main] INFO  o.o.codegen.AbstractGenerator - writing file /home/gwalters/software/code/ipfs-pinning-service/flask-app/tox.ini
[main] INFO  o.o.codegen.AbstractGenerator - writing file /home/gwalters/software/code/ipfs-pinning-service/flask-app/test-requirements.txt
[main] INFO  o.o.codegen.AbstractGenerator - writing file /home/gwalters/software/code/ipfs-pinning-service/flask-app/requirements.txt
[main] INFO  o.o.codegen.AbstractGenerator - writing file /home/gwalters/software/code/ipfs-pinning-service/flask-app/git_push.sh
[main] INFO  o.o.codegen.AbstractGenerator - writing file /home/gwalters/software/code/ipfs-pinning-service/flask-app/.gitignore
[main] INFO  o.o.codegen.AbstractGenerator - writing file /home/gwalters/software/code/ipfs-pinning-service/flask-app/.travis.yml
[main] INFO  o.o.codegen.AbstractGenerator - writing file /home/gwalters/software/code/ipfs-pinning-service/flask-app/Dockerfile
[main] INFO  o.o.codegen.AbstractGenerator - writing file /home/gwalters/software/code/ipfs-pinning-service/flask-app/.dockerignore
[main] INFO  o.o.codegen.AbstractGenerator - writing file /home/gwalters/software/code/ipfs-pinning-service/flask-app/openapi_server/__init__.py
[main] INFO  o.o.codegen.AbstractGenerator - writing file /home/gwalters/software/code/ipfs-pinning-service/flask-app/openapi_server/__main__.py
[main] INFO  o.o.codegen.AbstractGenerator - writing file /home/gwalters/software/code/ipfs-pinning-service/flask-app/openapi_server/encoder.py
[main] INFO  o.o.codegen.AbstractGenerator - writing file /home/gwalters/software/code/ipfs-pinning-service/flask-app/openapi_server/util.py
[main] INFO  o.o.codegen.AbstractGenerator - writing file /home/gwalters/software/code/ipfs-pinning-service/flask-app/openapi_server/controllers/__init__.py
[main] INFO  o.o.codegen.AbstractGenerator - writing file /home/gwalters/software/code/ipfs-pinning-service/flask-app/openapi_server/models/__init__.py
[main] INFO  o.o.codegen.AbstractGenerator - writing file /home/gwalters/software/code/ipfs-pinning-service/flask-app/openapi_server/models/base_model_.py
[main] INFO  o.o.codegen.AbstractGenerator - writing file /home/gwalters/software/code/ipfs-pinning-service/flask-app/openapi_server/test/__init__.py
[main] INFO  o.o.codegen.AbstractGenerator - writing file /home/gwalters/software/code/ipfs-pinning-service/flask-app/openapi_server/openapi/openapi.yaml
[main] INFO  o.o.codegen.AbstractGenerator - writing file /home/gwalters/software/code/ipfs-pinning-service/flask-app/.openapi-generator-ignore
[main] INFO  o.o.codegen.AbstractGenerator - writing file /home/gwalters/software/code/ipfs-pinning-service/flask-app/.openapi-generator/VERSION
anakornk commented 2 years ago

Same problem here. Any updates on this?