rospatent 1.4.2 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +38 -0
- data/README.md +102 -2
- data/lib/rospatent/client.rb +15 -27
- data/lib/rospatent/configuration.rb +23 -0
- data/lib/rospatent/search.rb +8 -7
- data/lib/rospatent/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4a3938079b33ac5c291c85501df526ec12b7721a91c9f7c9a4b5c35c56a8fdab
|
4
|
+
data.tar.gz: 2a8cb80112a1c0380f2dd15f2e3e4909ae37f84e7ef3a819aa9d86fce6d1e765
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8843ca4bd8c87de711bed059c9f315a8d46a6123c0763a3eb7dcbfc5af6512e1d35b03782a22b37eb74578942592cb699b4ab8eb07c7744f651230b950c03e41
|
7
|
+
data.tar.gz: 29896e1b71030d368a54fc4d40bc3a9cd79318b82089618f71e98eafee65ce266d781dd2d1518001e0bd388af0937f2d46a5c7f911673d155738fa61e48fda44
|
data/CHANGELOG.md
CHANGED
@@ -5,6 +5,44 @@ All notable changes to this project will be documented in this file.
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
7
|
|
8
|
+
## [1.5.0] - 2025-06-09
|
9
|
+
|
10
|
+
### Added
|
11
|
+
- **Configurable Validation Limits**: Major enhancement to configuration system with customizable validation thresholds
|
12
|
+
- New `validation_limits` hash in configuration with 16 configurable parameters
|
13
|
+
- Users can now customize query length limits, pagination limits, array sizes, and more
|
14
|
+
- Fine-grained control over validation behavior without code modifications
|
15
|
+
- Environment-specific validation tuning support
|
16
|
+
- **Comprehensive Validation Configuration**: All validation limits now centralized and configurable
|
17
|
+
- Query parameters: `query_max_length`, `natural_query_max_length` (default: 2000)
|
18
|
+
- Pagination: `limit_max_value` (default: 100), `offset_max_value` (default: 10,000)
|
19
|
+
- Arrays: `array_max_size` (default: 10), various tag limits
|
20
|
+
- Classification: `classification_query_max_length`, `classification_code_max_length`
|
21
|
+
- Similar search: `similar_text_min_words`, `similar_text_max_length`, `similar_count_max_value`
|
22
|
+
- Batch operations: `batch_size_max_value`, `batch_ids_max_size`
|
23
|
+
|
24
|
+
### Changed
|
25
|
+
- **Consolidated Validation Logic**: Eliminated code duplication by centralizing validation in Search class
|
26
|
+
- Removed duplicate validation limits from Client class
|
27
|
+
- All validation now happens in single location (Search class)
|
28
|
+
- Improved maintainability and reduced code duplication
|
29
|
+
- **Enhanced Configuration System**: Extended configuration to support nested validation limits
|
30
|
+
- Configuration now supports hash-based validation limits
|
31
|
+
- All validation methods updated to use configurable limits
|
32
|
+
- Backward compatible configuration structure
|
33
|
+
|
34
|
+
### Deprecated
|
35
|
+
- **Client#validate_search_params**: Method deprecated in favor of centralized validation
|
36
|
+
- Method now returns parameters as-is for backward compatibility
|
37
|
+
- Validation responsibility moved to Search class
|
38
|
+
- Marked with deprecation notice for future removal
|
39
|
+
|
40
|
+
### Fixed
|
41
|
+
- **Validation Duplication**: Resolved issue where validation limits were hardcoded in multiple places
|
42
|
+
- Single source of truth for validation configuration
|
43
|
+
- Easier maintenance when API specifications change
|
44
|
+
- Consistent validation behavior across all methods
|
45
|
+
|
8
46
|
## [1.4.2] - 2025-07-15
|
9
47
|
|
10
48
|
## Fixed
|
data/README.md
CHANGED
@@ -11,7 +11,7 @@ A comprehensive Ruby client for the Rospatent patent search API with advanced fe
|
|
11
11
|
- 🔍 **Complete API Coverage** - Search, retrieve patents, media files, and datasets
|
12
12
|
- 🛡️ **Robust Error Handling** - Comprehensive error types with detailed context
|
13
13
|
- ⚡ **Intelligent Caching** - In-memory caching with TTL and LRU eviction
|
14
|
-
- ✅ **Input Validation** - Automatic parameter validation with helpful error messages
|
14
|
+
- ✅ **Input Validation** - Automatic parameter validation with configurable limits and helpful error messages
|
15
15
|
- 📊 **Structured Logging** - JSON/text logging with request/response tracking
|
16
16
|
- 🚀 **Batch Operations** - Process multiple patents concurrently
|
17
17
|
- ⚙️ **Environment-Aware** - Different configurations for dev/staging/production
|
@@ -101,6 +101,56 @@ Rospatent.configure do |config|
|
|
101
101
|
end
|
102
102
|
```
|
103
103
|
|
104
|
+
### Validation Limits Configuration
|
105
|
+
|
106
|
+
Customize validation thresholds for different parameters to suit your specific needs:
|
107
|
+
|
108
|
+
```ruby
|
109
|
+
Rospatent.configure do |config|
|
110
|
+
config.token = "your_jwt_token"
|
111
|
+
|
112
|
+
# Customize validation limits
|
113
|
+
config.validation_limits = {
|
114
|
+
# Query parameters
|
115
|
+
query_max_length: 5000, # Default: 2000
|
116
|
+
natural_query_max_length: 3000, # Default: 2000
|
117
|
+
|
118
|
+
# Pagination limits
|
119
|
+
limit_max_value: 200, # Default: 100
|
120
|
+
offset_max_value: 50_000, # Default: 10,000
|
121
|
+
|
122
|
+
# Array and string limits
|
123
|
+
array_max_size: 20, # Default: 10
|
124
|
+
string_max_length: 2000, # Default: 1000
|
125
|
+
|
126
|
+
# Highlighting limits
|
127
|
+
pre_tag_max_length: 100, # Default: 50
|
128
|
+
post_tag_max_length: 100, # Default: 50
|
129
|
+
pre_tag_max_size: 20, # Default: 10
|
130
|
+
post_tag_max_size: 20, # Default: 10
|
131
|
+
|
132
|
+
# Classification search limits
|
133
|
+
classification_query_max_length: 2000, # Default: 1000
|
134
|
+
classification_code_max_length: 100, # Default: 50
|
135
|
+
|
136
|
+
# Similar search limits
|
137
|
+
similar_text_min_words: 30, # Default: 50
|
138
|
+
similar_text_max_length: 20_000, # Default: 10,000
|
139
|
+
similar_count_max_value: 2000, # Default: 1000
|
140
|
+
|
141
|
+
# Batch operation limits
|
142
|
+
batch_size_max_value: 100, # Default: 50
|
143
|
+
batch_ids_max_size: 2000 # Default: 1000
|
144
|
+
}
|
145
|
+
end
|
146
|
+
```
|
147
|
+
|
148
|
+
**Benefits of configurable validation limits:**
|
149
|
+
- **Flexibility**: Adjust limits based on your application's requirements
|
150
|
+
- **Performance**: Fine-tune validation for optimal performance
|
151
|
+
- **API Evolution**: Easily adapt to changes in Rospatent API specifications
|
152
|
+
- **Environment-specific**: Different limits for development, staging, and production
|
153
|
+
|
104
154
|
### Environment-Specific Configuration
|
105
155
|
|
106
156
|
The gem automatically adjusts settings based on environment with sensible defaults:
|
@@ -1126,7 +1176,7 @@ $ bundle exec rake release
|
|
1126
1176
|
- 🔍 **Полное покрытие API** - поиск, получение патентов, медиафайлы и датасеты
|
1127
1177
|
- 🛡️ **Надежная обработка ошибок** - комплексные типы ошибок с детальным контекстом
|
1128
1178
|
- ⚡ **Интеллектуальное кеширование** - кеширование в памяти с TTL и LRU исключением
|
1129
|
-
- ✅ **Валидация входных данных** - автоматическая валидация параметров с полезными сообщениями
|
1179
|
+
- ✅ **Валидация входных данных** - автоматическая валидация параметров с настраиваемыми лимитами и полезными сообщениями
|
1130
1180
|
- 📊 **Структурированное логирование** - JSON/текстовое логирование с отслеживанием запросов/ответов
|
1131
1181
|
- 🚀 **Пакетные операции** - параллельная обработка множества патентов
|
1132
1182
|
- ⚙️ **Адаптивные окружения** - различные конфигурации для development/staging/production
|
@@ -1215,6 +1265,56 @@ Rospatent.configure do |config|
|
|
1215
1265
|
end
|
1216
1266
|
```
|
1217
1267
|
|
1268
|
+
### Конфигурация лимитов валидации
|
1269
|
+
|
1270
|
+
Настройте пороговые значения валидации для различных параметров в соответствии с вашими потребностями:
|
1271
|
+
|
1272
|
+
```ruby
|
1273
|
+
Rospatent.configure do |config|
|
1274
|
+
config.token = "ваш_jwt_токен"
|
1275
|
+
|
1276
|
+
# Настройка лимитов валидации
|
1277
|
+
config.validation_limits = {
|
1278
|
+
# Параметры запросов
|
1279
|
+
query_max_length: 5000, # По умолчанию: 2000
|
1280
|
+
natural_query_max_length: 3000, # По умолчанию: 2000
|
1281
|
+
|
1282
|
+
# Лимиты пагинации
|
1283
|
+
limit_max_value: 200, # По умолчанию: 100
|
1284
|
+
offset_max_value: 50_000, # По умолчанию: 10,000
|
1285
|
+
|
1286
|
+
# Лимиты массивов и строк
|
1287
|
+
array_max_size: 20, # По умолчанию: 10
|
1288
|
+
string_max_length: 2000, # По умолчанию: 1000
|
1289
|
+
|
1290
|
+
# Лимиты подсветки
|
1291
|
+
pre_tag_max_length: 100, # По умолчанию: 50
|
1292
|
+
post_tag_max_length: 100, # По умолчанию: 50
|
1293
|
+
pre_tag_max_size: 20, # По умолчанию: 10
|
1294
|
+
post_tag_max_size: 20, # По умолчанию: 10
|
1295
|
+
|
1296
|
+
# Лимиты поиска по классификации
|
1297
|
+
classification_query_max_length: 2000, # По умолчанию: 1000
|
1298
|
+
classification_code_max_length: 100, # По умолчанию: 50
|
1299
|
+
|
1300
|
+
# Лимиты поиска похожих патентов
|
1301
|
+
similar_text_min_words: 30, # По умолчанию: 50
|
1302
|
+
similar_text_max_length: 20_000, # По умолчанию: 10,000
|
1303
|
+
similar_count_max_value: 2000, # По умолчанию: 1000
|
1304
|
+
|
1305
|
+
# Лимиты пакетных операций
|
1306
|
+
batch_size_max_value: 100, # По умолчанию: 50
|
1307
|
+
batch_ids_max_size: 2000 # По умолчанию: 1000
|
1308
|
+
}
|
1309
|
+
end
|
1310
|
+
```
|
1311
|
+
|
1312
|
+
**Преимущества настраиваемых лимитов валидации:**
|
1313
|
+
- **Гибкость**: Настройка лимитов в соответствии с требованиями вашего приложения
|
1314
|
+
- **Производительность**: Точная настройка валидации для оптимальной производительности
|
1315
|
+
- **Эволюция API**: Легкая адаптация к изменениям в спецификациях API Роспатента
|
1316
|
+
- **Специфичность окружения**: Различные лимиты для разработки, staging и продакшна
|
1317
|
+
|
1218
1318
|
### Конфигурация для конкретных окружений
|
1219
1319
|
|
1220
1320
|
Gem автоматически настраивается под окружение с разумными значениями по умолчанию:
|
data/lib/rospatent/client.rb
CHANGED
@@ -35,9 +35,8 @@ module Rospatent
|
|
35
35
|
# @param params [Hash] Search parameters
|
36
36
|
# @return [Rospatent::SearchResult] Search result object
|
37
37
|
def search(**params)
|
38
|
-
#
|
39
|
-
|
40
|
-
Search.new(self).execute(**validated_params)
|
38
|
+
# Validation is now handled by Search class to avoid duplication
|
39
|
+
Search.new(self).execute(**params)
|
41
40
|
end
|
42
41
|
|
43
42
|
# Fetch a specific patent by its document ID using dedicated endpoint
|
@@ -117,7 +116,7 @@ module Rospatent
|
|
117
116
|
def similar_patents_by_id(document_id, count: 100)
|
118
117
|
# Validate inputs
|
119
118
|
validated_id = validate_patent_id(document_id)
|
120
|
-
validated_count = validate_positive_integer(count, "count", max_value:
|
119
|
+
validated_count = validate_positive_integer(count, "count", max_value: Rospatent.configuration.validation_limits[:similar_count_max_value])
|
121
120
|
|
122
121
|
# Check cache first
|
123
122
|
cache_key = "similar:id:#{validated_id}:#{validated_count}"
|
@@ -153,9 +152,10 @@ module Rospatent
|
|
153
152
|
# @raise [Rospatent::Errors::ValidationError] If text has insufficient words or errors
|
154
153
|
def similar_patents_by_text(text, count: 100)
|
155
154
|
# Validate inputs - text must have at least 50 words for the API
|
156
|
-
|
157
|
-
|
158
|
-
|
155
|
+
validated_text = validate_text_with_word_count(text, "search_text",
|
156
|
+
min_words: Rospatent.configuration.validation_limits[:similar_text_min_words],
|
157
|
+
max_length: Rospatent.configuration.validation_limits[:similar_text_max_length])
|
158
|
+
validated_count = validate_positive_integer(count, "count", max_value: Rospatent.configuration.validation_limits[:similar_count_max_value])
|
159
159
|
|
160
160
|
# Check cache first (using hash of text for key)
|
161
161
|
text_hash = validated_text.hash.abs.to_s(16)
|
@@ -337,7 +337,7 @@ module Rospatent
|
|
337
337
|
def classification_search(classifier_id, query:, lang: "ru")
|
338
338
|
# Validate inputs
|
339
339
|
validated_classifier = validate_enum(classifier_id, %w[ipc cpc], "classifier_id").to_s
|
340
|
-
validated_query = validate_string(query, "query", max_length:
|
340
|
+
validated_query = validate_string(query, "query", max_length: Rospatent.configuration.validation_limits[:classification_query_max_length])
|
341
341
|
validated_lang = validate_enum(lang, %w[ru en], "lang").to_s
|
342
342
|
|
343
343
|
# Check cache first
|
@@ -378,7 +378,7 @@ module Rospatent
|
|
378
378
|
def classification_code(classifier_id, code:, lang: "ru")
|
379
379
|
# Validate inputs
|
380
380
|
validated_classifier = validate_enum(classifier_id, %w[ipc cpc], "classifier_id").to_s
|
381
|
-
validated_code = validate_string(code, "code", max_length:
|
381
|
+
validated_code = validate_string(code, "code", max_length: Rospatent.configuration.validation_limits[:classification_code_max_length])
|
382
382
|
validated_lang = validate_enum(lang, %w[ru en], "lang").to_s
|
383
383
|
|
384
384
|
# Check cache first
|
@@ -482,8 +482,8 @@ module Rospatent
|
|
482
482
|
def batch_patents(document_ids, batch_size: 10)
|
483
483
|
return enum_for(:batch_patents, document_ids, batch_size: batch_size) unless block_given?
|
484
484
|
|
485
|
-
validate_array(document_ids, "document_ids", max_size:
|
486
|
-
validated_batch_size = validate_positive_integer(batch_size, "batch_size", max_value:
|
485
|
+
validate_array(document_ids, "document_ids", max_size: Rospatent.configuration.validation_limits[:batch_ids_max_size])
|
486
|
+
validated_batch_size = validate_positive_integer(batch_size, "batch_size", max_value: Rospatent.configuration.validation_limits[:batch_size_max_value])
|
487
487
|
|
488
488
|
document_ids.each_slice(validated_batch_size) do |batch|
|
489
489
|
threads = batch.map do |doc_id|
|
@@ -542,23 +542,11 @@ module Rospatent
|
|
542
542
|
# Validate search parameters
|
543
543
|
# @param params [Hash] Search parameters to validate
|
544
544
|
# @return [Hash] Validated parameters
|
545
|
+
# @deprecated This method is deprecated. Validation now happens in Search class.
|
545
546
|
def validate_search_params(params)
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
limit: { type: :positive_integer, min_value: 1, max_value: 100 },
|
550
|
-
offset: { type: :positive_integer, min_value: 0, max_value: 10_000 },
|
551
|
-
pre_tag: { type: :string_or_array, max_length: 50, max_size: 10 },
|
552
|
-
post_tag: { type: :string_or_array, max_length: 50, max_size: 10 },
|
553
|
-
sort: { type: :enum, allowed_values: %i[relevance pub_date filing_date] },
|
554
|
-
group_by: { type: :string_enum, allowed_values: %w[family:docdb family:dwpi] },
|
555
|
-
include_facets: { type: :boolean },
|
556
|
-
highlight: { type: :hash },
|
557
|
-
filter: { type: :filter },
|
558
|
-
datasets: { type: :array, max_size: 10 }
|
559
|
-
}
|
560
|
-
|
561
|
-
validate_params(params, validations)
|
547
|
+
# Validation is now handled by Search class to avoid duplication
|
548
|
+
# This method remains for backward compatibility but does no validation
|
549
|
+
params
|
562
550
|
end
|
563
551
|
|
564
552
|
# Parse a patent ID string into its component parts
|
@@ -27,6 +27,8 @@ module Rospatent
|
|
27
27
|
attr_accessor :token_expires_at, :token_refresh_callback
|
28
28
|
# Connection pooling
|
29
29
|
attr_accessor :connection_pool_size, :connection_keep_alive
|
30
|
+
# Validation limits
|
31
|
+
attr_accessor :validation_limits
|
30
32
|
|
31
33
|
# Initialize a new configuration with default values
|
32
34
|
def initialize
|
@@ -57,6 +59,27 @@ module Rospatent
|
|
57
59
|
@connection_pool_size = ENV.fetch("ROSPATENT_POOL_SIZE", "5").to_i
|
58
60
|
@connection_keep_alive = ENV.fetch("ROSPATENT_KEEP_ALIVE", "true") == "true"
|
59
61
|
|
62
|
+
# Validation limits
|
63
|
+
@validation_limits = {
|
64
|
+
query_max_length: 2000,
|
65
|
+
natural_query_max_length: 2000,
|
66
|
+
limit_max_value: 100,
|
67
|
+
offset_max_value: 10_000,
|
68
|
+
array_max_size: 10,
|
69
|
+
string_max_length: 1000,
|
70
|
+
pre_tag_max_length: 50,
|
71
|
+
post_tag_max_length: 50,
|
72
|
+
pre_tag_max_size: 10,
|
73
|
+
post_tag_max_size: 10,
|
74
|
+
classification_query_max_length: 1000,
|
75
|
+
classification_code_max_length: 50,
|
76
|
+
similar_text_min_words: 50,
|
77
|
+
similar_text_max_length: 10_000,
|
78
|
+
similar_count_max_value: 1000,
|
79
|
+
batch_size_max_value: 50,
|
80
|
+
batch_ids_max_size: 1000
|
81
|
+
}
|
82
|
+
|
60
83
|
load_environment_config
|
61
84
|
end
|
62
85
|
|
data/lib/rospatent/search.rb
CHANGED
@@ -97,17 +97,18 @@ module Rospatent
|
|
97
97
|
validated = {}
|
98
98
|
|
99
99
|
# Validate query parameters
|
100
|
-
|
101
|
-
validated[:
|
100
|
+
config = Rospatent.configuration
|
101
|
+
validated[:q] = validate_string(params[:q], "q", max_length: config.validation_limits[:query_max_length]) if params[:q]
|
102
|
+
validated[:qn] = validate_string(params[:qn], "qn", max_length: config.validation_limits[:natural_query_max_length]) if params[:qn]
|
102
103
|
|
103
104
|
# Validate pagination parameters (only if provided)
|
104
105
|
if params[:limit]
|
105
106
|
validated[:limit] =
|
106
|
-
validate_positive_integer(params[:limit], "limit", min_value: 1, max_value:
|
107
|
+
validate_positive_integer(params[:limit], "limit", min_value: 1, max_value: config.validation_limits[:limit_max_value])
|
107
108
|
end
|
108
109
|
if params[:offset]
|
109
110
|
validated[:offset] =
|
110
|
-
validate_positive_integer(params[:offset], "offset", min_value: 0, max_value:
|
111
|
+
validate_positive_integer(params[:offset], "offset", min_value: 0, max_value: config.validation_limits[:offset_max_value])
|
111
112
|
end
|
112
113
|
|
113
114
|
# Validate highlighting parameters (only if provided)
|
@@ -119,9 +120,9 @@ module Rospatent
|
|
119
120
|
end
|
120
121
|
|
121
122
|
validated[:pre_tag] =
|
122
|
-
validate_string_or_array(params[:pre_tag], "pre_tag", max_length:
|
123
|
+
validate_string_or_array(params[:pre_tag], "pre_tag", max_length: config.validation_limits[:pre_tag_max_length], max_size: config.validation_limits[:pre_tag_max_size])
|
123
124
|
validated[:post_tag] =
|
124
|
-
validate_string_or_array(params[:post_tag], "post_tag", max_length:
|
125
|
+
validate_string_or_array(params[:post_tag], "post_tag", max_length: config.validation_limits[:post_tag_max_length], max_size: config.validation_limits[:post_tag_max_size])
|
125
126
|
end
|
126
127
|
|
127
128
|
# Validate highlight parameter (complex object for advanced highlighting)
|
@@ -152,7 +153,7 @@ module Rospatent
|
|
152
153
|
|
153
154
|
# Validate datasets parameter
|
154
155
|
if params[:datasets]
|
155
|
-
validated[:datasets] = validate_array(params[:datasets], "datasets", max_size:
|
156
|
+
validated[:datasets] = validate_array(params[:datasets], "datasets", max_size: config.validation_limits[:array_max_size]) do |dataset|
|
156
157
|
validate_string(dataset, "dataset")
|
157
158
|
end
|
158
159
|
end
|
data/lib/rospatent/version.rb
CHANGED