我刚开始使用Connexion和Flask,却不知道如何处理HTTP错误,例如401,是通过调用另一个API产生的。换句话说,我要实现的是简单地转发来自外部API的可能错误。
server.py
import json
import os
import connexion
import requests
from connexion import FlaskApp
def auth():
credential: Credential = connexion.request.get_json()
print("Credential")
print(credential)
AUTHENTICATION_SERVER: str = 'AUTHENTICATION_SERVER'
AUTHENTICATION_API: str = 'AUTHENTICATION_API'
authentication_server: str = 'http://localhost:8080'
authentication_api = '/api/authenticate'
if AUTHENTICATION_SERVER in os.environ:
authentication_server = os.environ.get(AUTHENTICATION_SERVER)
if AUTHENTICATION_API in os.environ:
authentication_api = os.environ.get(AUTHENTICATION_API)
authentication_url: str = authentication_server + authentication_api
headers = {'Content-type': 'application/json'}
response: Response = requests.post(authentication_url, data=json.dumps(credential), headers=headers)
response.raise_for_status()
return response.json()
def render_unauthorized(exception):
print('Unauthorized handler fn')
return Response(response=json.dumps({'error': 'Wrong credentials'}), status=401,
mimetype="application/json")
# If we're running in stand alone mode, run the application
if __name__ == '__main__':
# Create the Connexion instance
app: FlaskApp = connexion.FlaskApp(__name__, specification_dir='OpenAPI')
# Add error handler
app.add_error_handler(AuthenticationProblem, render_unauthorized)
# Read the swagger.yml file to configure the endpoints
app.add_api('swagger.yml')
app.run(host='0.0.0.0', port=5000, debug=True)
凭据类:
class Credential:
def __init__(self, username: str, password: str):
self.username = username
self.password = password
如Connexion所述,我为错误创建了该类,同时扩展了ProblemException
和Unauthorized
。
AuthenticationProblem类:
from connexion import ProblemException
from werkzeug.exceptions import Unauthorized
class AuthenticationProblem(ProblemException, Unauthorized):
def __init__(self, title=None, **kwargs):
super(Unauthorized, self).__init__(title=title, **kwargs)
最后,这是相应的 swagger.yml 文件:
openapi: 3.0.0
info:
title: Swagger REST Article
description: API Swagger file
contact: {}
version: '1.0.0'
servers:
- url: https://{host}:{port}/api
variables:
host:
default: localhost
port:
default: '5000'
paths:
/auth:
post:
summary: Authenticate the user
description: Authenticate the user
operationId: server.auth
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/credential'
description: The user credentials
required: true
responses:
200:
description: Authentication success
401:
description: Wrong Credentials
security: [] # No Authentication Required
# Define the security scheme type (HTTP bearer)
components:
securitySchemes:
jwt: # arbitrary name for the security scheme
type: http
scheme: bearer
bearerFormat: JWT # optional, arbitrary value for documentation purposes
x-bearerInfoFunc: security.jwt_filter.validate
schemas:
credential:
type: object
properties:
username:
description: The username of the user
password:
description: The password of the user
required:
- username
- password
当我尝试在 / auth 上通过 POST 提供错误的凭据时,会导致500 Internal Server错误,而不是401响应。 此代码有什么问题?