bitvavo-api-upgraded 1.16.0__py3-none-any.whl → 1.17.1__py3-none-any.whl

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.
@@ -0,0 +1,8 @@
1
+ from bitvavo_api_upgraded.bitvavo import Bitvavo
2
+ from bitvavo_api_upgraded.settings import BitvavoApiUpgradedSettings, BitvavoSettings
3
+
4
+ __all__ = [
5
+ "Bitvavo",
6
+ "BitvavoApiUpgradedSettings",
7
+ "BitvavoSettings",
8
+ ]
@@ -14,23 +14,23 @@ from structlog.stdlib import get_logger
14
14
  from websocket import WebSocketApp # missing stubs for WebSocketApp
15
15
 
16
16
  from bitvavo_api_upgraded.helper_funcs import configure_loggers, time_ms, time_to_wait
17
- from bitvavo_api_upgraded.settings import BITVAVO_API_UPGRADED
18
- from bitvavo_api_upgraded.type_aliases import anydict, errordict, intdict, ms, s_f, strdict
17
+ from bitvavo_api_upgraded.settings import bitvavo_upgraded_settings
18
+ from bitvavo_api_upgraded.type_aliases import anydict, errordict, intdict, ms, s_f, strdict, strintdict
19
19
 
20
20
  configure_loggers()
21
21
 
22
22
  logger = get_logger(__name__)
23
23
 
24
24
 
25
- def createSignature(timestamp: ms, method: str, url: str, body: anydict, api_secret: str) -> str:
25
+ def createSignature(timestamp: ms, method: str, url: str, body: anydict | None, api_secret: str) -> str:
26
26
  string = f"{timestamp}{method}/v2{url}"
27
- if len(body.keys()) != 0:
27
+ if body is not None and len(body.keys()) > 0:
28
28
  string += json.dumps(body, separators=(",", ":"))
29
29
  signature = hmac.new(api_secret.encode("utf-8"), string.encode("utf-8"), hashlib.sha256).hexdigest()
30
30
  return signature
31
31
 
32
32
 
33
- def createPostfix(options: anydict) -> str:
33
+ def createPostfix(options: anydict | None) -> str:
34
34
  """Generate a URL postfix, based on the `options` dict.
35
35
 
36
36
  ---
@@ -41,11 +41,29 @@ def createPostfix(options: anydict) -> str:
41
41
  Returns:
42
42
  str: [description]
43
43
  """
44
+ options = _default(options, {})
44
45
  params = [f"{key}={options[key]}" for key in options]
45
46
  postfix = "&".join(params) # intersperse
46
47
  return f"?{postfix}" if len(options) > 0 else postfix
47
48
 
48
49
 
50
+ def _default(value: anydict | None, fallback: anydict) -> anydict:
51
+ """
52
+ Note that is close, but not actually equal to:
53
+
54
+ `return value or fallback`
55
+
56
+ I checked this with a temporary hypothesis test.
57
+
58
+ This note is all you will get out of me.
59
+ """
60
+ return value if value is not None else fallback
61
+
62
+
63
+ def _epoch_millis(dt: dt.datetime) -> int:
64
+ return int(dt.timestamp() * 1000)
65
+
66
+
49
67
  def asksCompare(a: float, b: float) -> bool:
50
68
  return a < b
51
69
 
@@ -105,12 +123,15 @@ def processLocalBook(ws: Bitvavo.WebSocketAppFacade, message: anydict) -> None:
105
123
 
106
124
 
107
125
  class ReceiveThread(Thread):
126
+ """This used to be `class rateLimitThread`."""
127
+
108
128
  def __init__(self, ws: WebSocketApp, ws_facade: Bitvavo.WebSocketAppFacade) -> None:
109
129
  self.ws = ws
110
130
  self.ws_facade = ws_facade
111
131
  Thread.__init__(self)
112
132
 
113
133
  def run(self) -> None:
134
+ """This used to be `self.waitForReset`."""
114
135
  try:
115
136
  while self.ws_facade.keepAlive:
116
137
  self.ws.run_forever()
@@ -283,10 +304,10 @@ class Bitvavo:
283
304
  )
284
305
  logger.info("napping-until-ban-lifted")
285
306
  time.sleep(timeToWait + 1) # plus one second to ENSURE we're able to run again.
286
- if "Bitvavo-Ratelimit-Remaining" in response:
287
- self.rateLimitRemaining = int(response["Bitvavo-Ratelimit-Remaining"])
288
- if "Bitvavo-Ratelimit-ResetAt" in response:
289
- self.rateLimitResetAt = int(response["Bitvavo-Ratelimit-ResetAt"])
307
+ if "bitvavo-ratelimit-remaining" in response:
308
+ self.rateLimitRemaining = int(response["bitvavo-ratelimit-remaining"])
309
+ if "bitvavo-ratelimit-resetat" in response:
310
+ self.rateLimitResetAt = int(response["bitvavo-ratelimit-resetat"])
290
311
 
291
312
  def publicRequest(
292
313
  self,
@@ -311,7 +332,7 @@ class Bitvavo:
311
332
  list[list[str]]
312
333
  ```
313
334
  """
314
- if (self.rateLimitRemaining - rateLimitingWeight) <= BITVAVO_API_UPGRADED.RATE_LIMITING_BUFFER:
335
+ if (self.rateLimitRemaining - rateLimitingWeight) <= bitvavo_upgraded_settings.RATE_LIMITING_BUFFER:
315
336
  self.sleep_until_can_continue()
316
337
  if self.debugging:
317
338
  logger.debug(
@@ -323,13 +344,13 @@ class Bitvavo:
323
344
  },
324
345
  )
325
346
  if self.APIKEY != "":
326
- now = time_ms() + BITVAVO_API_UPGRADED.LAG
327
- sig = createSignature(now, "GET", url.replace(self.base, ""), {}, self.APISECRET)
347
+ now = time_ms() + bitvavo_upgraded_settings.LAG
348
+ sig = createSignature(now, "GET", url.replace(self.base, ""), None, self.APISECRET)
328
349
  headers = {
329
- "Bitvavo-Access-Key": self.APIKEY,
330
- "Bitvavo-Access-Signature": sig,
331
- "Bitvavo-Access-Timestamp": str(now),
332
- "Bitvavo-Access-Window": str(self.ACCESSWINDOW),
350
+ "bitvavo-access-key": self.APIKEY,
351
+ "bitvavo-access-signature": sig,
352
+ "bitvavo-access-timestamp": str(now),
353
+ "bitvavo-access-window": str(self.ACCESSWINDOW),
333
354
  }
334
355
  r = get(url, headers=headers, timeout=(self.ACCESSWINDOW / 1000))
335
356
  else:
@@ -344,7 +365,7 @@ class Bitvavo:
344
365
  self,
345
366
  endpoint: str,
346
367
  postfix: str,
347
- body: anydict,
368
+ body: anydict | None = None,
348
369
  method: str = "GET",
349
370
  rateLimitingWeight: int = 1,
350
371
  ) -> list[anydict] | list[list[str]] | intdict | strdict | anydict | Any | errordict:
@@ -370,17 +391,17 @@ class Bitvavo:
370
391
  list[list[str]]
371
392
  ```
372
393
  """
373
- if (self.rateLimitRemaining - rateLimitingWeight) <= BITVAVO_API_UPGRADED.RATE_LIMITING_BUFFER:
394
+ if (self.rateLimitRemaining - rateLimitingWeight) <= bitvavo_upgraded_settings.RATE_LIMITING_BUFFER:
374
395
  self.sleep_until_can_continue()
375
396
  # if this method breaks: add `= {}` after `body: dict`
376
- now = time_ms() + BITVAVO_API_UPGRADED.LAG
397
+ now = time_ms() + bitvavo_upgraded_settings.LAG
377
398
  sig = createSignature(now, method, (endpoint + postfix), body, self.APISECRET)
378
399
  url = self.base + endpoint + postfix
379
400
  headers = {
380
- "Bitvavo-Access-Key": self.APIKEY,
381
- "Bitvavo-Access-Signature": sig,
382
- "Bitvavo-Access-Timestamp": str(now),
383
- "Bitvavo-Access-Window": str(self.ACCESSWINDOW),
401
+ "bitvavo-access-key": self.APIKEY,
402
+ "bitvavo-access-signature": sig,
403
+ "bitvavo-access-timestamp": str(now),
404
+ "bitvavo-access-window": str(self.ACCESSWINDOW),
384
405
  }
385
406
  if self.debugging:
386
407
  logger.debug(
@@ -438,7 +459,7 @@ class Bitvavo:
438
459
  """
439
460
  return self.publicRequest(f"{self.base}/time") # type: ignore[return-value]
440
461
 
441
- def markets(self, options: strdict) -> list[anydict] | anydict | errordict:
462
+ def markets(self, options: strdict | None = None) -> list[anydict] | anydict | errordict:
442
463
  """Get all available markets with some meta-information, unless options is given a `market` key.
443
464
  Then you will get a single market, instead of a list of markets.
444
465
 
@@ -490,7 +511,7 @@ class Bitvavo:
490
511
  postfix = createPostfix(options)
491
512
  return self.publicRequest(f"{self.base}/markets{postfix}") # type: ignore[return-value]
492
513
 
493
- def assets(self, options: strdict) -> list[anydict] | anydict:
514
+ def assets(self, options: strdict | None = None) -> list[anydict] | anydict:
494
515
  """Get all available assets, unless `options` is given a `symbol` key.
495
516
  Then you will get a single asset, instead of a list of assets.
496
517
 
@@ -539,7 +560,7 @@ class Bitvavo:
539
560
  postfix = createPostfix(options)
540
561
  return self.publicRequest(f"{self.base}/assets{postfix}") # type: ignore[return-value]
541
562
 
542
- def book(self, market: str, options: intdict) -> dict[str, str | int | list[str]] | errordict:
563
+ def book(self, market: str, options: intdict | None = None) -> dict[str, str | int | list[str]] | errordict:
543
564
  """Get a book (with two lists: asks and bids, as they're called)
544
565
 
545
566
  ---
@@ -583,7 +604,7 @@ class Bitvavo:
583
604
  postfix = createPostfix(options)
584
605
  return self.publicRequest(f"{self.base}/{market}/book{postfix}") # type: ignore[return-value]
585
606
 
586
- def publicTrades(self, market: str, options: dict[str, str | int]) -> list[anydict] | errordict:
607
+ def publicTrades(self, market: str, options: strintdict | None = None) -> list[anydict] | errordict:
587
608
  """Publically available trades
588
609
 
589
610
  ---
@@ -633,11 +654,14 @@ class Bitvavo:
633
654
  postfix = createPostfix(options)
634
655
  return self.publicRequest(f"{self.base}/{market}/trades{postfix}", 5) # type: ignore[return-value]
635
656
 
636
- def candles(
657
+ def candles( # noqa: PLR0913
637
658
  self,
638
659
  market: str,
639
660
  interval: str,
640
- options: dict[str, str | int],
661
+ options: strintdict | None = None,
662
+ limit: int | None = None,
663
+ start: dt.datetime | None = None,
664
+ end: dt.datetime | None = None,
641
665
  ) -> list[list[str]] | errordict:
642
666
  """Get up to 1440 candles for a market, with a specific interval (candle size)
643
667
 
@@ -684,11 +708,18 @@ class Bitvavo:
684
708
  ]
685
709
  ```
686
710
  """
711
+ options = _default(options, {})
687
712
  options["interval"] = interval
713
+ if limit is not None:
714
+ options["limit"] = limit
715
+ if start is not None:
716
+ options["start"] = _epoch_millis(start)
717
+ if end is not None:
718
+ options["end"] = _epoch_millis(end)
688
719
  postfix = createPostfix(options)
689
720
  return self.publicRequest(f"{self.base}/{market}/candles{postfix}") # type: ignore[return-value]
690
721
 
691
- def tickerPrice(self, options: strdict) -> list[strdict] | strdict:
722
+ def tickerPrice(self, options: strdict | None = None) -> list[strdict] | strdict:
692
723
  """Get the current price for each market
693
724
 
694
725
  ---
@@ -736,7 +767,7 @@ class Bitvavo:
736
767
  postfix = createPostfix(options)
737
768
  return self.publicRequest(f"{self.base}/ticker/price{postfix}") # type: ignore[return-value]
738
769
 
739
- def tickerBook(self, options: strdict) -> list[strdict] | strdict:
770
+ def tickerBook(self, options: strdict | None = None) -> list[strdict] | strdict:
740
771
  """Get current bid/ask, bidsize/asksize per market
741
772
 
742
773
  ---
@@ -777,7 +808,7 @@ class Bitvavo:
777
808
  postfix = createPostfix(options)
778
809
  return self.publicRequest(f"{self.base}/ticker/book{postfix}") # type: ignore[return-value]
779
810
 
780
- def ticker24h(self, options: strdict) -> list[anydict] | anydict | errordict:
811
+ def ticker24h(self, options: strdict | None = None) -> list[anydict] | anydict | errordict:
781
812
  """Get current bid/ask, bidsize/asksize per market
782
813
 
783
814
  ---
@@ -839,6 +870,7 @@ class Bitvavo:
839
870
  ]
840
871
  ```
841
872
  """
873
+ options = _default(options, {})
842
874
  rateLimitingWeight = 25
843
875
  if "market" in options:
844
876
  rateLimitingWeight = 1
@@ -1143,7 +1175,7 @@ class Bitvavo:
1143
1175
  postfix = createPostfix({"market": market, "orderId": orderId})
1144
1176
  return self.privateRequest("/order", postfix, {}, "GET") # type: ignore[return-value]
1145
1177
 
1146
- def getOrders(self, market: str, options: anydict) -> list[anydict] | errordict:
1178
+ def getOrders(self, market: str, options: anydict | None = None) -> list[anydict] | errordict:
1147
1179
  """Get multiple existing orders for a specific market
1148
1180
 
1149
1181
  ---
@@ -1214,11 +1246,12 @@ class Bitvavo:
1214
1246
  ]
1215
1247
  ```
1216
1248
  """ # noqa: E501
1249
+ options = _default(options, {})
1217
1250
  options["market"] = market
1218
1251
  postfix = createPostfix(options)
1219
1252
  return self.privateRequest("/orders", postfix, {}, "GET", 5) # type: ignore[return-value]
1220
1253
 
1221
- def cancelOrders(self, options: anydict) -> list[strdict] | errordict:
1254
+ def cancelOrders(self, options: anydict | None = None) -> list[strdict] | errordict:
1222
1255
  """Cancel all existing orders for a specific market (or account)
1223
1256
 
1224
1257
  ---
@@ -1246,7 +1279,7 @@ class Bitvavo:
1246
1279
  postfix = createPostfix(options)
1247
1280
  return self.privateRequest("/orders", postfix, {}, "DELETE") # type: ignore[return-value]
1248
1281
 
1249
- def ordersOpen(self, options: anydict) -> list[anydict] | errordict:
1282
+ def ordersOpen(self, options: anydict | None = None) -> list[anydict] | errordict:
1250
1283
  """Get all open orders, either for all markets, or a single market
1251
1284
 
1252
1285
  ---
@@ -1311,13 +1344,14 @@ class Bitvavo:
1311
1344
  ]
1312
1345
  ```
1313
1346
  """
1347
+ options = _default(options, {})
1314
1348
  rateLimitingWeight = 25
1315
1349
  if "market" in options:
1316
1350
  rateLimitingWeight = 1
1317
1351
  postfix = createPostfix(options)
1318
1352
  return self.privateRequest("/ordersOpen", postfix, {}, "GET", rateLimitingWeight) # type: ignore[return-value]
1319
1353
 
1320
- def trades(self, market: str, options: anydict) -> list[anydict] | errordict:
1354
+ def trades(self, market: str, options: anydict | None = None) -> list[anydict] | errordict:
1321
1355
  """Get all historic trades from this account
1322
1356
 
1323
1357
  ---
@@ -1359,6 +1393,7 @@ class Bitvavo:
1359
1393
  ]
1360
1394
  ```
1361
1395
  """ # noqa: E501
1396
+ options = _default(options, {})
1362
1397
  options["market"] = market
1363
1398
  postfix = createPostfix(options)
1364
1399
  return self.privateRequest("/trades", postfix, {}, "GET", 5) # type: ignore[return-value]
@@ -1386,7 +1421,16 @@ class Bitvavo:
1386
1421
  """
1387
1422
  return self.privateRequest("/account", "", {}, "GET") # type: ignore[return-value]
1388
1423
 
1389
- def balance(self, options: strdict) -> list[strdict] | errordict:
1424
+ def fees(self, market: str | None = None, quote: str | None = None) -> list[strdict] | errordict:
1425
+ options = {}
1426
+ if market is not None:
1427
+ options["market"] = market
1428
+ if quote is not None:
1429
+ options["quote"] = quote
1430
+ postfix = createPostfix(options)
1431
+ return self.privateRequest("/account/fees", postfix, {}, "GET") # type: ignore[return-value]
1432
+
1433
+ def balance(self, options: strdict | None = None) -> list[strdict] | errordict:
1390
1434
  """Get the balance for this account
1391
1435
 
1392
1436
  ---
@@ -1452,7 +1496,7 @@ class Bitvavo:
1452
1496
  postfix = createPostfix({"symbol": symbol})
1453
1497
  return self.privateRequest("/deposit", postfix, {}, "GET") # type: ignore[return-value]
1454
1498
 
1455
- def depositHistory(self, options: anydict) -> list[anydict] | errordict:
1499
+ def depositHistory(self, options: anydict | None = None) -> list[anydict] | errordict:
1456
1500
  """Get the deposit history of the account
1457
1501
 
1458
1502
  Even when you want something from a single `symbol`, you'll still receive a list with multiple deposits.
@@ -1540,7 +1584,7 @@ class Bitvavo:
1540
1584
  body["address"] = address
1541
1585
  return self.privateRequest("/withdrawal", "", body, "POST") # type: ignore[return-value]
1542
1586
 
1543
- def withdrawalHistory(self, options: anydict) -> list[anydict] | errordict:
1587
+ def withdrawalHistory(self, options: anydict | None = None) -> list[anydict] | errordict:
1544
1588
  """Get the withdrawal history
1545
1589
 
1546
1590
  ---
@@ -1700,6 +1744,8 @@ class Bitvavo:
1700
1744
  callbacks["trades"](msg_dict["response"])
1701
1745
  elif msg_dict["action"] == "privateGetAccount":
1702
1746
  callbacks["account"](msg_dict["response"])
1747
+ elif msg_dict["action"] == "privateGetFees":
1748
+ callbacks["fees"](msg_dict["response"])
1703
1749
  elif msg_dict["action"] == "privateGetBalance":
1704
1750
  callbacks["balance"](msg_dict["response"])
1705
1751
  elif msg_dict["action"] == "privateDepositAssets":
@@ -1786,7 +1832,7 @@ class Bitvavo:
1786
1832
  self.subscriptionBook(market, self.callbacks["subscriptionBookUser"][market])
1787
1833
 
1788
1834
  def on_open(self, ws: Any) -> None: # noqa: ARG002
1789
- now = time_ms() + BITVAVO_API_UPGRADED.LAG
1835
+ now = time_ms() + bitvavo_upgraded_settings.LAG
1790
1836
  self.open = True
1791
1837
  self.reconnectTimer = 0.5
1792
1838
  if self.APIKEY != "":
@@ -34,7 +34,7 @@ def configure_loggers() -> None:
34
34
  source: https://docs.python.org/3.9/library/logging.config.html#dictionary-schema-details
35
35
  """
36
36
  shared_pre_chain: list[Callable[[WrappedLogger, str, EventDict], EventDict]] = [
37
- structlog.threadlocal.merge_threadlocal,
37
+ # structlog.threadlocal.merge_threadlocal,
38
38
  structlog.stdlib.add_logger_name, # show which named logger made the message!
39
39
  structlog.processors.add_log_level, # info, warning, error, etc
40
40
  structlog.processors.TimeStamper(fmt="%Y-%m-%dT%H:%M:%S", utc=False), # add an ISO formatted string
@@ -1,47 +1,70 @@
1
1
  import logging
2
2
  from pathlib import Path
3
3
 
4
- from decouple import AutoConfig, Choices
4
+ from pydantic import Field, field_validator, model_validator
5
+ from pydantic_settings import BaseSettings, SettingsConfigDict
5
6
 
6
7
  from bitvavo_api_upgraded.type_aliases import ms
7
8
 
8
- # don't use/import python-decouple's `config`` variable, because the search_path isn't set,
9
- # which means applications that use a .env file can't override these variables :(
10
- config = AutoConfig(search_path=Path.cwd())
11
9
 
10
+ class BitvavoApiUpgradedSettings(BaseSettings):
11
+ """
12
+ These settings provide extra functionality. Originally I wanted to combine
13
+ then, but I figured that would be a bad idea.
14
+ """
12
15
 
13
- class _BitvavoApiUpgraded:
14
- # default LOG_LEVEL is WARNING, so users don't get their ass spammed.
15
- LOG_LEVEL: str = config(
16
- "BITVAVO_API_UPGRADED_LOG_LEVEL",
17
- default="INFO",
18
- cast=Choices(list(logging._nameToLevel.keys())), # noqa: SLF001
19
- )
20
- LOG_EXTERNAL_LEVEL: str = config(
21
- "BITVAVO_API_UPGRADED_EXTERNAL_LOG_LEVEL",
22
- default="WARNING",
23
- cast=Choices(list(logging._nameToLevel.keys())), # noqa: SLF001
16
+ LOG_LEVEL: str = Field("INFO")
17
+ LOG_EXTERNAL_LEVEL: str = Field("WARNING")
18
+ LAG: ms = Field(ms(50))
19
+ RATE_LIMITING_BUFFER: int = Field(25)
20
+
21
+ # Configuration for Pydantic Settings
22
+ model_config = SettingsConfigDict(
23
+ env_file=Path.cwd() / ".env",
24
+ env_file_encoding="utf-8",
25
+ env_prefix="BITVAVO_API_UPGRADED_",
26
+ extra="ignore",
24
27
  )
25
- LAG: ms = config("BITVAVO_API_UPGRADED_LAG", default=ms(50), cast=ms)
26
- RATE_LIMITING_BUFFER: int = config("BITVAVO_API_UPGRADED_RATE_LIMITING_BUFFER", default=25, cast=int)
27
28
 
29
+ @classmethod
30
+ @field_validator("LOG_LEVEL", "LOG_EXTERNAL_LEVEL", mode="before")
31
+ def validate_log_level(cls, v: str) -> str:
32
+ if v not in logging._nameToLevel: # noqa: SLF001
33
+ msg = f"Invalid log level: {v}"
34
+ raise ValueError(msg)
35
+ return v
28
36
 
29
- class _Bitvavo:
37
+
38
+ class BitvavoSettings(BaseSettings):
30
39
  """
31
- Changeable variables are handled by the decouple lib, anything else is just static, because they are based on
32
- Bitvavo's documentation and thus should not be able to be set outside of the application.
40
+ These are the base settings from the original library.
33
41
  """
34
42
 
35
- ACCESSWINDOW: int = config("BITVAVO_ACCESSWINDOW", default=10_000, cast=int)
36
- API_RATING_LIMIT_PER_MINUTE: int = 1000
37
- API_RATING_LIMIT_PER_SECOND: float = API_RATING_LIMIT_PER_MINUTE / 60
38
- APIKEY: str = config("BITVAVO_APIKEY", default="BITVAVO_APIKEY is missing")
39
- APISECRET: str = config("BITVAVO_APISECRET", default="BITVAVO_APISECRET is missing")
40
- DEBUGGING: bool = config("BITVAVO_DEBUGGING", default=False, cast=bool)
41
- RESTURL: str = "https://api.bitvavo.com/v2"
42
- WSURL: str = "wss://ws.bitvavo.com/v2/"
43
+ ACCESSWINDOW: int = Field(10_000)
44
+ API_RATING_LIMIT_PER_MINUTE: int = Field(default=1000)
45
+ API_RATING_LIMIT_PER_SECOND: int = Field(default=1000)
46
+ APIKEY: str = Field(default="BITVAVO_APIKEY is missing")
47
+ APISECRET: str = Field(default="BITVAVO_APISECRET is missing")
48
+ DEBUGGING: bool = Field(default=False)
49
+ RESTURL: str = Field(default="https://api.bitvavo.com/v2")
50
+ WSURL: str = Field(default="wss://ws.bitvavo.com/v2/")
51
+
52
+ # Configuration for Pydantic Settings
53
+ model_config = SettingsConfigDict(
54
+ env_file=Path.cwd() / ".env",
55
+ env_file_encoding="utf-8",
56
+ env_prefix="BITVAVO_",
57
+ extra="ignore",
58
+ )
59
+
60
+ @model_validator(mode="after")
61
+ def set_api_rating_limit_per_second(self) -> "BitvavoSettings":
62
+ self.API_RATING_LIMIT_PER_SECOND = self.API_RATING_LIMIT_PER_SECOND // 60
63
+ return self
43
64
 
44
65
 
45
- # Just import these variables to use the settings :)
46
- BITVAVO_API_UPGRADED = _BitvavoApiUpgraded()
47
- BITVAVO = _Bitvavo()
66
+ # Initialize the settings
67
+ bitvavo_upgraded_settings = BitvavoApiUpgradedSettings()
68
+ BITVAVO_API_UPGRADED = bitvavo_upgraded_settings
69
+ bitvavo_settings = BitvavoSettings()
70
+ BITVAVO = bitvavo_settings
@@ -3,12 +3,14 @@ This file contains all type aliases that I use within the lib,
3
3
  to clearify the intention or semantics/meaning/unit of a variable
4
4
  """
5
5
 
6
- from typing import Any
6
+ from typing import Any, Union
7
7
 
8
8
  # type simplification
9
9
  anydict = dict[str, Any]
10
10
  strdict = dict[str, str]
11
11
  intdict = dict[str, int]
12
+ # can't use | here, with __future__. Not sure why.
13
+ strintdict = dict[str, Union[str, int]]
12
14
  errordict = dict[str, Any] # same type as anydict, but the semantics/meaning is different
13
15
 
14
16
  # note: You can also use these for type conversion, so instead of int(some_float / 1000), you can just do ms(some_float