GithubHelp home page GithubHelp logo

Comments (20)

kemingy avatar kemingy commented on May 16, 2024 3

One possible way is to use __root__ pydantic root.

class Item(BaseModel):
    name: str
    price: float


class ItemList(BaseModel):
    __root__: List[Item]


@app.route("/", method=["POST"])
@api.validate(json=Item, resp=Response(HTTP_200=ItemList), tags=["demo"])
def demo():
    item = request.context.json
    return ItemList.parse_obj([item, item, item])

By the way, you don't need to parse request.context.json again. For the return statement, you can use return ItemList.parse_obj([item, item, item]) or return ItemList(__root__=[item, item, item]).

from spectree.

onecrayon avatar onecrayon commented on May 16, 2024 2

Has anyone undertaken this issue yet? It’s something I need and I was wondering if I should take a swing at it or if it’s already underway.

from spectree.

sunlin92 avatar sunlin92 commented on May 16, 2024 1

I really appreciate your help. 😄
Are there any plans to support this syntax(HTTP_200=List[Item])?
It looks like be easier to read and use.

Thanks again

from spectree.

kemingy avatar kemingy commented on May 16, 2024 1

This syntax looks nice. But I feel it can be difficult to support. Because it means the library should be able to verify any types:

  • List[Item]
  • Dict[str, Item]
  • Dict[str, List[Item]]
  • ...

I'm not sure if there is an easy way to do this. Let me know if you have any ideas.

from spectree.

sunlin92 avatar sunlin92 commented on May 16, 2024 1

FastAPI seems to support this syntax, I will create a pr when i complete it if needed.

from spectree.

kemingy avatar kemingy commented on May 16, 2024 1

from spectree.

yoursvivek avatar yoursvivek commented on May 16, 2024 1

Data validation is easy. Pydantic provides a function to load data of any supported type or a combination thereof.

One just needs to handle registry into spec.models.

https://pydantic-docs.helpmanual.io/usage/models/#parsing-data-into-a-specified-type

from spectree.

kemingy avatar kemingy commented on May 16, 2024 1

Has anyone undertaken this issue yet? It’s something I need and I was wondering if I should take a swing at it or if it’s already underway.

This issue has been inactive for a long time. @onecrayon Feel free to create a WIP PR and link to this issue. Thanks for your help.

from spectree.

kemingy avatar kemingy commented on May 16, 2024 1

Hey, guys! This feature is incredibly necessary! When are you going to do it? I really need it! @sunlin92 @yoursvivek @kemingy where are you, guys? pls, do it!

pydantic.parse_obj_as seems a good solution for the List[BaseModel]. One more thing is how to generate the corresponding OpenAPI doc.

If we narrow it down to support List[BaseModel] only, it's possible to write a function to handle it.

Hi, @onecrayon are you still willing to take this one?

from spectree.

kemingy avatar kemingy commented on May 16, 2024 1

After reading the source code of pydantic.main.ModelMetaclass, I found a way to do this:

from typing import List, Type
from flask import Flask, jsonify
from spectree import SpecTree, Response
from pydantic import BaseModel


class User(BaseModel):
    name: str
    page: int


app = Flask(__name__)
spec = SpecTree("flask")


@app.route("/")
@spec.validate(resp=Response(HTTP_200=User))
def index():
    return User(name="John", page=1)


def gen_list_model(model: Type[BaseModel]):
    assert issubclass(model, BaseModel)
    ListModel = type(
        f"{model.__name__}List",
        (BaseModel,),
        {
            "__annotations__": {"__root__": List[model]},
        },
    )
    return ListModel


@app.route("/list")
@spec.validate(resp=Response(HTTP_200=gen_list_model(User)))
def list_user():
    return jsonify([{"name": "John", "page": 1}, {"name": "Jane", "page": 2}])


if __name__ == "__main__":
    spec.register(app)
    app.run()

from spectree.

kemingy avatar kemingy commented on May 16, 2024 1

@kemingy It looks like some kind of crutches...and looks not 'pythonic'. Isn't there a way to do it literally like in FastAPI - to make it work by just wrapping the model in List[]?

That example is just an idea (also the real implementation). Check #222 for the interface.

from spectree.

kemingy avatar kemingy commented on May 16, 2024 1

I have created a pre-release: https://github.com/0b01001001/spectree/releases/tag/v0.10.0a1

Can try to use this one to see if it can fulfill your requirements.

from spectree.

yedpodtrzitko avatar yedpodtrzitko commented on May 16, 2024 1

@alexted you know it's an open-source project, right?

from spectree.

alexted avatar alexted commented on May 16, 2024

Hey, guys! This feature is incredibly necessary! When are you going to do it? I really need it!
@sunlin92 @yoursvivek @kemingy where are you, guys? pls, do it!

from spectree.

onecrayon avatar onecrayon commented on May 16, 2024

Possibly; my app that leverages SpecTree has been lying fallow for a bit here, but I’ve been hoping to get back into it. I’ll let you know if I start actual coding on this, but don’t want to make any solid promises at this point.

from spectree.

alexted avatar alexted commented on May 16, 2024

@kemingy It looks like some kind of crutches...and looks not 'pythonic'.
Isn't there a way to do it literally like in FastAPI - to make it work by just wrapping the model in List[]?

from spectree.

alexted avatar alexted commented on May 16, 2024

An error occurs when I try to run this code:

FLASK_APP = app.py
FLASK_ENV = development
FLASK_DEBUG = 0
In folder /home/alex/PycharmProjects/flask-spectree
/home/alex/.cache/pypoetry/virtualenvs/flask-spectree-64sAPQko-py3.10/bin/python -m flask run
 * Serving Flask app 'app.py' (lazy loading)
 * Environment: development
 * Debug mode: off
Traceback (most recent call last):
  File "/usr/lib/python3.10/runpy.py", line 196, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/usr/lib/python3.10/runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "/home/alex/.cache/pypoetry/virtualenvs/flask-spectree-64sAPQko-py3.10/lib/python3.10/site-packages/flask/__main__.py", line 3, in <module>
    main()
  File "/home/alex/.cache/pypoetry/virtualenvs/flask-spectree-64sAPQko-py3.10/lib/python3.10/site-packages/flask/cli.py", line 988, in main
    cli.main()
  File "/home/alex/.cache/pypoetry/virtualenvs/flask-spectree-64sAPQko-py3.10/lib/python3.10/site-packages/flask/cli.py", line 579, in main
    return super().main(*args, **kwargs)
  File "/home/alex/.cache/pypoetry/virtualenvs/flask-spectree-64sAPQko-py3.10/lib/python3.10/site-packages/click/core.py", line 1055, in main
    rv = self.invoke(ctx)
  File "/home/alex/.cache/pypoetry/virtualenvs/flask-spectree-64sAPQko-py3.10/lib/python3.10/site-packages/click/core.py", line 1657, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/alex/.cache/pypoetry/virtualenvs/flask-spectree-64sAPQko-py3.10/lib/python3.10/site-packages/click/core.py", line 1404, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/alex/.cache/pypoetry/virtualenvs/flask-spectree-64sAPQko-py3.10/lib/python3.10/site-packages/click/core.py", line 760, in invoke
    return __callback(*args, **kwargs)
  File "/home/alex/.cache/pypoetry/virtualenvs/flask-spectree-64sAPQko-py3.10/lib/python3.10/site-packages/click/decorators.py", line 84, in new_func
    return ctx.invoke(f, obj, *args, **kwargs)
  File "/home/alex/.cache/pypoetry/virtualenvs/flask-spectree-64sAPQko-py3.10/lib/python3.10/site-packages/click/core.py", line 760, in invoke
    return __callback(*args, **kwargs)
  File "/home/alex/.cache/pypoetry/virtualenvs/flask-spectree-64sAPQko-py3.10/lib/python3.10/site-packages/flask/cli.py", line 850, in run_command
    app = DispatchingApp(info.load_app, use_eager_loading=eager_loading)
  File "/home/alex/.cache/pypoetry/virtualenvs/flask-spectree-64sAPQko-py3.10/lib/python3.10/site-packages/flask/cli.py", line 299, in __init__
    self._load_unlocked()
  File "/home/alex/.cache/pypoetry/virtualenvs/flask-spectree-64sAPQko-py3.10/lib/python3.10/site-packages/flask/cli.py", line 333, in _load_unlocked
    self._app = rv = self.loader()
  File "/home/alex/.cache/pypoetry/virtualenvs/flask-spectree-64sAPQko-py3.10/lib/python3.10/site-packages/flask/cli.py", line 389, in load_app
    app = locate_app(import_name, name)
  File "/home/alex/.cache/pypoetry/virtualenvs/flask-spectree-64sAPQko-py3.10/lib/python3.10/site-packages/flask/cli.py", line 234, in locate_app
    __import__(module_name)
  File "/home/alex/PycharmProjects/flask-spectree/app.py", line 24, in <module>
    @spec.validate(resp=Response(HTTP_200=List[User]))
  File "/home/alex/.cache/pypoetry/virtualenvs/flask-spectree-64sAPQko-py3.10/lib/python3.10/site-packages/spectree/response.py", line 59, in __init__
    assert issubclass(model, BaseModel), "invalid `pydantic.BaseModel`"
  File "/usr/lib/python3.10/abc.py", line 123, in __subclasscheck__
    return _abc_subclasscheck(cls, subclass)
TypeError: issubclass() arg 1 must be a class

Process finished with exit code 1

from spectree.

kemingy avatar kemingy commented on May 16, 2024

An error occurs when I try to run this code:

Sorry I cannot reproduce this with Python 3.10

from spectree.

alexted avatar alexted commented on May 16, 2024

Just what I needed, thank you!
But i think it would be good to correct the type hints:
Screenshot from 2022-05-08 08-18-32

from spectree.

alexted avatar alexted commented on May 16, 2024

@kemingy what about update type hinting? ^^

from spectree.

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.