## Аргументы подключения

Все приведенные ниже аргументы могут использоваться как в контекстном менеджере, так и в обычном конструкторе.

Почти все аргументы могут быть прочитаны из переменных окружения - их имя указано в скобках.
Если аргумент присутствует одновременно и в конструкторе, и в окружении, 
то приоритет будет отдан переменной окружения. Для отключения этого поведения используйте аргумент:

- `trust_env`

    Использовать переменные окружения для инициализации. 
    При значении `False` переменные окружения, указанные ниже скобках, будут проигнорированы.
    По умолчанию `True`.

### Обработка "плохих" запросов

- `client_timeout` (`PYNSPD_CLIENT_TIMEOUT`)

    Время ожидания ответа.
    Если не установлен - есть вероятность бесконечного ожидания. По умолчанию `None`.

- `client_retries` (`PYNSPD_CLIENT_RETRIES`)

    Количество попыток при неудачном запросе
    (таймаут, неожиданный обрыв соединения, 5хх ошибки). По умолчанию `10`.

- `client_retry_on_blocked_ip` (`PYNSPD_CLIENT_RETRY_ON_BLOCKED_IP`)

    При получении ошибки 403 (доступ заблокирован для вашего IP),
    продолжать попытки запроса до исчерпания `retries`.
    Рекомендуется использовать только c ротируемыми прокси. По умолчанию `False`.

!!! warning "Риск блокировок"
    Крайне рекомендуется пользоваться сервисами проксирования, 
    чтобы избежать длительной блокировки со стороны НСПД, особенно при больших объемах запросов.
    Были зафиксированы случаи полной блокировки на несколько суток.

### Настройка прокси

- `client_proxy` (`PYNSPD_CLIENT_PROXY`)

    Адрес для проксирования запросов. По умолчанию `None`.

!!! warning "Внешняя зависимость"
    Для использования SOCKS-прокси, требуется установить дополнительный модуль:

    `pip install pynspd[socks]`  

    Для HTTP-прокси дополнительных действий не требуется.

- `client_dns_resolve` (`PYNSPD_CLIENT_DNS_RESOLVE`)

    Использовать в запросах IP адрес НСПД вместо доменного имени.
    Рекомендуется включить, если используемый прокси
    не может сам разрешать доменные имена.
    По умолчанию `False`.

??? info "Подробнее"
    В большинстве случаев мы хотим, чтобы доменное имя разрешалось само на уровне клиента.
    Однако, в случае, например, ротируемых прокси, это может быть невозможно, т.к. заблокировано
    на уровне провайдера.

    `pynspd` умеет определять, когда запрос сталкивается с такой проблемой - и самостоятельно переключает
    режим разрешения домена (и предупреждает вас о таком поведении). 
    Тем не менее, это влечет за собой потенциальное удвоение количества запросов.
    Поэтому, если вы уверены, что сталкиваетесь с таким поведением, то лучше включить этот аргумент.

### Настройка кэширования

- `cache_folder_path` (`PYNSPD_CACHE_FOLDER_PATH`)

    Путь до папки для кэша запросов. По умолчанию `None`.

- `cache_sqlite_url` (`PYNSPD_CACHE_SQLITE_URL`)

    Строка подключения для sqlite-хранилища кэша. По умолчанию `None`.

!!! warning "Внешняя зависимость"
    Для использования sqlite-кэша в асинхронном режиме, требуется установить дополнительный модуль:

    `pip install pynspd[sqlite]`      

- `cache_redis_url` (`PYNSPD_CACHE_REDIS_URL`)

    Строка подключения для redis-хранилища кэша. По умолчанию `None`.

!!! warning "Внешняя зависимость"
    Для использования redis-кэша, требуется установить дополнительный модуль:

    `pip install pynspd[redis]` 

- `cache_ttl` (`PYNSPD_CACHE_TTL`)

    Количество времени (в секундах) сколько будет храниться кэш. По умолчанию `None`.

- `cache_storage`

    Ручная настройка объекта хранилища кэша. Подробнее читайте [здесь](https://hishel.com/advanced/storages/). По умолчанию `None`.


## `Nspd` и `AsyncNspd`: что выбрать?

!!! info "TL;DR"
    Для подавляющего большинства случаев вам подойдет синхронный клиент `Nspd`.

    Если вы строите асинхронное приложение, например, в [FastAPI](https://fastapi.tiangolo.com/) -
    используйте асинхронный клиент `AsyncNspd`.

Объяснение сути асинхронного программирования выходит за рамки данной документации. Однако, если попытаться сжать все в один тезис - 
это способ "параллельного" выполнения задач, требующих больших затрат на время ожидания (например, запрос к серверу).

`pynspd` предлагает оба, как синхронный, так и асинхронный клиент, что позволяет вам использовать его в любом проекте. Например, для разных API-фреймворков:

- [Flask](https://flask.palletsprojects.com/en/stable/) -> `from pynspd import Nspd`
- [FastAPI](https://fastapi.tiangolo.com/) -> `from pynspd import AsyncNspd`

Все методы, которые доступны в синхронном клиенте `Nspd`, также доступны и в асинхронном `AsyncNspd`. 
Однако, нужно не забывать про две важные вещи:

- всем вызовам асинхронных методов должно предшествовать ключевое слово `await`;
- все вызовы асихронных методов должны осуществляться в `async` функциях.

!!! example "Пример простого скрипта получения GeoJSON с НСПД, используя асинхронный API"
    ```python
    # Стандартная библиотека для работы с `async` функциями 
    import asyncio
    # Сторонняя библиотека - асинхронной аналог `open` для работы с файлами
    import aiofiles
    from pynspd import AsyncNspd


    async def main():
        async with AsyncNspd() as nspd:
            q = input("Введите к/н: ")
            feat = await nspd.find(q)
            if feat is None:
                print("Ничего не найдено!")
                return
            async with aiofiles.open(f"{q.replace(':', '-')}.geojson", "w") as file:
                await file.write(feat.model_dump_json())


    if __name__ == "__main__":
        # Запуск функции в event-loop
        asyncio.run(main())
    ```