【问题标题】:TypeError TypeError: 'NoneType' object is not callableTypeError TypeError:“NoneType”对象不可调用
【发布时间】:2021-03-12 03:05:26
【问题描述】:

我没有几天试图找出解决以下失败(类型错误)的方法,但没有运气。 出于某种原因,它在下面出现此错误,我找不到解决方案 或调试,以便我知道出了什么问题。

把事情放在上下文中。我有一个正在运行的 app.py,它试图在 auth.py 中执行一些授权,并检查令牌的权限(我通过 Postmen 传递)

************************
TypeError
TypeError: 'NoneType' object is not callable

Traceback (most recent call last)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/Users/ml_1/class-demos/Project_Fyyur/Files/Project_Fyyur-master/projects/capstone/starter_capstone_ml/starter/app.py", line 85, in <module>
@requires_auth('get:actors')
TypeError: 'NoneType' object is not callable
*********************************


**Auth.py**

#AUTH0_DOMAIN = os.getenv('AUTH0_DOMAIN')
AUTH0_DOMAIN = 'fsnd-ml-casting-agency.eu.auth0.com'
ALGORITHMS = ['RS256']
API_AUDIENCE = 'Casting'

## AuthError Exception
'''
AuthError Exception
A standardized way to communicate auth failure modes
'''
class AuthError(Exception):
    def __init__(self, error, status_code):
        self.error = error
        self.status_code = status_code

def get_token_auth_header():
        auth = request.headers.get('Authorization', None)
        print(auth)
        if not auth:
            raise AuthError({
                'code': 'authorization_header_missing',
                'description': 'Authorization header is expected.'
            }, 401)

        parts = auth.split()
        if parts[0].lower() != 'bearer':
            raise AuthError({
                'code': 'invalid_header',
                'description': 'Authorization header must start with "Bearer".'
            }, 401)

        elif len(parts) == 1:
            raise AuthError({
                'code': 'invalid_header',
                'description': 'Token not found.'
            }, 401)

        elif len(parts) > 2:
            raise AuthError({
                'code': 'invalid_header',
                'description': 'Authorization header must be bearer token.'
            }, 401)

        token = parts[1]
        return token

def verify_decode_jwt(token):
    jsonurl = urlopen(f'https://{AUTH0_DOMAIN}/.well-known/jwks.json')
    jwks = json.loads(jsonurl.read())
    unverified_header = jwt.get_unverified_header(token)
    rsa_key = {}
    #print("jwsks",jwks)
    for key in jwks["keys"]:
        if key["kid"] == unverified_header["kid"]:
            rsa_key = {
                "kty": key["kty"],
                "kid": key["kid"],
                "use": key["use"],
                "n": key["n"],
                "e": key["e"]
            }
           
    if rsa_key:
        try:
            payload = jwt.decode(
                token,
                rsa_key,
                algorithms=ALGORITHMS,
                audience=API_AUDIENCE,
                issuer="https://"+AUTH0_DOMAIN+"/"
            )
            return payload

        except jwt.ExpiredSignatureError:
            raise AuthError("token has expired", 401)
        except jwt.JWTClaimsError:
            raise AuthError("invalid claims (Error): check the audience", 401)
        except Exception:
            raise AuthError("invalid header: Unable to parse token", 401)

    print("rsa_key",rsa_key)     
    raise AuthError("invalid header: Unable to find right key", 401)

    def requires_auth(permission=''):
        def requires_auth_decorator(f):
            #print(permission)
            @wraps(f)
            def wrapper(*args, **kwargs):
                try:
                    token = None
                    if session['token']:
                        token = session['token']
                    else:
                        token = get_token_auth_header()
                    print('token at authorization time: {}'.format(token))
                    if token is None:
                        abort(400)
                    payload = verify_decode_jwt(token)
                    print('Payload is: {}'.format(payload))
                    print(f'testing for permission: {permission}')
                    if check_permissions(permission, payload):
                    print('Permission is in permissions!')
                    
                    return f(payload, *args, **kwargs)
                except Exception:
                    abort(401)
    
    
            return wrapper
        return requires_auth_decorator 
    **End Auth.py**
#  Actors
#  ----------------------------------------------------------------
# route handler to get list of actors
        @app.route('/actors', methods = ['GET'])
@cross_origin()
@requires_auth('get:actors')
def list_actors(payload):
#def get_actors():
    #auth_header = request.headers['Authorization']
    #print ("Aut_header:", auth_header)
    #header_parts =  auth_header.split(' ') [1]
    #print("header_part", header_parts)
    # payload_data = check_permissions('permission','payload')
    # print("payload_data-1111", payload_data)
    token_data = requires_auth('token')
    print("token_data", token_data)
    #decorator_data = requires_auth('requires_auth_decorator')
    decorator_data = requires_auth('f')
    print("dec_data"), decorator_data
    actors = Actor.query.all()
    actors_data = []
    for actor in actors:
        actors_data.append({
            "id": actor.id,
            "name": actor.name,
            "age": actor.age,
            "gender": actor.gender,
            "image_link": actor.image_link
            })
        result = actors_data    

    return jsonify(result)

【问题讨论】:

  • 它正在寻找一个名为get_actors的函数,但找不到,可能您已将其重命名为list_actors,因此您可能需要在@requires_auth('get:actors')进行相应的更改跨度>
  • get:actors 是代码必须签入给定令牌的权限。而 list_actors 只是 def 的名称。你能进一步解释我需要改变什么吗?然后我可以测试它。
  • 我在您的代码中看不到名为 get_actors 的函数。 (其声明)被评论。请检查
  • 每当您收到NoneType 错误时,您首先想到的应该是查找返回None 或完全没有返回的函数。

标签: python postman


【解决方案1】:

似乎找不到装饰器函数requires_auth,这可能是因为Auth.py 被导入app.py 的方式

试试这个

  1. Auth.py的内容直接复制到app.py
  2. 再次运行代码,看看问题是否消失

您还有一个装饰器cross_origin,它在您的示例代码中不可见。确保它没有覆盖其他内容

3 月 11 日更新

  1. 试试import Auth 然后你就可以做@Auth.requires_auth

【讨论】:

  • 我没有运气就这样做了,错误困扰......而且我有 @cross origin 的 cmets,我可以看到整个令牌通过 print 语句正确传递
  • 我已经复制了 auth.py 的整个代码...也许我遗漏了什么?
  • 嗨 NoCommandLine 现在它在从 app.py 中的 auth.py 复制我的所有代码后工作,但我无法弄清楚为什么 auth.py 的导入没有正确导入我的应用程序也许是我的文件夹的设置,但在这种情况下,我的应用程序应该给出一个警告,提示找不到我的 auth.py
  • 您是如何准确导入的?尝试更新 app.py 中的代码示例以显示您对 auth.py 的导入。这也很可能是由于文件夹结构。看看是否可以包含屏幕截图
  • from auth import AuthError, requires_auth, check_permissions, verify_decode_jwt 我在 app.py 中使用上述语句导入我的 auth.py ,我看到类似文件夹结构的内容可能是原因。但不知道如何解决。我有一个根文件夹,其中有一个 auth.py 文件夹,它有 auth.py,在根目录中有我的 env 文件夹和我的 app.py。
猜你喜欢
  • 1970-01-01
  • 2016-08-17
  • 2012-04-28
  • 2021-08-18
  • 2016-10-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多