Giter VIP home page Giter VIP logo

Comments (14)

lafrech avatar lafrech commented on May 27, 2024 1

I'm afraid the content type (application/json) must be specified by the user.

The fact that you don't need to pass the components/requestBody part is nice, though.

from apispec.

lafrech avatar lafrech commented on May 27, 2024 1

I didn't check but I'm not sure what you're trying to achieve is valid OpenAPI. You may want to double-check.

I wouldn't worry about the duplication in the generated spec file. However, code factoring is nice. You could define a function to add the content type for you. Or use a wrapper such as flask-smorest that does that and more.

from apispec.

lafrech avatar lafrech commented on May 27, 2024 1

Yes, the feature should be added to apispec as per the "what's to be done" section of my comment.

You may try to achieve this in a local branch and propose a PR. (Feel free to ask if you're not used to do that.)

Thanks.

from apispec.

Kostadin-Ivanov avatar Kostadin-Ivanov commented on May 27, 2024 1

Thank you very much.

I will see if I have the time and might try to do something on it.
For this I will check the ApiSpec contributing guidelines.

from apispec.

lafrech avatar lafrech commented on May 27, 2024

I'm pretty sure it works by just passing

requestBody ="MyItem"

the string being interpreted as a ref (whether or not it is actually defined)

from apispec.

Kostadin-Ivanov avatar Kostadin-Ivanov commented on May 27, 2024

If I pass
requestBody = "MyItem"

I get error:
File "c:\workspace\.venv\Lib\site-packages\apispec\core.py", line 352, in _resolve_refs_in_request_body
for media_type in request_body["content"].values():
~~~~~~~~~~~~^^^^^^^^^^^
TypeError: string indices must be integers, not 'str'

From this code:

**def _resolve_refs_in_request_body(self, request_body) -> None:
    # requestBody is OpenAPI v3+
    for media_type in request_body["content"].values():
        self._resolve_schema(media_type)
        self._resolve_examples(media_type)**

which is from the .venv\Lib\site-packages\apispec\core.py

Sorry, i tried to add a screenshot but did not work for some reason.

I tracked the usage of: _resolve_refs_in_request_body and it is called by: _resolve_refs_in_operation, which is called by: resolve_refs_in_path, which then is called by the path() function, which is called by my code with: apiSpec.path(...) in the description of this ticket.

In other words, the flow is:
**
apiSpec.path(...)
-> resolve_refs_in_path
--> _resolve_refs_in_operation
---> _resolve_refs_in_request_body**

where the _resolve_refs_in_request_body is handling the passed "MyItem" string as dict and throws the above error.

from apispec.

lafrech avatar lafrech commented on May 27, 2024

Sorry, please try

requestBody = {
    "content": {"application/json": {"schema": "MyItem"}}
}

as in this test.

from apispec.

Kostadin-Ivanov avatar Kostadin-Ivanov commented on May 27, 2024

Thank you, Jerome.

This example works fine, but my question was if could set it more like:
requestBody = "#/components/requestBodies/MyItem"
or
requestBody = { "$ref": "#/components/requestBodies/MyItem" }

which will then result in:
post:
description: Create MyItem
operationId: createMyItem
requestBody:
$ref: "#/components/requestBodies/MyItem"

from apispec.

Kostadin-Ivanov avatar Kostadin-Ivanov commented on May 27, 2024

Thank you Jerome.

so, for the moment the requestBody needs to be setup with its schema definition like:
{
content:
application/json:
schema:
...
}

Thank you for your support on this and hopefully, the _resolve_refs_in_request_body function, and others similar to it, might be updated in such way that to handle exact schema parameters, like the one above and $ref like { "$ref": "#/components/requestBodies/MyItem" }.

I guess that you can close this ticket as "replied" :)

Thank you and have a great day.

from apispec.

lafrech avatar lafrech commented on May 27, 2024

I'm not sure I get it. You need to pass the content type because apispec can't guess this is JSON. In flask-smorest, for instance, things are more automatic because we define a default content type.

I don't see the point of passing the full component path, I think it is nice that apispec does that for you and you only need to pass the component name. If using marshmallow plugin, you may also pass the schema object and apispec resolves it for you.

from apispec.

Kostadin-Ivanov avatar Kostadin-Ivanov commented on May 27, 2024

Sorry, I misunderstood you.

Your example:

 requestBody = {
     "content": {"application/json": {"schema": "MyItem"}}
 }

worked. However, it still added some kind of duplication in my generated OpenApi under each of my generated operations like:

post:
  requestBody:
    content:
      application/json:
        schema:
          $ref: '#/components/schemas/MyItem'
put:
  requestBody:
    content:
      application/json:
        schema:
          $ref: '#/components/schemas/MyItem'

in my generated OpenAPI file, where I am looking to get more like:

post:
  requestBody:
    $ref: '#/components/requestBodies/MyItem'
put:
  requestBody:
    $ref: '#/components/requestBodies/MyItem'

where the $ref is pointing to a pre-defined request body schema like the one below:

components:
  requestBodies:
    MyItem:
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/MyItem'

Anyway, for the moment it does not seem to be achievable with this
requestBody = { "content": {"application/json": {"schema": "MyItem"}}} approach.

I will follow your example and see if I can find some other way to save 3 lines of text under each operation :)

Thank you again and have a great day :)

from apispec.

Kostadin-Ivanov avatar Kostadin-Ivanov commented on May 27, 2024

The swagger editor accepts the components:requestBodies:...

It is not perfect example, but here is one, of "MyItem".
my_item_example_openapi.json

Works fine on SWAGGER editor.

Thank you very much for your time and help on this question :)

from apispec.

lafrech avatar lafrech commented on May 27, 2024

You're totally right. I got confused. Sorry about that.

The example I picked from the tests resolves the schema in the request body, not the request body itself.

What you're trying to achieve is absolutely correct and in fact desirable.

It should work with

requestBody ="MyItem"

but this is apparently not implemented.

What would need to be done:

  • Add
    "request_body": "requestBodies",

to utils.COMPONENT_SUBSECTIONS.

  • Add a Components.request_body method to register request bodies in components section.

  • Add a call to get_ref in resolve_refs_in_operation like

        if "requestBody" in operation:
            operation["requestBody"] = self.get_ref("request_body", operation["requestBody"])
            self._resolve_refs_in_request_body(operation["requestBody"])

I haven't been looking to this code for a while so I may be mistaken again but I think the solution should be along these lines.

Can't look into it right now but anyone, feel free to work on this.

from apispec.

Kostadin-Ivanov avatar Kostadin-Ivanov commented on May 27, 2024

This is great, Jérôme :)

Thank you very much for this detailed guidance. I will try it and will let you know with results.

Thanks again and hopefully, we will get the easy solution like:

requestBody = "MyItem"

in the future updates :)

I sorry, but I can do these additions in my code by somehow inject / extend the ApiSpec functionality, or these updates need to be added to the ApiSpec core functionality in the future?

from apispec.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.