Skip to content

Commit 77010d3

Browse files
authored
Merge pull request #42 from MaxxRK/deepsource-transform-9ad9744f
style: format code with Black and isort
2 parents d9d8376 + 65d704e commit 77010d3

1 file changed

Lines changed: 54 additions & 36 deletions

File tree

firstrade/account.py

Lines changed: 54 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
import os
22
import pickle
3-
import pyotp
43

4+
import pyotp
55
import requests
66

77
from firstrade import urls
8-
from firstrade.exceptions import LoginRequestError, LoginResponseError, AccountResponseError
8+
from firstrade.exceptions import (
9+
AccountResponseError,
10+
LoginRequestError,
11+
LoginResponseError,
12+
)
913

1014

1115
class FTSession:
12-
1316
"""
1417
Class creating a session for Firstrade.
1518
@@ -47,7 +50,17 @@ class FTSession:
4750
_handle_mfa():
4851
Handles multi-factor authentication.
4952
"""
50-
def __init__(self, username, password, pin=None, email=None, phone=None, mfa_secret=None, profile_path=None):
53+
54+
def __init__(
55+
self,
56+
username,
57+
password,
58+
pin=None,
59+
email=None,
60+
phone=None,
61+
mfa_secret=None,
62+
profile_path=None,
63+
):
5164
"""
5265
Initializes a new instance of the FTSession class.
5366
@@ -88,7 +101,7 @@ def login(self):
88101
self.session.headers["ftat"] = ftat
89102
response = self.session.get(url="https://api3x.firstrade.com/", timeout=10)
90103
self.session.headers["access-token"] = urls.access_token()
91-
104+
92105
data = {
93106
"username": r"" + self.username,
94107
"password": r"" + self.password,
@@ -99,7 +112,11 @@ def login(self):
99112
data=data,
100113
)
101114
self.login_json = response.json()
102-
if "mfa" not in self.login_json and "ftat" in self.login_json and self.login_json["error"] == "":
115+
if (
116+
"mfa" not in self.login_json
117+
and "ftat" in self.login_json
118+
and self.login_json["error"] == ""
119+
):
103120
self.session.headers["sid"] = self.login_json["sid"]
104121
return False
105122
self.t_token = self.login_json.get("t_token")
@@ -108,10 +125,10 @@ def login(self):
108125
if response.status_code != 200:
109126
raise LoginRequestError(response.status_code)
110127
if self.login_json["error"] != "":
111-
raise LoginResponseError(self.login_json['error'])
128+
raise LoginResponseError(self.login_json["error"])
112129
need_code = self._handle_mfa()
113-
if self.login_json["error"]!= "":
114-
raise LoginResponseError(self.login_json['error'])
130+
if self.login_json["error"] != "":
131+
raise LoginResponseError(self.login_json["error"])
115132
if need_code:
116133
return True
117134
self.session.headers["ftat"] = self.login_json["ftat"]
@@ -126,23 +143,23 @@ def login_two(self, code):
126143
"verificationSid": self.session.headers["sid"],
127144
"remember_for": "30",
128145
"t_token": self.t_token,
129-
}
146+
}
130147
response = self.session.post(urls.verify_pin(), data=data)
131148
self.login_json = response.json()
132-
if self.login_json["error"]!= "":
133-
raise LoginResponseError(self.login_json['error'])
149+
if self.login_json["error"] != "":
150+
raise LoginResponseError(self.login_json["error"])
134151
self.session.headers["ftat"] = self.login_json["ftat"]
135152
self.session.headers["sid"] = self.login_json["sid"]
136153
self._save_cookies()
137-
138-
def delete_cookies(self):
154+
155+
def delete_cookies(self):
139156
"""Deletes the session cookies."""
140157
if self.profile_path is not None:
141158
path = os.path.join(self.profile_path, f"ft_cookies{self.username}.pkl")
142159
else:
143160
path = f"ft_cookies{self.username}.pkl"
144161
os.remove(path)
145-
162+
146163
def _load_cookies(self):
147164
"""
148165
Checks if session cookies were saved.
@@ -152,7 +169,9 @@ def _load_cookies(self):
152169
"""
153170

154171
ftat = ""
155-
directory = os.path.abspath(self.profile_path) if self.profile_path is not None else "."
172+
directory = (
173+
os.path.abspath(self.profile_path) if self.profile_path is not None else "."
174+
)
156175
if not os.path.exists(directory):
157176
os.makedirs(directory)
158177

@@ -162,7 +181,7 @@ def _load_cookies(self):
162181
with open(filepath, "rb") as f:
163182
ftat = pickle.load(f)
164183
return ftat
165-
184+
166185
def _save_cookies(self):
167186
"""Saves session cookies to a file."""
168187
if self.profile_path is not None:
@@ -175,7 +194,7 @@ def _save_cookies(self):
175194
with open(path, "wb") as f:
176195
ftat = self.session.headers.get("ftat")
177196
pickle.dump(ftat, f)
178-
197+
179198
@staticmethod
180199
def _mask_email(email):
181200
"""
@@ -187,12 +206,12 @@ def _mask_email(email):
187206
Returns:
188207
str: The masked email address.
189208
"""
190-
local, domain = email.split('@')
191-
masked_local = local[0] + '*' * 4
192-
domain_name, tld = domain.split('.')
193-
masked_domain = domain_name[0] + '*' * 4
209+
local, domain = email.split("@")
210+
masked_local = local[0] + "*" * 4
211+
domain_name, tld = domain.split(".")
212+
masked_domain = domain_name[0] + "*" * 4
194213
return f"{masked_local}@{masked_domain}.{tld}"
195-
214+
196215
def _handle_mfa(self):
197216
"""
198217
Handles multi-factor authentication.
@@ -207,11 +226,13 @@ def _handle_mfa(self):
207226
data = {
208227
"pin": self.pin,
209228
"remember_for": "30",
210-
"t_token": self.t_token,
229+
"t_token": self.t_token,
211230
}
212231
response = self.session.post(urls.verify_pin(), data=data)
213232
self.login_json = response.json()
214-
elif not self.login_json["mfa"] and (self.email is not None or self.phone is not None):
233+
elif not self.login_json["mfa"] and (
234+
self.email is not None or self.phone is not None
235+
):
215236
for item in self.otp_options:
216237
if item["channel"] == "sms" and self.phone is not None:
217238
if self.phone in item["recipientMask"]:
@@ -223,7 +244,7 @@ def _handle_mfa(self):
223244
if self.email == item["recipientMask"]:
224245
data = {
225246
"recipientId": item["recipientId"],
226-
"t_token": self.t_token,
247+
"t_token": self.t_token,
227248
}
228249
response = self.session.post(urls.request_code(), data=data)
229250
elif self.login_json["mfa"] and self.mfa_secret is not None:
@@ -242,7 +263,6 @@ def _handle_mfa(self):
242263
self.session.headers["sid"] = self.login_json["verificationSid"]
243264
return True
244265

245-
246266
def __getattr__(self, name):
247267
"""
248268
Forwards unknown attribute access to session object.
@@ -279,7 +299,7 @@ def __init__(self, session):
279299
self.all_accounts = response.json()
280300
for item in self.all_accounts["items"]:
281301
self.account_numbers.append(item["account"])
282-
self.account_balances[item['account']] = item["total_value"]
302+
self.account_balances[item["account"]] = item["total_value"]
283303

284304
def get_account_balances(self, account):
285305
"""Gets account balances for a given account.
@@ -290,7 +310,7 @@ def get_account_balances(self, account):
290310
Returns:
291311
dict: Dict of the response from the API.
292312
"""
293-
response = self.session.get(urls.account_balances(account))
313+
response = self.session.get(urls.account_balances(account))
294314
return response.json()
295315

296316
def get_positions(self, account):
@@ -302,10 +322,10 @@ def get_positions(self, account):
302322
Returns:
303323
dict: Dict of the response from the API.
304324
"""
305-
325+
306326
response = self.session.get(urls.account_positions(account))
307327
return response.json()
308-
328+
309329
def get_account_history(self, account):
310330
"""Gets account history for a given account.
311331
@@ -317,7 +337,7 @@ def get_account_history(self, account):
317337
"""
318338
response = self.session.get(urls.account_history(account))
319339
return response.json()
320-
340+
321341
def get_orders(self, account):
322342
"""
323343
Retrieves existing order data for a given account.
@@ -348,7 +368,5 @@ def cancel_order(self, order_id):
348368
"order_id": order_id,
349369
}
350370

351-
response = self.session.post(
352-
url=urls.cancel_order(), data=data
353-
)
354-
return response.json()
371+
response = self.session.post(url=urls.cancel_order(), data=data)
372+
return response.json()

0 commit comments

Comments
 (0)