You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Requests POST请求EasyRedmine API返回422,curl/Postman调用正常

Requests调用EasyRedmine创建项目返回422错误排查方案

对比可正常运行的curl命令与Python实现代码,422 Unprocessable Entity错误由请求参数不符合接口校验规则导致,核心诱因按出现概率排序如下:

  • 布尔类型字段传值格式错误:代码中is_planned默认值为字符串'false'、easy_is_easy_template默认值为字符串"true",但接口要求两个字段为JSON原生布尔值。使用requests的json=参数序列化请求时,字符串类型的'true'/'false'会被转义为带引号的字符串值,直接触发类型校验失败。
  • 空值字段未做过滤:代码中parent_id、author_id、easy_start_date、easy_due_date、custom_fields、tag_list这类非必填字段的默认值为空字符串/空列表,即使没有传入有效值,也会被序列化进请求体。接口收到空字符串格式的数字、日期类型字段时,会直接判定参数非法;而测试用的curl命令仅传入了有有效值的字段,未携带空值字段,因此可正常执行。
  • 请求路径不匹配:curl请求的接口路径为/projects.json,但Python代码中拼接的路径为/projects,部分Redmine系接口对路径后缀有路由校验,不带.json后缀可能进入错误的参数解析逻辑。
  • API Key传法差异:curl同时在URL查询参数、请求头中传入了API Key,Python代码仅在请求头中传入API Key,部分特殊配置的EasyRedmine实例会要求两种传法匹配对应路由规则,可作为补充校验点。

修正后可直接运行的代码

def create_project(self, name: str, description="", external_id="", homepage="", parent_id=None, author_id=0,
                   is_planned=False, is_easy_template=True, start_date=None, due_date=None, custom_fields=None,
                   tag_list=None, currency='EUR'):
    # 构造核心必填字段,所有字段类型与接口要求对齐
    project_data = {
        "easy_external_id": external_id,
        "name": name,
        "homepage": homepage,
        "description": description,
        "author_id": author_id,
        "is_planned": is_planned,
        "easy_is_easy_template": is_easy_template,
        "easy_currency_code": currency
    }
    # 仅当字段有实际有效值时才加入请求体,避免空值触发校验
    if parent_id:
        project_data["parent_id"] = parent_id
    if start_date:
        project_data["easy_start_date"] = start_date
    if due_date:
        project_data["easy_due_date"] = due_date
    if custom_fields:
        project_data["custom_fields"] = custom_fields
    if tag_list:
        project_data["tag_list"] = tag_list

    data = {"project": project_data}

    # 补全.json后缀,与curl请求路径保持一致
    endpoint_path = "/projects.json"
    endpoint = f'{self.base_url}{endpoint_path}'
    headers = {
        'X-Redmine-API-Key': self.api_key,
        'accept': 'application/json',
        'Content-Type': 'application/json'
    }

    r = requests.post(endpoint, headers=headers, json=data)
    # 调试时可取消下一行注释,直接查看接口返回的具体字段校验错误,无需盲目排查
    # print(r.text)

排查这类422参数校验错误时,不需要反复对比参数猜问题,直接打印响应对象的r.text属性,就能拿到接口返回的明确错误提示,比如具体哪个字段类型错误、哪个字段取值非法,可快速定位问题。

内容的提问来源于stack exchange,提问作者Aymanete

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 00:06:34