Fastapi: [BUG] python class not support

Created on 28 Apr 2020  ·  8Comments  ·  Source: tiangolo/fastapi

class IndexController: @app.get("/test") def test(self): return {"Hello": "IndexController"}
after app started, get http://127.0.0.1:8080/test
then the browser show message
{"detail":[{"loc":["query","self"],"msg":"field required","type":"value_error.missing"}]}
Want to support the formal API of classes
example :

from app.common.results import Results
from app.lib.classy import route
from app.lib.classy_plus import FlaskViewPlus, controller
from app.lib.utils import validate, ignore_auth
from app.service.user_service import UserService
from app.web.validates.form import LoginForm, UpdatePwdForm

@controller(route_base='user')
class UserController(FlaskViewPlus):
"""
用户控制器相关
"""

@route('/login', methods=['POST'])
@validate(LoginForm)
def login(self, loginForm=None):
    """
    登录
    :param loginForm: 登录表单
    :return: 用户信息 + token
    """
    res = UserService.login(loginForm)
    return Results.success(data=res)

@route('/logout', methods=['GET', 'POST'])
def logout(self):
    """
    注销 退出
    :return:
    """
    UserService.logout()
    return Results.success(data=True)

@route('/updatepwd', methods=['POST'])
@validate(UpdatePwdForm)
def updatepwd(self, updatePwdForm):
    """
    修改自己密码
    :return:
    """
    UserService.updatepwd(updatePwdForm.newpwd.data, updatePwdForm.oldpwd.data)
    return Results.success(data=True)
question

Most helpful comment

Yes, you will have to pass it along the whole way. If you really want something similar to Flask, you can use contextvars but they are a complicated beast and I would prefer to just pass the values around.

All 8 comments

The issue here is that you're placing the @route decorator on methods of a class which take a self parameter. If you want to do this, you need to remove the self parameter and add a @staticmethod decorator to each method. For example:

class Foo:
    @route("/hello")
    @staticmethod
    def hello():
        return "hello"

Make sure you add the staticmethod decorator on the very inside.

However, this is not a general intended use for Python classes. I don't know what your @controller decorator does, but it would be better to just put these functions in a module and decorate each one.

Thank you! Got it; And I have an another question; How to get the current request or current data ? in the sync framwork like flask, it is sample to get current data( use thread local), and this question in the asyc framwork, How to handle it?

You can add a request: Request parameter to your endpoints, which will then contain the raw request object if you need to access it. However the recommended way is to use the various Header, Cookie, Form, Model, Field, Body, Query, etc. dependency objects.

I recommend you read the first few pages of the User Guide starting at Path Parameters to get a sense of how values are generally passed.

I know what you said; but I'm not using it in some endpoints function; I'm using it in other classes or functions; do I have to pass it on all the time as long as it's this way?

in flask ; we can use current_app get current data anywhere( in the same Thread)

Yes, you will have to pass it along the whole way. If you really want something similar to Flask, you can use contextvars but they are a complicated beast and I would prefer to just pass the values around.

thank you!

Thanks for the help here @retnikt ! :clap: :bow:

Thanks for reporting back and closing the issue @1144388620lq :+1:

Was this page helpful?
0 / 5 - 0 ratings