Skip to content

Instantly share code, notes, and snippets.

@laixintao
Last active February 20, 2024 12:05
Show Gist options
  • Star 49 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • 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
@liangnuaa
Copy link

liangnuaa commented Dec 21, 2023

用tenacity也可以?

import requests
from tenacity import retry, stop_after_attempt, wait_fixed

class Requester:
    def __init__(self):
        self.session = requests.Session()
        # You can set additional parameters for the session here, like headers or authentication

    @retry(stop=stop_after_attempt(3), wait=wait_fixed(1))
    def make_request_with_retry(self, url):
        try:
            response = self.session.get(url, timeout=5)  # Timeout set to 5 seconds
            response.raise_for_status()  # Raises a HTTPError for unsuccessful status codes
            return response
        except requests.exceptions.RequestException as e:
            print(f"Request failed: {e}")
            raise

if __name__ == "__main__":
    requester = Requester()
    url = "https://example.com"
    response = requester.make_request_with_retry(url)
    if response:
        print("Success:", response.status_code)

@douglarek
Copy link

session.mount("http://", HTTPAdapter(max_retries=retries))
session.mount("https://", HTTPAdapter(max_retries=retries))

from requests import adapters
from requests.adapters import Retry

adapters.DEFAULT_RETRIES = Retry(total=5, backoff_factor=1, status_forcelist=[502, 503, 504])  # type: ignore

@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