rate-api-python 1.0.0__tar.gz → 1.0.1__tar.gz

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.
@@ -0,0 +1,124 @@
1
+ Metadata-Version: 2.4
2
+ Name: rate-api-python
3
+ Version: 1.0.1
4
+ Summary: Official Python client for the Rate-API.com exchange-rate & crypto API
5
+ Author-email: Vilgar <digitalbrainsllc@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://rate-api.com
8
+ Project-URL: Documentation, https://rate-api.com/en/docs
9
+ Project-URL: Repository, https://github.com/Vilgar/rate-api.com
10
+ Project-URL: Issues, https://rate-api.com/en/docs
11
+ Keywords: exchange-rate,currency,forex,crypto,api,rate-api
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
16
+ Classifier: Topic :: Office/Business :: Financial
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.8
19
+ Classifier: Programming Language :: Python :: 3.9
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Programming Language :: Python :: 3.13
24
+ Requires-Python: >=3.8
25
+ Description-Content-Type: text/markdown
26
+ License-File: LICENSE
27
+ Dynamic: license-file
28
+
29
+ # rate-api-python
30
+
31
+ Official Python client for [Rate-API.com](https://rate-api.com). Standard library only — no dependencies. Python 3.8+.
32
+
33
+ ## Install
34
+
35
+ ```bash
36
+ pip install rate-api-python
37
+ ```
38
+
39
+ ## Usage
40
+
41
+ ```python
42
+ from rate_api import RateApiClient, RateApiError
43
+
44
+ client = RateApiClient("YOUR_API_KEY")
45
+
46
+ rates = client.latest("USD", ["EUR", "GBP"])
47
+ print(rates["rates"]["EUR"])
48
+
49
+ client.convert("USD", "EUR", 100) # Pro+
50
+ client.historical("2026-01-15", "USD", ["EUR"]) # Pro+
51
+ client.pair("USD", "EUR") # single pair
52
+ client.timeseries("2026-01-01", "2026-01-31") # Business+
53
+ client.fluctuation("2026-01-01", "2026-01-31") # Business+
54
+ client.crypto(["BTC", "ETH"]) # Pro+
55
+ client.currencies() # supported currencies
56
+ client.health() # public
57
+
58
+ try:
59
+ client.timeseries("2020-01-01", "2026-12-31")
60
+ except RateApiError as e:
61
+ print(e, e.status) # "Date range too large. Maximum is 366 days." 400
62
+ ```
63
+
64
+ ## v2 features
65
+
66
+ The client exposes the v2 endpoints directly (they resolve to `/api/v2` regardless of base URL):
67
+
68
+ ```python
69
+ # Latest with 24h change, metadata and precision
70
+ r = client.latest_v2("USD", ["EUR", "GBP"], include_change=True, include_metadata=True, precision=4)
71
+ print(r["changes_pct"]["EUR"])
72
+
73
+ # Historical comparison between two dates (Pro+)
74
+ cmp = client.historical_compare("2026-01-15", "2026-01-01", "USD", ["EUR"])
75
+
76
+ # Batch conversion — up to 100 pairs in one call (Pro+)
77
+ batch = client.batch_convert([
78
+ {"from": "USD", "to": "EUR", "amount": 100},
79
+ {"from": "GBP", "to": "JPY", "amount": 50},
80
+ ])
81
+
82
+ # Your configured rate alerts (Business+)
83
+ alerts = client.alerts()
84
+ ```
85
+
86
+ ## Errors
87
+
88
+ Every failure raises `RateApiError` (or a subclass), so a single `except RateApiError` catches everything:
89
+
90
+ ```python
91
+ import time
92
+ from rate_api import RateApiClient, RateApiError, RateLimitError, RateApiTimeoutError
93
+
94
+ try:
95
+ client.latest("USD", ["EUR"])
96
+ except RateLimitError as e:
97
+ time.sleep(e.retry_after) # honour the server's backoff
98
+ except RateApiTimeoutError:
99
+ ... # request exceeded `timeout`
100
+ except RateApiError as e:
101
+ print(e, e.status, e.type, e.request_id)
102
+ ```
103
+
104
+ | Class | When | Extra attributes |
105
+ |---|---|---|
106
+ | `RateApiError` | any API/HTTP error | `status` (HTTP code; `None` on network/timeout), `type` (stable `error.type` slug), `request_id` (`X-Request-Id` — quote it when contacting support) |
107
+ | `RateLimitError` | HTTP 429 | `retry_after` (seconds to wait) |
108
+ | `RateApiTimeoutError` | request exceeded `timeout` | — |
109
+
110
+ ## Configuration
111
+
112
+ ```python
113
+ RateApiClient(api_key, base_url="https://rate-api.com/api/v1", timeout=15, max_retries=2)
114
+ ```
115
+
116
+ | Argument | Default | Notes |
117
+ |---|---|---|
118
+ | `base_url` | `https://rate-api.com/api/v1` | pass `…/api/v2` to target v2 directly |
119
+ | `timeout` | `15` | per-request socket timeout in seconds (covers headers and body) |
120
+ | `max_retries` | `2` | automatically retries 429/503/network/timeout with exponential backoff, honouring the server's `Retry-After` header |
121
+
122
+ ## License
123
+
124
+ MIT
@@ -0,0 +1,96 @@
1
+ # rate-api-python
2
+
3
+ Official Python client for [Rate-API.com](https://rate-api.com). Standard library only — no dependencies. Python 3.8+.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pip install rate-api-python
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```python
14
+ from rate_api import RateApiClient, RateApiError
15
+
16
+ client = RateApiClient("YOUR_API_KEY")
17
+
18
+ rates = client.latest("USD", ["EUR", "GBP"])
19
+ print(rates["rates"]["EUR"])
20
+
21
+ client.convert("USD", "EUR", 100) # Pro+
22
+ client.historical("2026-01-15", "USD", ["EUR"]) # Pro+
23
+ client.pair("USD", "EUR") # single pair
24
+ client.timeseries("2026-01-01", "2026-01-31") # Business+
25
+ client.fluctuation("2026-01-01", "2026-01-31") # Business+
26
+ client.crypto(["BTC", "ETH"]) # Pro+
27
+ client.currencies() # supported currencies
28
+ client.health() # public
29
+
30
+ try:
31
+ client.timeseries("2020-01-01", "2026-12-31")
32
+ except RateApiError as e:
33
+ print(e, e.status) # "Date range too large. Maximum is 366 days." 400
34
+ ```
35
+
36
+ ## v2 features
37
+
38
+ The client exposes the v2 endpoints directly (they resolve to `/api/v2` regardless of base URL):
39
+
40
+ ```python
41
+ # Latest with 24h change, metadata and precision
42
+ r = client.latest_v2("USD", ["EUR", "GBP"], include_change=True, include_metadata=True, precision=4)
43
+ print(r["changes_pct"]["EUR"])
44
+
45
+ # Historical comparison between two dates (Pro+)
46
+ cmp = client.historical_compare("2026-01-15", "2026-01-01", "USD", ["EUR"])
47
+
48
+ # Batch conversion — up to 100 pairs in one call (Pro+)
49
+ batch = client.batch_convert([
50
+ {"from": "USD", "to": "EUR", "amount": 100},
51
+ {"from": "GBP", "to": "JPY", "amount": 50},
52
+ ])
53
+
54
+ # Your configured rate alerts (Business+)
55
+ alerts = client.alerts()
56
+ ```
57
+
58
+ ## Errors
59
+
60
+ Every failure raises `RateApiError` (or a subclass), so a single `except RateApiError` catches everything:
61
+
62
+ ```python
63
+ import time
64
+ from rate_api import RateApiClient, RateApiError, RateLimitError, RateApiTimeoutError
65
+
66
+ try:
67
+ client.latest("USD", ["EUR"])
68
+ except RateLimitError as e:
69
+ time.sleep(e.retry_after) # honour the server's backoff
70
+ except RateApiTimeoutError:
71
+ ... # request exceeded `timeout`
72
+ except RateApiError as e:
73
+ print(e, e.status, e.type, e.request_id)
74
+ ```
75
+
76
+ | Class | When | Extra attributes |
77
+ |---|---|---|
78
+ | `RateApiError` | any API/HTTP error | `status` (HTTP code; `None` on network/timeout), `type` (stable `error.type` slug), `request_id` (`X-Request-Id` — quote it when contacting support) |
79
+ | `RateLimitError` | HTTP 429 | `retry_after` (seconds to wait) |
80
+ | `RateApiTimeoutError` | request exceeded `timeout` | — |
81
+
82
+ ## Configuration
83
+
84
+ ```python
85
+ RateApiClient(api_key, base_url="https://rate-api.com/api/v1", timeout=15, max_retries=2)
86
+ ```
87
+
88
+ | Argument | Default | Notes |
89
+ |---|---|---|
90
+ | `base_url` | `https://rate-api.com/api/v1` | pass `…/api/v2` to target v2 directly |
91
+ | `timeout` | `15` | per-request socket timeout in seconds (covers headers and body) |
92
+ | `max_retries` | `2` | automatically retries 429/503/network/timeout with exponential backoff, honouring the server's `Retry-After` header |
93
+
94
+ ## License
95
+
96
+ MIT
@@ -0,0 +1,36 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "rate-api-python"
7
+ version = "1.0.1"
8
+ description = "Official Python client for the Rate-API.com exchange-rate & crypto API"
9
+ readme = "README.md"
10
+ license = { text = "MIT" }
11
+ requires-python = ">=3.8"
12
+ keywords = ["exchange-rate", "currency", "forex", "crypto", "api", "rate-api"]
13
+ authors = [{ name = "Vilgar", email = "digitalbrainsllc@gmail.com" }]
14
+ classifiers = [
15
+ "License :: OSI Approved :: MIT License",
16
+ "Operating System :: OS Independent",
17
+ "Intended Audience :: Developers",
18
+ "Topic :: Software Development :: Libraries :: Python Modules",
19
+ "Topic :: Office/Business :: Financial",
20
+ "Programming Language :: Python :: 3",
21
+ "Programming Language :: Python :: 3.8",
22
+ "Programming Language :: Python :: 3.9",
23
+ "Programming Language :: Python :: 3.10",
24
+ "Programming Language :: Python :: 3.11",
25
+ "Programming Language :: Python :: 3.12",
26
+ "Programming Language :: Python :: 3.13",
27
+ ]
28
+
29
+ [project.urls]
30
+ Homepage = "https://rate-api.com"
31
+ Documentation = "https://rate-api.com/en/docs"
32
+ Repository = "https://github.com/Vilgar/rate-api.com"
33
+ Issues = "https://rate-api.com/en/docs"
34
+
35
+ [tool.setuptools]
36
+ packages = ["rate_api"]
@@ -12,7 +12,7 @@ import urllib.error
12
12
  import urllib.parse
13
13
  import urllib.request
14
14
 
15
- __version__ = "1.0.0"
15
+ __version__ = "1.0.1"
16
16
  __all__ = ["RateApiClient", "RateApiError", "RateLimitError", "RateApiTimeoutError"]
17
17
 
18
18
 
@@ -116,10 +116,16 @@ class RateApiClient:
116
116
  def _get(self, endpoint, query=None):
117
117
  return self._request(f"{self.base_url}/{self.api_key}/{endpoint}", query or {})
118
118
 
119
+ @staticmethod
120
+ def _normalize_headers(headers):
121
+ # urllib's HTTPMessage.get() is case-insensitive, but dict(...) is not — and
122
+ # Cloudflare/HTTP-2 send header names lowercased. Normalize to lowercase keys.
123
+ return {k.lower(): v for k, v in dict(headers or {}).items()}
124
+
119
125
  @staticmethod
120
126
  def _retry_after(headers, default=60):
121
127
  try:
122
- return int(headers.get("Retry-After", default))
128
+ return int(headers.get("retry-after", default))
123
129
  except (TypeError, ValueError):
124
130
  return default
125
131
 
@@ -148,11 +154,15 @@ class RateApiClient:
148
154
  try:
149
155
  with urllib.request.urlopen(req, timeout=self.timeout) as resp:
150
156
  status = resp.status
151
- resp_headers = dict(resp.headers)
152
- data = json.loads(resp.read().decode("utf-8"))
157
+ resp_headers = self._normalize_headers(resp.headers)
158
+ raw = resp.read().decode("utf-8")
159
+ try:
160
+ data = json.loads(raw)
161
+ except ValueError:
162
+ raise RateApiError(f"Invalid JSON response (HTTP {status}).", status)
153
163
  except urllib.error.HTTPError as e:
154
164
  status = e.code
155
- resp_headers = dict(e.headers or {})
165
+ resp_headers = self._normalize_headers(e.headers)
156
166
  # Retry transient statuses, honoring Retry-After.
157
167
  if status in (429, 503) and attempt < self.max_retries:
158
168
  attempt += 1
@@ -176,7 +186,7 @@ class RateApiClient:
176
186
  err = data.get("error") or {}
177
187
  msg = err.get("message") or data.get("message") or "Unknown API error"
178
188
  etype = err.get("type")
179
- rid = data.get("request_id") or resp_headers.get("X-Request-Id")
189
+ rid = data.get("request_id") or resp_headers.get("x-request-id")
180
190
  if status == 429:
181
191
  raise RateLimitError(msg, status, etype, rid, self._retry_after(resp_headers))
182
192
  raise RateApiError(msg, status, etype, rid)
@@ -0,0 +1,124 @@
1
+ Metadata-Version: 2.4
2
+ Name: rate-api-python
3
+ Version: 1.0.1
4
+ Summary: Official Python client for the Rate-API.com exchange-rate & crypto API
5
+ Author-email: Vilgar <digitalbrainsllc@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://rate-api.com
8
+ Project-URL: Documentation, https://rate-api.com/en/docs
9
+ Project-URL: Repository, https://github.com/Vilgar/rate-api.com
10
+ Project-URL: Issues, https://rate-api.com/en/docs
11
+ Keywords: exchange-rate,currency,forex,crypto,api,rate-api
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
16
+ Classifier: Topic :: Office/Business :: Financial
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.8
19
+ Classifier: Programming Language :: Python :: 3.9
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Programming Language :: Python :: 3.13
24
+ Requires-Python: >=3.8
25
+ Description-Content-Type: text/markdown
26
+ License-File: LICENSE
27
+ Dynamic: license-file
28
+
29
+ # rate-api-python
30
+
31
+ Official Python client for [Rate-API.com](https://rate-api.com). Standard library only — no dependencies. Python 3.8+.
32
+
33
+ ## Install
34
+
35
+ ```bash
36
+ pip install rate-api-python
37
+ ```
38
+
39
+ ## Usage
40
+
41
+ ```python
42
+ from rate_api import RateApiClient, RateApiError
43
+
44
+ client = RateApiClient("YOUR_API_KEY")
45
+
46
+ rates = client.latest("USD", ["EUR", "GBP"])
47
+ print(rates["rates"]["EUR"])
48
+
49
+ client.convert("USD", "EUR", 100) # Pro+
50
+ client.historical("2026-01-15", "USD", ["EUR"]) # Pro+
51
+ client.pair("USD", "EUR") # single pair
52
+ client.timeseries("2026-01-01", "2026-01-31") # Business+
53
+ client.fluctuation("2026-01-01", "2026-01-31") # Business+
54
+ client.crypto(["BTC", "ETH"]) # Pro+
55
+ client.currencies() # supported currencies
56
+ client.health() # public
57
+
58
+ try:
59
+ client.timeseries("2020-01-01", "2026-12-31")
60
+ except RateApiError as e:
61
+ print(e, e.status) # "Date range too large. Maximum is 366 days." 400
62
+ ```
63
+
64
+ ## v2 features
65
+
66
+ The client exposes the v2 endpoints directly (they resolve to `/api/v2` regardless of base URL):
67
+
68
+ ```python
69
+ # Latest with 24h change, metadata and precision
70
+ r = client.latest_v2("USD", ["EUR", "GBP"], include_change=True, include_metadata=True, precision=4)
71
+ print(r["changes_pct"]["EUR"])
72
+
73
+ # Historical comparison between two dates (Pro+)
74
+ cmp = client.historical_compare("2026-01-15", "2026-01-01", "USD", ["EUR"])
75
+
76
+ # Batch conversion — up to 100 pairs in one call (Pro+)
77
+ batch = client.batch_convert([
78
+ {"from": "USD", "to": "EUR", "amount": 100},
79
+ {"from": "GBP", "to": "JPY", "amount": 50},
80
+ ])
81
+
82
+ # Your configured rate alerts (Business+)
83
+ alerts = client.alerts()
84
+ ```
85
+
86
+ ## Errors
87
+
88
+ Every failure raises `RateApiError` (or a subclass), so a single `except RateApiError` catches everything:
89
+
90
+ ```python
91
+ import time
92
+ from rate_api import RateApiClient, RateApiError, RateLimitError, RateApiTimeoutError
93
+
94
+ try:
95
+ client.latest("USD", ["EUR"])
96
+ except RateLimitError as e:
97
+ time.sleep(e.retry_after) # honour the server's backoff
98
+ except RateApiTimeoutError:
99
+ ... # request exceeded `timeout`
100
+ except RateApiError as e:
101
+ print(e, e.status, e.type, e.request_id)
102
+ ```
103
+
104
+ | Class | When | Extra attributes |
105
+ |---|---|---|
106
+ | `RateApiError` | any API/HTTP error | `status` (HTTP code; `None` on network/timeout), `type` (stable `error.type` slug), `request_id` (`X-Request-Id` — quote it when contacting support) |
107
+ | `RateLimitError` | HTTP 429 | `retry_after` (seconds to wait) |
108
+ | `RateApiTimeoutError` | request exceeded `timeout` | — |
109
+
110
+ ## Configuration
111
+
112
+ ```python
113
+ RateApiClient(api_key, base_url="https://rate-api.com/api/v1", timeout=15, max_retries=2)
114
+ ```
115
+
116
+ | Argument | Default | Notes |
117
+ |---|---|---|
118
+ | `base_url` | `https://rate-api.com/api/v1` | pass `…/api/v2` to target v2 directly |
119
+ | `timeout` | `15` | per-request socket timeout in seconds (covers headers and body) |
120
+ | `max_retries` | `2` | automatically retries 429/503/network/timeout with exponential backoff, honouring the server's `Retry-After` header |
121
+
122
+ ## License
123
+
124
+ MIT
@@ -1,71 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: rate-api-python
3
- Version: 1.0.0
4
- Summary: Official Python client for the Rate-API.com exchange-rate & crypto API
5
- License: MIT
6
- Project-URL: Homepage, https://rate-api.com
7
- Project-URL: Documentation, https://rate-api.com/en/docs
8
- Project-URL: Repository, https://github.com/Vilgar/rate-api.com
9
- Keywords: exchange-rate,currency,forex,crypto,api,rate-api
10
- Requires-Python: >=3.8
11
- Description-Content-Type: text/markdown
12
- License-File: LICENSE
13
- Dynamic: license-file
14
-
15
- # rate-api-python
16
-
17
- Official Python client for [Rate-API.com](https://rate-api.com). Standard library only — no dependencies. Python 3.8+.
18
-
19
- ## Install
20
-
21
- ```bash
22
- pip install rate-api-python
23
- ```
24
-
25
- ## Usage
26
-
27
- ```python
28
- from rate_api import RateApiClient, RateApiError
29
-
30
- client = RateApiClient("YOUR_API_KEY")
31
-
32
- rates = client.latest("USD", ["EUR", "GBP"])
33
- print(rates["rates"]["EUR"])
34
-
35
- client.convert("USD", "EUR", 100) # Pro+
36
- client.historical("2026-01-15", "USD", ["EUR"]) # Pro+
37
- client.timeseries("2026-01-01", "2026-01-31") # Business+
38
- client.crypto(["BTC", "ETH"]) # Pro+
39
- client.health() # public
40
-
41
- try:
42
- client.timeseries("2020-01-01", "2026-12-31")
43
- except RateApiError as e:
44
- print(e, e.status) # "Date range too large. Maximum is 366 days." 400
45
- ```
46
-
47
- ## v2 features
48
-
49
- The client exposes the v2 endpoints directly (they resolve to `/api/v2` regardless of base URL):
50
-
51
- ```python
52
- # Latest with 24h change, metadata and precision
53
- r = client.latest_v2("USD", ["EUR", "GBP"], include_change=True, include_metadata=True, precision=4)
54
- print(r["changes_pct"]["EUR"])
55
-
56
- # Historical comparison between two dates (Pro+)
57
- cmp = client.historical_compare("2026-01-15", "2026-01-01", "USD", ["EUR"])
58
-
59
- # Batch conversion — up to 100 pairs in one call (Pro+)
60
- batch = client.batch_convert([
61
- {"from": "USD", "to": "EUR", "amount": 100},
62
- {"from": "GBP", "to": "JPY", "amount": 50},
63
- ])
64
-
65
- # Your configured rate alerts (Business+)
66
- alerts = client.alerts()
67
- ```
68
-
69
- ## License
70
-
71
- MIT
@@ -1,57 +0,0 @@
1
- # rate-api-python
2
-
3
- Official Python client for [Rate-API.com](https://rate-api.com). Standard library only — no dependencies. Python 3.8+.
4
-
5
- ## Install
6
-
7
- ```bash
8
- pip install rate-api-python
9
- ```
10
-
11
- ## Usage
12
-
13
- ```python
14
- from rate_api import RateApiClient, RateApiError
15
-
16
- client = RateApiClient("YOUR_API_KEY")
17
-
18
- rates = client.latest("USD", ["EUR", "GBP"])
19
- print(rates["rates"]["EUR"])
20
-
21
- client.convert("USD", "EUR", 100) # Pro+
22
- client.historical("2026-01-15", "USD", ["EUR"]) # Pro+
23
- client.timeseries("2026-01-01", "2026-01-31") # Business+
24
- client.crypto(["BTC", "ETH"]) # Pro+
25
- client.health() # public
26
-
27
- try:
28
- client.timeseries("2020-01-01", "2026-12-31")
29
- except RateApiError as e:
30
- print(e, e.status) # "Date range too large. Maximum is 366 days." 400
31
- ```
32
-
33
- ## v2 features
34
-
35
- The client exposes the v2 endpoints directly (they resolve to `/api/v2` regardless of base URL):
36
-
37
- ```python
38
- # Latest with 24h change, metadata and precision
39
- r = client.latest_v2("USD", ["EUR", "GBP"], include_change=True, include_metadata=True, precision=4)
40
- print(r["changes_pct"]["EUR"])
41
-
42
- # Historical comparison between two dates (Pro+)
43
- cmp = client.historical_compare("2026-01-15", "2026-01-01", "USD", ["EUR"])
44
-
45
- # Batch conversion — up to 100 pairs in one call (Pro+)
46
- batch = client.batch_convert([
47
- {"from": "USD", "to": "EUR", "amount": 100},
48
- {"from": "GBP", "to": "JPY", "amount": 50},
49
- ])
50
-
51
- # Your configured rate alerts (Business+)
52
- alerts = client.alerts()
53
- ```
54
-
55
- ## License
56
-
57
- MIT
@@ -1,20 +0,0 @@
1
- [build-system]
2
- requires = ["setuptools>=61"]
3
- build-backend = "setuptools.build_meta"
4
-
5
- [project]
6
- name = "rate-api-python"
7
- version = "1.0.0"
8
- description = "Official Python client for the Rate-API.com exchange-rate & crypto API"
9
- readme = "README.md"
10
- license = { text = "MIT" }
11
- requires-python = ">=3.8"
12
- keywords = ["exchange-rate", "currency", "forex", "crypto", "api", "rate-api"]
13
-
14
- [project.urls]
15
- Homepage = "https://rate-api.com"
16
- Documentation = "https://rate-api.com/en/docs"
17
- Repository = "https://github.com/Vilgar/rate-api.com"
18
-
19
- [tool.setuptools]
20
- packages = ["rate_api"]
@@ -1,71 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: rate-api-python
3
- Version: 1.0.0
4
- Summary: Official Python client for the Rate-API.com exchange-rate & crypto API
5
- License: MIT
6
- Project-URL: Homepage, https://rate-api.com
7
- Project-URL: Documentation, https://rate-api.com/en/docs
8
- Project-URL: Repository, https://github.com/Vilgar/rate-api.com
9
- Keywords: exchange-rate,currency,forex,crypto,api,rate-api
10
- Requires-Python: >=3.8
11
- Description-Content-Type: text/markdown
12
- License-File: LICENSE
13
- Dynamic: license-file
14
-
15
- # rate-api-python
16
-
17
- Official Python client for [Rate-API.com](https://rate-api.com). Standard library only — no dependencies. Python 3.8+.
18
-
19
- ## Install
20
-
21
- ```bash
22
- pip install rate-api-python
23
- ```
24
-
25
- ## Usage
26
-
27
- ```python
28
- from rate_api import RateApiClient, RateApiError
29
-
30
- client = RateApiClient("YOUR_API_KEY")
31
-
32
- rates = client.latest("USD", ["EUR", "GBP"])
33
- print(rates["rates"]["EUR"])
34
-
35
- client.convert("USD", "EUR", 100) # Pro+
36
- client.historical("2026-01-15", "USD", ["EUR"]) # Pro+
37
- client.timeseries("2026-01-01", "2026-01-31") # Business+
38
- client.crypto(["BTC", "ETH"]) # Pro+
39
- client.health() # public
40
-
41
- try:
42
- client.timeseries("2020-01-01", "2026-12-31")
43
- except RateApiError as e:
44
- print(e, e.status) # "Date range too large. Maximum is 366 days." 400
45
- ```
46
-
47
- ## v2 features
48
-
49
- The client exposes the v2 endpoints directly (they resolve to `/api/v2` regardless of base URL):
50
-
51
- ```python
52
- # Latest with 24h change, metadata and precision
53
- r = client.latest_v2("USD", ["EUR", "GBP"], include_change=True, include_metadata=True, precision=4)
54
- print(r["changes_pct"]["EUR"])
55
-
56
- # Historical comparison between two dates (Pro+)
57
- cmp = client.historical_compare("2026-01-15", "2026-01-01", "USD", ["EUR"])
58
-
59
- # Batch conversion — up to 100 pairs in one call (Pro+)
60
- batch = client.batch_convert([
61
- {"from": "USD", "to": "EUR", "amount": 100},
62
- {"from": "GBP", "to": "JPY", "amount": 50},
63
- ])
64
-
65
- # Your configured rate alerts (Business+)
66
- alerts = client.alerts()
67
- ```
68
-
69
- ## License
70
-
71
- MIT
File without changes