Monzo-API 1.2.6__tar.gz → 1.2.7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. {monzo_api-1.2.6 → monzo_api-1.2.7/Monzo_API.egg-info}/PKG-INFO +1 -1
  2. {monzo_api-1.2.6/Monzo_API.egg-info → monzo_api-1.2.7}/PKG-INFO +1 -1
  3. {monzo_api-1.2.6 → monzo_api-1.2.7}/monzo/authentication.py +16 -14
  4. {monzo_api-1.2.6 → monzo_api-1.2.7}/monzo/endpoints/account.py +2 -2
  5. {monzo_api-1.2.6 → monzo_api-1.2.7}/monzo/endpoints/balance.py +1 -1
  6. {monzo_api-1.2.6 → monzo_api-1.2.7}/monzo/endpoints/feed_item.py +1 -1
  7. {monzo_api-1.2.6 → monzo_api-1.2.7}/monzo/endpoints/pot.py +9 -9
  8. {monzo_api-1.2.6 → monzo_api-1.2.7}/monzo/endpoints/receipt.py +11 -11
  9. {monzo_api-1.2.6 → monzo_api-1.2.7}/monzo/helpers.py +2 -2
  10. {monzo_api-1.2.6 → monzo_api-1.2.7}/pyproject.toml +1 -9
  11. {monzo_api-1.2.6 → monzo_api-1.2.7}/tests/test_endpoints.py +9 -5
  12. {monzo_api-1.2.6 → monzo_api-1.2.7}/tests/test_httpio_errors.py +3 -4
  13. {monzo_api-1.2.6 → monzo_api-1.2.7}/LICENSE +0 -0
  14. {monzo_api-1.2.6 → monzo_api-1.2.7}/Monzo_API.egg-info/SOURCES.txt +0 -0
  15. {monzo_api-1.2.6 → monzo_api-1.2.7}/Monzo_API.egg-info/dependency_links.txt +0 -0
  16. {monzo_api-1.2.6 → monzo_api-1.2.7}/Monzo_API.egg-info/top_level.txt +0 -0
  17. {monzo_api-1.2.6 → monzo_api-1.2.7}/README.rst +0 -0
  18. {monzo_api-1.2.6 → monzo_api-1.2.7}/monzo/__init__.py +0 -0
  19. {monzo_api-1.2.6 → monzo_api-1.2.7}/monzo/endpoints/__init__.py +0 -0
  20. {monzo_api-1.2.6 → monzo_api-1.2.7}/monzo/endpoints/attachment.py +3 -3
  21. {monzo_api-1.2.6 → monzo_api-1.2.7}/monzo/endpoints/monzo.py +0 -0
  22. {monzo_api-1.2.6 → monzo_api-1.2.7}/monzo/endpoints/transaction.py +0 -0
  23. {monzo_api-1.2.6 → monzo_api-1.2.7}/monzo/endpoints/webhooks.py +0 -0
  24. {monzo_api-1.2.6 → monzo_api-1.2.7}/monzo/endpoints/whoami.py +0 -0
  25. {monzo_api-1.2.6 → monzo_api-1.2.7}/monzo/exceptions.py +0 -0
  26. {monzo_api-1.2.6 → monzo_api-1.2.7}/monzo/handlers/__init__.py +0 -0
  27. {monzo_api-1.2.6 → monzo_api-1.2.7}/monzo/handlers/filesystem.py +0 -0
  28. {monzo_api-1.2.6 → monzo_api-1.2.7}/monzo/handlers/storage.py +0 -0
  29. {monzo_api-1.2.6 → monzo_api-1.2.7}/monzo/httpio.py +0 -0
  30. {monzo_api-1.2.6 → monzo_api-1.2.7}/setup.cfg +0 -0
  31. {monzo_api-1.2.6 → monzo_api-1.2.7}/tests/test_authentication.py +0 -0
  32. {monzo_api-1.2.6 → monzo_api-1.2.7}/tests/test_payload.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: Monzo-API
3
- Version: 1.2.6
3
+ Version: 1.2.7
4
4
  Summary: Package to interact with the API provided by Monzo bank
5
5
  Author-email: Peter McDonald <git@petermcdonald.co.uk>
6
6
  License: MIT License
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: Monzo-API
3
- Version: 1.2.6
3
+ Version: 1.2.7
4
4
  Summary: Package to interact with the API provided by Monzo bank
5
5
  Author-email: Peter McDonald <git@petermcdonald.co.uk>
6
6
  License: MIT License
@@ -14,6 +14,8 @@ from monzo.httpio import DEFAULT_TIMEOUT, REQUEST_RESPONSE_TYPE, HttpIO
14
14
  MONZO_AUTH_URL = "https://auth.monzo.com"
15
15
  MONZO_API_URL = "https://api.monzo.com"
16
16
 
17
+ logger: logging.Logger = logging.getLogger(name=__name__)
18
+
17
19
 
18
20
  class Authentication:
19
21
  """
@@ -72,12 +74,12 @@ class Authentication:
72
74
  Raises:
73
75
  MonzoAuthenticationError On missing authorization token or mismatching state tokens
74
76
  """
75
- logging.debug("Attempting authentication")
77
+ logger.debug(msg="Attempting authentication")
76
78
  if not authorization_token:
77
- logging.debug("Authentication - Missing token")
79
+ logger.debug(msg="Authentication - Missing token")
78
80
  raise MonzoAuthenticationError("Code missing from response")
79
81
  if state_token != self.state_token:
80
- logging.debug("Authentication - state token mismatch")
82
+ logger.debug(msg="Authentication - state token mismatch")
81
83
  raise MonzoAuthenticationError("State tokens do not match")
82
84
  tmp_file_name = "monzo"
83
85
  tmp_file_path = PurePath(gettempdir(), tmp_file_name)
@@ -86,7 +88,7 @@ class Authentication:
86
88
 
87
89
  def logout(self) -> None:
88
90
  """Invalidate the access token."""
89
- logging.debug("Invalidating token")
91
+ logger.debug(msg="Invalidating token")
90
92
  self.make_request(path="/oauth2/logout", method="post")
91
93
 
92
94
  def make_request(
@@ -140,9 +142,9 @@ class Authentication:
140
142
  Raises:
141
143
  MonzoAuthenticationError: On lack of refresh token or failure to refresh a token
142
144
  """
143
- logging.debug("Fetching new token")
145
+ logger.debug(msg="Fetching new token")
144
146
  if not self.refresh_token:
145
- logging.debug("Unable to fetch new token without a refresh token")
147
+ logger.debug(msg="Unable to fetch new token without a refresh token")
146
148
  raise MonzoAuthenticationError("Unable to refresh without a refresh token")
147
149
  data = {
148
150
  "grant_type": "refresh_token",
@@ -153,9 +155,9 @@ class Authentication:
153
155
  conn = HttpIO(MONZO_API_URL)
154
156
  try:
155
157
  res = conn.post(path="/oauth2/token", data=data)
156
- self._populate_tokens(res)
158
+ self._populate_tokens(response=res)
157
159
  except MonzoError as exc:
158
- logging.debug("Failed to fetch new token")
160
+ logger.debug(msg="Failed to fetch new token")
159
161
  raise MonzoAuthenticationError("Could not refresh the access token") from exc
160
162
 
161
163
  @property
@@ -240,7 +242,7 @@ class Authentication:
240
242
  Raises:
241
243
  MonzoAuthenticationError On failure to create a token
242
244
  """
243
- logging.debug("Authentication - swapping authorization token for an access token")
245
+ logger.debug(msg="Authentication - swapping authorization token for an access token")
244
246
  data = {
245
247
  "grant_type": "authorization_code",
246
248
  "client_id": self._client_id,
@@ -249,10 +251,10 @@ class Authentication:
249
251
  "code": authorization_token,
250
252
  }
251
253
  try:
252
- res = self.make_request("/oauth2/token", authenticated=False, method="post", data=data)
253
- self._populate_tokens(res)
254
+ res = self.make_request(path="/oauth2/token", authenticated=False, method="post", data=data)
255
+ self._populate_tokens(response=res)
254
256
  except MonzoError as exc:
255
- logging.debug(f"Could not fetch access token {exc}")
257
+ logger.debug(msg=f"Could not fetch access token {exc}")
256
258
  raise MonzoAuthenticationError("Could not fetch a valid access token") from exc
257
259
 
258
260
  def _populate_tokens(self, response: REQUEST_RESPONSE_TYPE) -> None:
@@ -262,7 +264,7 @@ class Authentication:
262
264
  Args:
263
265
  response: Response from an auth request.
264
266
  """
265
- logging.debug("Populating tokens")
267
+ logger.debug(msg="Populating tokens")
266
268
  self._access_token = response["data"]["access_token"]
267
269
  self.access_token_expiry = response["data"]["expires_in"]
268
270
  self._refresh_token = ""
@@ -285,5 +287,5 @@ class Authentication:
285
287
  Args:
286
288
  handler: Credential handler implementing Storage
287
289
  """
288
- logging.debug("Registered a new callback handler")
290
+ logger.debug(msg="Registered a new callback handler")
289
291
  self._handlers.append(handler)
@@ -35,10 +35,10 @@ class Account(Monzo):
35
35
  "_account_id",
36
36
  "_auth",
37
37
  "_balance",
38
+ "_closed",
38
39
  "_created",
39
40
  "_description",
40
41
  "_has_balance",
41
- "_closed",
42
42
  ]
43
43
 
44
44
  def __init__(
@@ -88,7 +88,7 @@ class Account(Monzo):
88
88
  return next(
89
89
  (
90
90
  MONZO_ACCOUNT_TYPES[account_type]
91
- for account_type in MONZO_ACCOUNT_TYPES.keys()
91
+ for account_type in MONZO_ACCOUNT_TYPES
92
92
  if self.description.lower().startswith(account_type)
93
93
  ),
94
94
  "UNKNOWN",
@@ -14,7 +14,7 @@ class Balance(Monzo):
14
14
  along with the balance property. Otherwise, you can fetch an account balance using the fetch class method.
15
15
  """
16
16
 
17
- __slots__ = ["_balance", "_total_balance", "_currency", "_spend_today"]
17
+ __slots__ = ("_balance", "_currency", "_spend_today", "_total_balance")
18
18
 
19
19
  def __init__(
20
20
  self,
@@ -98,7 +98,7 @@ class FeedItem(Monzo):
98
98
  }
99
99
  if self._url:
100
100
  data["url"] = self._url
101
- for parameter in parameters.keys():
101
+ for parameter in parameters:
102
102
  data[f"params[{parameter}]"] = parameters[parameter]
103
103
  self._monzo_auth.make_request(path="/feed", method="POST", data=data)
104
104
 
@@ -19,22 +19,22 @@ class Pot(Monzo):
19
19
  Class provides methods to fetch pots as well as depositing and withdrawing from pots.
20
20
  """
21
21
 
22
- __slots__ = [
23
- "_pot_id",
24
- "_name",
25
- "_style",
22
+ __slots__ = (
26
23
  "_balance",
27
- "_currency",
28
24
  "_created",
29
- "_updated",
25
+ "_currency",
30
26
  "_deleted",
31
27
  "_goal_amount",
32
28
  "_has_round_up",
33
- "_round_up_multiplier",
34
- "_pot_type",
35
29
  "_locked",
36
30
  "_locked_until",
37
- ]
31
+ "_name",
32
+ "_pot_id",
33
+ "_pot_type",
34
+ "_round_up_multiplier",
35
+ "_style",
36
+ "_updated",
37
+ )
38
38
 
39
39
  def __init__(
40
40
  self,
@@ -103,14 +103,14 @@ class Receipt(Monzo):
103
103
  """
104
104
 
105
105
  __slots__ = (
106
- "_external_id",
107
- "_transaction_id",
108
- "_total",
109
106
  "_currency",
107
+ "_external_id",
110
108
  "_items",
111
- "_taxes",
112
- "_payments",
113
109
  "_merchant",
110
+ "_payments",
111
+ "_taxes",
112
+ "_total",
113
+ "_transaction_id",
114
114
  )
115
115
 
116
116
  def __init__(
@@ -363,9 +363,9 @@ class Receipt(Monzo):
363
363
  receipt_data = res["data"]["receipt"]
364
364
  receipt_items: list[ReceiptItem] = []
365
365
  for item in receipt_data["items"]:
366
- quantity = float(item["quantity"]) if "quantity" in item else 0.0
367
- tax = item["tax"] if "tax" in item else 0
368
- unit = item["unit"] if "unit" in item else ""
366
+ quantity = float(item.get("quantity", 0.0)) if "quantity" in item else 0.0
367
+ tax = item.get("tax", 0) if "tax" in item else 0
368
+ unit = item.get("unit", "") if "unit" in item else ""
369
369
  receipt_item: ReceiptItem = ReceiptItem(
370
370
  description=item["description"],
371
371
  amount=item["amount"],
@@ -376,9 +376,9 @@ class Receipt(Monzo):
376
376
  )
377
377
 
378
378
  for sub_item in item["sub_items"]:
379
- sub_item_quantity = sub_item["quantity"] if "quantity" in sub_item else 0.0
380
- sub_item_tax = sub_item["tax"] if "tax" in sub_item else 0
381
- sub_item_unit = sub_item["unit"] if "unit" in sub_item else ""
379
+ sub_item_quantity = sub_item.get("quantity", 0.0) if "quantity" in sub_item else 0.0
380
+ sub_item_tax = sub_item.get("tax", 0) if "tax" in sub_item else 0
381
+ sub_item_unit = sub_item.get("unit", "") if "unit" in sub_item else ""
382
382
  receipt_sub_item = ReceiptItem(
383
383
  description=sub_item["description"],
384
384
  amount=sub_item["amount"],
@@ -1,6 +1,6 @@
1
1
  """Helper functions."""
2
2
 
3
- from datetime import datetime
3
+ from datetime import UTC, datetime
4
4
 
5
5
 
6
6
  def create_date(date_str: str) -> datetime:
@@ -13,7 +13,7 @@ def create_date(date_str: str) -> datetime:
13
13
  Returns:
14
14
  Converted date and time
15
15
  """
16
- return datetime.strptime(date_str[:19], "%Y-%m-%dT%H:%M:%S")
16
+ return datetime.strptime(date_str[:19], "%Y-%m-%dT%H:%M:%S").replace(tzinfo=UTC)
17
17
 
18
18
 
19
19
  def format_date(date: datetime) -> str:
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "Monzo-API"
3
- version = "1.2.6"
3
+ version = "1.2.7"
4
4
  authors = [{ name = "Peter McDonald", email = "git@petermcdonald.co.uk"}]
5
5
  description = "Package to interact with the API provided by Monzo bank"
6
6
  keywords = ["monzo", "bank", "api"]
@@ -29,19 +29,11 @@ documentation = "https://monzo-api.readthedocs.io"
29
29
 
30
30
  [dependency-groups]
31
31
  dev = [
32
- "cosmic-ray>=8.4.6",
33
- "idna>=3.16", # To resolve security vulnerabilities in dependencies pip-audit
34
- "pip-audit>=2.9.0",
35
- "pygments>=2.20.0", # To resolve security vulnerabilities in dependencies pytest sphinx
36
32
  "pytest>=9.0.3",
37
33
  "pytest-cov>=7.1.0",
38
34
  "pytest-mock>=3.15.1",
39
- "ruff>=0.15.10",
40
35
  "sphinx>=9.1.0",
41
36
  "sphinx-rtd-theme>=3.1.0",
42
- "troml>=0.4.1",
43
- "ty>=0.0.29",
44
- "urllib3>=2.7.0", # To resolve security vulnerabilities in dependencies pip-audit
45
37
  ]
46
38
 
47
39
  [tool.pytest.ini_options]
@@ -1,6 +1,6 @@
1
1
  """Tests for endpoints."""
2
2
 
3
- from datetime import datetime
3
+ from datetime import UTC, datetime
4
4
  from typing import Any
5
5
 
6
6
  import pytest
@@ -225,7 +225,7 @@ class TestEndPoints:
225
225
  {"bills": -2775},
226
226
  "bills",
227
227
  {},
228
- datetime(2022, 8, 9, 14, 15, 1),
228
+ datetime(year=2022, month=8, day=9, hour=14, minute=15, second=1, tzinfo=UTC),
229
229
  "GBP",
230
230
  "123ABC",
231
231
  "",
@@ -250,9 +250,9 @@ class TestEndPoints:
250
250
  "",
251
251
  False,
252
252
  "mastercard",
253
- datetime(2022, 8, 10, 0, 30, 40),
253
+ datetime(year=2022, month=8, day=10, hour=0, minute=30, second=40, tzinfo=UTC),
254
254
  "tx_123ABC1",
255
- datetime(2022, 8, 10, 0, 30, 40),
255
+ datetime(year=2022, month=8, day=10, hour=0, minute=30, second=40, tzinfo=UTC),
256
256
  "user_ABC123",
257
257
  ),
258
258
  ],
@@ -358,7 +358,11 @@ class TestEndPoints:
358
358
 
359
359
  auth.register_callback_handler(handler)
360
360
 
361
- transactions = Transaction.fetch(auth=auth, account_id=expected_account_id, since=datetime.now())
361
+ transactions = Transaction.fetch(
362
+ auth=auth,
363
+ account_id=expected_account_id,
364
+ since=datetime.now(tz=UTC),
365
+ )
362
366
  assert len(transactions) == 1
363
367
  transaction = transactions[0]
364
368
 
@@ -1,3 +1,4 @@
1
+ from email.message import Message
1
2
  from unittest.mock import patch
2
3
  from urllib.error import HTTPError
3
4
 
@@ -5,12 +6,10 @@ import pytest
5
6
 
6
7
  from monzo.exceptions import MonzoGeneralError
7
8
  from monzo.httpio import HttpIO
8
- from email.message import Message
9
9
 
10
10
 
11
11
  def test_unknown_status_code_raises_monzogeneralerror():
12
12
  http = HttpIO("https://example.com")
13
13
  error = HTTPError(url="https://example.com/test", code=418, msg="teapot", hdrs=Message(), fp=None)
14
- with patch("monzo.httpio.urlopen", side_effect=error):
15
- with pytest.raises(MonzoGeneralError):
16
- http.get("/test")
14
+ with patch("monzo.httpio.urlopen", side_effect=error), pytest.raises(MonzoGeneralError):
15
+ http.get("/test")
File without changes
File without changes
File without changes
@@ -27,11 +27,11 @@ class Attachment(Monzo):
27
27
 
28
28
  __slots__ = [
29
29
  "_attachment_id",
30
- "_user_id",
30
+ "_created",
31
+ "_file_type",
31
32
  "_transaction_id",
32
33
  "_url",
33
- "_file_type",
34
- "_created",
34
+ "_user_id",
35
35
  ]
36
36
 
37
37
  def __init__(
File without changes
File without changes
File without changes