DaData Ruby Client | Клиент DaData для Ruby
Описание
Gem для работы с API DaData.ru. Поддерживает все основные методы API и предоставляет удобную интеграцию с Ruby on Rails.
В качестве отправной точки взята официальная библиотека для Python.
Основные возможности
Стандартизация данных:
- Адреса
- ФИО
- Телефоны
- Паспортные данные
- Даты
- И другие типы данных
Подсказки (автодополнение):
- Адреса
- Организации
- Банки
- ФИО
- И другие справочники
Дополнительные методы:
- Геолокация
- Определение города по 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); дляname≠addressвместоdivision/language—filters: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.}"
rescue Dadata::ApiError => e
puts "Ошибка API (#{e.status}): #{e.}"
rescue Dadata::TimeoutError => e
puts "Таймаут запроса: #{e.}"
rescue Dadata::ConnectionError => e
puts "Ошибка соединения: #{e.}"
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
- Passport data
- Dates
- And other data types
Suggestions (Autocomplete):
- Addresses
- Organizations
- Banks
- Names
- 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-SecretandAPI-Keyheaders - 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); forname≠address, usefilters:instead ofdivision/languageiplocate(ip, **kwargs)—language:(ru,en),division:(ADMINISTRATIVE,MUNICIPAL)
from_bound/to_boundlevels: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.}"
rescue Dadata::ApiError => e
puts "API Error (#{e.status}): #{e.}"
rescue Dadata::TimeoutError => e
puts "Request Timeout: #{e.}"
rescue Dadata::ConnectionError => e
puts "Connection Error: #{e.}"
end