Search code examples
pythonopenapiconnexion

ModuleNotFoundError in Connexion


I have an OpenAPI 3.0 specification and I want to use it with Connexion to run a Python service.

The relevant part of the API specification is here:

paths:
  /find:
    post:
      summary: XXX
      description: XXX
      operationId: service.controllers.api.find
      requestBody:
        content:
          application/json:
            schema:
              type: object
              [...]
servers:
  - url: /v2
[...]

The Python code is structured like this:

├── lib
│   └── service
│       ├── controllers
│       │   ├── api.py
│       │   ├── __init__.py
│       ├── __init__.py
│       ├── models
│       │   └── __init__.py
│       └── resources
│           └── openapi
│               └── openapi.yaml

The content of api.py:

def find():
    return "TEST"

The find function itself works as expected:

import service.controllers.api
service.controllers.api.find_skills()

'TEST'

In Python, Connexion loads the API fine:

import connexion
app = connexion.FlaskApp(__name__, 
specification_dir='lib/service/resources/openapi/')
app.add_api('openapi.yaml')                                                                                                

<connexion.apis.flask_api.FlaskApi at 0x7f2241e35b38>

app.run()

Now, I can call the endpoint with success:

$ curl -X POST http://localhost:5000/v2/find

However, when I run it using the Connexion CLI, I see a ModuleNotFoundError:

$ connexion run lib/service/resources/openapi/openapi.yaml

Output:

ERROR:connexion.apis.abstract:Failed to add operation for POST /v2/find
Traceback (most recent call last):
  File "/home/XXX/anaconda3/envs/find/lib/python3.6/site-packages/connexion/apis/abstract.py", line 206, in add_paths
    self.add_operation(path, method)
[...]
  File "/home/XXX/anaconda3/envs/find/lib/python3.6/site-packages/connexion/resolver.py", line 64, in resolve_function_from_operation_id
raise ResolverError(msg, sys.exc_info())
connexion.exceptions.ResolverError: <ResolverError: Cannot resolve operationId "service.controllers.api.find"! Import error was "No module named 'service'">

In this case, something is probably wrong with the paths/package names. However, I have also tried many variations of calling it from within the lib directory etc., but no luck. Also, I tried using the method name only and to specify the package in the x-swagger-router-controller property, but no luck either.

I could not find more specific details about how to specify the operationId correctly in the Connexion documentation, so I am not even clear if this is related to the Python module itself, to the OpenAPI specification, or to the way of calling Connexion.

Any hints on where to start digging? Why does the command line client not find the service module? Where is the module supposed to reside relative to the working directory?


Solution

  • I could not reproduce your problem but I believe it happens due to the PYTHONPATH.

    Try execute:

    PYTHONPATH=. connexion run lib/service/resources/openapi/openapi.yaml