import json from dataclasses import dataclass from logging import getLogger from PyQt5.QtCore import QObject, pyqtSignal, QUrl, QJsonParseError, QJsonDocument from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply logger = getLogger("QtRequests") class QtRequestManager(QObject): data_ready = pyqtSignal(object) request = None request_active = None def __init__(self, type: str = "json", authorization_token: str = None): super(QtRequestManager, self).__init__() self.manager = QNetworkAccessManager() self.type = type self.authorization_token = authorization_token self.request_queue = [] def post(self, url: str, payload: dict, handle_func): if not self.request_active: request = QNetworkRequest(QUrl(url)) request.setHeader(QNetworkRequest.ContentTypeHeader, "application/json") self.request_active = RequestQueueItem(handle_func=handle_func) payload = json.dumps(payload).encode("utf-8") request.setHeader(QNetworkRequest.UserAgentHeader, "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36") if self.authorization_token is not None: request.setRawHeader(b"Authorization", self.authorization_token.encode()) self.request = self.manager.post(request, payload) self.request.finished.connect(self.prepare_data) else: self.request_queue.append( RequestQueueItem(method="post", url=url, payload=payload, handle_func=handle_func)) def get(self, url: str, handle_func: callable): if not self.request_active: request = QNetworkRequest(QUrl(url)) request.setHeader(QNetworkRequest.UserAgentHeader, "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36") self.request_active = RequestQueueItem(handle_func=handle_func) self.request = self.manager.get(request) self.request.finished.connect(self.prepare_data) else: self.request_queue.append(RequestQueueItem(method="get", url=url, handle_func=handle_func)) def prepare_data(self): # self.request_active = False data = {} if self.type == "json" else b"" if self.request: try: if self.request.error() == QNetworkReply.NoError: if self.type == "json": error = QJsonParseError() json_data = QJsonDocument.fromJson(self.request.readAll().data(), error) if QJsonParseError.NoError == error.error: data = json.loads(json_data.toJson().data().decode()) else: logger.error(error.errorString()) else: data = self.request.readAll().data() except RuntimeError as e: logger.error(str(e)) self.request_active.handle_func(data) self.request.deleteLater() self.request_active = None if self.request_queue: if self.request_queue[0].method == "post": self.post(self.request_queue[0].url, self.request_queue[0].payload, self.request_queue[0].handle_func) else: self.get(self.request_queue[0].url, self.request_queue[0].handle_func) self.request_queue.pop(0) @dataclass class RequestQueueItem: method: str = None url: str = None handle_func: callable = None payload: dict = None