Skip to content

Commit 4ed8988

Browse files
Let REST and websocket clients be used as context manager (#83)
# Summary All clients can now be used as context manager. The documentation and examples were extended.
1 parent 2eaf179 commit 4ed8988

21 files changed

Lines changed: 286 additions & 14 deletions

File tree

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,14 @@ General:
4242
- access both public and private endpoints
4343
- responsive error handling, custom exceptions and logging
4444
- extensive example scripts (see `/examples`)
45+
- clients can be used as context manager
46+
- coding standards like snake case are not always followed to maintain the parameter naming convention of the Kraken API
47+
- ...
4548

4649
Documentation:
4750

4851
- Stable: [https://python-kraken-sdk.readthedocs.io/en/stable](https://python-kraken-sdk.readthedocs.io/en/stable)
49-
- Latest: [https://python-kraken-sdk.readthedocs.io/en/katest](https://python-kraken-sdk.readthedocs.io/en/latest)
52+
- Latest: [https://python-kraken-sdk.readthedocs.io/en/latest](https://python-kraken-sdk.readthedocs.io/en/latest)
5053

5154
---
5255

docs/src/introduction.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ General:
4646
- access both public and private endpoints
4747
- responsive error handling, custom exceptions and logging
4848
- extensive examples
49+
- all clients can be used as context manager
4950
- coding standards like snake case are not always followed to maintain the parameter naming convention of the Kraken API
5051

5152
Important Notice

examples/futures_examples.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -190,11 +190,10 @@ def funding_examples() -> None:
190190

191191

192192
def main() -> None:
193-
"""Main"""
194-
# user_examples()
193+
user_examples()
195194
market_examples()
196-
# trade_examples()
197-
# funding_examples()
195+
trade_examples()
196+
funding_examples()
198197

199198

200199
if __name__ == "__main__":

examples/futures_ws_examples.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ async def on_message(self, event) -> Coroutine:
5656
# unsubscribe from a websocket feed
5757
time.sleep(2) # in case subscribe is not done yet
5858
# await bot.unsubscribe(feed='ticker', products=['PI_XBTUSD'])
59-
await bot.unsubscribe(feed="ticker", products=["PF_SOLUSD"])
59+
await bot.unsubscribe(feed="ticker", products=["PF_XBTUSD"])
6060
await bot.unsubscribe(feed="book", products=products)
6161
# ....
6262

@@ -100,3 +100,28 @@ async def on_message(self, event) -> Coroutine:
100100
pass
101101
finally:
102102
loop.close()
103+
104+
# ============================================================
105+
# Alternative - as ContextManager:
106+
107+
# from kraken.futures import KrakenFuturesWSClient
108+
# import asyncio
109+
110+
# async def on_message(msg):
111+
# print(msg)
112+
113+
# async def main() -> None:
114+
# async with KrakenFuturesWSClient(callback=on_message) as session:
115+
# await session.subscribe(feed="ticker", products=["PF_XBTUSD"])
116+
# while True:
117+
# await asyncio.sleep(6)
118+
119+
# if __name__ == "__main__":
120+
# loop = asyncio.new_event_loop()
121+
# asyncio.set_event_loop(loop)
122+
# try:
123+
# asyncio.run(main())
124+
# except KeyboardInterrupt:
125+
# pass
126+
# finally:
127+
# loop.close()

examples/spot_examples.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ def trade_examples() -> None:
128128
},
129129
],
130130
pair="BTC/USD",
131-
validate=False,
131+
validate=True,
132132
)
133133
)
134134

@@ -195,7 +195,6 @@ def staking_examples() -> None:
195195

196196

197197
def main() -> None:
198-
"""Main"""
199198
user_examples()
200199
market_examples()
201200
trade_examples()

examples/spot_ws_examples.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,29 @@ async def on_message(self, event) -> Coroutine:
103103
# so you can handle the behaviour/next actions individually within you bot
104104
finally:
105105
loop.close()
106+
107+
# ============================================================
108+
# Alternative - as ContextManager:
109+
110+
# from kraken.spot import KrakenSpotWSClient
111+
# import asyncio
112+
113+
# async def on_message(msg):
114+
# print(msg)
115+
116+
# async def main() -> None:
117+
# async with KrakenSpotWSClient(callback=on_message) as session:
118+
# await session.subscribe(subscription={"name": "ticker"}, pair=["XBT/USD"])
119+
120+
# while True:
121+
# await asyncio.sleep(6)
122+
123+
# if __name__ == "__main__":
124+
# loop = asyncio.new_event_loop()
125+
# asyncio.set_event_loop(loop)
126+
# try:
127+
# asyncio.run(main())
128+
# except KeyboardInterrupt:
129+
# pass
130+
# finally:
131+
# loop.close()

kraken/base_api/__init__.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,12 @@ def check_send_status(self, data: dict) -> dict:
7474
return data
7575
return data
7676

77-
def check_batch_status(self, data: List[dict]) -> dict:
77+
def check_batch_status(self, data: dict) -> dict:
7878
"""
7979
Used to check the Futures batch order responses for errors
8080
8181
:param data: The response as dict to check for an error
82-
:type data: List[dict]
82+
:type data: dict
8383
:raise kraken.exceptions.KrakenException.*: raises a KrakenError if the response contains an error
8484
:return: The response as List[dict]
8585
:rtype: List[dict]
@@ -308,6 +308,12 @@ def _to_str_list(self, value: Union[str, list]) -> str:
308308
return ",".join(value)
309309
raise ValueError("a must be type of str or list of strings")
310310

311+
def __enter__(self):
312+
return self
313+
314+
def __exit__(self, *exc) -> None:
315+
pass
316+
311317

312318
class KrakenBaseFuturesAPI:
313319
"""
@@ -532,3 +538,9 @@ def __check_response_data(
532538
raise Exception(
533539
f"{response.status_code} - {response.text}"
534540
) # pylint: disable=W0719
541+
542+
def __enter__(self):
543+
return self
544+
545+
def __exit__(self, *exc) -> None:
546+
pass

kraken/futures/funding/__init__.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,14 @@ class Funding(KrakenBaseFuturesAPI):
3333
>>> from kraken.futures import Funding
3434
>>> funding = Funding() # unauthenticated
3535
>>> funding = Funding(key="api-key", secret="secret-key") # authenticated
36+
37+
.. code-block:: python
38+
:linenos:
39+
:caption: Futures Funding: Create the funding client as context manager
40+
41+
>>> from kraken.futures import Funding
42+
>>> with Funding(key="api-key", secret="secret-key") as funding:
43+
... print(funding.get_historical_funding_rates(symbol="PI_XBTUSD"))
3644
"""
3745

3846
def __init__(

kraken/futures/market/__init__.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,16 @@ class Market(KrakenBaseFuturesAPI):
3131
:caption: Futures Market: Create the market client
3232
3333
>>> from kraken.futures import Market
34-
>>> marker = Market() # unauthenticated
35-
>>> marker = Market(key="api-key", secret="secret-key") # authenticated
34+
>>> market = Market() # unauthenticated
35+
>>> market = Market(key="api-key", secret="secret-key") # authenticated
36+
37+
.. code-block:: python
38+
:linenos:
39+
:caption: Futures Market: Create the market client as context manager
40+
41+
>>> from kraken.futures import Market
42+
>>> with Market() as market:
43+
... print(market.get_tick_types())
3644
"""
3745

3846
def __init__(

kraken/futures/trade/__init__.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,14 @@ class Trade(KrakenBaseFuturesAPI):
3333
>>> from kraken.futures import Trade
3434
>>> trade = Trade() # unauthenticated
3535
>>> trade = Trade(key="api-key", secret="secret-key") # authenticated
36+
37+
.. code-block:: python
38+
:linenos:
39+
:caption: Futures Trade: Create the trade client as context manager
40+
41+
>>> from kraken.futures import Trade
42+
>>> with Trade(key="api-key", secret="secret-key") as trade:
43+
... print(trade.get_fills())
3644
"""
3745

3846
def __init__(

0 commit comments

Comments
 (0)