o
    _�¿j%&  ã                   @  s®   d Z ddlmZ ddlZddlmZ ddlmZmZm	Z	 ddl
mZmZ ddlmZmZmZmZmZmZmZmZmZmZmZ G dd	„ d	eƒZejd
d�ddd„ƒZd	dgZdS )aÆ  Typed, validated settings for indiaopt.

Configuration is loaded (in priority order) from:

1. Explicit keyword arguments to :class:`Settings`.
2. Environment variables (prefixed with ``INDIAOPT_``).
3. A ``.env`` file in the current working directory.
4. Hard-coded defaults.

Example .env file::

    INDIAOPT_SYMBOLS=NIFTY,BANKNIFTY,RELIANCE
    INDIAOPT_MAX_RETRIES=5
    INDIAOPT_FETCH_TIMEOUT=20.0
    INDIAOPT_PROXY_URLS=http://proxy1:8080,http://proxy2:8080
    INDIAOPT_LOG_LEVEL=DEBUG

Example usage::

    from indiaopt import Settings, get_settings

    # Use defaults / env vars
    settings = get_settings()

    # Or override at runtime
    settings = Settings(symbols=["NIFTY"], max_retries=3)
é    )ÚannotationsN)Ú	Annotated)ÚFieldÚfield_validatorÚmodel_validator)ÚBaseSettingsÚSettingsConfigDict)ÚDEFAULT_ASYNC_TIMEOUT_SÚDEFAULT_BACKOFF_BASEÚDEFAULT_BACKOFF_CAP_SÚDEFAULT_CACHE_TTL_SÚDEFAULT_CIRCUIT_BACKOFF_SÚ!DEFAULT_CIRCUIT_FAILURE_THRESHOLDÚDEFAULT_EXPIRY_CACHE_TTL_SÚDEFAULT_FETCH_TIMEOUT_SÚDEFAULT_MAX_RETRIESÚDEFAULT_THREAD_POOL_WORKERSÚDEFAULT_WARMUP_TIMEOUT_Sc                   @  sò  e Zd ZU dZeddddddd�Zed	gd
d�Zded< eddd�Z	ded< ee
dd�Zded< eedd�Zded< eedd�Zded< eddd�Zded< eedd�Zded < eed!d�Zd"ed#< eed$d�Zd%ed&< eg d'd�Zded(< eed)d�Zd*ed+< eed,d�Zd-ed.< eed/d�Zd0ed1< eed2d�Zd3ed4< ee d5d�Z!d6ed7< ed8d9d�Z"d:ed;< ed<d=d�Z#d>ed?< ed@dAd�Z$dBedC< e%ddDdE�e&dRdIdJ„ƒƒZ'e%d(dDdE�e&dRdKdL„ƒƒZ(e%d;dDdE�e&dSdMdN„ƒƒZ)e*dOdE�dTdPdQ„ƒZ+d@S )UÚSettingsu.  All runtime configuration for indiaopt.

    Fields can be set via environment variables prefixed with ``INDIAOPT_``
    or via ``.env`` file.

    Attributes:
        symbols:                    Default list of symbols to fetch.
        poll_interval_seconds:      Polling interval in seconds (for polling use-cases).
        max_retries:                Maximum number of retry attempts (1-10).
        backoff_base:               Exponential backoff base in seconds.
        backoff_cap_seconds:        Maximum backoff sleep duration in seconds.
        backoff_jitter:             Random jitter added to each sleep (seconds).
        fetch_timeout:              Per-request HTTP timeout in seconds.
        warmup_timeout:             Session warm-up HTTP timeout in seconds.
        async_timeout:              Total coroutine-level timeout in seconds.
        proxy_urls:                 Optional HTTP proxy URLs (rotated randomly).
        circuit_failure_threshold:  Consecutive failures before circuit opens.
        circuit_backoff_seconds:    How long the circuit stays open (seconds).
        cache_ttl:                  TTL for option chain cache entries (seconds).
        expiry_cache_ttl:           TTL for expiry date cache entries (seconds).
        thread_pool_workers:        Thread pool size for sync-in-async execution.
        log_level:                  Logging level (``"DEBUG"``, ``"INFO"``, â€¦).
        session_retention_hours:    Hours before purging old session data.
        redis_url:                  Optional Redis URL for distributed caching.
    Ú	INDIAOPT_z.envzutf-8FÚignoreT)Ú
env_prefixÚenv_fileÚenv_file_encodingÚcase_sensitiveÚextraÚpopulate_by_nameÚNIFTYzDefault symbols to watch.)ÚdefaultÚdescriptionú	list[str]Úsymbolsé<   zPolling interval in seconds.z&Annotated[int, Field(ge=10, le=86400)]Úpoll_interval_secondsu*   Maximum number of retry attempts (1â€“10).z"Annotated[int, Field(ge=1, le=10)]Úmax_retriesz$Exponential backoff base multiplier.z$Annotated[float, Field(gt=0, le=10)]Úbackoff_basez*Maximum backoff sleep duration in seconds.z%Annotated[float, Field(gt=0, le=120)]Úbackoff_cap_secondsg      ð?z4Random jitter (seconds) added to each backoff sleep.z#Annotated[float, Field(ge=0, le=5)]Úbackoff_jitterz$Per-request HTTP timeout in seconds.Úfetch_timeoutz#Session warm-up timeout in seconds.z$Annotated[float, Field(gt=0, le=30)]Úwarmup_timeoutz)Total async coroutine timeout in seconds.z%Annotated[float, Field(gt=0, le=300)]Úasync_timeoutz$List of proxy URLs rotated randomly.Ú
proxy_urlsz*Consecutive failures before circuit opens.z"Annotated[int, Field(ge=1, le=50)]Úcircuit_failure_thresholdz+How long the circuit stays open in seconds.z&Annotated[float, Field(gt=0, le=3600)]Úcircuit_backoff_secondsz.TTL for option chain cache entries in seconds.z%Annotated[int, Field(ge=1, le=86400)]Ú	cache_ttlz-TTL for expiry date cache entries in seconds.z&Annotated[int, Field(ge=60, le=86400)]Úexpiry_cache_ttlz-Thread pool size for sync-in-async execution.z"Annotated[int, Field(ge=1, le=64)]Úthread_pool_workersÚINFOz5Logging level: DEBUG, INFO, WARNING, ERROR, CRITICAL.ÚstrÚ	log_levelé   z3Session data older than this is eligible for purge.z"Annotated[int, Field(ge=1, le=48)]Úsession_retention_hoursNz-Redis URL for distributed caching (optional).z
str | NoneÚ	redis_urlÚbefore)ÚmodeÚvÚobjectÚreturnc                 C  s@   t |tƒrdd„ | d¡D ƒS t |ttfƒrdd„ |D ƒS dgS )ú&Accept comma-separated string or list.c                 S  s    g | ]}|  ¡ r|  ¡  ¡ ‘qS © )ÚstripÚupper©Ú.0Úsr=   r=   úS/home/dinkstrade/pdmp/venv/lib/python3.10/site-packages/indiaopt/config/settings.pyÚ
<listcomp>µ   s     z+Settings._parse_symbols.<locals>.<listcomp>ú,c                 S  s(   g | ]}t |ƒ ¡ rt |ƒ ¡  ¡ ‘qS r=   )r2   r>   r?   r@   r=   r=   rC   rD   ·   s   ( r   ©Ú
isinstancer2   ÚsplitÚlistÚtuple©Úclsr9   r=   r=   rC   Ú_parse_symbols°   s
   
zSettings._parse_symbolsc                 C  s>   t |tƒrdd„ | d¡D ƒS t |ttfƒrdd„ |D ƒS g S )r<   c                 S  s   g | ]
}|  ¡ r|  ¡ ‘qS r=   )r>   ©rA   Úpr=   r=   rC   rD   ¿   s    z.Settings._parse_proxy_urls.<locals>.<listcomp>rE   c                 S  s$   g | ]}t |ƒ ¡ rt |ƒ ¡ ‘qS r=   )r2   r>   rN   r=   r=   rC   rD   Á   s   $ rF   rK   r=   r=   rC   Ú_parse_proxy_urlsº   s
   
zSettings._parse_proxy_urlsc                 C  s4   h d£}t |ƒ ¡ }||vrtd|› d|›�ƒ‚|S )N>   r1   ÚDEBUGÚERRORÚWARNINGÚCRITICALzlog_level must be one of z, got )r2   r?   Ú
ValueError)rL   r9   ÚvalidrB   r=   r=   rC   Ú_validate_log_levelÄ   s
   zSettings._validate_log_levelÚafterc                 C  s*   | j | jkrtd| j › d| j› d�ƒ‚| S )Nzasync_timeout (z's) must be greater than fetch_timeout (zs).)r*   r(   rU   )Úselfr=   r=   rC   Ú_validate_timeout_orderÍ   s   
ÿÿz Settings._validate_timeout_order)r9   r:   r;   r    )r9   r:   r;   r2   ©r;   r   ),Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   Úmodel_configr   r!   Ú__annotations__r#   r   r$   r
   r%   r   r&   r'   r   r(   r   r)   r	   r*   r+   r   r,   r   r-   r   r.   r   r/   r   r0   r3   r5   r6   r   ÚclassmethodrM   rP   rW   r   rZ   r=   r=   r=   rC   r   4   sº   
 ú
þþþþþþþþþþþþþþþþþþ


r   é   )Úmaxsizer;   c                   C  s   t ƒ S )aŠ  Return the cached global :class:`Settings` instance.

    Reads configuration from environment variables and ``.env`` file on
    first call. Subsequent calls return the cached instance.

    To reset (e.g. in tests), call ``get_settings.cache_clear()`` first::

        from indiaopt.config.settings import get_settings
        get_settings.cache_clear()
        settings = get_settings()
    )r   r=   r=   r=   rC   Úget_settings×   s   re   r[   )r_   Ú
__future__r   Ú	functoolsÚtypingr   Úpydanticr   r   r   Úpydantic_settingsr   r   Úindiaopt.constantsr	   r
   r   r   r   r   r   r   r   r   r   r   Ú	lru_cachere   Ú__all__r=   r=   r=   rC   Ú<module>   s    4 
$