Skip to content

Commit 14e5a9c

Browse files
committed
Rethink API model and method naming
- carefully consider the true meaning of api endpoints, despite their naming - rename models and method names for better meaning - rename and explain all the clients! - fix renames in tests, marimo notebook, readme - upgrade marimo
1 parent 0604f91 commit 14e5a9c

5 files changed

Lines changed: 372 additions & 354 deletions

File tree

README.md

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,15 @@ Create a script named `balances.py`:
2929
```python
3030
from getpass import getpass
3131

32-
from ubank import Api, Passkey
32+
from ubank import Client, Passkey
3333

3434
# Load passkey from file.
3535
with open("passkey.txt", "rb") as f:
3636
passkey = Passkey.load(f, password=getpass("Enter ubank password: "))
3737

3838
# Print account balances.
39-
with Api(passkey) as api:
40-
for account in api.get_accounts().linkedBanks[0].accounts:
39+
with Client(passkey) as client:
40+
for account in client.get_linked_banks().linkedBanks[0].accounts:
4141
print(
4242
f"{account.label} ({account.type}): {account.balance.available} {account.balance.currency}"
4343
)
@@ -58,7 +58,7 @@ Savings account (SAVINGS): 1577.17 AUD
5858
- [Getting started](#getting-started)
5959
- [Contents](#contents)
6060
- [ubank CLI](#ubank-cli)
61-
- [ubank API](#ubank-api)
61+
- [ubank API client](#ubank-api-client)
6262
- [Example web application](#example-web-application)
6363
- [How to set up a development environment](#how-to-set-up-a-development-environment)
6464
- [How to test](#how-to-test)
@@ -90,32 +90,32 @@ You will be asked for your ubank password and secret code interactively. The pas
9090
```
9191

9292

93-
## ubank API
93+
## ubank API client
9494

95-
The `ubank.Api` class provides a number of methods for accessing ubank's API:
95+
Create an instance of `ubank.Client` to access ubank's API:
9696

9797
```python
9898
from datetime import date
9999
from getpass import getpass
100100

101-
from ubank import Api, Passkey, TransactionsSearchBody
101+
from ubank import Client, Filter, Passkey
102102

103103
with open("passkey.txt", "rb") as f:
104104
passkey = Passkey.load(f, password=getpass("Enter ubank password: "))
105105

106-
with Api(passkey) as api:
107-
api.post_accounts_transactions_search(
108-
body=TransactionsSearchBody(fromDate=date(2025, 1, 1), toDate=date(2025, 2, 1))
106+
with Client(passkey) as client:
107+
client.summarise_transactions(
108+
body=Filter(fromDate=date(2025, 1, 1), toDate=date(2025, 2, 1))
109109
)
110-
bank = api.get_accounts().linkedBanks[0]
111-
api.get_account_transactions(
110+
bank = client.get_linked_banks().linkedBanks[0]
111+
client.search_account_transactions(
112112
account_id=bank.accounts[0].id,
113113
bank_id=bank.bankId,
114-
customerId=api.get_customer_details().customerId,
114+
customerId=client.get_customer_details().customerId,
115115
)
116-
api.get_cards()
117-
api.get_devices(deviceUuid=passkey.device_id)
118-
api.get_contacts()
116+
client.get_cards()
117+
client.get_devices(deviceUuid=passkey.device_id)
118+
client.get_contacts()
119119
```
120120

121121

notebook.py

Lines changed: 13 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
@app.cell
1818
def _():
1919
import marimo as mo
20-
2120
return (mo,)
2221

2322

@@ -145,7 +144,7 @@ def _(
145144
password,
146145
uploaded_passkey,
147146
):
148-
from ubank import Api
147+
from ubank import Client
149148

150149
if create_client.value:
151150
try:
@@ -155,8 +154,8 @@ def _(
155154
io.BytesIO(uploaded_passkey.contents() or new_passkey_file.getvalue()),
156155
password.value,
157156
)
158-
api = Api(passkey)
159-
devices = api.get_devices(deviceUuid=passkey.device_id)
157+
client = Client(passkey)
158+
devices = client.get_devices(deviceUuid=passkey.device_id)
160159
mo.output.append(
161160
mo.md(
162161
f"""
@@ -172,7 +171,7 @@ def _(
172171
)
173172
except InvalidToken:
174173
pass
175-
return Api, api, devices, passkey
174+
return Client, client, devices, passkey
176175

177176

178177
@app.cell
@@ -190,24 +189,24 @@ def _(mo):
190189

191190

192191
@app.cell
193-
def _(api, get_balances, mo):
192+
def _(client, get_balances, mo):
194193
if get_balances.value:
195194
with mo.status.spinner():
196-
accounts_response = api.get_accounts()
195+
bank = client.get_linked_banks().linkedBanks[0]
197196
mo.output.append(
198197
mo.tree(
199198
[
200199
account.model_dump(include={"number", "label", "type", "balance"})
201-
for account in accounts_response.linkedBanks[0].accounts
200+
for account in bank.accounts
202201
]
203202
)
204203
)
205-
return (accounts_response,)
204+
return (bank,)
206205

207206

208207
@app.cell
209208
def _(mo):
210-
from ubank import TransactionsSearchBody
209+
from ubank import Filter
211210

212211
search_transactions = mo.ui.run_button(label="Search")
213212
from_date = mo.ui.date()
@@ -223,28 +222,15 @@ def _(mo):
223222
Limit the number of results to {limit}.
224223
"""
225224
)
226-
return (
227-
TransactionsSearchBody,
228-
from_date,
229-
limit,
230-
search_transactions,
231-
to_date,
232-
)
225+
return Filter, from_date, limit, search_transactions, to_date
233226

234227

235228
@app.cell
236-
def _(
237-
TransactionsSearchBody,
238-
api,
239-
from_date,
240-
mo,
241-
search_transactions,
242-
to_date,
243-
):
229+
def _(Filter, client, from_date, mo, search_transactions, to_date):
244230
if search_transactions.value:
245231
with mo.status.spinner():
246-
search_response = api.post_accounts_transactions_search(
247-
body=TransactionsSearchBody(fromDate=from_date.value, toDate=to_date.value)
232+
search_response = client.summarise_transactions(
233+
body=Filter(fromDate=from_date.value, toDate=to_date.value)
248234
)
249235
mo.output.append(
250236
mo.ui.table(

tests/test_ubank.py

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
from httpx import HTTPStatusError
66

77
from ubank import (
8-
Api,
8+
Client,
9+
Filter,
910
Passkey,
1011
SoftWebauthnDevice,
11-
TransactionsSearchBody,
1212
__version__,
1313
add_passkey,
1414
int8array_to_bytes,
@@ -155,8 +155,8 @@ def test_add_passkey_bad_username():
155155
assert "Username invalid" in e.__notes__[0]
156156

157157

158-
def test_api():
159-
"""Tests declared API methods using passkey loaded from passkey.txt."""
158+
def test_client():
159+
"""Tests declared API endpoint methods using passkey loaded from passkey.txt."""
160160
# Skip test if hard-coded passkey file is not available.
161161
try:
162162
with open("passkey.txt", "rb") as f:
@@ -165,39 +165,33 @@ def test_api():
165165
pytest.skip(str(e))
166166

167167
# Authenticate to ubank with passkey.
168-
with Api(passkey) as api:
168+
with Client(passkey) as client:
169169
assert (
170-
api.client.get("accounts").json()["linkedBanks"][0]["accounts"][0][
170+
client.client.get("accounts").json()["linkedBanks"][0]["accounts"][0][
171171
"balance"
172172
]["currency"]
173173
== "AUD"
174174
)
175175

176-
customer = api.get_customer_details()
176+
customer = client.get_customer_details()
177177
assert customer.addresses[0].addressFormat == "AUS"
178-
accounts = api.get_accounts()
179-
assert accounts.linkedBanks[0].accounts[0].balance.currency == "AUD"
180-
assert (
181-
api.get_accounts_summary().linkedBanks[0].accounts[0].balance.currency
182-
== "AUD"
183-
)
184-
assert api.post_accounts_transactions_search(
185-
body=TransactionsSearchBody(
186-
fromDate=date(2024, 1, 1), toDate=date(2025, 1, 1), limit=100
187-
)
178+
banks = client.get_linked_banks().linkedBanks
179+
assert banks[0].accounts[0].balance.currency == "AUD"
180+
assert client.summarise_transactions(
181+
body=Filter(fromDate=date(2024, 1, 1), toDate=date(2025, 1, 1), limit=100)
188182
)
189-
for account in accounts.linkedBanks[0].accounts:
190-
assert api.get_account_transactions(
183+
for account in banks[0].accounts:
184+
assert client.search_account_transactions(
191185
account_id=account.id,
192-
bank_id=accounts.linkedBanks[0].bankId,
186+
bank_id=banks[0].bankId,
193187
customerId=customer.customerId,
194188
)
195-
assert api.get_cards()
189+
assert client.get_cards()
196190
# Name of a device should match this passkey.
197191
assert [
198192
device
199-
for device in api.get_devices(deviceUuid=passkey.device_id)
193+
for device in client.get_devices(deviceUuid=passkey.device_id)
200194
if device.deviceName == passkey.name
201195
]
202-
assert api.delete_device(device_id="test-2f9ae784c84d")
203-
assert api.get_contacts()
196+
assert client.delete_device(device_id="test-2f9ae784c84d")
197+
assert client.get_contacts()

0 commit comments

Comments
 (0)