Enhance README with detailed /proxy/rotate endpoint documentation and add VSCode launch configuration for FastAPI debugging. Update /rotate endpoint to support query, form, and JSON parameters with priority handling.

This commit is contained in:
wangqifan 2025-10-17 18:33:07 +08:00
parent 93f05f13c1
commit 6a4f21a743
3 changed files with 98 additions and 3 deletions

42
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,42 @@
{
// 使 IntelliSense
//
// 访: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Python Debugger: FastAPI",
"type": "debugpy",
"request": "launch",
"module": "uvicorn",
"args": [
"app.main:app",
"--reload"
],
"jinja": true,
"cwd": "${workspaceFolder}",
"subProcess": true,
"env": {
"PYTHONPATH": "${workspaceFolder}"
}
},
{
"name": "Python Debugger: FastAPI (no reload)",
"type": "debugpy",
"request": "launch",
"module": "uvicorn",
"args": [
"app.main:app",
"--host",
"127.0.0.1",
"--port",
"8000"
],
"jinja": true,
"cwd": "${workspaceFolder}",
"env": {
"PYTHONPATH": "${workspaceFolder}"
}
}
]
}

View File

@ -34,6 +34,41 @@ app/
- POST `/proxy/rotate` 执行轮换(可传 cityhash/num
- GET `/proxy/status` 当前状态
#### POST `/proxy/rotate`
- 请求体JSON
- `cityhash`可选string城市哈希若不传将使用环境变量 `EIP_DEFAULT_CITYHASH`
- `num`可选int拉取设备数量上限若不传使用环境变量 `EIP_DEFAULT_NUM`,再不设则默认 10。
- 行为说明:
- 根据 `cityhash` 调用设备列表接口(数量为 `num`),从中选择「今天未使用过」的第一个 IP。
- 将选中设备的 `edge` 配置到网关规则中,并把该 IP 记录为当天已使用。
- 若没有可用且今天未使用的 IP则返回未变更原因。
- 请求示例:
```bash
curl -X POST 'http://localhost:8000/proxy/rotate' \
-H 'Content-Type: application/json' \
-d '{"cityhash": "310000", "num": 20}'
```
- 响应示例(变更成功):
```json
{
"changed": true,
"ip": "1.2.3.4",
"edge": "edge-id-xxx",
"status": { "...": "gateway_status_payload" }
}
```
- 响应示例(无可用 IP
```json
{
"changed": false,
"reason": "没有可用且今天未使用的 IP"
}
```
### 备注
- EIP 详细接口见 `API.md`

View File

@ -1,6 +1,6 @@
from typing import Optional
from fastapi import APIRouter
from fastapi import APIRouter, Body, Query, Form
from pydantic import BaseModel
from ..rotation_service import rotate as rotate_impl, status as status_impl
@ -15,8 +15,26 @@ class RotateRequest(BaseModel):
@router.post("/rotate")
def rotate(req: RotateRequest):
result = rotate_impl(cityhash=req.cityhash, num=req.num)
def rotate(
# 查询参数
cityhash_q: Optional[str] = Query(None, alias="cityhash"),
num_q: Optional[int] = Query(None, alias="num"),
# 表单参数multipart/form-data 或 application/x-www-form-urlencoded
cityhash_f: Optional[str] = Form(None),
num_f: Optional[int] = Form(None),
# JSON 请求体application/json
req: Optional[RotateRequest] = Body(None),
):
# 优先级Query > Form > JSON
effective_cityhash = (
cityhash_q
if cityhash_q is not None
else (cityhash_f if cityhash_f is not None else (req.cityhash if req else None))
)
effective_num = (
num_q if num_q is not None else (num_f if num_f is not None else (req.num if req else None))
)
result = rotate_impl(cityhash=effective_cityhash, num=effective_num)
return result