1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
|
"""
Copyright (c) 2023 Proton AG
This file is part of Proton.
Proton is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Proton is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with ProtonVPN. If not, see <https://www.gnu.org/licenses/>.
"""
import weakref
from dataclasses import dataclass
from typing import Optional, Any, Tuple
@dataclass
class RawResponse:
"""
A response that contains the status code and headers along with the body
as json. This gives more context to clients when receiving a response.
This type is returned where return_raw is set to True.
:param status_code: The status code of the response
:param headers: The headers in the response
:param json: The body the response parsed as json
"""
status_code: int
headers: Tuple[Tuple[str, Any]]
json: Optional[dict]
def find_first_header(self, key, default=None):
"""
Searches for the given key in the headers and returns the first value
if found, otherwise returns the default value.
"""
for k, v in self.headers:
if key == k:
return v
return default
class Transport:
"""
The base class of all transports. This class should be subclassed to
implement the async_api_request method, which is the main method that
is used to make requests to the API.
A transport abstracts away the details of how requests are made to the API,
for example, it could be using requests, aiohttp, or any other library.
"""
def __init__(self, session):
self.__session = weakref.ref(session)
@property
def _session(self):
return self.__session()
@property
def _environment(self):
#Shortcut to access environment
return self._session.environment
def __eq__(self, other):
# It's the same transport if it's the same type (that's what users would generally assume)
return self.__class__ == other.__class__
async def is_working(self):
try:
return await self.async_api_request('/tests/ping').get('Code') == '1000'
except:
return False
async def async_api_request(
self, endpoint,
jsondata=None, additional_headers=None,
method=None, params=None
):
raise NotImplementedError("async_api_request should be implemented")
class TransportFactory:
def __init__(self, cls, *args, **kwargs):
self._cls = cls
self._args = args
self._kwargs = kwargs
def __call__(self, session):
return self._cls(session, *self._args, **self._kwargs)
def __eq__(self, other):
# It's the same transport if it's the same type (that's what users would generally assume)
return self._cls == other._cls
|