I would like to specialize / subclass the requests package to add some method with custom functionality.
I tried to do this:
# concrete_requests.py
import requests
class concreteRequests(requests):
def __init__(self):
super(concreteRequests, self).__init__()
self.session()
def login(self):
payload = {'user': 'foo', 'pass': 'bar'}
self.get('loginUrl', headers=header, data=payload)
# more login stuff...
# my_class.py
class MyClass:
def __init__():
self.requests = concreteRequests()
self.requests.login()
This way I could still benefit from self.requests
members + my concrete implementation. So I could do: self.requests.get(...)
or print(self.requests.post(...).status_code)
and so on.
I guess that this line super(concreteRequests, self).__init__()
can be stupidly useless since requests doesn't have any class declaration inside just imports...
So, the requests package can be subclassed/specialized through inheritance ?
requests
is a python module not a class. You can only subclass classes.
So basically you should just leverage its methods/functions inside your own custom class.
import requests
class MyRequests:
def __init__(self, username, passwd):
self.username = username
self.passwd = passwd
def get(self, *args, **kwargs):
# do your thing
resp = requests.get(...)
# do more processing
What I wrote above is just an example to get you going.
A good way is to subclass a Session
object from requests. A basic example:
from requests import Session
class MyClient(Session):
"""Specialized client that inherits the requests api."""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
def get_google(self):
return self.get("http://google.com")
MyClient
includes the Session (request
) api for for free, and anything else you want to add to it.
A real-world example: suppose a client requires an auth header specified at runtime (in this case the auth requires a current timestamp). Here is an example client that subclasses Session
and of subclassed AuthBase
that achieves that (this code requires values set for api_key, secret_key, passphrase):
import json, hmac, hashlib, time, requests, base64
from requests.auth import AuthBase
from requests import Session
class MyClient(Session):
"""Client with specialized auth required by api."""
def __init__(self, api_key, secret_key, passphrase, *args, **kwargs):
# allow passing args to `Session.__init__`
super().__init__(*args, **kwargs)
# `self.auth` callable that creates timestamp when request is made
self.auth = MyAuth(api_key, secret_key, passphrase)
class MyAuth(AuthBase):
"""Auth includes current timestamp when called.
https://docs.python-requests.org/en/master/user/advanced/#custom-authentication
"""
def __init__(self, api_key, secret_key, passphrase):
self.api_key = api_key
self.secret_key = secret_key
self.passphrase = passphrase
def __call__(self, request):
timestamp = str(time.time())
message = timestamp + request.method + request.path_url + (request.body or "")
message = message.encode("utf-8")
hmac_key = base64.b64decode(self.secret_key)
signature = hmac.new(hmac_key, message, hashlib.sha256)
signature_b64 = base64.b64encode(signature.digest())
request.headers.update(
{
"ACCESS-SIGN": signature_b64,
"ACCESS-TIMESTAMP": timestamp,
"ACCESS-KEY": self.api_key,
"ACCESS-PASSPHRASE": self.passphrase,
"Content-Type": "application/json",
}
)
return request
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With