staddress 0.1.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 +7 -0
- data/README.md +85 -0
- data/lib/staddress/client.rb +136 -0
- data/lib/staddress/errors.rb +37 -0
- data/lib/staddress/models.rb +141 -0
- data/lib/staddress/version.rb +5 -0
- data/lib/staddress.rb +10 -0
- metadata +81 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: b5619831aa074839a1fdb4b2c4db74dd302d3c22effb66dec18416fb676064b6
|
|
4
|
+
data.tar.gz: c9f03cf74fbaef729e88fddfb9fc1c65f00da9af004c7865b2863ca3175a7793
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 45d4ac6515b8b6f1da89d9d6dcfbfa8d3b862a228e4031dea9100566bdef54cdbc600d8fe8ca299405608ea8fc115e7c91ca8e15bd64070c1f6d9aa00929e2b6
|
|
7
|
+
data.tar.gz: 5c4fe314c6eb3342ea07766c8ccab57b853f4480aeb8f1750b1b77d14a4272928d73435956b9c8ee99e6fe84dec870ee11b88c60b139b0e43e3c7cac57d8aacd
|
data/README.md
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# staddress (Ruby Gem)
|
|
2
|
+
|
|
3
|
+
Staddress AI API 公式 Ruby SDK。
|
|
4
|
+
|
|
5
|
+
## ステータス
|
|
6
|
+
|
|
7
|
+
**Phase 4 — v0.1 実装済み**(`parse_address` / `parse_batch` / `get_usage`)
|
|
8
|
+
|
|
9
|
+
- HTTP: 標準ライブラリ `net/http`(**ランタイム依存なし**)
|
|
10
|
+
- Ruby 3.1+
|
|
11
|
+
|
|
12
|
+
## インストール
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
gem install staddress
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
```ruby
|
|
19
|
+
# Gemfile
|
|
20
|
+
gem "staddress"
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## 使い方
|
|
24
|
+
|
|
25
|
+
```ruby
|
|
26
|
+
require "staddress"
|
|
27
|
+
|
|
28
|
+
client = Staddress::Client.new(
|
|
29
|
+
api_key: "sk_xxx", # 省略時は環境変数 STADDRESS_API_KEY
|
|
30
|
+
base_url: "https://api.staddress.com", # 省略時は既定値(STADDRESS_BASE_URL も可)
|
|
31
|
+
timeout: 30 # 任意(秒)
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
# 単件解析
|
|
35
|
+
result = client.parse_address(input: "六本木ヒルズ 森タワー 52F", postal_code: "106-6100")
|
|
36
|
+
puts result.normalized
|
|
37
|
+
puts result.components.pref
|
|
38
|
+
|
|
39
|
+
# 一括解析(Standard プラン以上、最大 100 件)
|
|
40
|
+
results = client.parse_batch([
|
|
41
|
+
{ id: "1", address: "東京都渋谷区道玄坂1-2-3" },
|
|
42
|
+
{ id: "2", address: "大阪府大阪市北区梅田1-1-1" }
|
|
43
|
+
])
|
|
44
|
+
results.each { |item| puts "#{item.id}: #{item.result&.normalized}" }
|
|
45
|
+
|
|
46
|
+
# 利用状況
|
|
47
|
+
usage = client.get_usage
|
|
48
|
+
puts "#{usage.plan} / #{usage.account_name}"
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## エラーハンドリング
|
|
52
|
+
|
|
53
|
+
API エラー・ネットワークエラーは `Staddress::Error` として送出されます。
|
|
54
|
+
|
|
55
|
+
```ruby
|
|
56
|
+
begin
|
|
57
|
+
client.parse_address(input: "...")
|
|
58
|
+
rescue Staddress::Error => err
|
|
59
|
+
err.code # 例: "unauthorized", "quota_exceeded", "unresolved"
|
|
60
|
+
err.http_status # HTTP ステータス(ネットワークエラー時は 0)
|
|
61
|
+
err.request_id # サポート問い合わせ用(あれば)
|
|
62
|
+
err.retry_after # 再試行可能日時(あれば)
|
|
63
|
+
end
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## API
|
|
67
|
+
|
|
68
|
+
| メソッド | HTTP | 説明 |
|
|
69
|
+
| --- | --- | --- |
|
|
70
|
+
| `parse_address(input:, postal_code: nil)` | `POST /api/v1/addresses/parse` | 単件解析 → `Models::ParseResult` |
|
|
71
|
+
| `parse_batch(items)` | `POST /api/v1/addresses/parse/batch` | 一括解析 → `Array<Models::BatchItemResult>` |
|
|
72
|
+
| `get_usage` | `GET /api/v1/usage` | 利用状況 → `Models::UsageResponse` |
|
|
73
|
+
|
|
74
|
+
レスポンスモデルは snake_case アクセサ(`match_level` 等)でアクセスでき、未知フィールドは `#raw`(元の Hash)から参照できます。
|
|
75
|
+
|
|
76
|
+
## 開発
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
cd packages/ruby
|
|
80
|
+
bundle install
|
|
81
|
+
bundle exec rspec # 単体テスト(webmock でモック、実 API 不要)
|
|
82
|
+
gem build staddress.gemspec
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
詳細: [docs/plan-tools.md §3.6](../../docs/plan-tools.md)
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "net/http"
|
|
4
|
+
require "json"
|
|
5
|
+
require "uri"
|
|
6
|
+
|
|
7
|
+
require_relative "errors"
|
|
8
|
+
require_relative "models"
|
|
9
|
+
|
|
10
|
+
module Staddress
|
|
11
|
+
DEFAULT_BASE_URL = "https://api.staddress.com"
|
|
12
|
+
DEFAULT_TIMEOUT = 30
|
|
13
|
+
MAX_BATCH_ITEMS = 100
|
|
14
|
+
|
|
15
|
+
# Staddress AI API クライアント(同期)。
|
|
16
|
+
#
|
|
17
|
+
# 例:
|
|
18
|
+
# client = Staddress::Client.new(api_key: "sk_xxx")
|
|
19
|
+
# result = client.parse_address(input: "六本木ヒルズ 森タワー 52F")
|
|
20
|
+
# puts result.normalized
|
|
21
|
+
class Client
|
|
22
|
+
# @param api_key [String, nil] 省略時は環境変数 STADDRESS_API_KEY
|
|
23
|
+
# @param base_url [String, nil] 省略時は STADDRESS_BASE_URL または既定値
|
|
24
|
+
# @param timeout [Numeric] 接続・読み取りタイムアウト(秒)
|
|
25
|
+
def initialize(api_key: nil, base_url: nil, timeout: DEFAULT_TIMEOUT)
|
|
26
|
+
@api_key = api_key || ENV.fetch("STADDRESS_API_KEY", nil)
|
|
27
|
+
if @api_key.nil? || @api_key.empty?
|
|
28
|
+
raise Error.new(
|
|
29
|
+
"API キーが設定されていません。api_key 引数または環境変数 STADDRESS_API_KEY を指定してください。",
|
|
30
|
+
code: "unauthorized",
|
|
31
|
+
http_status: 0
|
|
32
|
+
)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
base = base_url || ENV.fetch("STADDRESS_BASE_URL", nil) || DEFAULT_BASE_URL
|
|
36
|
+
@base_url = base.sub(%r{/+\z}, "")
|
|
37
|
+
@timeout = timeout
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# 単件住所解析 (POST /api/v1/addresses/parse)。
|
|
41
|
+
# @return [Staddress::Models::ParseResult]
|
|
42
|
+
def parse_address(input:, postal_code: nil)
|
|
43
|
+
if input.nil? || input.empty?
|
|
44
|
+
raise Error.new("input は必須です。", code: "invalid_request", http_status: 0)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
body = { "input" => input }
|
|
48
|
+
body["postalCode"] = postal_code if postal_code && !postal_code.empty?
|
|
49
|
+
|
|
50
|
+
data = request("POST", "/api/v1/addresses/parse", body)
|
|
51
|
+
Models::ParseResult.from(data["result"]) || Models::ParseResult.from({})
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# 一括住所解析 (POST /api/v1/addresses/parse/batch)。Standard プラン以上、最大 100 件。
|
|
55
|
+
# @param items [Array<Hash>] 例: [{ id: "1", address: "東京都..." }]
|
|
56
|
+
# @return [Array<Staddress::Models::BatchItemResult>]
|
|
57
|
+
def parse_batch(items)
|
|
58
|
+
list = items.to_a
|
|
59
|
+
if list.empty?
|
|
60
|
+
raise Error.new("items には1件以上を指定してください。", code: "invalid_request", http_status: 0)
|
|
61
|
+
end
|
|
62
|
+
if list.size > MAX_BATCH_ITEMS
|
|
63
|
+
raise Error.new(
|
|
64
|
+
"items は最大 #{MAX_BATCH_ITEMS} 件です(現在: #{list.size} 件)。",
|
|
65
|
+
code: "batch_size_exceeded",
|
|
66
|
+
http_status: 0
|
|
67
|
+
)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
data = request("POST", "/api/v1/addresses/parse/batch", { "items" => list })
|
|
71
|
+
(data["results"] || []).map { |item| Models::BatchItemResult.from(item) }
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# 利用状況取得 (GET /api/v1/usage)。
|
|
75
|
+
# @return [Staddress::Models::UsageResponse]
|
|
76
|
+
def get_usage
|
|
77
|
+
data = request("GET", "/api/v1/usage", nil)
|
|
78
|
+
Models::UsageResponse.from(data)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
private
|
|
82
|
+
|
|
83
|
+
def request(method, path, body)
|
|
84
|
+
uri = URI.parse("#{@base_url}#{path}")
|
|
85
|
+
req = build_request(method, uri, body)
|
|
86
|
+
req["X-Api-Key"] = @api_key
|
|
87
|
+
req["Content-Type"] = "application/json"
|
|
88
|
+
|
|
89
|
+
response = perform(uri, req)
|
|
90
|
+
interpret(response.code.to_i, response.body)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def build_request(method, uri, body)
|
|
94
|
+
klass = { "GET" => Net::HTTP::Get, "POST" => Net::HTTP::Post }.fetch(method)
|
|
95
|
+
req = klass.new(uri)
|
|
96
|
+
req.body = JSON.generate(body) unless body.nil?
|
|
97
|
+
req
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def perform(uri, req)
|
|
101
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
|
102
|
+
http.use_ssl = uri.scheme == "https"
|
|
103
|
+
http.open_timeout = @timeout
|
|
104
|
+
http.read_timeout = @timeout
|
|
105
|
+
http.request(req)
|
|
106
|
+
rescue Net::OpenTimeout, Net::ReadTimeout
|
|
107
|
+
raise Error.new("リクエストがタイムアウトしました。", code: "timeout", http_status: 0)
|
|
108
|
+
rescue SocketError, SystemCallError, IOError
|
|
109
|
+
raise Error.new("ネットワークエラーが発生しました。", code: "network_error", http_status: 0)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# HTTP レスポンスを解釈し、成功なら Hash を返す。エラーなら Error を送出する。
|
|
113
|
+
def interpret(status, text)
|
|
114
|
+
data = parse_json(text, status)
|
|
115
|
+
|
|
116
|
+
if status >= 400
|
|
117
|
+
err = data.is_a?(Hash) ? data["error"] : nil
|
|
118
|
+
if err.is_a?(Hash) && err["code"] && err["message"]
|
|
119
|
+
raise Error.from_body(err, status)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
raise Error.new("API エラー (HTTP #{status})", code: "internal_error", http_status: status)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
data.is_a?(Hash) ? data : {}
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def parse_json(text, status)
|
|
129
|
+
return nil if text.nil? || text.empty?
|
|
130
|
+
|
|
131
|
+
JSON.parse(text)
|
|
132
|
+
rescue JSON::ParserError
|
|
133
|
+
raise Error.new("レスポンスの JSON 解析に失敗しました。", code: "internal_error", http_status: status)
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Staddress
|
|
4
|
+
# Staddress API 呼び出しで発生したエラーを表す統一例外。
|
|
5
|
+
#
|
|
6
|
+
# - HTTP 4xx / 5xx で API がエラーボディを返した場合
|
|
7
|
+
# - ネットワークエラー・タイムアウト(code: "network_error" / "timeout")
|
|
8
|
+
# - 入力バリデーションエラー(code: "invalid_request")
|
|
9
|
+
#
|
|
10
|
+
# 属性:
|
|
11
|
+
# code API エラーコード("unauthorized", "quota_exceeded" 等)
|
|
12
|
+
# http_status HTTP ステータスコード(ネットワークエラー時は 0)
|
|
13
|
+
# request_id サポート問い合わせ用のリクエスト ID(あれば)
|
|
14
|
+
# retry_after 再試行可能日時(ISO 8601、あれば)
|
|
15
|
+
class Error < StandardError
|
|
16
|
+
attr_reader :code, :http_status, :request_id, :retry_after
|
|
17
|
+
|
|
18
|
+
def initialize(message, code: "internal_error", http_status: 0, request_id: nil, retry_after: nil)
|
|
19
|
+
super(message)
|
|
20
|
+
@code = code
|
|
21
|
+
@http_status = http_status
|
|
22
|
+
@request_id = request_id
|
|
23
|
+
@retry_after = retry_after
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# API のエラーボディ(Hash)から Error を生成する。
|
|
27
|
+
def self.from_body(body, http_status)
|
|
28
|
+
new(
|
|
29
|
+
body["message"] || "API error (#{body["code"]})",
|
|
30
|
+
code: body["code"],
|
|
31
|
+
http_status: http_status,
|
|
32
|
+
request_id: body["requestId"],
|
|
33
|
+
retry_after: body["retryAfter"]
|
|
34
|
+
)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Staddress
|
|
4
|
+
# Staddress AI API のデータモデル。
|
|
5
|
+
#
|
|
6
|
+
# OpenAPI 定義(openapi/staddress-api.yaml)に準拠する。
|
|
7
|
+
# API は camelCase、Ruby 側は snake_case アクセサでアクセスできるようマッピングする。
|
|
8
|
+
# 未知のフィールドは +raw+(元の Hash)から参照できる(前方互換)。
|
|
9
|
+
module Models
|
|
10
|
+
class Base
|
|
11
|
+
# 元の(パース済み)レスポンス Hash。未定義フィールドはここから参照できる。
|
|
12
|
+
attr_reader :raw
|
|
13
|
+
|
|
14
|
+
class << self
|
|
15
|
+
def fields
|
|
16
|
+
@fields ||= {}
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# フィールド定義。
|
|
20
|
+
# name Ruby 側の snake_case 名(アクセサになる)
|
|
21
|
+
# key: JSON 側のキー(省略時は name を camelCase 化)
|
|
22
|
+
# model: ネストしたモデルクラス
|
|
23
|
+
# list: true なら配列としてマッピング
|
|
24
|
+
def field(name, key: nil, model: nil, list: false)
|
|
25
|
+
fields[name] = { key: key || camelize(name), model: model, list: list }
|
|
26
|
+
attr_reader name
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Hash からインスタンスを生成する。nil の場合は nil を返す。
|
|
30
|
+
def from(data)
|
|
31
|
+
return nil if data.nil?
|
|
32
|
+
|
|
33
|
+
obj = allocate
|
|
34
|
+
obj.send(:populate, data, fields)
|
|
35
|
+
obj
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def camelize(name)
|
|
39
|
+
head, *rest = name.to_s.split("_")
|
|
40
|
+
(rest.empty? ? head : head + rest.map(&:capitalize).join)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
|
|
46
|
+
def populate(data, fields)
|
|
47
|
+
@raw = data
|
|
48
|
+
fields.each do |name, meta|
|
|
49
|
+
value = data[meta[:key]]
|
|
50
|
+
value = data[meta[:key].to_sym] if value.nil?
|
|
51
|
+
instance_variable_set("@#{name}", cast(value, meta))
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def cast(value, meta)
|
|
56
|
+
return nil if value.nil?
|
|
57
|
+
return value unless meta[:model]
|
|
58
|
+
return value.map { |item| meta[:model].from(item) } if meta[:list]
|
|
59
|
+
|
|
60
|
+
meta[:model].from(value)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# 住所の構成要素。
|
|
65
|
+
class AddressComponents < Base
|
|
66
|
+
field :pref
|
|
67
|
+
field :pref_code
|
|
68
|
+
field :city
|
|
69
|
+
field :city_code
|
|
70
|
+
field :oaza_cho
|
|
71
|
+
field :chome_koaza
|
|
72
|
+
field :chome_koaza_normalized
|
|
73
|
+
field :chome_number
|
|
74
|
+
field :street_number_block
|
|
75
|
+
field :building_name
|
|
76
|
+
field :room_number
|
|
77
|
+
field :room_number_unit
|
|
78
|
+
field :lon
|
|
79
|
+
field :lat
|
|
80
|
+
field :lg_code
|
|
81
|
+
field :machiaza_id
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# 解析の信頼度。
|
|
85
|
+
class Confidence < Base
|
|
86
|
+
field :score
|
|
87
|
+
field :match_level
|
|
88
|
+
field :query
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# 住所解析結果。
|
|
92
|
+
class ParseResult < Base
|
|
93
|
+
field :normalized
|
|
94
|
+
field :standard
|
|
95
|
+
field :components, model: AddressComponents
|
|
96
|
+
field :confidence, model: Confidence
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# API エラー本体(エラーレスポンスの error フィールド)。
|
|
100
|
+
class ErrorBody < Base
|
|
101
|
+
field :code
|
|
102
|
+
field :message
|
|
103
|
+
field :request_id
|
|
104
|
+
field :retry_after
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# 一括解析の結果アイテム(result か error のいずれかを持つ)。
|
|
108
|
+
class BatchItemResult < Base
|
|
109
|
+
field :id
|
|
110
|
+
field :result, model: ParseResult
|
|
111
|
+
field :error, model: ErrorBody
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
class UsagePeriod < Base
|
|
115
|
+
field :start
|
|
116
|
+
field :end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
class UsageCredit < Base
|
|
120
|
+
field :valid_until
|
|
121
|
+
field :total_amount
|
|
122
|
+
field :used_amount
|
|
123
|
+
field :remaining
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
class UsageDetail < Base
|
|
127
|
+
field :period, model: UsagePeriod
|
|
128
|
+
field :count
|
|
129
|
+
field :monthly_limit
|
|
130
|
+
field :contract_period_remaining
|
|
131
|
+
field :credits, model: UsageCredit, list: true
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# 利用状況レスポンス。
|
|
135
|
+
class UsageResponse < Base
|
|
136
|
+
field :account_name
|
|
137
|
+
field :plan
|
|
138
|
+
field :usage, model: UsageDetail
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|
data/lib/staddress.rb
ADDED
metadata
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: staddress
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- StaddressAI
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-08-15 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: rspec
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '3.13'
|
|
20
|
+
type: :development
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '3.13'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: webmock
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '3.23'
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '3.23'
|
|
41
|
+
description: Ruby SDK for the Staddress AI address parsing API (parse_address / parse_batch
|
|
42
|
+
/ get_usage). Zero runtime dependencies.
|
|
43
|
+
email:
|
|
44
|
+
executables: []
|
|
45
|
+
extensions: []
|
|
46
|
+
extra_rdoc_files: []
|
|
47
|
+
files:
|
|
48
|
+
- README.md
|
|
49
|
+
- lib/staddress.rb
|
|
50
|
+
- lib/staddress/client.rb
|
|
51
|
+
- lib/staddress/errors.rb
|
|
52
|
+
- lib/staddress/models.rb
|
|
53
|
+
- lib/staddress/version.rb
|
|
54
|
+
homepage: https://staddress.com/api
|
|
55
|
+
licenses:
|
|
56
|
+
- MIT
|
|
57
|
+
metadata:
|
|
58
|
+
homepage_uri: https://staddress.com/api
|
|
59
|
+
source_code_uri: https://github.com/StaddressAI/staddress-tools
|
|
60
|
+
bug_tracker_uri: https://github.com/StaddressAI/staddress-tools/issues
|
|
61
|
+
rubygems_mfa_required: 'true'
|
|
62
|
+
post_install_message:
|
|
63
|
+
rdoc_options: []
|
|
64
|
+
require_paths:
|
|
65
|
+
- lib
|
|
66
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
67
|
+
requirements:
|
|
68
|
+
- - ">="
|
|
69
|
+
- !ruby/object:Gem::Version
|
|
70
|
+
version: '3.1'
|
|
71
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - ">="
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '0'
|
|
76
|
+
requirements: []
|
|
77
|
+
rubygems_version: 3.5.22
|
|
78
|
+
signing_key:
|
|
79
|
+
specification_version: 4
|
|
80
|
+
summary: Official Ruby client for Staddress AI address parsing API
|
|
81
|
+
test_files: []
|