Skip to content

Instantly share code, notes, and snippets.

@laixintao
Last active February 20, 2024 12:05
Show Gist options
  • Save laixintao/e9eae48a835e741969ae06af3ad45f71 to your computer and use it in GitHub Desktop.
Save laixintao/e9eae48a835e741969ae06af3ad45f71 to your computer and use it in GitHub Desktop.
Send HTTP requests using python-requests with timeout, tcp reuse(session) and retry.
from requests.adapters import HTTPAdapter, Retry
from requests import Session
retries = Retry(
total=5, backoff_factor=1, status_forcelist=[502, 503, 504]
)
session = Session() # reuse tcp connection
session.mount("http://", HTTPAdapter(max_retries=retries))
session.mount("https://", HTTPAdapter(max_retries=retries))
session.get("https://example.com", timeout=5) # seconds
@amazingchow
Copy link

Sharing my code snippt used to r/w mongo,

import logging
from typing import Any, Callable

import pymongo.errors as perrors
from loguru import logger as loguru_logger
from tenacity import (
    before_sleep_log,
    retry,
    retry_if_exception_type,
    stop_after_attempt,
    wait_exponential
)

def _create_retry_decorator(min_secs: int = 1, max_secs: int = 60, max_retries: int = 3) -> Callable[[Any], Any]:
    return retry(
        reraise=True,
        stop=stop_after_attempt(max_retries),
        wait=wait_exponential(multiplier=1, min=min_secs, max=max_secs),
        retry=(
            # When the client was unable to find an available server to
            # run the operation within the given timeout.
            retry_if_exception_type(perrors.ServerSelectionTimeoutError)
            # When either the client was unable to establish a connection
            # within the given timeout or the operation was sent but the
            # server was not able to respond in time.
            | retry_if_exception_type(perrors.NetworkTimeout)
            # When the server cancelled the operation because it exceeded
            # the given timeout. Note that the operation may have partially
            # completed on the server (depending on the operation).
            # Or When the client cancelled the operation because it was not
            # possible to complete within the given timeout.
            | retry_if_exception_type(perrors.ExecutionTimeout)
            # When the client attempted a write operation but the server could
            # not replicate that write (according to the configured write
            # concern) within the given timeout.
            | retry_if_exception_type(perrors.WTimeoutError)
            # The same error as WTimeoutError but for insert_many() or bulk_write().
            | retry_if_exception_type(perrors.BulkWriteError)
        ),
        before_sleep=before_sleep_log(loguru_logger, logging.WARNING),
    )


retry_decorator = _create_retry_decorator()

@QuantumGhost
Copy link

QuantumGhost commented Dec 22, 2023

以及, 如 https://t.me/laiskynotes/100 这条提到的, 如果你请求的是个很慢的服务器 (比如每 3s 给你返回一个字节),
那实际的请求时间可能远大于 timeout

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment