Skip to content

Commit 3b42f5c

Browse files
authored
Merge pull request #16 from Patch-Code-Prosperity/mod
module
2 parents 7ad3d4d + 6d9f444 commit 3b42f5c

File tree

16 files changed

+925
-218
lines changed

16 files changed

+925
-218
lines changed

.github/workflows/pylint.yml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@ jobs:
77
runs-on: ubuntu-latest
88
strategy:
99
matrix:
10-
python-version: ["3.8", "3.9", "3.10"]
10+
python-version: ["3.10", "3.12"]
1111
steps:
1212
- uses: actions/checkout@v4
13+
with:
14+
fetch-depth: 0
1315
- name: Set up Python ${{ matrix.python-version }}
1416
uses: actions/setup-python@v3
1517
with:
@@ -18,6 +20,10 @@ jobs:
1820
run: |
1921
python -m pip install --upgrade pip
2022
pip install pylint
23+
pip install setuptools
24+
pip install .
2125
- name: Analysing the code with pylint
26+
env:
27+
PYTHONIOENCODING: utf-8
2228
run: |
23-
pylint $(git ls-files '*.py')
29+
pylint --exit-zero --rcfile=.pylintrc $(git ls-files '*.py')

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,7 @@ __pycache__/
44
token_data.json
55
custom/
66
tmp/*
7+
build/
8+
pythonic_schwab_api.egg-info/
9+
.vscode
10+
dist/

.pylintrc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
[MASTER]
2+
# Specify the maximum line length
3+
max-line-length=160
4+
5+
[BASIC]
6+
good-names=f, e
7+
8+
[REPORTS]
9+
# Set the verbosity of the pylint output
10+
output-format=colorized
11+
12+
[CLASSES]
13+
# Disable too-few-public-methods check
14+
disable=too-few-public-methods
15+
16+
[MESSAGES CONTROL]
17+
# Adjust severity of certain messages
18+
disable=R0902,W0719,R0902,W0718,R0913

pythonic_schwab_api/accounts.py

Lines changed: 78 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,109 @@
1+
"""
2+
This module provides the Accounts class for interacting with account-related
3+
endpoints of the Schwab API.
4+
5+
Classes:
6+
- Accounts: A class to handle operations related to user accounts, such as
7+
retrieving account numbers, detailed account information, and transactions.
8+
9+
Usage example:
10+
client = SchwabClient(api_key, secret_key)
11+
accounts = Accounts(client)
12+
account_numbers = accounts.get_account_numbers()
13+
all_accounts = accounts.get_all_accounts(fields=['balance', 'status'])
14+
specific_account = accounts.get_account(account_hash='abc123', fields=['balance'])
15+
transactions = accounts.get_account_transactions(
16+
account_hash='abc123',
17+
start_date=datetime.datetime(2023, 1, 1),
18+
end_date=datetime.datetime(2023, 1, 31)
19+
)
20+
"""
121
import datetime
222
import logging
23+
from requests.exceptions import RequestException, HTTPError, Timeout
324

425

526
class Accounts:
27+
"""
28+
A class to handle operations related to user accounts, such as retrieving
29+
account numbers, detailed account information, and transactions.
30+
31+
Methods:
32+
- get_account_numbers: Retrieve account numbers associated with the user's profile.
33+
- get_all_accounts: Retrieve detailed information for all linked accounts.
34+
- get_account: Retrieve detailed information for a specific account using its hash.
35+
- get_account_transactions: Retrieve transactions for a specific account
36+
over a specified date range.
37+
"""
638
def __init__(self, client):
39+
"""
40+
Initialize the Accounts class.
41+
42+
:param client: The client instance used to make API requests.
43+
"""
744
self.client = client
845
self.logger = logging.getLogger(__name__)
946
self.base_url = client.config.ACCOUNTS_BASE_URL
1047

1148
def get_account_numbers(self):
12-
"""Retrieve account numbers associated with the user's profile."""
49+
"""
50+
Retrieve account numbers associated with the user's profile.
51+
52+
:return: A list of account numbers or None if the request fails.
53+
"""
1354
try:
1455
print(f'{self.base_url}/accountNumbers')
1556
return self.client.make_request(f'{self.base_url}/accountNumbers')
16-
except Exception as e:
17-
self.logger.error(f"Failed to get account numbers: {e}")
57+
except (RequestException, HTTPError, ConnectionError, Timeout) as e:
58+
self.logger.error("Failed to get account numbers: %s", e)
1859
return None
1960

2061
def get_all_accounts(self, fields=None):
21-
"""Retrieve detailed information for all linked accounts, optionally filtering the fields."""
62+
"""
63+
Retrieve detailed information for all linked accounts,
64+
optionally filtering the fields.
65+
66+
:param fields: Optional; A list of fields to filter the account information.
67+
:return: A list of account details or None if the request fails.
68+
"""
2269
params = {'fields': fields} if fields else {}
2370
try:
2471
return self.client.make_request(f'{self.base_url}', params=params)
25-
except Exception as e:
26-
self.logger.error(f"Failed to get all accounts: {e}")
72+
except (RequestException, HTTPError, ConnectionError, Timeout) as e:
73+
self.logger.error("Failed to get all accounts: %s", e)
2774
return None
2875

2976
def get_account(self, account_hash, fields=None):
30-
"""Retrieve detailed information for a specific account using its hash."""
77+
"""
78+
Retrieve detailed information for a specific account using its hash.
79+
80+
:param account_hash: The hash of the account to retrieve.
81+
:param fields: Optional; A list of fields to filter the account information.
82+
:return: Account details or None if the request fails.
83+
"""
3184
if not account_hash:
3285
self.logger.error("Account hash is required for getting account details")
3386
return None
3487
params = {'fields': fields} if fields else {}
3588
try:
3689
return self.client.make_request(f'{self.base_url}/{account_hash}', params=params)
37-
except Exception as e:
38-
self.logger.error(f"Failed to get account {account_hash}: {e}")
90+
except (RequestException, HTTPError, ConnectionError, Timeout) as e:
91+
self.logger.error("Failed to get account %s: %s", account_hash, e)
3992
return None
4093

4194
def get_account_transactions(self, account_hash, start_date, end_date, types=None, symbol=None):
42-
"""Retrieve transactions for a specific account over a specified date range."""
43-
if not (isinstance(start_date, datetime.datetime) and isinstance(end_date, datetime.datetime)):
95+
"""
96+
Retrieve transactions for a specific account over a specified date range.
97+
98+
:param account_hash: The hash of the account to retrieve transactions for.
99+
:param start_date: The start date for the transaction retrieval (datetime object).
100+
:param end_date: The end date for the transaction retrieval (datetime object).
101+
:param types: Optional; A list of transaction types to filter.
102+
:param symbol: Optional; A specific symbol to filter transactions.
103+
:return: A list of transactions or None if the request fails.
104+
"""
105+
if not (isinstance(start_date, datetime.datetime) and
106+
isinstance(end_date, datetime.datetime)):
44107
self.logger.error("Invalid date format. Dates must be datetime objects")
45108
return None
46109
params = {
@@ -50,7 +113,8 @@ def get_account_transactions(self, account_hash, start_date, end_date, types=Non
50113
'symbol': symbol
51114
}
52115
try:
53-
return self.client.make_request(f'{self.base_url}/{account_hash}/transactions', params=params)
54-
except Exception as e:
55-
self.logger.error(f"Failed to get transactions for account {account_hash}: {e}")
116+
return self.client.make_request(f'{self.base_url}/{account_hash}/transactions',
117+
params=params)
118+
except (RequestException, HTTPError, ConnectionError, Timeout) as e:
119+
self.logger.error("Failed to get transactions for account %s: %s", account_hash, e)
56120
return None

0 commit comments

Comments
 (0)