Проверка скорости интернета библиотекой Requests в мультипроцессинге

от автора

Доброго времени, уважаемые жители Хабра!

Сегодня речь пойдет о том, как из идеи по замеру скорости, был создан скрипт для загрузки файла изображения и отправки его же обратно на сервер, с расчетом времени выполнения каждой из функций и вычисления скорости.

Начну со списка используемых библиотек:

  • os
  • multiprocessing(Process, Pipe)
  • time
  • requests
  • pandas
  • datetime

В первую очередь, записываем текущее время:

dt = datetime.datetime.now()

Далее нам нужен список серверов, я предпочел создать для этого словарь:

server_list = [     {         'server_id': 3682,         'download': 'http://moscow.speedtest.rt.ru:8080/speedtest/random7000x7000.jpg',         'upload': 'http://moscow.speedtest.rt.ru:8080/speedtest/upload.php'     } ]

Пишем первую функцию:

def download(id, path):     start = time()     file_name = str(id) + str(path.split('/')[-1])     r = requests.get(path, stream=True)     size = int(r.headers.get('Content-Length', 0))     with open(file_name, 'wb') as f:         for chunk in r.iter_content(chunk_size=1024):             if chunk:                 f.write(chunk)      end = time()     duration = end - start     sp = (((size * 8) / 1024) / 1024) / duration      return sp

Теперь подробнее о том, что происходит.

В функции есть время старта и время окончания(в секундах), из которых в дальнейшем мы получаем время жизни. В имя файла записываем id сервера и название изображения(сделано для того, чтобы не возникало конфликтов при загрузке из множества источников). Далее делаем GET запрос, получаем размер файла(в байтах) и сохраняем его на диск. Переводим байты в биты, еще немного магии с формулами и на выходе имеем скорость в MBit/s.

Следующая функция — отдача файла на сервер:

def upload(id, path):     start = time()     file_name = str(id) + 'random7000x7000.jpg'     with open(file_name, 'rb') as f:         files = {'Upload': (file_name, f.read())}     requests.post(path, files=files)     size = os.path.getsize(file_name)     end = time()     duration = end - start     sp = (((size * 8) / 1024) / 1024) / duration      return sp

Здесь принцип тот же, только мы берем файл из локальной папки и POST запросом отправляем.

Наша следующая задача получить данные из двух предыдущих функций. Пишем еще одну функцию:

def test_f(conn, server):     speed_download = download(server['server_id'], server['download'])     speed_upload = upload(server['server_id'], server['upload'])     conn.send([server['server_id'], speed_download, speed_upload])     conn.close()

Осталось дело за малым, все это обернуть в цикл и прикрутить мультипроцессинг:

d = 0  if __name__ == '__main__':     for server in server_list:         parent_conn, child_conn = Pipe()         try:             p = Process(target=test_f, args=(child_conn, server))             p.start()             d = (parent_conn.recv())         except:             d[1] = d[2] = 0          df = pd.DataFrame({                 'Date': dt,                 'Server': d[0],                 'Download': "%.2f" % d[1],                 'Upload': "%.2f" % d[2]         }, index=[0])         print(df)

Скрипт готов к использованию, для удобства вывода я использовал библиотеку pandas. Так же вывод можно поместить в базу и собирать статистику для анализа.

Спасибо за внимание!

ссылка на оригинал статьи https://habr.com/ru/post/513978/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *