-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.py
185 lines (145 loc) · 5.62 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# ----------------------------------------
# create fastapi app
# ----------------------------------------
from fastapi import FastAPI
app = FastAPI()
# ----------------------------------------
# setup templates folder
# ----------------------------------------
from fastapi.templating import Jinja2Templates
templates = Jinja2Templates(directory="templates")
# ----------------------------------------
# setup db
# ----------------------------------------
import models
from models import CurPairs
from sqlalchemy.orm import Session
from database import SessionLocal, engine
models.Base.metadata.create_all(bind=engine) #creates tables
# stocks db will appear once you run uvicorn.
# get into sqlite and try `.schema`
# ----------------------------------------
# import custom modules
# ----------------------------------------
from scraper import CurPairScraper
# ----------------------------------------
# dependency injection
# ----------------------------------------
from fastapi import Depends
def get_db():
""" returns db session """
try:
db = SessionLocal()
yield db
finally:
db.close
# ----------------------------------------
# bg tasks
# ----------------------------------------
from fastapi import BackgroundTasks
collect = True
def fetch_real_time():
db = SessionLocal()
global collect
while (collect):
all_pairs_scraper = CurPairScraper("https://finance.yahoo.com/currencies")
for pair_info in all_pairs_scraper.obj_genrator():
print("{} of {} : {}".format(pair_info["row_num"], pair_info["total_rows"], pair_info["name"]))
curPair = models.CurPairs()
curPair.cur_pair = pair_info["name"]
curPair.price = pair_info["price"]
curPair.change = pair_info["change"]
curPair.per_change = pair_info["per_change"]
db.add(curPair)
db.commit()
# ----------------------------------------
# define structure for requests (Pydantic & more)
# ----------------------------------------
from fastapi import Request # for get
from pydantic import BaseModel # for post
class CurPairRequest(BaseModel):
status: str
# ----------------------------------------
# ----------------------------------------
# routes and related funcs
# ----------------------------------------
# ----------------------------------------
@app.get("/")
def api_home(request: Request, db: Session = Depends(get_db)):
"""
home page to display all real time values
"""
# try to get atleast only last 100 from db. Saves overhead; Note we use only last 26
cur_pairs = db.query(CurPairs).order_by(CurPairs.id.desc())
realtime = {
"btcusd": cur_pairs.filter(CurPairs.cur_pair=="BTC/USD").first() ,
"ethusd": cur_pairs.filter(CurPairs.cur_pair=="ETH/USD").first() ,
"eurusd": cur_pairs.filter(CurPairs.cur_pair=="EUR/USD").first() ,
"usdjpy": cur_pairs.filter(CurPairs.cur_pair=="USD/JPY").first() ,
"gbpusd": cur_pairs.filter(CurPairs.cur_pair=="GBP/USD").first() ,
"audusd": cur_pairs.filter(CurPairs.cur_pair=="AUD/USD").first() ,
"nzdusd": cur_pairs.filter(CurPairs.cur_pair=="NZD/USD").first() ,
"eurjpy": cur_pairs.filter(CurPairs.cur_pair=="EUR/JPY").first() ,
"gbpjpy": cur_pairs.filter(CurPairs.cur_pair=="GBP/JPY").first() ,
"eurgbp": cur_pairs.filter(CurPairs.cur_pair=="EUR/GBP").first(),
"eurcad": cur_pairs.filter(CurPairs.cur_pair=="EUR/CAD").first(),
"eursek": cur_pairs.filter(CurPairs.cur_pair=="EUR/SEK").first(),
"eurchf": cur_pairs.filter(CurPairs.cur_pair=="EUR/CHF").first(),
"eurhuf": cur_pairs.filter(CurPairs.cur_pair=="EUR/HUF").first(),
"eurjpy": cur_pairs.filter(CurPairs.cur_pair=="EUR/JPY").first(),
"usdcny": cur_pairs.filter(CurPairs.cur_pair=="USD/CNY").first(),
"usdhkd": cur_pairs.filter(CurPairs.cur_pair=="USD/HKD").first(),
"usdsgd": cur_pairs.filter(CurPairs.cur_pair=="USD/SGD").first(),
"usdinr": cur_pairs.filter(CurPairs.cur_pair=="USD/INR").first(),
"usdmxn": cur_pairs.filter(CurPairs.cur_pair=="USD/MXN").first(),
"usdphp": cur_pairs.filter(CurPairs.cur_pair=="USD/PHP").first(),
"usdidr": cur_pairs.filter(CurPairs.cur_pair=="USDIDR").first(),
"usdthb": cur_pairs.filter(CurPairs.cur_pair=="USD/THB").first(),
"usdmyr": cur_pairs.filter(CurPairs.cur_pair=="USD/MYR").first(),
"usdzar": cur_pairs.filter(CurPairs.cur_pair=="USD/ZAR").first(),
"usdrub": cur_pairs.filter(CurPairs.cur_pair=="USD/RUB").first(),
}
context = {
"request": request,
"realtime": realtime
}
return templates.TemplateResponse("home.html", context)
@app.post("/api/currencypairs")
async def start_fetching(cur_pair_req: CurPairRequest, background_tasks: BackgroundTasks, db: Session = Depends(get_db)):
"""
Starts/stops collecting realtime data and stores in db.
"""
global collect
if cur_pair_req.status == "STOP":
collect = False
if cur_pair_req.status == "START":
collect = True
background_tasks.add_task(fetch_real_time)
"""
curPair = models.CurPairs()
curPair.cur_pair = cur_pair_req.cur_pair
db.add(curPair)
db.commit()
# in correct place
background_tasks.add_task(fetch_real_time, curPair.id)
"""
return {"status": "ok"}
@app.get("/api/history/{pair}")
def generate_history(pair: str, db: Session = Depends(get_db)):
"""
expected input format: "eurusd"
Note: we provide history only since time you click `Start Live Feed`
and not stop it using `Stop Live Feed`.
I dont have live server and big storage :(
"""
l_pair, r_pair = pair.upper()[:3], pair.upper()[3:]
pair = l_pair + "/" + r_pair
# get hist
cur_pair_hist = db.query(CurPairs).filter(CurPairs.cur_pair==pair).all()
context = {
"cur_pair_hist": cur_pair_hist
}
return context #returned as json
# ----------------------------------------
# end
# ----------------------------------------