tdeinge REST API 客户端


一、总体设计思路(先看这个)

我们把 tdeinge REST API 客户端 设计成 4 层:

复制代码
TDEngineClient
├─ HTTP 会话层(requests.Session)
├─ 重试机制(Retry + Backoff)
├─ 错误处理(网络 / 超时 / 业务错误)
└─ 业务接口(query / read / health)

📌 目标:

调用方只关心:client.query(sql) 是否成功


二、核心技术选型

功能 技术
HTTP 客户端 requests.Session
重试 urllib3.Retry
超时 connect / read timeout
日志 logging
线程安全 Session 级别

三、tdeinge REST API 客户端封装(完整代码)

1️⃣ tdeinge_client.py

python 复制代码
import requests
import logging
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

logger = logging.getLogger(__name__)


class TDEngineClient:
    def __init__(
        self,
        base_url: str,
        username: str,
        password: str,
        timeout: int = 5,
        max_retries: int = 3
    ):
        """
        :param base_url: http://localhost:6041
        :param username: root
        :param password: taosdata
        :param timeout: 请求超时时间(秒)
        :param max_retries: 最大重试次数
        """
        self.base_url = base_url.rstrip("/")
        self.timeout = timeout

        self.session = requests.Session()
        self.session.auth = (username, password)

        retry_strategy = Retry(
            total=max_retries,
            backoff_factor=0.5,   # 0.5s, 1s, 2s
            status_forcelist=[500, 502, 503, 504],
            allowed_methods=["GET", "POST"],
            raise_on_status=False
        )

        adapter = HTTPAdapter(max_retries=retry_strategy)
        self.session.mount("http://", adapter)
        self.session.mount("https://", adapter)

    # =============================
    # 基础请求方法
    # =============================
    def _post(self, path: str, payload: dict):
        url = f"{self.base_url}{path}"

        try:
            resp = self.session.post(
                url,
                json=payload,
                timeout=self.timeout
            )
            resp.raise_for_status()
            return resp.json()

        except requests.exceptions.Timeout:
            logger.error("TDEngine request timeout")
            raise

        except requests.exceptions.ConnectionError:
            logger.error("TDEngine connection error")
            raise

        except requests.exceptions.HTTPError as e:
            logger.error(f"TDEngine HTTP error: {e}")
            raise

        except Exception as e:
            logger.exception("Unexpected TDEngine error")
            raise

    # =============================
    # 业务接口
    # =============================
    def query(self, sql: str):
        """
        执行 SQL 查询
        """
        result = self._post(
            path="/rest/sql",
            payload={"sql": sql}
        )

        # TDEngine 业务错误判断
        if result.get("status") != "succ":
            raise RuntimeError(
                f"TDEngine query failed: {result}"
            )

        return result["data"]

    def ping(self) -> bool:
        """
        健康检查
        """
        try:
            self.query("select server_version()")
            return True
        except Exception:
            return False

四、使用示例(非常干净)

python 复制代码
client = TDEngineClient(
    base_url="http://localhost:6041",
    username="root",
    password="taosdata"
)

rows = client.query("""
    SELECT ts, temperature
    FROM sensor_data
    LIMIT 10
""")

返回数据示例:

python 复制代码
[
  ["2025-01-01 10:00:00", 23.4],
  ["2025-01-01 10:01:00", 23.6]
]

五、和 FastAPI 结合(推荐)

1️⃣ 单例注入(避免重复建连接)

python 复制代码
# deps.py
from .tdeinge_client import TDEngineClient

td_client = TDEngineClient(
    base_url="http://localhost:6041",
    username="root",
    password="taosdata"
)

def get_td_client():
    return td_client

2️⃣ FastAPI 路由中使用

python 复制代码
from fastapi import APIRouter, Depends
from deps import get_td_client

router = APIRouter()

@router.get("/cop")
def read_cop(client=Depends(get_td_client)):
    data = client.query("""
        SELECT AVG(cop)
        FROM cop_table
        WHERE ts > now - 1h
    """)
    return {"value": data[0][0]}

六、稳定性保障点(这是重点)

✅ 1️⃣ 自动重试(网络抖动)

  • 连接失败
  • 500 / 503
  • 指数退避

✅ 2️⃣ 超时控制

python 复制代码
timeout=5

不会卡死 FastAPI worker


✅ 3️⃣ Session 复用

  • TCP 连接池
  • 性能稳定

✅ 4️⃣ 明确的异常边界

异常 含义
Timeout 网络慢
ConnectionError TD 未启动
HTTPError 网关异常
RuntimeError SQL / 业务错误

七、增强版(生产环境强烈推荐)

1️⃣ 熔断(连续失败直接失败)

text 复制代码
失败 N 次 → 短时间拒绝请求

可用:

  • pybreaker
  • 自己用计数器

2️⃣ 读写分离

python 复制代码
query_read()
query_write()

3️⃣ SQL 注入保护

python 复制代码
assert "drop" not in sql.lower()

4️⃣ 统一监控

  • 请求耗时
  • 错误率
  • 重试次数

八、你现在已经具备的能力

✅ 稳定读取 tdeinge REST API

✅ 自动重试 & 超时

✅ 可直接用于 FastAPI

✅ 易维护、易测试

✅ 可扩展到 WebSocket / 批量查询


相关推荐
郝学胜-神的一滴11 分钟前
AI 编程智能体 27:吃透MCP通信机制
人工智能·python·langchain·wpf·numpy·scikit-learn
天天被压力19 分钟前
【A股分钟级高频数据完全手册 #09】A股历史分时交易数据接口:普通分时怎么批量下
java·人工智能·python
天天被压力27 分钟前
【A股分钟级高频数据完全手册 #10】股票实时行情数据接口Python:公开源实时交易取数
java·人工智能·python
特立独行的猫A10 小时前
我给女儿写了个打字练习:一边敲键盘,一边把小学英语单词记牢
java·后端·python
cpolar技术支持10 小时前
「我这边连不上你那个服务」—— 用清单驱动的 TCP 连通性只读看板,cpolar 让远端同事自己取证
python·内网穿透·tcp·cpolar·网络诊断
云和数据.ChenGuang11 小时前
LangGraph 异步 Node 的设计与写法实践
开发语言·人工智能·python·机器学习·php
天诰12 小时前
SA-K-11 检索会消失吗与四个未解问题
java·服务器·人工智能·python·机器学习·ai编程
benchmark_cc13 小时前
用 QuantDash 读取美股行情:AAPL.US 的运行前检查、排错顺序与数据校验清单
python·数据分析·pandas·量化交易·股票数据·quantdash
羲云网络16 小时前
GPT Image 2.6 接入指南:Flare、Sunburst 怎么选,编辑失败如何排查
人工智能·python·aigc·图像生成·acedatacloud
FungLeo17 小时前
成为全栈·基础补充·缓存的层次与失效:浏览器、CDN、服务端、数据库
缓存·cdn·数据一致性·http缓存·成为全栈·flutter缓存