ksxt 0.0.10__py3-none-any.whl → 1.0.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.
@@ -1,19 +1,14 @@
1
1
  import asyncio
2
+ import time
2
3
  import aiohttp
3
- import json
4
- import os
5
- import platform
6
- import tomllib
7
4
  from datetime import datetime
8
- from pathlib import Path
9
5
  from typing import Any, Dict, Literal, Optional
10
6
 
11
- import yarl
12
7
 
13
- from ksxt.async_.base.throttler import Throttler
14
8
  from ksxt.base.errors import NotSupportedError
9
+ from ksxt.base.rate_limiter import RateLimiterContext
15
10
  from ksxt.base.rest_exchange import RestExchange
16
- from ksxt.config import CONFIG_DIR
11
+ from ksxt.config import VALID_METHODS
17
12
  import ksxt.models
18
13
 
19
14
 
@@ -23,22 +18,26 @@ class AsyncExchange(RestExchange):
23
18
  def __init__(self, config: Dict = None, filename: str = None):
24
19
  super().__init__(config, filename)
25
20
 
26
- self.asyncio_loop = asyncio.get_event_loop()
27
- self.session = aiohttp.ClientSession()
28
- self.throttle = Throttler({}, self.asyncio_loop)
21
+ self.asyncio_loop = None
22
+ self.session: aiohttp.ClientSession = None
29
23
 
30
24
  async def initialize(self):
31
25
  if self.asyncio_loop is None:
32
26
  self.asyncio_loop = asyncio.get_event_loop()
33
- if self.session is None:
27
+
28
+ if self.session is None or (
29
+ self.session_last_used and (time.time() - self.session_last_used > self.session_lifetime)
30
+ ):
31
+ if self.session:
32
+ await self.session.close()
34
33
  self.session = aiohttp.ClientSession()
35
- if self.throttle is None:
36
- self.throttle = Throttler({}, self.asyncio_loop)
34
+ self.session_last_used = time.time()
37
35
 
38
36
  async def close(self):
39
37
  if self.session:
40
38
  await self.session.close()
41
39
  self.session = None
40
+ self.session_last_used = None
42
41
 
43
42
  async def __aenter__(self):
44
43
  await self.initialize()
@@ -47,49 +46,43 @@ class AsyncExchange(RestExchange):
47
46
  async def __aexit__(self, *args):
48
47
  await self.close()
49
48
 
50
- def _get_api_from_file(self, filename: str):
51
- if filename is None:
52
- tr_config_filename = "tr_dev.json" if self.is_dev else "tr_app.json"
53
- else:
54
- tr_config_filename = filename
55
-
56
- config_path = os.path.join(CONFIG_DIR, tr_config_filename)
49
+ async def fetch(self, url, method="GET", headers=None, body=None, params=None):
50
+ # Ensure that resources are initialized before the request
51
+ await self.initialize()
57
52
 
58
- if Path(tr_config_filename).suffix == ".json":
59
- with open(
60
- config_path,
61
- encoding="utf-8",
62
- ) as f:
63
- c = json.load(f)
64
- return {"apis": c[self.name]}
53
+ method_lower = method.lower()
54
+ if method_lower not in VALID_METHODS:
55
+ raise ValueError(f"Invalid HTTP method: {method}")
65
56
 
66
- elif Path(tr_config_filename).suffix == ".toml":
67
- with open(config_path, mode="rb") as f:
68
- c = tomllib.load(f)
69
- return c
57
+ session_method = getattr(self.session, method.lower())
70
58
 
71
- async def fetch(self, url, method="GET", headers=None, body=None, params=None):
72
- request_headers = headers
73
- request_body = str(body).encode() if body else None
74
- request_params = params
59
+ # TODO : Set rate limiters value when config load
60
+ api_name = ""
75
61
 
76
- session_method = getattr(self.session, method.lower())
62
+ if api_name and api_name in self.rate_limiters:
63
+ await self.rate_limiters[api_name].async_acquire()
77
64
 
78
65
  try:
79
66
  async with session_method(
80
67
  url,
81
- # yarl.URL(url, encoded=True),
82
- headers=request_headers,
83
- data=request_body,
84
- params=request_params,
68
+ headers=headers,
69
+ data=str(body).encode() if body else None,
70
+ params=params,
85
71
  timeout=aiohttp.ClientTimeout(total=int(self.timeout / 1000)),
86
72
  ) as response:
87
73
  http_response = await response.text(errors="replace")
88
74
  json_response = self.parse_json(http_response)
89
75
  return json_response
90
- except asyncio.TimeoutError as e:
76
+ except (asyncio.TimeoutError, aiohttp.ClientError) as e:
91
77
  details = f"{self.id} {method} {url}"
92
78
  raise TimeoutError(details) from e
79
+ finally:
80
+ if (
81
+ api_name
82
+ and api_name in self.rate_limiters
83
+ and isinstance(self.rate_limiters[api_name], RateLimiterContext)
84
+ ):
85
+ self.rate_limiters[api_name].release()
93
86
 
94
87
  async def fetch2(
95
88
  self, path, security_type, params={}, headers: Optional[Any] = None, body: Optional[Any] = None, config={}