
    ѫfik                         d dl Z d dlmZmZ d dlmZ d dlmZ d dlmZm	Z	m
Z
 ddlmZ erddlmZ e G d	 d
             Z G d de      Zy)    N)ABCabstractmethod)	dataclass)datetime)TYPE_CHECKINGListOptional   )Proxy)	Algorithmc                        e Zd ZU dZdZeed<   y)ProxyConfiga+  Provides standard shared configuration options for all proxy providers.

    Example:

    .. code-block:: python

        from proxyproviders import Webshare, ProxyConfig

        config = ProxyConfig(refresh_interval=5)
        proxy_provider = Webshare(api_key="your-api-key", config=config)
    iX  refresh_intervalN)__name__
__module____qualname____doc__r   float__annotations__     ]/home/homepc/tiktok-worker/venv/lib/python3.12/site-packages/proxyproviders/proxy_provider.pyr   r      s    
 "e!Ir   r   c                       e Zd ZdZddee   fdZddedee	   fdZ
dded	   de	fd
Zedee	   fd       ZdefdZdee	   fdZy)ProxyProvidera  
    Base class for all proxy providers that provides shared functionality across all providers.

    You'll need to use a specific provider to fetch proxies and this shouldn't directly be initialized. However, this class is useful for
    type hinting and for creating custom providers that are not included in the library, although consider contributing them to the library if you are making them.

    :param config: Configuration for the proxy provider. View the ProxyConfig class docs for more information.
    Nconfigc                     |
t               }|| _        d | _        d | _        t	        j
                         | _        ddlm}  |       | _	        y )Nr
   )
RoundRobin)
r   r   _proxies_last_refresh	threadingLock_lock
algorithmsr   _default_algorithm)selfr   r   s      r   __init__zProxyProvider.__init__*   sA    > ]F#)/315^^%
 	+",,r   force_refreshreturnc                 
   |s| j                         s| j                  s!| j                         }| j                  |       | j                  5  | j                  rt        | j                        ng cddd       S # 1 sw Y   yxY w)z
        Returns the stored proxies.
        If a format function is provided, it applies that function to each proxy.

        :param force_refresh: If True, fetches new proxies even if the list is not considered stale.
        N)should_refreshr   _fetch_proxies_set_proxiesr"   list)r%   r'   proxiess      r   list_proxieszProxyProvider.list_proxies8   sh     D//1))+Gg&ZZ 	@*.--4&R	@ 	@ 	@s   #A99B	algorithmr   c                 z    | j                         }|st        d      || j                  }|j                  |      S )a  Get a single proxy using the specified selection algorithm.

        :param algorithm: Selection algorithm to use. If None, uses the provider's default RoundRobin algorithm.
        :return: Selected proxy
        :raises ValueError: If no proxies are available

        Example:
            >>> from proxyproviders import Webshare
            >>> from proxyproviders.algorithms import Random, RoundRobin
            >>>
            >>> provider = Webshare(api_key="your-key")
            >>>
            >>> # Uses default RoundRobin (cycles through proxies)
            >>> proxy = provider.get_proxy()
            >>>
            >>> # Uses Random selection
            >>> proxy = provider.get_proxy(Random())
            >>>
            >>> # One-liner with requests
            >>> import requests
            >>> from proxyproviders.models.proxy import ProxyFormat
            >>> requests.get("https://httpbin.org/ip", proxies=provider.get_proxy().format(ProxyFormat.REQUESTS))
        z"No proxies available from provider)r/   
ValueErrorr$   select)r%   r0   r.   s      r   	get_proxyzProxyProvider.get_proxyF   sC    0 ##%ABB//I((r   c                      y)zFetch proxies from the provider implementation.
        This is not meant to be called directly, as it will always pull from the API even if not stale.
        Nr   r%   s    r   r+   zProxyProvider._fetch_proxiesj   s    
 	r   c                 8   | j                   | j                  y| j                  j                  dkD  r\| j                  5  t        j                         | j                  z
  j                         | j                  j                  k\  cddd       S y# 1 sw Y   yxY w)zQReturns True if the proxy list should be refreshed based on the refresh_interval.NTr   F)r   r   r   r   r"   r   nowtotal_secondsr6   s    r   r*   zProxyProvider.should_refreshq   s    == D$6$6$>;;''!+ BLLNT%7%77-/T[[%A%ABB B
 B
 s   ABBr.   c                     | j                   5  || _        t        j                         | _        ddd       y# 1 sw Y   yxY w)z;Sets the list of proxies and updates the last refresh time.N)r"   r   r   r8   r   )r%   r.   s     r   r,   zProxyProvider._set_proxies~   s3    ZZ 	0#DM!)D	0 	0 	0s	   !7A )N)F)r   r   r   r   r	   r   r&   boolr   r   r/   r4   r   r+   r*   r,   r   r   r   r   r       s    /x4 /@$ @4; @)8K#8 )E )H U   0DK 0r   r   )r    abcr   r   dataclassesr   r   typingr   r   r	   models.proxyr   r#   r   r   r   r   r   r   <module>r@      sJ     # !  0 0 % I I I$b0C b0r   