Skip to content

Commit

Permalink
dry run and other improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
NelsonDane committed Apr 21, 2024
1 parent 11360a8 commit e6e17ed
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 8 deletions.
7 changes: 4 additions & 3 deletions fennel_invest_api/endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,15 +108,16 @@ def stock_order_query(self, symbol, quantity, isin, side, priceRule):
return json.dumps(self.build_graphql_payload(query, variables))

@staticmethod
def build_headers(Bearer, graphql=True):
def build_headers(Bearer=None, accounts_host=False):
headers = {
"accept": "*/*",
"accept-encoding": "gzip",
"authorization": f"Bearer {Bearer}",
"content-type": "application/json",
"host": "fennel-api.prod.fennel.com",
"user-agent": "Dart/3.3 (dart:io)",
}
if not graphql:
if Bearer is not None:
headers["authorization"] = f"Bearer {Bearer}"
if accounts_host:
headers["host"] = "accounts.fennel.com"
return headers
12 changes: 8 additions & 4 deletions fennel_invest_api/fennel.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,18 +114,20 @@ def login(self, email, wait_for_code=True, code=None):
self.Bearer = response["access_token"]
self.Refresh = response["refresh_token"]
self.ID_Token = response["id_token"]
self.refresh_token()
self._save_credentials()
return True

def refresh_token(self):
url = self.endpoints.oauth_url()
headers = self.endpoints.build_headers(accounts_host=True)
payload = {
"grant_type": "refresh_token",
"client_id": self.client_id,
"refresh_token": self.Refresh,
"scope": "openid profile offline_access email",
}
response = self.session.post(url, json=payload)
response = self.session.post(url, json=payload, headers=headers)
if response.status_code != 200:
raise Exception(f"Failed to refresh bearer token: {response.text}")
response = response.json()
Expand All @@ -140,8 +142,8 @@ def _verify_login(self):
self.get_portfolio_summary()
return True
except Exception:
self.refresh_token()
try:
self.refresh_token()
self.get_portfolio_summary()
return True
except Exception:
Expand All @@ -158,7 +160,7 @@ def get_portfolio_summary(self):
raise Exception(
f"Portfolio Request failed with status code {response.status_code}: {response.text}"
)
return response.json()
return response.json()["data"]["portfolio"]

@check_login
def get_stock_holdings(self):
Expand Down Expand Up @@ -189,7 +191,7 @@ def is_market_open(self):
return response["data"]["securityMarketInfo"]["isOpen"]

@check_login
def place_order(self, ticker, quantity, side, price="market"):
def place_order(self, ticker, quantity, side, price="market", dry_run=False):
if side.lower() not in ["buy", "sell"]:
raise Exception("Side must be either 'buy' or 'sell'")
# Check if market is open
Expand All @@ -206,6 +208,8 @@ def place_order(self, ticker, quantity, side, price="market"):
f"Stock Search Request failed with status code {search_response.status_code}: {search_response.text}"
)
search_response = search_response.json()
if dry_run:
return search_response
isin = search_response["data"]["searchSearch"]["searchSecurities"][0]["isin"]
# Place order
query = self.endpoints.stock_order_query(ticker, quantity, isin, side, price)
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

setup(
name="fennel_invest_api",
version="1.0.1",
version="1.0.2",
description="Unofficial Fennel.com Invest API written in Python Requests",
long_description=open("README.md").read(),
long_description_content_type="text/markdown",
Expand Down

0 comments on commit e6e17ed

Please sign in to comment.