1818LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
1919FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2020DEALINGS IN THE SOFTWARE.
21- """
21+ """ # noqa: A005 # we access this via namespace
2222
2323from __future__ import annotations
2424
5252 T = TypeVar ("T" )
5353 Response = Coroutine [None , None , T ]
5454 MU = TypeVar ("MU" , bound = "MaybeUnlock" )
55- BE = TypeVar ("BE" , bound = BaseException )
5655 from .types .responses import CreatePasteResponse , GetPasteResponse
5756
5857
@@ -69,8 +68,14 @@ def _clean_dt(dt: datetime.datetime) -> str:
6968 return dt .isoformat ()
7069
7170
72- async def json_or_text (response : aiohttp .ClientResponse , / ) -> dict [str , Any ] | str :
73- """A quick method to parse a `aiohttp.ClientResponse` and test if it's json or text."""
71+ async def _json_or_text (response : aiohttp .ClientResponse , / ) -> dict [str , Any ] | str :
72+ """A quick method to parse a `aiohttp.ClientResponse` and test if it's json or text.
73+
74+ Returns
75+ --------
76+ Union[Dict[:class:`str`, Any], :class:`str`]
77+ The JSON object, or request text.
78+ """
7479 text = await response .text (encoding = "utf-8" )
7580 try :
7681 if response .headers ["content-type" ] == "application/json" :
@@ -97,8 +102,8 @@ def defer(self) -> None:
97102
98103 def __exit__ (
99104 self ,
100- exc_type : type [BE ] | None ,
101- exc : BE | None ,
105+ exc_type : type [BaseException ] | None ,
106+ exc : BaseException | None ,
102107 traceback : TracebackType | None ,
103108 ) -> None :
104109 if self ._unlock :
@@ -115,14 +120,14 @@ class Route:
115120 API_BASE : ClassVar [str ] = "https://mystb.in/api"
116121
117122 def __init__ (self , verb : SupportedHTTPVerb , path : str , ** params : Any ) -> None :
118-
119123 self .verb : SupportedHTTPVerb = verb
120124 self .path : str = path
121125 url = self .API_BASE + path
122126 if params :
123127 url = url .format_map ({k : _uriquote (v ) if isinstance (v , str ) else v for k , v in params .items ()})
124128 self .url : str = url
125129
130+
126131class HTTPClient :
127132 __slots__ = (
128133 "_async" ,
@@ -131,7 +136,7 @@ class HTTPClient:
131136 "_session" ,
132137 "_token" ,
133138 "api_base" ,
134- "user_agent"
139+ "user_agent" ,
135140 )
136141
137142 def __init__ (self , * , session : aiohttp .ClientSession | None = None , api_base : str | None = None ) -> None :
@@ -142,12 +147,9 @@ def __init__(self, *, session: aiohttp.ClientSession | None = None, api_base: st
142147 self .user_agent : str = user_agent .format (__version__ , sys .version_info , aiohttp .__version__ )
143148 self ._resolve_api (api_base )
144149
145- def _resolve_api (self , api : str | None ) -> None :
146- if api :
147- Route .API_BASE = api + "api" if api .endswith ("/" ) else api + "/api"
148- self .api_base = api + ("/" if not api .endswith ("/" ) else "" )
149- else :
150- self .api_base = "https://mystb.in/"
150+ def _resolve_api (self , api_base : str | None , / ) -> None :
151+ if api_base :
152+ Route .API_BASE = f"https://{ api_base } /api"
151153
152154 async def close (self ) -> None :
153155 if self ._session and self ._owns_session :
@@ -194,28 +196,28 @@ async def request(self, route: Route, **kwargs: Any) -> Any:
194196 retry = response .headers .get ("x-ratelimit-retry-after" , None )
195197 LOGGER .debug ("retry is: %s" , retry )
196198 if retry is not None :
197- retry = datetime .datetime .fromtimestamp (int (retry ))
199+ retry = datetime .datetime .fromtimestamp (int (retry ), tz = datetime . timezone . utc )
198200 # The total ratelimit session hits
199201 limit = response .headers .get ("x-ratelimit-limit" , None )
200202 LOGGER .debug ("limit is: %s" , limit )
201203
202204 if remaining == "0" and response .status != 429 :
203205 assert retry is not None
204- delta = retry - datetime .datetime .now ()
206+ delta = retry - datetime .datetime .now (datetime . timezone . utc )
205207 sleep = delta .total_seconds () + 1
206208 LOGGER .warning ("A ratelimit has been exhausted, sleeping for: %d" , sleep )
207209 maybe_lock .defer ()
208210 loop = asyncio .get_running_loop ()
209211 loop .call_later (sleep , lock .release )
210212
211- data = await json_or_text (response )
213+ data = await _json_or_text (response )
212214
213215 if 300 > response .status >= 200 :
214216 return data
215217
216218 if response .status == 429 :
217219 assert retry is not None
218- delta = retry - datetime .datetime .now ()
220+ delta = retry - datetime .datetime .now (datetime . timezone . utc )
219221 sleep = delta .total_seconds () + 1
220222 LOGGER .warning ("A ratelimit has been hit, sleeping for: %d" , sleep )
221223 await asyncio .sleep (sleep )
@@ -227,15 +229,14 @@ async def request(self, route: Route, **kwargs: Any) -> Any:
227229 await asyncio .sleep (sleep_ )
228230 continue
229231
230- print (data )
231232 assert isinstance (data , dict )
232233 LOGGER .exception ("Unhandled HTTP error occurred: %s -> %s" , response .status , data )
233234 raise APIException (
234235 response = response ,
235236 status_code = response .status ,
236237 )
237- except (aiohttp .ServerDisconnectedError , aiohttp .ServerTimeoutError ) as error :
238- LOGGER .exception ("Network error occurred: %s" , error )
238+ except (aiohttp .ServerDisconnectedError , aiohttp .ServerTimeoutError ):
239+ LOGGER .exception ("Network error occurred:" )
239240 await asyncio .sleep (5 )
240241 continue
241242
0 commit comments