sharbov / open-cli

Generate client based on OpenAPI Specification and wrap it in a command line interface.
MIT License
52 stars 7 forks source link

Implicit assumption of base path #4

Open posener opened 6 years ago

posener commented 6 years ago

I've tried the opencli with a "imposter" mock server that I ran on the same swagger.yaml.

The command to run the mock server, assuming you have a swagger.yaml in CWD:

$ echo '{"plugin":"com.gatehill.imposter.plugin.openapi.OpenApiPluginImpl","specFile":"swagger.yaml"}' > openapi-plugin-petstore-config.json
$ docker run -ti -p 8443:8443 -v $PWD:/opt/imposter/config outofcoffee/imposter-openapi

The mock server serves the swagger.json on http://localhost:8443/_spec/combined.json - under _spec path. Running open-cli http://localhost:8443/_spec/combined.json -v results in:

Imposter Mock APIs $ pet Create --pet.name=kitty
DEBUG:open-cli:Parsing the input text pet Create --pet.name=kitty
DEBUG:open-cli:Invoke operation <bravado.client.CallableOperation object at 0x7f7e1e977590> with arguments {'pet': {'name': 'kitty'}}
DEBUG:bravado.client:Create({'pet': {'name': 'kitty'}})
DEBUG:urllib3.connectionpool:http://localhost:8443 "POST /_spec/combined.json/api/pets HTTP/1.1" 404 53
ERROR:open-cli:404 Not Found: Response specification matching http status_code 404 not found for operation Operation(Create). Either add a response specification for the status_code or use a `default` response.

The open-cli tries to access the api on path /_spec/combined.json/api/pets instead of /api/pets.

posener commented 6 years ago

I noticed that imposter modified the swagger: It removed the host and basePath from root of swagger and added it to each path entry.

Might it be the reason?

sharbov commented 6 years ago

The bravado client used by opencli uses the host & basePath to determine the endpoints URLs. If basePath is not specified, it defaults to /.

I've tries reproducing your problem but failed doing so, the said command returned

Imposter Mock APIs $ pet addPet --body.name=test
'photoUrls' is a required property

Failed validating 'required' in schema:
    {'properties': {'category': {'$ref': '#/definitions/Category',
                                 'x-scope': ['http://localhost:8443/_spec/combined.json']},
                    'id': {'format': 'int64', 'type': 'integer'},
                    'name': {'example': 'doggie', 'type': 'string'},
                    'photoUrls': {'items': {'type': 'string'},
                                  'type': 'array',
                                  'xml': {'name': 'photoUrl',
                                          'wrapped': True}},
                    'status': {'description': 'pet status in the store',
                               'enum': ['available', 'pending', 'sold'],
                               'type': 'string'},
                    'tags': {'items': {'$ref': '#/definitions/Tag',
                                       'x-scope': ['http://localhost:8443/_spec/combined.json']},
                             'type': 'array',
                             'xml': {'name': 'tag', 'wrapped': True}}},
     'required': ['name', 'photoUrls'],
     'type': 'object',
     'x-model': 'Pet',
     'xml': {'name': 'Pet'}}

On instance:
    {'name': 'test'}

Which is a valid response.

Can you attach the swagger file you've used.

posener commented 6 years ago

Please

swagger: '2.0'
info:
  version: '1.0.0'
  title: Minimal Pet Store Example
host: example.org
basePath: /api
schemes: [http]
consumes: [application/json]
produces: [application/json]
paths:
  /pets:
    post:
      tags: [pet]
      operationId: Create
      parameters:
      - in: body
        name: pet
        required: true
        schema:
          $ref: '#/definitions/Pet'
      responses:
        201:
          description: Pet Created
          schema:
            $ref: '#/definitions/Pet'
        400:
          description: Bad Request
    get:
      tags: [pet]
      operationId: List
      parameters:
      - in: query
        name: category
        type: string
      responses:
        200:
          description: 'Pet list'
          schema:
            type: array
            items:
                $ref: '#/definitions/Pet'
  /pets/{petId}:
    get:
      tags: [pet]
      operationId: Get
      parameters:
      - name: petId
        in: path
        required: true
        type: integer
        format: int64
      responses:
        200:
          description: Pet get
          schema:
            $ref: '#/definitions/Pet'
        400:
          description: Bad Request
        404:
          description: Pet Not Found

definitions:
  Pet:
    type: object
    required:
    - name
    properties:
      id:
        type: integer
        format: int64
        readOnly: true
      category:
        type: string
      name:
        type: string
        example: doggie