Skip to content

Commit 62c5fa0

Browse files
author
rob
committed
Upgrade to version 1.0.0: Introduced VAT rates and historical limits endpoints, enhanced error handling, and updated method signatures for improved usability. Added support for multiple output formats (JSON, XML, CSV, TSV) and JSONP callback. Updated README and examples to reflect new features and changes.
1 parent ca177b4 commit 62c5fa0

5 files changed

Lines changed: 523 additions & 138 deletions

File tree

README.md

Lines changed: 211 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
# Unirate Python API Client
22

3-
A simple Python client for the [Unirate API](https://unirateapi.com) - providing free, real-time and historical currency exchange rates.
3+
A comprehensive Python client for the [Unirate API](https://unirateapi.com) - providing free, real-time and historical currency exchange rates, plus VAT rates.
44

55
## Features
66

77
- 🔄 **Real-time exchange rates** - Get current currency conversion rates
8-
- 📈 **Historical data** - Access historical exchange rates for any date
9-
-**Time series data** - Retrieve exchange rate data over date ranges
8+
- 📈 **Historical data** - Access historical exchange rates for any date (1999-2025)
9+
-**Time series data** - Retrieve exchange rate data over date ranges (max 5 years)
1010
- 💰 **Currency conversion** - Convert amounts between currencies (current and historical)
11-
- 🌍 **590+ currencies supported** - Including cryptocurrencies
11+
- 🏛️ **VAT rates** - Get VAT rates for countries worldwide
12+
- 📊 **Multiple output formats** - JSON, XML, CSV, TSV support
13+
- 🌍 **170+ currencies supported** - Including cryptocurrencies
1214
- 🆓 **Completely free** - No credit card required
1315
- 🚀 **Easy to use** - Simple, intuitive API
1416

@@ -30,8 +32,8 @@ client = UnirateClient('your-api-key-here')
3032
rate = client.get_rate('USD', 'EUR')
3133
print(f'USD to EUR rate: {rate}')
3234

33-
# Convert currency
34-
amount = client.convert(100, 'USD', 'EUR')
35+
# Convert currency (note: to_currency is first parameter)
36+
amount = client.convert('EUR', 100, 'USD')
3537
print(f'100 USD = {amount} EUR')
3638

3739
# Get supported currencies
@@ -43,65 +45,158 @@ print(f'Supported currencies: {len(currencies)}')
4345

4446
### Current Rates & Conversion
4547

46-
#### `get_rate(from_currency, to_currency)`
47-
Get the current exchange rate between two currencies.
48+
#### `get_rate(from_currency='USD', to_currency=None, format='json', callback=None)`
49+
Get current exchange rates. If `to_currency` is omitted, returns rates for all currencies.
4850

4951
```python
52+
# Single currency rate
5053
rate = client.get_rate('USD', 'EUR')
54+
55+
# All rates for base currency
56+
all_rates = client.get_rate('USD')
57+
58+
# Get rates in CSV format
59+
csv_data = client.get_rate('USD', 'EUR', format='csv')
5160
```
5261

53-
#### `convert(amount, from_currency, to_currency)`
62+
#### `convert(to_currency, amount=1, from_currency='USD', format='json', callback=None)`
5463
Convert an amount from one currency to another using current rates.
5564

5665
```python
57-
converted = client.convert(100, 'USD', 'EUR')
66+
# Convert with default amount (1)
67+
converted = client.convert('EUR', from_currency='USD')
68+
69+
# Convert specific amount
70+
converted = client.convert('EUR', 100, 'USD')
71+
72+
# Get conversion result in XML format
73+
xml_result = client.convert('EUR', 100, 'USD', format='xml')
5874
```
5975

60-
#### `get_supported_currencies()`
76+
#### `get_supported_currencies(format='json', callback=None)`
6177
Get a list of all supported currency codes.
6278

6379
```python
6480
currencies = client.get_supported_currencies()
81+
82+
# Get currencies in CSV format
83+
csv_currencies = client.get_supported_currencies(format='csv')
6584
```
6685

6786
### Historical Data
6887

69-
#### `get_historical_rate(from_currency, to_currency, date)`
70-
Get the exchange rate between two currencies for a specific historical date.
88+
#### `get_historical_rate(date, amount=1, from_currency='USD', to_currency=None, format='json', callback=None)`
89+
Get historical exchange rates for a specific date. If `to_currency` is omitted, returns rates for all currencies.
7190

7291
```python
73-
# Get USD to EUR rate for January 1st, 2024
74-
historical_rate = client.get_historical_rate('USD', 'EUR', '2024-01-01')
75-
print(f'USD to EUR on 2024-01-01: {historical_rate}')
92+
# Single currency historical rate
93+
rate = client.get_historical_rate('2024-01-01', from_currency='USD', to_currency='EUR')
94+
95+
# All historical rates for base currency
96+
all_rates = client.get_historical_rate('2024-01-01', from_currency='USD')
97+
98+
# Historical conversion with amount
99+
converted = client.get_historical_rate('2024-01-01', amount=100, from_currency='USD', to_currency='EUR')
76100
```
77101

78-
#### `get_historical_rates(base_currency, date)`
79-
Get all exchange rates for a base currency on a specific historical date.
102+
#### `get_historical_rates(date, amount=1, base_currency='USD', format='json', callback=None)`
103+
Alias for `get_historical_rate` to get all exchange rates for a base currency on a specific date.
80104

81105
```python
82-
# Get all USD rates for January 1st, 2024
83-
rates = client.get_historical_rates('USD', '2024-01-01')
84-
print(f'USD to EUR: {rates["EUR"]}')
85-
print(f'USD to GBP: {rates["GBP"]}')
106+
rates = client.get_historical_rates('2024-01-01', base_currency='USD')
86107
```
87108

88-
#### `convert_historical(amount, from_currency, to_currency, date)`
109+
#### `convert_historical(amount, from_currency, to_currency, date, format='json', callback=None)`
89110
Convert an amount using historical exchange rates for a specific date.
90111

91112
```python
92-
# Convert 100 USD to EUR using rates from January 1st, 2024
93113
converted = client.convert_historical(100, 'USD', 'EUR', '2024-01-01')
94-
print(f'100 USD = {converted} EUR (on 2024-01-01)')
95114
```
96115

97-
#### `get_time_series(from_currency, to_currency, start_date, end_date)`
98-
Get time series exchange rate data for a currency pair over a date range.
116+
#### `get_time_series(start_date, end_date, amount=1, base_currency='USD', currencies=None, format='json', callback=None)`
117+
Get time series exchange rate data over a date range (max 5 years).
118+
119+
```python
120+
# Time series for specific currencies
121+
time_series = client.get_time_series(
122+
'2024-01-01',
123+
'2024-01-07',
124+
base_currency='USD',
125+
currencies=['EUR', 'GBP']
126+
)
127+
128+
# Time series for all currencies
129+
all_series = client.get_time_series('2024-01-01', '2024-01-07', base_currency='USD')
130+
131+
# Time series with amount conversion
132+
converted_series = client.get_time_series(
133+
'2024-01-01',
134+
'2024-01-07',
135+
amount=100,
136+
base_currency='USD',
137+
currencies=['EUR']
138+
)
139+
```
140+
141+
### New Features
142+
143+
#### `get_historical_limits(format='json', callback=None)`
144+
Get information about available historical data limits per currency.
145+
146+
```python
147+
limits = client.get_historical_limits()
148+
print(f"Total currencies with historical data: {limits['total_currencies']}")
149+
150+
for currency, info in limits['currencies'].items():
151+
print(f"{currency}: {info['earliest_date']} to {info['latest_date']}")
152+
```
153+
154+
#### `get_vat_rates(country=None, format='json', callback=None)`
155+
Get VAT rates for all countries or a specific country.
99156

100157
```python
101-
# Get USD to EUR rates for the first week of January 2024
102-
time_series = client.get_time_series('USD', 'EUR', '2024-01-01', '2024-01-07')
103-
for date, rate in time_series.items():
104-
print(f'{date}: {rate}')
158+
# Get all VAT rates
159+
all_vat = client.get_vat_rates()
160+
print(f"Total countries: {all_vat['total_countries']}")
161+
162+
# Get VAT rate for specific country
163+
germany_vat = client.get_vat_rates('DE')
164+
vat_info = germany_vat['vat_data']
165+
print(f"Germany VAT rate: {vat_info['vat_rate']}%")
166+
167+
# Get VAT rates in CSV format
168+
csv_vat = client.get_vat_rates(format='csv')
169+
```
170+
171+
## Output Formats
172+
173+
All methods support multiple output formats:
174+
175+
- `json` (default) - Returns Python dict/list
176+
- `xml` - Returns XML string
177+
- `csv` - Returns CSV string
178+
- `tsv` - Returns TSV string
179+
180+
```python
181+
# JSON (default)
182+
json_data = client.get_rate('USD', 'EUR')
183+
184+
# XML format
185+
xml_data = client.get_rate('USD', 'EUR', format='xml')
186+
187+
# CSV format
188+
csv_data = client.get_rate('USD', 'EUR', format='csv')
189+
190+
# TSV format
191+
tsv_data = client.get_rate('USD', 'EUR', format='tsv')
192+
```
193+
194+
## JSONP Support
195+
196+
For JSON responses, you can specify a JSONP callback function:
197+
198+
```python
199+
jsonp_data = client.get_rate('USD', 'EUR', callback='myCallback')
105200
```
106201

107202
## Complete Example
@@ -110,36 +205,63 @@ for date, rate in time_series.items():
110205
from unirate import UnirateClient
111206

112207
def main():
113-
# Initialize client
114208
client = UnirateClient('your-api-key-here')
115209

116210
try:
117211
print('=== Current Rates ===')
118212

119213
# Current exchange rate
120-
current_rate = client.get_rate('USD', 'EUR')
121-
print(f'Current USD to EUR: {current_rate}')
214+
rate = client.get_rate('USD', 'EUR')
215+
print(f'Current USD to EUR: {rate}')
216+
217+
# All rates for USD
218+
all_rates = client.get_rate('USD')
219+
print(f'EUR: {all_rates["EUR"]}, GBP: {all_rates["GBP"]}')
122220

123221
# Currency conversion
124-
converted = client.convert(1000, 'USD', 'EUR')
222+
converted = client.convert('EUR', 1000, 'USD')
125223
print(f'1000 USD = {converted} EUR')
126224

127225
print('\n=== Historical Data ===')
128226

129-
# Historical rate for specific date
130-
historical_rate = client.get_historical_rate('USD', 'EUR', '2024-01-01')
227+
# Historical rate
228+
historical_rate = client.get_historical_rate('2024-01-01', from_currency='USD', to_currency='EUR')
131229
print(f'USD to EUR on 2024-01-01: {historical_rate}')
132230

133231
# Historical conversion
134232
historical_converted = client.convert_historical(1000, 'USD', 'EUR', '2024-01-01')
135233
print(f'1000 USD = {historical_converted} EUR (on 2024-01-01)')
136234

137235
# Time series data
138-
time_series = client.get_time_series('USD', 'EUR', '2024-01-01', '2024-01-05')
139-
print('USD to EUR time series:')
140-
for date, rate in time_series.items():
141-
print(f' {date}: {rate}')
142-
236+
time_series = client.get_time_series(
237+
'2024-01-01', '2024-01-05',
238+
base_currency='USD',
239+
currencies=['EUR', 'GBP']
240+
)
241+
print('USD time series:')
242+
for date, rates in time_series.items():
243+
print(f' {date}: EUR={rates["EUR"]}, GBP={rates["GBP"]}')
244+
245+
print('\n=== New Features ===')
246+
247+
# Historical limits
248+
limits = client.get_historical_limits()
249+
print(f'Total currencies: {limits["total_currencies"]}')
250+
251+
# VAT rates
252+
vat_rates = client.get_vat_rates()
253+
print(f'Total countries with VAT: {vat_rates["total_countries"]}')
254+
255+
# Germany VAT
256+
germany_vat = client.get_vat_rates('DE')
257+
print(f'Germany VAT: {germany_vat["vat_data"]["vat_rate"]}%')
258+
259+
print('\n=== Format Examples ===')
260+
261+
# CSV format
262+
csv_data = client.get_rate('USD', 'EUR', format='csv')
263+
print('CSV format:', csv_data[:50] + '...')
264+
143265
except Exception as e:
144266
print(f'Error: {e}')
145267

@@ -149,36 +271,79 @@ if __name__ == '__main__':
149271

150272
## Error Handling
151273

152-
The client raises `UnirateError` for API-related errors:
274+
The client provides specific exception types for different error scenarios:
153275

154276
```python
155-
from unirate import UnirateClient, UnirateError
277+
from unirate import UnirateClient
278+
from unirate.exceptions import (
279+
UnirateError,
280+
AuthenticationError,
281+
RateLimitError,
282+
InvalidCurrencyError,
283+
InvalidDateError,
284+
APIError
285+
)
156286

157287
client = UnirateClient('your-api-key')
158288

159289
try:
160290
rate = client.get_rate('USD', 'INVALID')
291+
except AuthenticationError:
292+
print('Invalid API key')
293+
except InvalidCurrencyError:
294+
print('Invalid currency code')
295+
except RateLimitError:
296+
print('Rate limit exceeded')
297+
except InvalidDateError:
298+
print('Invalid date format')
299+
except APIError as e:
300+
print(f'API Error: {e} (Status: {e.status_code})')
161301
except UnirateError as e:
162-
print(f'API Error: {e}')
302+
print(f'General API Error: {e}')
163303
```
164304

305+
## Rate Limits
306+
307+
- **Currency endpoints**: Standard rate limits apply
308+
- **Historical endpoints**: 50 requests per hour
309+
- **VAT endpoints**: 1800 requests per hour
310+
165311
## API Key
166312

167313
Get your free API key from [https://unirateapi.com](https://unirateapi.com). No credit card required!
168314

169315
## Supported Currencies
170316

171-
The API supports 590+ currencies including:
317+
The API supports 170+ currencies including:
172318
- **Traditional currencies**: USD, EUR, GBP, JPY, CAD, AUD, etc.
173319
- **Cryptocurrencies**: BTC, ETH, LTC, and many more
174320

175321
Use `get_supported_currencies()` to get the complete list.
176322

323+
## Historical Data Coverage
324+
325+
Historical data is available from 1999 to 2025, with coverage varying by currency:
326+
- **Major currencies**: Full coverage from 1999-01-01
327+
- **Some currencies**: Limited historical data (use `get_historical_limits()` to check)
328+
177329
## Requirements
178330

179331
- Python 3.7+
180332
- requests
181333

334+
## Changelog
335+
336+
### Version 1.0.0
337+
- **NEW**: VAT rates endpoint (`get_vat_rates()`)
338+
- **NEW**: Historical limits endpoint (`get_historical_limits()`)
339+
- **NEW**: Multiple output formats (JSON, XML, CSV, TSV)
340+
- **NEW**: JSONP callback support
341+
- **BREAKING**: Updated method signatures with optional parameters and defaults
342+
- **BREAKING**: `convert()` method parameter order changed (`to_currency` first)
343+
- **BREAKING**: Historical methods now require `date` as first parameter
344+
- **IMPROVED**: Better error handling with specific exception types
345+
- **IMPROVED**: Enhanced response parsing for new API structure
346+
182347
## License
183348

184349
MIT License

0 commit comments

Comments
 (0)