Skip to content

Commit cc7c19d

Browse files
committed
2 parents 360adc1 + ef2f16f commit cc7c19d

File tree

8 files changed

+826
-361
lines changed

8 files changed

+826
-361
lines changed

OLD_Pipfile.lock

Lines changed: 363 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

OLD_README.md

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
# Exchange Rates API
2+
3+
Exchange rates API is a free service for current and historical foreign exchange rates [published by the European Central Bank](https://www.ecb.europa.eu/stats/policy_and_exchange_rates/euro_reference_exchange_rates/html/index.en.html).
4+
5+
[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy?template=https://github.com/madisvain/exchangeratesapi)
6+
7+
## Usage
8+
9+
#### Lates & specific date rates
10+
Get the latest foreign exchange rates.
11+
12+
```http
13+
GET /latest
14+
```
15+
16+
Get historical rates for any day since 1999.
17+
18+
```http
19+
GET /2018-03-26
20+
```
21+
22+
Rates are quoted against the Euro by default. Quote against a different currency by setting the base parameter in your request.
23+
24+
```http
25+
GET /latest?base=USD
26+
```
27+
28+
Request specific exchange rates by setting the symbols parameter.
29+
30+
```http
31+
GET /latest?symbols=USD,GBP
32+
```
33+
34+
#### Rates history
35+
Get historical rates for a time period.
36+
37+
```http
38+
GET /history?start_at=2018-01-01&end_at=2018-09-01
39+
```
40+
41+
Limit results to specific exchange rates to save bandwidth with the symbols parameter.
42+
43+
```http
44+
GET /history?start_at=2018-01-01&end_at=2018-09-01&symbols=ILS,JPY
45+
```
46+
47+
Quote the historical rates against a different currency.
48+
49+
```http
50+
GET /history?start_at=2018-01-01&end_at=2018-09-01&base=USD
51+
```
52+
53+
#### Client side usage
54+
55+
The primary use case is client side. For instance, with [money.js](https://openexchangerates.github.io/money.js/) in the browser
56+
57+
```js
58+
let demo = () => {
59+
let rate = fx(1).from("GBP").to("USD")
60+
alert("£1 = $" + rate.toFixed(4))
61+
}
62+
63+
fetch('https://api.exchangeratesapi.io/latest')
64+
.then((resp) => resp.json())
65+
.then((data) => fx.rates = data.rates)
66+
.then(demo)
67+
```
68+
69+
## API wrappers
70+
* PHP - [https://github.com/benmajor/ExchangeRatesAPI](https://github.com/benmajor/ExchangeRatesAPI)
71+
* Laravel (PHP) - [https://github.com/ash-jc-allen/laravel-exchange-rates](https://github.com/ash-jc-allen/laravel-exchange-rates)
72+
73+
## Stack
74+
75+
Exchange rates API is built upon Sanic to achieve high throughput. The current setup can asyncronously handle thousands of requests per second.
76+
77+
#### Libraries used
78+
* [Sanic](https://github.com/channelcat/sanic)
79+
* [GINO](https://github.com/fantix/gino)
80+
* [asyncpg](https://github.com/MagicStack/asyncpg)
81+
* [requests](https://github.com/requests/requests)
82+
* [APScheduler](https://github.com/agronholm/apscheduler)
83+
* [uvloop](https://github.com/MagicStack/uvloop)
84+
* [ultraJSON](https://github.com/esnme/ultrajson)
85+
86+
## Deployment
87+
#### Virtualenv
88+
```shell
89+
pipenv shell
90+
```
91+
92+
#### Install packages
93+
```shell
94+
pipenv install
95+
```
96+
97+
#### Load in initial data & Scheduler
98+
The scheduler will keep your database up to date hourly with information from European Central bank. It will download the last 90 days worth of data every hour.
99+
100+
_The reference rates are usually updated around 16:00 CET on every working day, except on TARGET closing days. They are based on a regular daily concertation procedure between central banks across Europe, which normally takes place at 14:15 CET._
101+
102+
On initialization it will check the database. If it's empty all the historic rates will be downloaded and records created in the database.
103+
104+
## Development
105+
```shell
106+
gunicorn exchangerates.app:app --worker-class sanic.worker.GunicornWorker --reload
107+
```
108+
109+
## Contributing
110+
Thanks for your interest in the project! All pull requests are welcome from developers of all skill levels. To get started, simply fork the master branch on GitHub to your personal account and then clone the fork into your development environment.
111+
112+
Madis Väin (madisvain on Github, Twitter) is the original creator of the Exchange Rates API framework.
113+
114+
## License
115+
MIT

Pipfile

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,18 @@ verify_ssl = true
44
name = "pypi"
55

66
[packages]
7-
sanic = "*"
8-
uvloop = "*"
9-
ujson = "*"
10-
requests = "*"
11-
gunicorn = "*"
12-
gino = "*"
13-
apscheduler = "*"
7+
SQLAlchemy = '==1.3.23'
8+
sanic = "==21.6.0"
9+
uvloop = "==0.15.2"
10+
ujson = "==4.0.2"
11+
requests = "==2.25.1"
12+
gunicorn = "==20.1.0"
13+
gino = "==0.8.7"
14+
apscheduler = "==3.7.0"
1415
raven = {extras = ["sanic"]}
15-
blinker = "*"
16-
17-
[dev-packages]
18-
pylint = "<2.0.0"
19-
black = "*"
20-
21-
[requires]
22-
python_version = "3.6"
16+
blinker = "==1.4"
17+
#[dev-packages]
18+
#pylint = "<2.0.0"
19+
#black = "*"
20+
#[requires]
21+
#python_version = "3.6"

Pipfile.lock

Lines changed: 248 additions & 252 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 31 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,115 +1,59 @@
1-
# Exchange Rates API
1+
New, Updated Exchange Rates API
2+
----------------------------------
23

3-
Exchange rates API is a free service for current and historical foreign exchange rates [published by the European Central Bank](https://www.ecb.europa.eu/stats/policy_and_exchange_rates/euro_reference_exchange_rates/html/index.en.html).
4+
So, to get it running on locally and/or Heroku, here are the steps:
45

5-
[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy?template=https://github.com/madisvain/exchangeratesapi)
66

7-
## Usage
7+
1. Clone our fork that has a few patches for version compatibility (Py 3.6, 3.8 and Sanic 2020+) <https://github.com/kickstartcoding/exchangeratesapi/>
88

9-
#### Lates & specific date rates
10-
Get the latest foreign exchange rates.
9+
2. Create new shell locally:
1110

12-
```http
13-
GET /latest
14-
```
11+
pipenv shell
12+
pipenv install
1513

16-
Get historical rates for any day since 1999.
14+
3. Create a new Heroku app:
1715

18-
```http
19-
GET /2018-03-26
20-
```
2116

22-
Rates are quoted against the Euro by default. Quote against a different currency by setting the base parameter in your request.
17+
heroku create
18+
heroku addons:create heroku-postgresql:hobby-dev
19+
# Add the remote DB url to a local .env file:
20+
heroku config:get DATABASE_URL -s > .env
2321

24-
```http
25-
GET /latest?base=USD
26-
```
22+
4. Ensure the `.env` file got created correctly:
2723

28-
Request specific exchange rates by setting the symbols parameter.
2924

30-
```http
31-
GET /latest?symbols=USD,GBP
32-
```
25+
cat .env
26+
# Should see something quite long, starting with: DATABASE_URL=
3327

34-
#### Rates history
35-
Get historical rates for a time period.
3628

37-
```http
38-
GET /history?start_at=2018-01-01&end_at=2018-09-01
39-
```
4029

41-
Limit results to specific exchange rates to save bandwidth with the symbols parameter.
30+
5. Test locally:
4231

43-
```http
44-
GET /history?start_at=2018-01-01&end_at=2018-09-01&symbols=ILS,JPY
45-
```
4632

47-
Quote the historical rates against a different currency.
33+
heroku local
4834

49-
```http
50-
GET /history?start_at=2018-01-01&end_at=2018-09-01&base=USD
51-
```
35+
curl http://localhost:5000/2020-03-05
36+
# or
37+
wget -qO - http://localhost:5000/2020-03-05
5238

53-
#### Client side usage
39+
# output:
40+
# {"base":"EUR","date":"2020-03-03","rates":.....
5441

55-
The primary use case is client side. For instance, with [money.js](https://openexchangerates.github.io/money.js/) in the browser
5642

57-
```js
58-
let demo = () => {
59-
let rate = fx(1).from("GBP").to("USD")
60-
alert("£1 = $" + rate.toFixed(4))
61-
}
43+
6. Launch to heroku:
6244

63-
fetch('https://api.exchangeratesapi.io/latest')
64-
.then((resp) => resp.json())
65-
.then((data) => fx.rates = data.rates)
66-
.then(demo)
67-
```
45+
git push heroku master
6846

69-
## API wrappers
70-
* PHP - [https://github.com/benmajor/ExchangeRatesAPI](https://github.com/benmajor/ExchangeRatesAPI)
71-
* Laravel (PHP) - [https://github.com/ash-jc-allen/laravel-exchange-rates](https://github.com/ash-jc-allen/laravel-exchange-rates)
7247

73-
## Stack
48+
Troubleshooting dependency installation
49+
----------------------------------------
7450

75-
Exchange rates API is built upon Sanic to achieve high throughput. The current setup can asyncronously handle thousands of requests per second.
51+
1. Try also:
7652

77-
#### Libraries used
78-
* [Sanic](https://github.com/channelcat/sanic)
79-
* [GINO](https://github.com/fantix/gino)
80-
* [asyncpg](https://github.com/MagicStack/asyncpg)
81-
* [requests](https://github.com/requests/requests)
82-
* [APScheduler](https://github.com/agronholm/apscheduler)
83-
* [uvloop](https://github.com/MagicStack/uvloop)
84-
* [ultraJSON](https://github.com/esnme/ultrajson)
53+
pipenv install --skip-lock
54+
pip install gino==0.8.7 # Ensure older version of Gino ORM is installed
8555

86-
## Deployment
87-
#### Virtualenv
88-
```shell
89-
pipenv shell
90-
```
56+
2. Try instead of "pipenv install" (in fresh venv):
9157

92-
#### Install packages
93-
```shell
94-
pipenv install
95-
```
58+
pip install -r frozen_requirements.txt
9659

97-
#### Load in initial data & Scheduler
98-
The scheduler will keep your database up to date hourly with information from European Central bank. It will download the last 90 days worth of data every hour.
99-
100-
_The reference rates are usually updated around 16:00 CET on every working day, except on TARGET closing days. They are based on a regular daily concertation procedure between central banks across Europe, which normally takes place at 14:15 CET._
101-
102-
On initialization it will check the database. If it's empty all the historic rates will be downloaded and records created in the database.
103-
104-
## Development
105-
```shell
106-
gunicorn exchangerates.app:app --worker-class sanic.worker.GunicornWorker --reload
107-
```
108-
109-
## Contributing
110-
Thanks for your interest in the project! All pull requests are welcome from developers of all skill levels. To get started, simply fork the master branch on GitHub to your personal account and then clone the fork into your development environment.
111-
112-
Madis Väin (madisvain on Github, Twitter) is the original creator of the Exchange Rates API framework.
113-
114-
## License
115-
MIT

exchangerates/app.py

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,26 +10,28 @@
1010
from apscheduler.schedulers.asyncio import AsyncIOScheduler
1111
from gino.dialects.asyncpg import JSONB
1212
from raven.contrib.sanic import Sentry
13+
from exchangerates.utils import Gino, cors, parse_database_url, patch_request
1314
from sanic import Sanic
1415
from sanic.response import file, html, json, redirect
1516

16-
from exchangerates.utils import Gino, cors, parse_database_url
1717

1818
HISTORIC_RATES_URL = "https://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist.xml"
1919
LAST_90_DAYS_RATES_URL = (
2020
"https://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist-90d.xml"
2121
)
2222

2323

24-
app = Sanic()
24+
app = Sanic(name='xchangeapi')
2525
app.config.update(
2626
parse_database_url(
27-
url=getenv("DATABASE_URL", "postgresql://localhost/exchangerates")
27+
url=getenv("DATABASE_URL")
2828
)
2929
)
3030

3131
# Database
32-
db = Gino(app)
32+
#app.config.DB_USE_CONNECTION_FOR_REQUEST = False
33+
db = Gino()
34+
db.init_app(app)
3335

3436
# Sentry
3537
sentry = Sentry(app)
@@ -69,6 +71,8 @@ async def update_rates(historic=False):
6971

7072
@app.listener("before_server_start")
7173
async def initialize_scheduler(app, loop):
74+
await db.set_bind(getenv("DATABASE_URL")) # hack: forced to rebind here
75+
7276
# Check that tables exist
7377
await db.gino.create_all()
7478

@@ -133,6 +137,9 @@ async def exchange_rates(request, date=None):
133137

134138
# Base
135139
base = "EUR"
140+
141+
request = patch_request(request) # HACK: Sanic 0.8 -> 2020 upgrade
142+
136143
if "base" in request.raw_args and request.raw_args["base"] != "EUR":
137144
base = request.raw_args["base"]
138145

@@ -176,6 +183,7 @@ async def exchange_rates(request, date=None):
176183
@app.route("/api/history", methods=["GET", "HEAD"])
177184
@cors()
178185
async def exchange_rates(request):
186+
request = patch_request(request) # HACK: Sanic 0.8 -> 2020 upgrade
179187
if request.method == "HEAD":
180188
return json("")
181189

@@ -250,9 +258,9 @@ async def exchange_rates(request):
250258

251259

252260
# api.ExchangeratesAPI.io
253-
@app.route("/", methods=["GET"], host="api.exchangeratesapi.io")
254-
async def index(request):
255-
return json({"details": "https://exchangeratesapi.io"}, escape_forward_slashes=False)
261+
#@app.route("/", methods=["GET"], host="api.exchangeratesapi.io")
262+
#async def index(request):
263+
# return json({"details": "https://exchangeratesapi.io"}, escape_forward_slashes=False)
256264

257265

258266
# Website

0 commit comments

Comments
 (0)