[flask小坑] request.json 无法获取请求body的json数据

写接口自动化测试的时候,发现用httpie发送带有put请求,flask后端api可以获取到json数据,而我用robotframework发送的请求就不行,flask的 request.json 获取到的数据为 None

怎么办?查文档,看代码呗

代码 https://github.com/pallets/flask/blob/master/flask/wrappers.py#L53:22

    @property
    def json(self):
        """This will contain the parsed JSON data if the mimetype indicates
        JSON (:mimetype:`application/json`, see :meth:`is_json`), otherwise it
        will be ``None``.
        """
        return self.get_json()

    def _get_data_for_json(self, cache):
        return self.get_data(cache=cache)

    def get_json(self, force=False, silent=False, cache=True):
        """Parse and return the data as JSON. If the mimetype does not
        indicate JSON (:mimetype:`application/json`, see
        :meth:`is_json`), this returns ``None`` unless ``force`` is
        true. If parsing fails, :meth:`on_json_loading_failed` is called
        and its return value is used as the return value.
        :param force: Ignore the mimetype and always try to parse JSON.
        :param silent: Silence parsing errors and return ``None``
            instead.
        :param cache: Store the parsed JSON to return for subsequent
            calls.
        """

原来这个 request.json 调用的是 request.get_json() 这个函数,但是 get_json 这个函数默认情况下只对 mime 为 application/json 的请求可以正确解析。

所以解决办法是

  • http 请求增加 Content-Type:application/json header
  • 或者 使用 request.get_json(force=True) 忽略mimetype

还是要仔细看文档呀,。。

<think>我们使用flasgger的swag_from装饰器来为Flask路由添加Swagger文档。具体步骤如下: 1. 安装flasgger: `pip install flasgger` 2.Flask应用中使用Swagger 3. 为路由函数添加`@swag_from`装饰器,指定YAML文件或字典形式的API文档 示例:使用`request.json`接收JSON数据的POST请求,并添加Swagger文档。 步骤1:创建YAML文件(例如:`swagger_specs/post_data.yml`): ```yaml post: tags: - 数据操作 summary: 处理JSON数据 description: 接收JSON数据并返回处理结果 parameters: - in: body name: body required: true schema: id: data_input properties: key1: type: string description: 示例字段1 key2: type: integer description: 示例字段2 responses: 200: description: 成功处理 schema: id: response_success properties: status: type: string result: type: object ``` 步骤2:在Flask路由中使用`@swag_from`装饰器: ```python from flask import Flask, request, jsonify from flasgger import Swagger, swag_from app = Flask(__name__) Swagger(app) @app.route('/process', methods=['POST']) @swag_from('swagger_specs/post_data.yml') # 指定YAML文件路径 def process_data(): # 获取JSON数据 data = request.json # 处理数据(示例:将key2乘以2) if 'key2' in data: data['key2'] *= 2 return jsonify({ 'status': 'success', 'result': data }) if __name__ == '__main__': app.run(debug=True) ``` 步骤3:运行应用并访问`http://localhost:5000/apidocs`查看Swagger UI 替代方案:直接在装饰器中使用字典(不推荐,但适用于简单情况) ```python swagger_spec = { "tags": ["数据操作"], "summary": "处理JSON数据", "description": "接收JSON数据并返回处理结果", "parameters": [ { "in": "body", "name": "body", "required": True, "schema": { "id": "data_input", "properties": { "key1": {"type": "string", "description": "示例字段1"}, "key2": {"type": "integer", "description": "示例字段2"} } } } ], "responses": { "200": { "description": "成功处理", "schema": { "id": "response_success", "properties": { "status": {"type": "string"}, "result": {"type": "object"} } } } } } @app.route('/process_dict', methods=['POST']) @swag_from(swagger_spec) def process_data_dict(): # 同上 ... ``` ### 注意事项: 1. **参数位置**:`@swag_from`装饰器必须在`@app.route`下方 2. **文件路径**:相对路径基于应用根目录 3. **自动验证**:Flasgger会自动根据文档验证请求数据(需配置) 4. **复杂结构**:推荐使用YAML文件维护大型文档 §§相关问题§§ 1. 如何为同一个Flask路由同时支持GET和POST方法并分别编写Swagger文档? 2. 如何引用外部定义的Swagger schema以避免重复定义? 3. 如何在Swagger文档中为请求体添加数组类型的参数? 4. 如何全局配置Swagger UI的页面标题和描述信息? 5. 如何实现请求参数的自动验证和错误处理?</think>以下是为 Flask 的 `request.json` 编写 `swag_from` 装饰器的完整实现方案,使用 Flasgger 库生成 Swagger 文档: ```python from flask import Flask, request, jsonify from flasgger import Swagger, swag_from app = Flask(__name__) swagger = Swagger(app) # 初始化Swagger # 定义Swagger YAML规范(可以直接嵌入Python代码) SWAGGER_SPEC = { "tags": ["用户管理"], "description": "处理JSON格式的用户数据", "parameters": [ { "in": "body", "name": "user_data", "required": True, "schema": { "id": "User", "properties": { "username": { "type": "string", "description": "用户名", "example": "john_doe" }, "email": { "type": "string", "format": "email", "description": "电子邮箱", "example": "john@example.com" }, "age": { "type": "integer", "minimum": 18, "description": "用户年龄", "example": 30 }, "interests": { "type": "array", "items": {"type": "string"}, "description": "兴趣爱好", "example": ["编程", "阅读", "运动"] } }, "required": ["username", "email"] } } ], "responses": { 200: { "description": "成功处理", "schema": { "id": "Response", "properties": { "status": {"type": "string", "example": "success"}, "message": {"type": "string", "example": "用户创建成功"}, "user_id": {"type": "integer", "example": 12345} } } }, 400: { "description": "无效输入", "schema": { "properties": { "error": {"type": "string", "example": "缺少必填字段: email"} } } } } } @app.route('/create_user', methods=['POST']) @swag_from(SWAGGER_SPEC) # 应用Swagger文档规范 def create_user(): """ 创建新用户接口 使用JSON格式接收用户数据 """ # 获取JSON格式的请求数据 user_data = request.json # 验证必填字段 if not user_data or 'username' not in user_data or 'email' not in user_data: return jsonify({ "error": "缺少必填字段: username 或 email" }), 400 # 处理业务逻辑(此处为示例) user_id = create_user_in_db(user_data) # 伪代码 # 返回JSON响应 return jsonify({ "status": "success", "message": "用户创建成功", "user_id": user_id }), 200 def create_user_in_db(user_data): """模拟数据库操作""" # 实际项目中这里会有数据库插入操作 return 12345 # 返回模拟的用户ID if __name__ == '__main__': app.run(debug=True) ``` ### 关键实现说明: 1. **Swagger 规范定义**: - 使用 Python 字典定义完整的 Swagger 规范 - `parameters` 部分定义 JSON 请求体结构 - `responses` 部分定义成功和错误的返回格式 2. **`@swag_from` 装饰器**: ```python @swag_from(SWAGGER_SPEC) ``` - 自动将规范附加到路由 - 支持直接传入字典或引用 YAML 文件路径 3. **JSON 请求处理**: ```python user_data = request.json # 获取解析后的JSON数据 ``` - 自动处理 `Content-Type: application/json` 请求 - 自动将 JSON 字符串转换为 Python 字典 4. **验证与响应**: - 检查必填字段是否存在 - 返回符合 Swagger 定义的 JSON 响应 - 包含正确的 HTTP 状态码 ### 访问 Swagger UI: 1. 运行应用后访问:`http://localhost:5000/apidocs` 2. 在 Swagger UI 中: - 查看 `/create_user` 接口文档 - 使用 "Try it out" 功能测试接口 - 自动生成请求示例 ### 替代方案(使用外部 YAML 文件): 1. 创建 `swagger_docs/create_user.yml`: ```yaml post: tags: - 用户管理 summary: 创建新用户 consumes: - application/json parameters: - in: body name: body required: true schema: $ref: '#/definitions/User' responses: 200: description: 用户创建成功 schema: $ref: '#/definitions/UserResponse' 400: description: 无效输入 definitions: User: type: object properties: username: type: string email: type: string format: email age: type: integer minimum: 18 required: - username - email UserResponse: type: object properties: status: type: string user_id: type: integer ``` 2. 在路由中使用: ```python @app.route('/create_user', methods=['POST']) @swag_from('swagger_docs/create_user.yml') def create_user(): # 处理逻辑不变 ```
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值