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

Автор Сообщение
news_bot ®

Стаж: 6 лет 3 месяца
Сообщений: 27286

Создавать темы news_bot ® написал(а)
05-Авг-2020 20:30

Доброго времени, уважаемые жители Хабра!
Сегодня речь пойдет о том, как из идеи по замеру скорости, был создан скрипт для загрузки файла изображения и отправки его же обратно на сервер, с расчетом времени выполнения каждой из функций и вычисления скорости.
Начну со списка используемых библиотек:
  • 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. Так же вывод можно поместить в базу и собирать статистику для анализа.
Спасибо за внимание!
===========
Источник:
habr.com
===========

Похожие новости: Теги для поиска: #_python, #_python, #_razrabotka (разработка), #_skripty (скрипты), #_zamery (замеры), #_python
Профиль  ЛС 
Показать сообщения:     

Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы

Текущее время: 17-Май 00:10
Часовой пояс: UTC + 5