# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/03_reqs.ipynb.

# %% auto 0
__all__ = ['JSONRequest', 'RateLimitRequest']

# %% ../nbs/03_reqs.ipynb 4
import sys, json, time
from urllib.parse import urlparse, urlencode, urljoin, ParseResult
from urllib.request import urlopen, Request
from urllib.error import HTTPError

# %% ../nbs/03_reqs.ipynb 5
from .cons import RATE_LIMIT, RETRY_AFTER, CONTENT_TYPE
from .errs import RateLimitError
from .util import RateLimiter

# %% ../nbs/03_reqs.ipynb 7
class JSONRequest(Request):
    def add_query(self, url, **kwargs) -> str:
        scheme, netloc, path, params, _, fragment = list(urlparse(url))
        return ParseResult(scheme, netloc, path, params, urlencode(kwargs), fragment).geturl()
       
    def request(self):
        res = urlopen(self)
        content = res.read()
        if content: data = json.loads(content)
        return data
    
    def __init__(
        self, url, data = None, headers = {}, origin_req_host = None, 
        unverifiable = False, method = None, **params,
    ):
        headers = headers or {}
        headers.setdefault(CONTENT_TYPE, 'application/json')
        url = self.add_query(url, **params)
        super().__init__(url, data, headers, origin_req_host, unverifiable, method)

    def __call__(self, **params):        
        try:
            return self.request()
        except HTTPError as err:
            RateLimitError(err, self.url).handle(self, **params)

# %% ../nbs/03_reqs.ipynb 9
class RateLimitRequest(JSONRequest, Request):
    # All RateLimitRequests share the same rate limiter
    rlim: RateLimiter = RateLimiter(RATE_LIMIT)

    def __init__(
        self, 
        url, data = None, headers = {}, origin_req_host = None, unverifiable = False, method = None, 
        rate: float = RATE_LIMIT, **params
    ):       
        super().__init__(url, data, headers, origin_req_host, unverifiable, method)
        self.rate = rate
        self.rlim.rate = rate # update rate limiter
        self.request = self.rlim(self.request)

    def __call__(self, **params):        
        try: return self.request()
        except HTTPError as err: RateLimitError(err, self.full_url).handle(self, **params)
