flask-openapi3 icon indicating copy to clipboard operation
flask-openapi3 copied to clipboard

operation_id_callback does not get called with the correct parameters

Open jangxx opened this issue 8 months ago • 7 comments

Environment:

  • Python version: 3.10.12
  • Operating system: Linux Mint 21.1
  • Flask version: 3.1.0
  • flask-openapi3 version: 4.1.0

I'm trying to influence the generation of the operationIds of my API and according to the documentation I can supply a function to APIBlueprint as the operation_id_callback, which is then supposed to be called with the name of the method and other parameters.

Sadly this does not work. The first parameter seems to always be the name of the blueprint instead of the name of the annotated method, making the callback completely useless.

Minimal testcase:

from flask_openapi3 import OpenAPI, APIBlueprint

def get_operation_id_for_path(*, name: str, path: str, method: str) -> str:
    print(name, path, method)
    return name

app = OpenAPI(__name__)

blueprint = APIBlueprint("test", "minimal_test", operation_id_callback=get_operation_id_for_path)

@blueprint.get('/')
def hello_world():
    return 'Hello, World!'

app.register_api(blueprint)

if __name__ == '__main__':
    app.run()

This will output test / HTTPMethod.GET instead of the expected hello_world / HTTPMethod.GET.

jangxx avatar Mar 27 '25 11:03 jangxx

In fact, this is to address intentionally the same endpoint(#127).

luolingchun avatar Apr 10 '25 02:04 luolingchun

Okay I see. Would it be possible to change the operation ID callback then, so that we get both the name of the blueprint and the name of the decorated function? Both of these are necessary to generate an operation ID and I really don't see how I could generate it based only on the name of the blueprint.

jangxx avatar Apr 10 '25 08:04 jangxx

To maintain compatibility, I suggest concatenating the blueprint name with the function name, or you can think of a better approach.

Hope you have time to submit a PR.

e.g. "test&hello_world" or "test-hello_world" ...

luolingchun avatar Apr 10 '25 09:04 luolingchun

That's what I'm trying to do, but the ID factory gets called with only the blueprint name so how am I supposed to concatenate the function name to it if I can't access it within the factory?

jangxx avatar Apr 10 '25 09:04 jangxx

https://github.com/luolingchun/flask-openapi3/blob/master/flask_openapi3/blueprint.py#L166

self.name is blueprint name, you can concatenate self.name and func.__name__

luolingchun avatar Apr 10 '25 09:04 luolingchun

Look, the factory has this signature

def get_operation_id_for_path(*, name: str, path: str, method: str) -> str

Where is self coming from? Where is func coming from? All I have is the name of the blueprint, the path and the method. There is no way for me to access the name of the decorated function in this factory, which is exactly what this issue is about.

jangxx avatar Apr 10 '25 09:04 jangxx

Yes, the current situation is like this. What I mean is that you should submit a PR to concatenate self.name and func.__name__, and then the callback function can receive the concatenated result.

luolingchun avatar Apr 10 '25 09:04 luolingchun