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

prompt-toolkit中如何转义API返回内容并保留自定义格式?

问题解决方案:YouTube搜索工具的HTML渲染与API限流问题

核心问题梳理

  • API返回含特殊字符时,print_formatted_text(HTML)触发"not well formed (invalid token)"错误
  • 转义整个f-string会丢失自定义颜色与格式
  • 拆分打印存在类型错误
  • 需要控制API请求数量避免超限

解决方案

1. 安全转义动态内容,保留自定义HTML格式

不要转义整个字符串,只针对API返回的动态文本做HTML转义,自己写的格式标签(比如<color>)保持原样。用Python内置的html.escape()处理动态内容即可:

from html import escape
from prompt_toolkit import print_formatted_text
from prompt_toolkit.formatted_text import HTML

# 示例:API返回带特殊字符的标题
api_title = "My <script> Test Playlist"
# 仅转义动态内容,保留自定义颜色标签
formatted_html = f"<color='blue'>{escape(api_title)}</color> - <color='green'>[Playlist]</color>"
print_formatted_text(HTML(formatted_html))

这样既解决了HTML解析错误,又不会丢失自定义的颜色和格式。

2. 拆分打印的类型错误修复

拆分打印时如果触发类型错误,要确保传入print_formatted_text的是合法的格式化文本类型(比如HTML对象或FormattedText),不要混合字符串和格式化对象。

错误示例(触发类型错误):

print_formatted_text("序号1: ", HTML("<color='red'>测试标题</color>"))

正确做法:把所有内容整合为一个HTML字符串,或者用FormattedText组合:

from prompt_toolkit.formatted_text import FormattedText

# 用FormattedText组合不同样式的内容
formatted_content = FormattedText([
    ("", "序号1: "),
    ("#ff0000", "测试标题"),
    ("", " - 播放列表")
])
print_formatted_text(formatted_content)

3. API请求数量限流控制

用计数器结合len()或直接计数的方式,限制最大请求次数,避免触发API限额:

MAX_REQUESTS = 10
request_count = 0
next_page_token = None

while request_count < MAX_REQUESTS:
    # 发送API请求
    response = youtube_search_api(query, page_token=next_page_token)
    request_count += 1
    
    # 处理返回结果
    for item in response.get("items", []):
        # 渲染逻辑
        pass
    
    # 没有下一页则提前终止循环
    next_page_token = response.get("nextPageToken")
    if not next_page_token:
        break

也可以把计数器封装成类或装饰器,让代码更整洁。

完整示例代码片段

from html import escape
from prompt_toolkit import print_formatted_text
from prompt_toolkit.formatted_text import HTML

MAX_API_REQUESTS = 10

def render_result(item):
    # 转义API返回的动态字段
    title = escape(item["snippet"]["title"])
    channel = escape(item["snippet"]["channelTitle"])
    item_type = "Playlist" if item["id"]["kind"] == "youtube#playlist" else "Video"
    
    # 拼接带格式的HTML内容
    html_str = f"""
    <color='cyan'>{title}</color>
    <color='gray'> | 作者: {channel}</color>
    <color='green'> [{item_type}]</color>
    """
    print_formatted_text(HTML(html_str))

def run_search(query):
    request_count = 0
    next_page_token = None
    
    while request_count < MAX_API_REQUESTS:
        # 模拟API调用
        api_response = call_youtube_api(query, page_token=next_page_token)
        request_count += 1
        
        for item in api_response.get("items", []):
            render_result(item)
        
        next_page_token = api_response.get("nextPageToken")
        if not next_page_token:
            break

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 15:55:06