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

本地Python脚本无法请求ECS上的Flask服务,但Postman可正常访问

本地Python脚本POST请求ECS Flask接口无响应,Postman却正常的排查方向

在ECS上部署了Flask服务,通过本地Python脚本用requests或http.client发送POST请求到/infr接口时,请求完全未到达ECS(服务日志无相关记录),但网页版、本地版Postman发送相同请求却能成功,以下是可能的原因及排查步骤:


Flask服务代码

import flask

app = flask.Flask(__name__)

@app.route("/infr", methods=["POST"])
def transformation():
    # 业务逻辑代码
    pass

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8080)

本地Python脚本1(http.client实现)

def exec_task(task, out):
    import http.client
    import json

    url = "<ecs-public-ip>"
    port = 8080
    endpoint = "/infr"

    conn = http.client.HTTPConnection(url, port)
    headers = {"Content-Type": "application/json", "Connection": "keep-alive"}

    data = {
        "task": {
            "bucket": task.bucket,
            "prefix": task.prefix,
            "metadata": task.metadata
        }
    }

    payload = json.dumps(data)

    conn.request("POST", endpoint, body=payload, headers=headers)
    response = conn.getresponse()

    if response.status == 200:
        print("\nRequest successful")
        response_data = json.loads(response.read().decode())
        out.put(ProcessedTask(bucket=task.bucket, prefix=task.prefix, metadata=response_data))
    else:
        print("\nRequest failed")

    conn.close()

本地Python脚本2(requests实现)

def exec_task(task, out):
    import requests

    url = "http://<ecs-public-ip>:8080/infr"
    data = {"task": {
        "bucket": task.bucket,
        "prefix": task.prefix,
        "metadata": task.metadata
    }}
    
    print("sending: " + str(data))
    headers = {"Content-Type": "application/json", "Connection": "keep-alive"}
    response = requests.post(url, json=data, headers=headers)

    if response.status_code == 200:
        print("\nRequest successful")
        response_data = response.json()
        out.put({ProcessedTask(bucket=task.bucket, prefix=task.prefix, metadata=response_data)})
    else:
        print("\nRequest failed")

Postman配置说明

  • 请求方法:POST
  • 请求地址:http://<ecs-public-ip>:8080/infr
  • 请求头:Content-Type: application/json
  • 请求体:选择raw格式、JSON类型,内容结构与Python脚本中的data一致
    (注:实际使用8080端口,之前误删该信息)

可能的原因及排查步骤

1. 本地网络代理/防火墙差异

  • Python脚本默认使用系统代理,而Postman可能关闭了代理。可以在脚本中强制禁用代理:
    • requests脚本:添加proxies={"http": None, "https": None}参数到post方法
    • http.client脚本:在创建连接后添加conn.set_tunnel(None)
  • 本地安全软件/防火墙拦截了Python脚本的出站请求,但放行Postman。可以临时关闭安全软件测试,或检查防火墙规则。

2. 请求头/请求体的细微冲突

  • requests脚本冗余头问题:使用json=data参数时,requests会自动添加Content-Type: application/json,手动重复添加可能导致服务器拒绝请求。可以去掉手动设置的该头:
    headers = {"Connection": "keep-alive"}
    response = requests.post(url, json=data, headers=headers)
    
  • 序列化异常:检查task.metadata是否包含不可JSON序列化的对象(如datetime),Postman手动输入的是合法JSON,但脚本序列化失败导致请求未正常发送。可添加print(payload)(http.client脚本)或print(requests.models.JSONEncoder().encode(data))(requests脚本)验证JSON格式。

3. ECS端的请求特征拦截

  • ECS安全组/防火墙可能针对User-Agent做了限制:Postman默认UA为PostmanRuntime/xxx,而Python脚本的UA是python-requests/xxx或Python-urllib/xxx。可以在脚本中模拟Postman的UA:
    # requests脚本示例
    headers = {"Content-Type": "application/json", "User-Agent": "PostmanRuntime/7.32.3"}
    

4. Flask日志配置不全

  • 确认Flask日志是否记录了所有请求,可开启DEBUG模式和详细日志:
    import logging
    logging.basicConfig(level=logging.DEBUG)
    app.run(host='0.0.0.0', port=8080, debug=True)
    
    同时检查ECS系统日志(如/var/log/messages或反向代理日志),看是否有请求被拦截的记录。

5. 脚本异常未被捕获

  • 脚本发送请求时可能抛出异常(如连接超时、DNS解析失败)但未处理,导致请求未发送就崩溃。添加异常捕获:
    # http.client脚本示例
    try:
        conn = http.client.HTTPConnection(url, port)
        conn.request("POST", endpoint, body=payload, headers=headers)
        response = conn.getresponse()
        # 后续逻辑
    except Exception as e:
        print(f"请求发送失败:{str(e)}")
    finally:
        conn.close()
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 00:14:52