Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python
- """
- Symulacja obciążenia /numer/api/validate-numer – wielu równoległych wywołań.
- Autor: ChatGPT (c) 2025
- """
- import asyncio
- import random
- import string
- import time
- from itertools import islice
- import aiohttp
- from aiohttp import ClientSession
- from tqdm.asyncio import tqdm_asyncio # progress-bar dla zadań asynchronicznych
- # --- Konfiguracja -----------------------------------------------------------
- BASE_URL = "https://testnr.org/numer" # ← zmień na produkcyjne / testowe
- TOTAL_REQUESTS = 1000 # ile łącznie żądań wysłać
- CONCURRENCY = 5 # maks. równoległych żądań
- TIMEOUT = aiohttp.ClientTimeout(total=10) # seconds
- # ---------------------------------------------------------------------------
- def random_numeric(length: int) -> str:
- return "".join(random.choices(string.digits, k=length))
- async def fetch_captcha(session: ClientSession):
- """Pobiera token i kod CAPTCHA z /…/generate-captcha."""
- url = f"{BASE_URL}/api/generate-captcha"
- async with session.post(url, json={}) as resp:
- resp.raise_for_status()
- data = await resp.json()
- return data["token"], data["code"]
- async def validate_numer(session: ClientSession, numer: str, phone: str):
- """
- Wysyła pojedyncze zapytanie /api/validate-numer.
- Zwraca (status_code, alreadyExists_flag, saved_flag) z odpowiedzi lub None
- przy wyjątku.
- """
- try:
- captcha_token, captcha_code = await fetch_captcha(session)
- payload = {
- "numer": numer,
- "phone": phone,
- "captchaToken": captcha_token,
- "captchaCode": captcha_code,
- }
- url = f"{BASE_URL}/api/validate-numer"
- async with session.post(url, json=payload) as resp:
- status = resp.status
- data = await resp.json()
- return status, data.get("alreadyExists"), data.get("saved")
- except Exception as exc:
- # Możesz tu dodać logging
- return None
- async def producer(task_queue: asyncio.Queue):
- """
- Generuje pary (numer, phone) i wrzuca je do kolejki.
- Tu: numer = losowa liczba 8-cyfrowa z prefiksem „99”, ale możesz podmienić
- na cokolwiek (np. odczyt z pliku).
- """
- for _ in range(TOTAL_REQUESTS):
- numer = "99" + random_numeric(6)
- phone = random_numeric(9)
- await task_queue.put((numer, phone))
- # sygnalizuj konsumentom, że więcej zadań nie będzie
- for _ in range(CONCURRENCY):
- await task_queue.put(None)
- async def consumer(task_queue: asyncio.Queue, session: ClientSession, stats: dict):
- """Pobiera zadania z kolejki i wykonuje validate_numer()."""
- while True:
- item = await task_queue.get()
- if item is None: # koniec
- break
- numer, phone = item
- result = await validate_numer(session, numer, phone)
- if result is None:
- stats["errors"] += 1
- else:
- status, already_exists, saved = result
- stats["status_counts"][status] = stats["status_counts"].get(status, 0) + 1
- if status == 200:
- if already_exists:
- stats["duplicates"] += 1
- elif saved:
- stats["newly_saved"] += 1
- async def main():
- task_queue: asyncio.Queue = asyncio.Queue(maxsize=CONCURRENCY * 2)
- stats = {
- "errors": 0,
- "duplicates": 0,
- "newly_saved": 0,
- "status_counts": {},
- }
- conn = aiohttp.TCPConnector(limit=CONCURRENCY, ssl=False)
- async with aiohttp.ClientSession(connector=conn, timeout=TIMEOUT) as session:
- prod = asyncio.create_task(producer(task_queue))
- cons = [
- asyncio.create_task(consumer(task_queue, session, stats))
- for _ in range(CONCURRENCY)
- ]
- start = time.perf_counter()
- # Elegancka belka postępu
- await tqdm_asyncio.gather(*cons, total=TOTAL_REQUESTS)
- await prod
- elapsed = time.perf_counter() - start
- # --- Podsumowanie --------------------------------------------------------
- print("\n=== STATYSTYKI ===")
- print(f"Łączny czas : {elapsed:8.2f} s")
- print(f"Żądania / sek. : {TOTAL_REQUESTS / elapsed:8.2f}")
- print(f"Błędy : {stats['errors']}")
- print(f"Duplikaty : {stats['duplicates']}")
- print(f"Dodane rekordy : {stats['newly_saved']}")
- print("Status HTTP :", stats["status_counts"])
- if __name__ == "__main__":
- asyncio.run(main())
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement