Перейти к содержанию

Настройка клиента

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

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

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

  • 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.

Риск блокировок

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

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

  • client_proxy (PYNSPD_CLIENT_PROXY)

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

Внешняя зависимость

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

pip install pynspd[socks]

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

  • client_dns_resolve (PYNSPD_CLIENT_DNS_RESOLVE)

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

Подробнее

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

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

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

  • cache_folder_path (PYNSPD_CACHE_FOLDER_PATH)

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

  • cache_sqlite_url (PYNSPD_CACHE_SQLITE_URL)

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

Внешняя зависимость

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

pip install pynspd[sqlite]

  • cache_redis_url (PYNSPD_CACHE_REDIS_URL)

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

Внешняя зависимость

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

pip install pynspd[redis]

  • cache_ttl (PYNSPD_CACHE_TTL)

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

  • cache_storage

    Ручная настройка объекта хранилища кэша. Подробнее читайте здесь. По умолчанию None.

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

TL;DR

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

Если вы строите асинхронное приложение, например, в FastAPI - используйте асинхронный клиент AsyncNspd.

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

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

  • Flask -> from pynspd import Nspd
  • FastAPI -> from pynspd import AsyncNspd

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

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

Пример простого скрипта получения GeoJSON с НСПД, используя асинхронный API

# Стандартная библиотека для работы с `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())