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 / 批量查询


相关推荐
好家伙VCC12 小时前
### WebRTC技术:实时通信的革新与实现####webRTC(Web Real-TimeComm
java·前端·python·webrtc
前端玖耀里13 小时前
如何使用python的boto库和SES发送电子邮件?
python
serve the people13 小时前
python环境搭建 (十二) pydantic和pydantic-settings类型验证与解析
java·网络·python
小天源13 小时前
Error 1053 Error 1067 服务“启动后立即停止” Java / Python 程序无法后台运行 windows nssm注册器下载与报错处理
开发语言·windows·python·nssm·error 1053·error 1067
喵手14 小时前
Python爬虫实战:HTTP缓存系统深度实战 — ETag、Last-Modified与requests-cache完全指南(附SQLite持久化存储)!
爬虫·python·爬虫实战·http缓存·etag·零基础python爬虫教学·requests-cache
喵手14 小时前
Python爬虫实战:容器化与定时调度实战 - Docker + Cron + 日志轮转 + 失败重试完整方案(附CSV导出 + SQLite持久化存储)!
爬虫·python·爬虫实战·容器化·零基础python爬虫教学·csv导出·定时调度
2601_9491465314 小时前
Python语音通知接口接入教程:开发者快速集成AI语音API的脚本实现
人工智能·python·语音识别
ALex_zry14 小时前
Redis Cluster 分布式缓存架构设计与实践
redis·分布式·缓存
寻梦csdn14 小时前
pycharm+miniconda兼容问题
ide·python·pycharm·conda
Java面试题总结15 小时前
基于 Java 的 PDF 文本水印实现方案(iText7 示例)
java·python·pdf