首页 > 解决方案 > Python中如何使用线程调用http API

问题描述

我有一个项目,我使用opencv. 在代码之间,有一个条件。当它变成True我必须调用 API 来获取我在实时视频馈送帧上显示的一些数据时。调用 API 并获得响应需要一些时间(2-3 秒),在此期间帧被冻结,看起来不太好。下面是代码片段:

if config['ROIX1'] < f_startX and config['ROIX2']:
    # Call the API and get the response
    """
    OTHER CODE
    """

    conn = http.client.HTTPSConnection('api.tive.com')
    conn.request("POST", "/get_status", json_data, headers)
    response = conn.getresponse()
    rdata = response.read()
    rdata = rdata.decode('utf8')
    rdata = json.loads(rdata)

    subject = rdata['subject']

    txt = "SUBJECT: {}".format(subject)
    cv2.putText(frame, txt, (5, 30), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1, (0, 0, 255), 1)

    cv2.imshow(win_name, frame)

    key = cv2.waitKey(1)
    if key == ord('q'):
        break

在上面的代码中,当 if 条件变为 True 时,代码会调用 API 并且响应rdata需要一些时间,因此应用程序会冻结一段时间。如何在另一个线程中有效地处理调用并从 API 获取响应,一旦得到结果,它就会显示在frame. 我不是很有经验threads。请帮忙。谢谢

标签: python-3.xmultithreadingopencv

解决方案


我相信您正在寻找的逻辑类似于:

1) 启动线程请求api

2)在请求未完成时做一些其他任务(显示没有api数据的框架)

3)完成后中断,(显示带有api数据的框架)

我相信您回答的关键是使用 thread.is_alive,它检查线程是否处于活动状态并根据线程状态返回一个布尔值。is_alive() 方法常用于线程同步。

我会通过执行类似于此虚拟代码的操作来完成您正在寻找的事情:

import sys
import trace
import threading
import time
def show_frame(subject=""):
    if subject:
        print(f"showing frame with {subject}")
    else:
        print(f"showing frame")

def request_api():
    time.sleep(5)
    return "data from api"

def show_frame_from_api():
    subject_dataAPI=request_api()
    show_frame(subject=subject_dataAPI)

t = threading.Thread(target=show_frame_from_api, args=())
t.start()

while t.is_alive():
    show_frame()

在你的例子中应用它,我会建议这样的事情:

import sys
import trace
import threading
import time
def show_frame(win_name, frame, apiText=""):
    if apiText:
        text=f'display with {apiText}'
        cv2.putText(frame, text, (5, 30), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1, (0, 0, 255), 1)
        cv2.imshow(win_name, frame)
    else
        text=f'display without api text :('
        cv2.putText(frame, text, (5, 30), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1, (0, 0, 255), 1)
        cv2.imshow(win_name, frame)

def show_frame_from_api(win_name, frame):
    subject_dataAPI=request_api()
    show_frame(win_name, frame, apiText=subject_dataAPI)


def request_api():
    conn = http.client.HTTPSConnection('api.tive.com')
    conn.request("POST", "/get_status", json_data, headers)
    response = conn.getresponse()
    rdata = response.read()
    rdata = rdata.decode('utf8')
    rdata = json.loads(rdata)

    subject = rdata['subject']

    txt = "SUBJECT: {}".format(subject)
    return txt

if config['ROIX1'] < f_startX and config['ROIX2']:
    # Call the API and get the response
    """
    OTHER CODE
    """

    t = threading.Thread(target=show_frame_from_api, args=(win_name, frame))
    t.start()

    while t.is_alive():
        show_frame(win_name, frame)


    key = cv2.waitKey(1)
    if key == ord('q'):
        break

推荐阅读