Ожидание ответа API в python3

#python #python-3.x

#python #python-3.x

Вопрос:

(фон) У меня есть ERP-приложение, которое управляется с веб-консоли. Недавно мы заметили, что те же действия, которые мы выполняем из консоли, могут быть выполнены с использованием предоставленных поставщиком вызовов REST API. Поэтому мы хотели использовать этот подход программно и попытаться создать некоторые автоматизации.

Это страница, с которой мы можем управлять одним из консольных изображений экземпляра, та же кнопка действует как Stop и Start для управления экземпляром start и stop.

Оба запуска и остановки имеют разные вызовы API, что имеет смысл. Полный документ API находится по адресу: https://docs.oracle.com/cd/E61420_01/doc.92/e80710/smcrestapis.htm#BABFHBJI

(Сейчас) я написал программу на python, используя метод запроса для вызова этих API, и она работает нормально. Ответ API может занять от 20 до 30 секунд, когда я использую stopInstance API, и обычно занимает от 60 до 90 секунд, когда я использую startInstance API, но если при запуске экземпляра возникает проблема, это занимает более 300 секунд и переходит в неопределенное ожидание.

Моя проблема в том, что при запуске экземпляра я хочу ждать ответа максимум 100 секунд. Если это занимает более 100 секунд, программа должна отобразить сообщение типа «Экземпляр не удалось запустить через 100 секунд»

Это моя программа. Я беру входные данные из текстового файла, и все присутствующие там значения были проверены.

 import requests
import json
import importlib.machinery
import importlib.util
import numpy
import time
import sys

loader = importlib.machinery.SourceFileLoader('SM','sm_details.txt')
spec = importlib.util.spec_from_loader(loader.name, loader)
mod = importlib.util.module_from_spec(spec)
loader.exec_module(mod)
username = str(mod.username)
password = str(mod.password)
hostname = str(mod.servermanagerHostname)
portnum = str(mod.servermanagerPort)
instanceDetails = numpy.array(mod.instanceName)

authenticationAPI = "http://" hostname ":" portnum "/manage/mgmtrestservice/authenticate"
startInstanceAPI = "http://" hostname ":" portnum "/manage/mgmtrestservice/startinstance"

headers = {
    'Content-Type':'application/json',
    'Cache-Control':'no-cache',
}

data = {}
data['username']= username
data['password']= password
instanceNameDict = {'instanceName':''}

#Authentication request and storing token
response = requests.post(authenticationAPI, data=json.dumps(data), headers=headers)
token = response.headers['TOKEN']
head2 = {}
head2['TOKEN']=token

def start(instance):
    print(f'nTrying to start instance : ' instance['instanceName'])
    startInstanceResponse = requests.post(startInstanceAPI,data=json.dumps(instance), headers=head2) #this is where the program is stuck and it does not move to the time.sleep step 
    time.sleep(100)
    if startInstanceResponse.status_code == 200:
        print('Instance ' instance['instanceName'] ' started.')
    else:
        print('Could not start instance in 100 seconds')
        sys.exit(1)
  

Ответ №1:

Я бы посоветовал вам использовать параметр timeout в запросах:

 requests.post(startInstanceAPI,data=json.dumps(instance), headers=head2, timeout=100.0)
  

Вы можете указать запросам прекратить ожидание ответа через заданное
количество секунд с параметром timeout . Почти весь производственный
код должен использовать этот параметр почти во всех запросах. Невыполнение
этого требования может привести к зависанию вашей программы на неопределенный срок.

Источник
Вот документация по тайм-аутам запросов, вы также найдете там более подробную информацию и обработку исключений.

Комментарии:

1. привет, Питто, спасибо, что прочитал этот огромный пост и нашел время для ответа. Я попробую этот вариант и проведу еще несколько тестов.