DaData Ruby Client | Клиент DaData для Ruby

Gem Version

English | Русский


Описание

Gem для работы с API DaData.ru. Поддерживает все основные методы API и предоставляет удобную интеграцию с Ruby on Rails.

В качестве отправной точки взята официальная библиотека для Python.

Основные возможности

  • Стандартизация данных:

    • Адреса
    • ФИО
    • Телефоны
    • Email
    • Паспортные данные
    • Даты
    • И другие типы данных
  • Подсказки (автодополнение):

    • Адреса
    • Организации
    • Банки
    • ФИО
    • Email
    • И другие справочники
  • Дополнительные методы:

    • Геолокация
    • Определение города по IP
    • Поиск аффилированных компаний
    • Работа с балансом и статистикой

Требования

  • Ruby >= 3.3.0

Установка

Добавьте в Gemfile вашего проекта:

# Из RubyGems
gem 'dadata-rb'

# Или напрямую из репозитория:
# gem 'dadata-rb', git: 'https://hub.mos.ru/ad/dadata'

Затем выполните:

bundle install

Конфигурация

Rails Generator

Для Rails-приложений предусмотрен генератор конфигурации. Запустите:

rails generate dadata:initializer

По умолчанию, генератор создаст:

  • Инициализатор config/initializers/dadata.rb
  • Добавит API-ключи в credentials.yml.enc

Опции генератора:

rails generate dadata:initializer [опции]

Опции:
    --api-key=КЛЮЧ          # Ваш API-ключ DaData
    --secret-key=КЛЮЧ       # Ваш секретный ключ DaData
    --[no-]use-credentials  # Использовать ли Rails credentials (по умолчанию: true)
    --timeout=СЕКУНДЫ      # Таймаут запросов (по умолчанию: 3)
    --suggestions-count=N   # Количество подсказок (по умолчанию: 10)

Ручная настройка

Dadata.configure do |config|
  # API-ключ из личного кабинета
  config.api_key = 'ВАШ_API_КЛЮЧ'

  # Секретный ключ (для некоторых методов)
  config.secret_key = 'ВАШ_СЕКРЕТНЫЙ_КЛЮЧ'

  # Таймаут запросов в секундах
  config.timeout_sec = 3

  # Количество подсказок в ответе
  config.suggestions_count = 10

  # Уровень логирования (:debug, :info, :warn, :error)
  config.log_level = :info

  # Логировать тело запроса на уровне :debug (по умолчанию: false).
  # ВНИМАНИЕ: тело запроса содержит персональные данные (паспорта, ФИО,
  # телефоны, email). Включайте только для отладки.
  config.log_request_bodies = false

  # Пользовательский логгер (опционально)
  config.logger = Logger.new('dadata.log')
end

Безопасное логирование

Gem автоматически фильтрует конфиденциальные данные в логах, такие как API-ключи и секретные ключи. По умолчанию используется встроенный SecureLogger, который:

  • Фильтрует заголовки Authorization, X-Secret и API-Key
  • Заменяет конфиденциальные данные на [FILTERED]
  • Поддерживает все стандартные уровни логирования

Пример лога запроса:

I, [2025-01-25T20:44:10+03:00] INFO -- : DaData Request: POST https://suggestions.dadata.ru/suggestions/api/4_1/rs/suggest/address
Headers: Authorization: [FILTERED], Content-Type: application/json

Постоянные соединения

Gem использует постоянные HTTP-соединения (net-http-persistent) для уменьшения накладных расходов на установку соединения. Соединения переиспользуются автоматически; при завершении работы вызовите client.close, чтобы освободить сокеты.

Использование

Общий клиент

# Используя настройки из конфигурации
api = Dadata::Client.new

# Или с явным указанием ключей
api = Dadata::Client.new('ВАШ_API_КЛЮЧ', 'ВАШ_СЕКРЕТНЫЙ_КЛЮЧ')

Специализированные клиенты

Подсказки (SuggestClient)

suggest = Dadata::SuggestClient.new

# Поиск адреса
suggest.suggest("address", "москва хабар")

# Поиск организации
suggest.suggest("party", "сбербанк")

# Поиск банка по БИК или названию
suggest.suggest("bank", "044525225")

Стандартизация (CleanClient)

cleaner = Dadata::CleanClient.new

# Стандартизация адреса
cleaner.clean("address", "мск сухонская 11")

# Стандартизация ФИО
cleaner.clean("name", "иванов сергей")

# Стандартизация телефона
cleaner.clean("phone", "9161234567")

Профиль (ProfileClient)

profile = Dadata::ProfileClient.new

# Проверка баланса
profile.balance

# Статистика использования
profile.daily_stats

Параметры запросов по типам справочников

Универсальные методы suggest, find_by_id, geolocate и iplocate принимают дополнительные параметры через **kwargs. Ниже — параметры, специфичные для каждого типа (name), согласно OpenAPI-схемам DaData (Suggestions API v4.1). count по умолчанию равен 10 и ограничивается значением 20 на стороне gem.

suggest(name, query, **kwargs)

name Дополнительные параметры
party branch_type: (MAIN, BRANCH), type: (LEGAL, INDIVIDUAL), status: (ACTIVE, LIQUIDATING, LIQUIDATED, REORGANIZING, BANKRUPT), locations:, locations_boost:, okved:
bank type: (BANK, NKO, BANK_BRANCH, NKO_BRANCH, RKC, CBR, TREASURY, OTHER), status: (как у party), locations:, locations_boost:
address locations:, locations_boost:, locations_geo:, from_bound:/to_bound: ({ value: 'city' }), restrict_value: (bool), division: (ADMINISTRATIVE, MUNICIPAL), language: (ru, en)
fio parts: (SURNAME, NAME, PATRONYMIC), gender: (MALE, FEMALE, UNKNOWN)
fias locations:, locations_boost:, from_bound:/to_bound:, restrict_value:
email — (только count)
прочие filters: (массив объектов { поле: значение })
api.suggest('party', 'сбер', status: ['ACTIVE'], type: 'LEGAL', branch_type: ['MAIN'])
api.suggest('address', 'москва', from_bound: { value: 'city' }, to_bound: { value: 'city' })

find_by_id(name, query, **kwargs)

name Дополнительные параметры
party kpp:, branch_type: (MAIN, BRANCH), type: (LEGAL, INDIVIDUAL), status: (как у suggest party)
bank kpp:
address division: (ADMINISTRATIVE, MUNICIPAL), from_bound:/to_bound:, language: (ru, en)
fias from_bound:/to_bound:

Остальные методы

  • find_affiliated(query, **kwargs)scope: (MANAGERS, FOUNDERS; по умолчанию оба)
  • geolocate(name, lat, lon, radius_meters, **kwargs)count:, division: (ADMINISTRATIVE, MUNICIPAL), language: (ru, en); для nameaddress вместо division/languagefilters:
  • iplocate(ip, **kwargs)language: (ru, en), division: (ADMINISTRATIVE, MUNICIPAL)

Уровни from_bound/to_bound: country, region, area, city, settlement, street, house, flat. Полный перечень параметров — в OpenAPI-схемах DaData (Suggestions API v4.1).

Примеры использования

Стандартизация адреса

result = api.clean("address", "мск сухонская 11")
puts result['result']      # Стандартизованный адрес
puts result['postal_code'] # Почтовый индекс
puts result['region']      # Регион
puts result['city']        # Город

Поиск организации по ИНН

result = api.suggest("party", "7707083893")
company = result[0]
puts company['value']    # Краткое название
puts company['inn']      # ИНН
puts company['address']  # Адрес

Определение города по IP

result = api.iplocate("46.226.227.20")
puts result['value']     # Город
puts result['region']    # Регион

Обработка ошибок

Все исключения наследуются от Dadata::Error:

Dadata::Error               # Базовый класс всех ошибок gem
Dadata::ConfigurationError  # Некорректная конфигурация

Dadata::ApiError            # Базовая ошибка API (HTTP-статус не из 2xx); содержит #status
Dadata::BadRequestError     # 400 — некорректный запрос
Dadata::UnauthorizedError   # 401 — отсутствует или неверный ключ
Dadata::AuthenticationError # 403 — неверный ключ, неподтверждённый email или превышен лимит
Dadata::NotFoundError       # 404 — сервис не найден
Dadata::RateLimitError      # 429 — слишком много запросов

Dadata::ConnectionError     # Ошибка соединения
Dadata::TimeoutError        # Превышен таймаут (подкласс ConnectionError)

Рекомендуется обрабатывать их следующим образом (более специфичные классы — выше):

begin
  api.clean("address", "мск сухонская 11")
rescue Dadata::RateLimitError => e
  puts "Превышен лимит запросов: #{e.message}"
rescue Dadata::ApiError => e
  puts "Ошибка API (#{e.status}): #{e.message}"
rescue Dadata::TimeoutError => e
  puts "Таймаут запроса: #{e.message}"
rescue Dadata::ConnectionError => e
  puts "Ошибка соединения: #{e.message}"
end

Description

A Ruby gem for working with DaData.ru API. Supports all main API methods and provides convenient Rails integration.

Based on the official Python library.

Key Features

  • Data Standardization:

    • Addresses
    • Names
    • Phone numbers
    • Email
    • Passport data
    • Dates
    • And other data types
  • Suggestions (Autocomplete):

    • Addresses
    • Organizations
    • Banks
    • Names
    • Email
    • And other reference data
  • Additional Methods:

    • Geolocation
    • City detection by IP
    • Finding affiliated companies
    • Balance and statistics

Requirements

  • Ruby >= 3.3.0

Installation

Add to your project's Gemfile:

# From RubyGems
gem 'dadata-rb'

# Or directly from the repository:
# gem 'dadata-rb', git: 'https://hub.mos.ru/ad/dadata'

Then run:

bundle install

Configuration

Rails Generator

For Rails applications, a configuration generator is provided. Run:

rails generate dadata:initializer

By default, the generator will:

  • Create initializer at config/initializers/dadata.rb
  • Add API keys to credentials.yml.enc

Generator Options:

rails generate dadata:initializer [options]

Options:
    --api-key=KEY           # Your DaData API key
    --secret-key=KEY        # Your DaData secret key
    --[no-]use-credentials  # Whether to use Rails credentials (default: true)
    --timeout=SECONDS       # Request timeout (default: 3)
    --suggestions-count=N   # Number of suggestions (default: 10)

Manual Configuration

Dadata.configure do |config|
  # API key from your account
  config.api_key = 'YOUR_API_KEY'

  # Secret key (required for some methods)
  config.secret_key = 'YOUR_SECRET_KEY'

  # Request timeout in seconds
  config.timeout_sec = 3

  # Number of suggestions in response
  config.suggestions_count = 10

  # Log level (:debug, :info, :warn, :error)
  config.log_level = :info

  # Log request bodies at :debug level (default: false).
  # WARNING: request bodies contain personal data (passports, names, phones,
  # emails). Enable only for debugging.
  config.log_request_bodies = false

  # Custom logger (optional)
  config.logger = Logger.new('dadata.log')
end

Secure Logging

The gem automatically filters confidential data in logs, such as API keys and secret keys. By default, the built-in SecureLogger is used, which:

  • Filters Authorization, X-Secret and API-Key headers
  • Replaces confidential data with [FILTERED]
  • Supports all standard log levels

Example log entry:

I, [2025-01-25T20:44:10+03:00] INFO -- : DaData Request: POST https://suggestions.dadata.ru/suggestions/api/4_1/rs/suggest/address
Headers: Authorization: [FILTERED], Content-Type: application/json

Persistent Connections

The gem uses persistent HTTP connections (net-http-persistent) to reduce connection setup overhead. Connections are reused automatically; call client.close when you are done to release the sockets.

Usage

General Client

# Using configuration settings
api = Dadata::Client.new

# Or with explicit keys
api = Dadata::Client.new('YOUR_API_KEY', 'YOUR_SECRET_KEY')

Specialized Clients

Suggestions (SuggestClient)

suggest = Dadata::SuggestClient.new

# Address search
suggest.suggest("address", "moscow tverskaya")

# Organization search
suggest.suggest("party", "sberbank")

# Bank search by BIC or name
suggest.suggest("bank", "044525225")

Standardization (CleanClient)

cleaner = Dadata::CleanClient.new

# Address standardization
cleaner.clean("address", "msk suhonskaya 11")

# Name standardization
cleaner.clean("name", "ivanov sergey")

# Phone standardization
cleaner.clean("phone", "9161234567")

Profile (ProfileClient)

profile = Dadata::ProfileClient.new

# Check balance
profile.balance

# Usage statistics
profile.daily_stats

Per-directory Request Parameters

The generic suggest, find_by_id, geolocate and iplocate methods accept extra parameters via **kwargs. Below are the directory-specific parameters (by name), per the DaData OpenAPI schemas (Suggestions API v4.1). count defaults to 10 and is capped at 20 by the gem.

suggest(name, query, **kwargs)

name Extra parameters
party branch_type: (MAIN, BRANCH), type: (LEGAL, INDIVIDUAL), status: (ACTIVE, LIQUIDATING, LIQUIDATED, REORGANIZING, BANKRUPT), locations:, locations_boost:, okved:
bank type: (BANK, NKO, BANK_BRANCH, NKO_BRANCH, RKC, CBR, TREASURY, OTHER), status: (same as party), locations:, locations_boost:
address locations:, locations_boost:, locations_geo:, from_bound:/to_bound: ({ value: 'city' }), restrict_value: (bool), division: (ADMINISTRATIVE, MUNICIPAL), language: (ru, en)
fio parts: (SURNAME, NAME, PATRONYMIC), gender: (MALE, FEMALE, UNKNOWN)
fias locations:, locations_boost:, from_bound:/to_bound:, restrict_value:
email — (count only)
others filters: (array of { field: value } objects)
api.suggest('party', 'sber', status: ['ACTIVE'], type: 'LEGAL', branch_type: ['MAIN'])
api.suggest('address', 'moscow', from_bound: { value: 'city' }, to_bound: { value: 'city' })

find_by_id(name, query, **kwargs)

name Extra parameters
party kpp:, branch_type: (MAIN, BRANCH), type: (LEGAL, INDIVIDUAL), status: (same as suggest party)
bank kpp:
address division: (ADMINISTRATIVE, MUNICIPAL), from_bound:/to_bound:, language: (ru, en)
fias from_bound:/to_bound:

Other methods

  • find_affiliated(query, **kwargs)scope: (MANAGERS, FOUNDERS; both by default)
  • geolocate(name, lat, lon, radius_meters, **kwargs)count:, division: (ADMINISTRATIVE, MUNICIPAL), language: (ru, en); for nameaddress, use filters: instead of division/language
  • iplocate(ip, **kwargs)language: (ru, en), division: (ADMINISTRATIVE, MUNICIPAL)

from_bound/to_bound levels: country, region, area, city, settlement, street, house, flat. See the DaData OpenAPI schemas (Suggestions API v4.1) for the full parameter list.

Usage Examples

Address Standardization

result = api.clean("address", "msk suhonskaya 11")
puts result['result']      # Standardized address
puts result['postal_code'] # Postal code
puts result['region']      # Region
puts result['city']        # City

Company Search by Tax ID (INN)

result = api.suggest("party", "7707083893")
company = result[0]
puts company['value']    # Short name
puts company['inn']      # Tax ID
puts company['address']  # Address

City Detection by IP

result = api.iplocate("46.226.227.20")
puts result['value']     # City
puts result['region']    # Region

Error Handling

All exceptions inherit from Dadata::Error:

Dadata::Error               # Base class for all gem errors
Dadata::ConfigurationError  # Invalid configuration

Dadata::ApiError            # Base API error (non-2xx HTTP status); exposes #status
Dadata::BadRequestError     # 400 — invalid request
Dadata::UnauthorizedError   # 401 — missing or unknown key
Dadata::AuthenticationError # 403 — invalid key, unconfirmed email, or limit exceeded
Dadata::NotFoundError       # 404 — service not found
Dadata::RateLimitError      # 429 — too many requests

Dadata::ConnectionError     # Connection error
Dadata::TimeoutError        # Request timeout (subclass of ConnectionError)

It's recommended to handle them as follows (most specific classes first):

begin
  api.clean("address", "msk suhonskaya 11")
rescue Dadata::RateLimitError => e
  puts "Rate limited: #{e.message}"
rescue Dadata::ApiError => e
  puts "API Error (#{e.status}): #{e.message}"
rescue Dadata::TimeoutError => e
  puts "Request Timeout: #{e.message}"
rescue Dadata::ConnectionError => e
  puts "Connection Error: #{e.message}"
end