zipcodestack 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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 3d7ad24f5015885f3629045a1c9a49a91f87d428f7cba2069ee3d9dfe19daa8b
4
+ data.tar.gz: 0cc66ec5e2a0042155dcdf4490153dff844f2cf4ec5c252afeaab094a6217da7
5
+ SHA512:
6
+ metadata.gz: 2f2c5a6a8671d15a4645e333906856fcc5d7267c668bb80028b88b238e2e5bb54df050729baad64701b99679a9cfb2e15774b8009d34f937b8e20d08029ec572
7
+ data.tar.gz: cb85ed40e2451bda78d9436a9e6672b0c62c1b569eeb7d8a13c5ba6e2c97f7501d6e7158acda76686b06102809e31e2358887722db06bd940c798b31f87a694f
data/README.md ADDED
@@ -0,0 +1,88 @@
1
+ # zipcodestack (Ruby SDK)
2
+
3
+ A lightweight Ruby client for the `zipcodestack.com` API.
4
+
5
+ - **Docs**: [zipcodestack.com API Documentation](https://zipcodestack.com/docs/)
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem "zipcodestack"
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ ```bash
18
+ bundle install
19
+ ```
20
+
21
+ Or install it yourself as:
22
+
23
+ ```bash
24
+ gem build zipcodestack.gemspec
25
+ gem install zipcodestack-$(ruby -e 'require "./lib/zipcodestack/version"; print Zipcodestack::Version::STRING').gem
26
+ ```
27
+
28
+ ## Getting an API key
29
+
30
+ Create an account and obtain your API key from the dashboard. See the official docs: [zipcodestack.com API Documentation](https://zipcodestack.com/docs/).
31
+
32
+ ## Quick start
33
+
34
+ ```ruby
35
+ require "zipcodestack"
36
+
37
+ client = Zipcodestack::Client.new(
38
+ api_key: ENV.fetch("ZIPCODESTACK_API_KEY"),
39
+ # Set your API base according to the docs; examples:
40
+ # "https://api.zipcodestack.com" or "https://zipcodestack.com/api"
41
+ api_base: ENV.fetch("ZIPCODESTACK_API_BASE", "https://api.zipcodestack.com"),
42
+ # By default the client sends Authorization: Bearer <API_KEY>.
43
+ # If you prefer API key via query params, set use_header_auth: false.
44
+ use_header_auth: true
45
+ )
46
+
47
+ # Perform a search request (refer to official docs for supported parameters)
48
+ result = client.search(query: "90210", country: "US")
49
+ puts result
50
+
51
+ # Compute distance (refer to official docs for supported parameters)
52
+ distance = client.distance(from: "90210", to: "10001", unit: "mi")
53
+ puts distance
54
+
55
+ # You can also call arbitrary GET endpoints
56
+ raw = client.get("/status")
57
+ puts raw
58
+ ```
59
+
60
+ ## Configuration
61
+
62
+ - **api_key**: Your API key string.
63
+ - **api_base**: The base URL for the API. Consult the docs to choose the correct host and path.
64
+ - **use_header_auth**: If true, sends `Authorization: Bearer <API_KEY>`. If false, sends `apikey=<API_KEY>` as a query parameter.
65
+ - **open_timeout / read_timeout**: Net::HTTP timeouts in seconds (defaults: 5s / 10s).
66
+ - **user_agent**: Custom user agent (defaults to `zipcodestack-ruby/<version>`).
67
+
68
+ ## Error handling
69
+
70
+ Non-2xx HTTP responses raise `Zipcodestack::HTTPError` with `status` and `body` fields. Rescue as needed:
71
+
72
+ ```ruby
73
+ begin
74
+ client.search(query: "00000")
75
+ rescue Zipcodestack::HTTPError => e
76
+ warn "Request failed: #{e.status} #{e.message}"
77
+ end
78
+ ```
79
+
80
+ ## Contributing
81
+
82
+ Bug reports and pull requests are welcome on GitHub. Please run tests and linters before submitting.
83
+
84
+ ## License
85
+
86
+ This gem is available as open source under the terms of the MIT License. See `LICENSE`.
87
+
88
+
@@ -0,0 +1,132 @@
1
+ require "net/http"
2
+ require "json"
3
+ require "uri"
4
+
5
+ module Zipcodestack
6
+ class Error < StandardError; end
7
+
8
+ class HTTPError < Error
9
+ attr_reader :status, :body
10
+
11
+ def initialize(message, status:, body: nil)
12
+ super(message)
13
+ @status = status
14
+ @body = body
15
+ end
16
+ end
17
+
18
+ class Client
19
+ DEFAULT_OPEN_TIMEOUT = 5
20
+ DEFAULT_READ_TIMEOUT = 10
21
+
22
+ attr_reader :api_key, :api_base, :use_header_auth, :open_timeout, :read_timeout, :user_agent
23
+
24
+ def initialize(api_key:, api_base:, use_header_auth: true, open_timeout: DEFAULT_OPEN_TIMEOUT, read_timeout: DEFAULT_READ_TIMEOUT, user_agent: nil)
25
+ @api_key = api_key
26
+ @api_base = api_base.sub(/\/$/, "")
27
+ @use_header_auth = use_header_auth
28
+ @open_timeout = open_timeout
29
+ @read_timeout = read_timeout
30
+ @user_agent = user_agent || default_user_agent
31
+ end
32
+
33
+ # Perform a GET request to an arbitrary path under the API base.
34
+ # params: Hash of query params
35
+ def get(path, params = {})
36
+ request(:get, path, params: params)
37
+ end
38
+
39
+ # Convenience: Search endpoint. Refer to API docs for supported parameters.
40
+ # Example params could include: { query: "90210", country: "US" }
41
+ def search(params = {})
42
+ get("/search", params)
43
+ end
44
+
45
+ # Convenience: Distance endpoint. Refer to API docs for supported parameters.
46
+ # Example params could include: { from: "90210", to: "10001", unit: "mi" }
47
+ def distance(params = {})
48
+ get("/distance", params)
49
+ end
50
+
51
+ private
52
+
53
+ def request(method, path, params: {})
54
+ uri = build_uri(path, params)
55
+ http = Net::HTTP.new(uri.host, uri.port)
56
+ http.use_ssl = uri.scheme == "https"
57
+ http.open_timeout = open_timeout
58
+ http.read_timeout = read_timeout
59
+
60
+ request = build_http_request(method, uri)
61
+ attach_authentication(request, uri)
62
+ attach_headers(request)
63
+
64
+ response = http.request(request)
65
+ handle_response(response)
66
+ end
67
+
68
+ def build_uri(path, params)
69
+ path = "/#{path}" unless path.start_with?("/")
70
+ uri = URI.parse("#{api_base}#{path}")
71
+
72
+ normalized_params = params.dup
73
+ unless use_header_auth
74
+ normalized_params = { apikey: api_key }.merge(normalized_params || {})
75
+ end
76
+
77
+ if normalized_params && !normalized_params.empty?
78
+ query = URI.encode_www_form(normalized_params)
79
+ uri.query = [uri.query, query].compact.join("&")
80
+ end
81
+ uri
82
+ end
83
+
84
+ def build_http_request(method, uri)
85
+ case method
86
+ when :get
87
+ Net::HTTP::Get.new(uri)
88
+ else
89
+ raise ArgumentError, "Unsupported method: #{method}"
90
+ end
91
+ end
92
+
93
+ def attach_authentication(request, _uri)
94
+ if use_header_auth
95
+ request["Authorization"] = "Bearer #{api_key}"
96
+ end
97
+ end
98
+
99
+ def attach_headers(request)
100
+ request["Accept"] = "application/json"
101
+ request["User-Agent"] = user_agent
102
+ end
103
+
104
+ def handle_response(response)
105
+ status = response.code.to_i
106
+ body = response.body
107
+
108
+ if status >= 200 && status < 300
109
+ parse_json(body)
110
+ else
111
+ message = begin
112
+ parsed = parse_json(body)
113
+ parsed.is_a?(Hash) && parsed["message"] || parsed["error"] || body
114
+ rescue JSON::ParserError
115
+ body
116
+ end
117
+ raise HTTPError.new("HTTP #{status}: #{message}", status: status, body: body)
118
+ end
119
+ end
120
+
121
+ def parse_json(string)
122
+ return nil if string.nil? || string.strip.empty?
123
+ JSON.parse(string)
124
+ end
125
+
126
+ def default_user_agent
127
+ "zipcodestack-ruby/#{Version::STRING} (Ruby #{RUBY_VERSION}; #{RUBY_PLATFORM})"
128
+ end
129
+ end
130
+ end
131
+
132
+
@@ -0,0 +1,7 @@
1
+ module Zipcodestack
2
+ module Version
3
+ STRING = "0.1.0"
4
+ end
5
+ end
6
+
7
+
@@ -0,0 +1,7 @@
1
+ require_relative "zipcodestack/version"
2
+ require_relative "zipcodestack/client"
3
+
4
+ module Zipcodestack
5
+ end
6
+
7
+
metadata ADDED
@@ -0,0 +1,51 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: zipcodestack
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - zipcodestack SDK Maintainers
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2025-09-30 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A lightweight Ruby wrapper for the zipcodestack.com API, providing authentication
14
+ and convenient helpers.
15
+ email:
16
+ - support@zipcodestack.com
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - README.md
22
+ - lib/zipcodestack.rb
23
+ - lib/zipcodestack/client.rb
24
+ - lib/zipcodestack/version.rb
25
+ homepage: https://zipcodestack.com/docs/
26
+ licenses:
27
+ - MIT
28
+ metadata:
29
+ homepage_uri: https://zipcodestack.com/docs/
30
+ source_code_uri: https://github.com/zipcodestack/zipcodestack-ruby
31
+ changelog_uri: https://github.com/zipcodestack/zipcodestack-ruby/releases
32
+ post_install_message:
33
+ rdoc_options: []
34
+ require_paths:
35
+ - lib
36
+ required_ruby_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '2.7'
41
+ required_rubygems_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ requirements: []
47
+ rubygems_version: 3.0.3.1
48
+ signing_key:
49
+ specification_version: 4
50
+ summary: Ruby client for the zipcodestack.com API
51
+ test_files: []