Langflow 本地 API 示例测试基座详解:make api_examples_local 的完整机制与实战
【免费下载链接】langflowLangflow is a powerful tool for building and deploying AI-powered agents and workflows.项目地址: https://gitcode.com/GitHub_Trending/la/langflow
Langflow 仓库内置了一个"本地 API 示例测试基座"(local test harness),能够一键拉起本地 Langflow 服务、自动完成登录与 API Key 创建、预置测试用项目/Flow,然后对docs目录下的全部 curl / Python / JavaScript API 示例脚本做语法检查与真实执行。本文以 版本 1.11.0 的 API-Reference README 为核心,结合 Makefile、scripts/test-api-examples-local.sh 及各示例目录中的 runner 脚本源码,完整讲解该基座的用法、环境变量、执行流程与跳过策略,读完你可以直接在本地验证所有官方 API 示例的可用性,并理解其底层调度逻辑。
基座定位:验证 docs 中全部 API 示例脚本
Langflow 的 API 文档(docs/docs/API-Reference)目录下按端点分组维护着三种语言的示例脚本:
curl-examples/:按api-files/、api-flows/、api-flows-run/、api-logs/、api-monitor/、api-openai-responses/、api-projects/、api-users/、workflows-api/等子目录组织的.sh脚本,以及入口 test-curl-examples.sh;python-examples/:同结构子目录的.py脚本,入口为 test-python-examples.sh;javascript-examples/:.js脚本,入口为 test-javascript-examples.sh。
scripts/test-api-examples-local.sh 是这三套 runner 的总调度器:它先自行启动一个临时 Langflow 后端,再注入示例脚本所需的完整环境变量,最后逐套执行。文档 README 中描述的正是这套机制。
快速上手:make api_examples_local
按照版本 1.11.0 文档 README 的说明,在仓库根目录执行:
# 运行全部示例套件(curl + python + javascript) make api_examples_local # 只运行单一套件 make api_examples_local suites=python make api_examples_local suites=javascript make api_examples_local suites=curlMakefile 中对应的两个目标定义如下:
# Comma-separated list; override e.g. suites=curl,javascript,python suites ?= curl,python,javascript api_examples_local: ## run docs API sample files against a local Langflow server @echo "$(GREEN)Running docs API examples locally...$(NC)" @SUITES="$(suites)" EXECUTE_MODE=true ./scripts/test-api-examples-local.sh api_examples_local_syntax: ## syntax-check docs API sample files locally without execution @echo "$(GREEN)Running docs API example syntax checks locally...$(NC)" @SUITES="$(suites)" EXECUTE_MODE=false ./scripts/test-api-examples-local.sh关键点:
suites变量是逗号分隔的列表,默认值为curl,python,javascript,可以任意组合,例如suites=curl,javascript;Makefile 中的注释特别指出不能用 GNU make 的$(or ...)来写默认值,因为它只返回第一个非空 token,因此采用了?=赋值。- 除了完整执行目标
api_examples_local(EXECUTE_MODE=true),还有一个只做语法检查、不实际执行的api_examples_local_syntax(EXECUTE_MODE=false),适合在没有网络凭据或不想真实调用 API 时快速校验示例脚本的可编译性。
底层编排:test-api-examples-local.sh 的完整流程
调度脚本 scripts/test-api-examples-local.sh 是理解整个基座的核心,其执行链条如下。
环境变量与端口处理
脚本开头定义并读取以下配置(均有默认值,均可通过环境覆盖):
| 变量 | 默认值 | 作用 |
|---|---|---|
LANGFLOW_HOST | 127.0.0.1 | 临时服务器绑定地址 |
LANGFLOW_PORT | 7860 | 临时服务器端口 |
SUITES | curl,python,javascript | 要运行的示例套件 |
EXECUTE_MODE | true | 是否真实执行(false时仅语法检查) |
另外脚本会强制导出两个服务端开关(见 第 12–15 行):
export LANGFLOW_AUTO_LOGIN="${LANGFLOW_AUTO_LOGIN:-true}" # /api/v2/workflows (docs Python workflow examples) requires this. export LANGFLOW_DEVELOPER_API_ENABLED=true其中LANGFLOW_DEVELOPER_API_ENABLED=true是必需的——workflows-api/下的 Python 示例会调用/api/v2/workflows,而该端点受开发者 API 开关控制;注释中特别强调"始终在基座中开启,以免用户级LANGFLOW_DEVELOPER_API_ENABLED=false打断测试"。
端口冲突处理是一个值得注意的细节:脚本先通过port_is_in_use()用 socket 探测目标端口,若被占用则用pick_free_port()让 OS 分配一个空闲端口继续运行,并提示"Port was in use; using ..."。注释解释了动机——如果端口被占,Langflow 可能会自动绑到PORT+1,而脚本仍按原端口发请求,就会打到错误的服务器(例如对/api/v2/workflows返回 403)。
启动服务器与就绪探测
基座以纯后端模式启动临时服务器(第 79 行):
LANGFLOW_DEVELOPER_API_ENABLED=true uv run langflow run --backend-only \ --host "$HOST" --port "$PORT" >/tmp/langflow-server.log 2>&1 & echo $! >/tmp/langflow-server.pid随后轮询GET /health_check等待就绪,最多 60 次、每次间隔 2 秒(约 2 分钟超时),失败时提示查看/tmp/langflow-server.log。脚本注释中说明了一个易踩的坑:/health端点由 uvicorn 在 Langflow 应用完全初始化之前就提供响应,不能可靠判断服务健康,因此就绪探测选用/health_check。脚本退出时通过trap cleanup EXIT终止服务器进程并清理 PID 文件。
自动登录与 API Key 创建
示例脚本调用大多数/v1端点需要 API Key。基座不要求用户手动配置,而是用一段内嵌 Python 脚本自动完成(第 101–153 行):
- 依次尝试
GET /api/v1/auto_login(因已开启LANGFLOW_AUTO_LOGIN)或POST /api/v1/login(默认超级用户langflow/langflow,可用LANGFLOW_SUPERUSER/LANGFLOW_SUPERUSER_PASSWORD覆盖),最多重试 8 次,获取access_token; - 携带
Authorization: Bearer <token>调用POST /api/v1/api_key/,创建一个名为local-docs-examples的 API Key; - 将该 Key 导出为
LANGFLOW_API_KEY,同时导出LANGFLOW_URL与LANGFLOW_SERVER_URL(两者指向http://$HOST:$PORT,因为部分示例读取任一变量)。
脚本注释还提到一个并发陷阱:此处刻意只通过 HTTP 创建 Key,而不是起第二个进程直接连 SQLite——"第二个进程在服务运行期间打开同一个 SQLite 数据库会导致 Alembic/initialize_services 阶段出现 database is locked"。
测试资源预置(Bootstrap)
执行模式下,基座还会预置一批示例脚本依赖的资源 ID(第 164–255 行):
POST /api/v1/projects/创建一个随机命名的项目api-example-project-<8位hex>,取回PROJECT_ID;POST /api/v1/flows/创建一个空 Flow(data: {nodes: [], edges: []}),取回FLOW_ID;POST /api/v1/build/{flow_id}/flow触发构建,取回JOB_ID;GET /api/v1/projects/download/{project_id}导出项目 ZIP 到/tmp/langflow-project-import.zip;若导出失败(脚本注释称部分本地实例可能失败),回退使用仓库内固定夹具 docs/docs/API-Reference/fixtures/project-import.zip。
最终导出的环境变量为:
PROJECT_ID # 同时用于 FOLDER_ID(很多示例在项目级路由中两者互换使用) FOLDER_ID # = PROJECT_ID FLOW_ID JOB_ID PROJECT_IMPORT_FILE # ZIP 导入夹具路径这解释了各 runner 脚本中大量os.environ.get("FLOW_ID")类代码为何能开箱即用。
套件分发
脚本末尾按逗号拆分SUITES,逐个分发到对应 runner(第 263–283 行):
case "$suite" in curl) bash docs/docs/API-Reference/curl-examples/test-curl-examples.sh $EXAMPLE_MODE_ARGS ;; python) bash docs/docs/API-Reference/python-examples/test-python-examples.sh $EXAMPLE_MODE_ARGS ;; javascript) bash docs/docs/API-Reference/javascript-examples/test-javascript-examples.sh $EXAMPLE_MODE_ARGS ;; *) echo "Unknown suite: '$suite'. Valid values: curl, python, javascript"; exit 1 ;; esacEXAMPLE_MODE_ARGS在执行模式下为--execute,语法检查模式下不传该参数。出现未知套件名会直接报错退出。
各套件 runner 的检查与跳过逻辑
三个 runner 都遵循"先语法检查、后(可选)执行、输出 PASS/FAIL/SKIP 汇总"的统一模式,且执行模式都会先加载仓库根目录的.env(如果存在)。
Python 套件
test-python-examples.sh 的行为:
- 用
rglob("*.py")收集目录下所有.py示例(排除自身),逐个执行python -m py_compile做语法检查; - 执行模式下:
- 用
signal.alarm实现单文件超时,默认 45 秒,可用PY_TIMEOUT_SECONDS覆盖; - 命中特定文件名即跳过(SKIP),例如流式/长时运行的
build-flow-and-stream-events-2.py、stream-llm-token-responses.py、example-streaming-request.py等; retrieve-logs-with-optional-parameters.py因/logs端点在本地服务器未实现而跳过;reset-password.py因在本地 SQLite 运行下可能返回 500 而跳过,注释建议"需要时手动运行";- 若
LANGFLOW_API_KEY及LANGFLOW_URL/LANGFLOW_SERVER_URL缺失,跳过该文件并给出设置提示; - 若脚本内容含占位符(
FILE_NAME、PATH/TO/FILE、<file contents>)则跳过; - 若脚本引用了
FLOW_ID、PROJECT_ID、FOLDER_ID、SESSION_ID、JOB_ID、USER_ID等环境变量而未设置,跳过。
- 用
curl 套件
test-curl-examples.sh 的逻辑类似:先用bash -n做语法检查;执行模式下跳过流式长时脚本(example-stream-agui-*.sh、example-stream-langflow-request.sh),同样检查LANGFLOW_API_KEY与LANGFLOW_URL/LANGFLOW_SERVER_URL,并用正则检测脚本中引用但未设置的FLOW_ID等变量。失败时会打印 stdout/stderr 的最后 12 行辅助定位。
汇总与退出码
所有 runner 最终输出形如:
Summary: PASS=xx FAIL=x SKIP=x TOTAL=xx只要存在FAIL,runner 即以退出码 1 结束,set -euo pipefail使整个make api_examples_local相应失败,因此该目标可以直接用作 CI 门禁。
哪些示例不在本地基座中执行
版本 1.11.0 文档 README 明确列出了本地基座不会执行的示例(对应各 runner 的 SKIP 规则或需要额外配置的场景):
api-build/build-flow-and-stream-events-2.pyapi-build/build-flow-and-stream-events-3.pyapi-flows-run/stream-llm-token-responses.pyapi-openai-responses/example-streaming-request.pyapi-logs/stream-logs.pyapi-logs/retrieve-logs-with-optional-parameters.pyapi-users/reset-password.pyworkflows-api/example-quickstart-sync.py(及对应.js/.sh;同步模式,读取output.text)workflows-api/example-quickstart-stream-tokens.py(及对应.js/.sh;流式模式,打印token事件)workflows-api/example-quickstart-background-poll.py(及对应.js/.sh;后台队列并轮询至完成)workflows-api/example-stream-agui-parse.py(及对应.js/.sh;解析 AG-UI 事件并串联两次运行)
从源码结构看,这些 SKIP 的原因可归为三类:流式/长时运行(本地易挂起或结果不稳定)、依赖本地未实现的端点(如/logs)、以及本地 SQLite 环境的已知不稳定行为(如reset-password可能 500)。这些示例仍保留在文档目录中供读者在具备相应条件的部署上手动验证。
排障要点
综合调度脚本与各 runner 的实现,本地运行make api_examples_local遇到问题时可按以下线索排查:
- 服务器日志:基座启动的服务器日志固定写入
/tmp/langflow-server.log,runner 单文件执行输出写入/tmp/langflow-python-example.out、/tmp/langflow-python-example.err(curl 套件对应/tmp/langflow-curl-example.*),FAIL 时 runner 已自动打印末尾 12 行; - 端口占用:若
LANGFLOW_PORT(默认 7860)被占,基座会自动换用空闲端口并在输出中提示;若需要固定端口可显式设置LANGFLOW_PORT; - 认证失败:基座依赖
LANGFLOW_AUTO_LOGIN=true或超级用户凭据(LANGFLOW_SUPERUSER/LANGFLOW_SUPERUSER_PASSWORD,默认均为langflow)登录,登录最多重试 8 次; - 仅做语法检查:只想校验脚本可编译性、不真实调用 API 时,使用
make api_examples_local_syntax(等价于EXECUTE_MODE=false),此时无需LANGFLOW_API_KEY等资源变量; - 示例引用的固定资源 ID:执行模式依赖基座导出的
PROJECT_ID/FLOW_ID/FOLDER_ID/JOB_ID/PROJECT_IMPORT_FILE;如果你绕过 Makefile 直接运行单个 runner,需要自行准备这些变量,否则相应示例会被 SKIP。
小结
make api_examples_local背后的是一套"自举式"验证设施:scripts/test-api-examples-local.sh 负责起服、探测就绪、自动登录签发 API Key、创建项目/Flow 预置资源 ID,再由 curl、Python、JavaScript 三个 runner 对docs/docs/API-Reference/下的示例做语法检查与受控执行(含超时、SKIP 白名单与统一汇总)。这一机制既保证了文档中的 API 示例与真实后端保持同步可运行,也为贡献者在改动 API 端点后提供了现成的回归验证手段——运行make api_examples_local suites=curl,python,javascript即可复现文档 README 描述的全量本地验证。
【免费下载链接】langflowLangflow is a powerful tool for building and deploying AI-powered agents and workflows.项目地址: https://gitcode.com/GitHub_Trending/la/langflow
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考