import asyncio import random import aiohttp import yaml import time import numpy as np status_stats = {} # init params def getParams(): with open('params.yml', 'r') as params_file: try: return yaml.safe_load(params_file) except yaml.YAMLError as error: print(error) params = getParams() requestsNumber = params['concurrent_requests'] endpoint = params['endpoint'] service = params['service'] parameters = params['parameters'] # init functions def fPar(param): return '?' + param + '=' + str(parameters[param]) def mPar(param): return '&' + param + '=' + str(parameters[param]) def mRandPar(param): #takes a random value from the list of values (comma separated) options = parameters[param].split(', ') selected = random.choice(options) return '&' + param + '=' + selected def nextUrl(id): url = endpoint + fPar('firsParam') + mRandPar('multipleValueParam') + mPar('otherParam') print("Id: {} to call {}".format(id, url)) return (id, url) async def asyncHttpGet(url_tuple, session): id, url = url_tuple try: start_time = time.time() async with session.get(url=url) as response: spent_time = round((time.time() - start_time)*1000) code = response.status resp = await response.read() print("Id: {}, Got {} status in {} milis with response length of {}.".format(id, code, spent_time, len(resp))) if code != 200 or len(resp) < 200: print("ID: {}. Error: {}.".format(id, resp)) # Save stats if code in status_stats: status_stats[code]['times'].append(spent_time) status_stats[code]['count'] += 1 else: status_stats[code] = {'times': [spent_time], 'count': 1} except Exception as e: print("Id: {}. Unable to get url {} due to {}.".format(id, url, e)) async def allRequests(urlsToCall): start_time = time.time() async with aiohttp.ClientSession() as session: ret = await asyncio.gather(*[asyncHttpGet(url, session) for url in urlsToCall]) spent_time = round((time.time() - start_time)*1000) print("Finalized all {} requests in {} milis.".format(len(ret), spent_time)) # MAIN asyncio.run(allRequests([nextUrl(i) for i in range(0, requestsNumber)])) print("### STATS ###") for status_code, stats in sorted(status_stats.items()): average_time = round(np.mean(stats['times'])) min_time = min(stats['times']) max_time = max(stats['times']) p50 = round(np.percentile(stats['times'], 50)) p95 = round(np.percentile(stats['times'], 95)) print("With status {} happened to {:<3} requests, average time was {} milis. Min: {}, p50: {}, p95: {}, Max: {}". format(status_code, stats['count'], average_time, min_time, p50, p95, max_time))