如何通过继承在Python中创建requests的子类

6

我希望专门化/子类化requests包,以添加一些具有自定义功能的方法。

我尝试这样做:

# 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()

这样我仍然可以从self.requests成员和我的具体实现中受益。所以我可以这样做:self.requests.get(...)或者print(self.requests.post(...).status_code)等等。
我猜这一行super(concreteRequests, self).__init__()可能是愚蠢无用的,因为requests没有任何类声明,只有导入...
所以,requests包可以通过继承进行子类化/专业化吗?
3个回答

7

requests 是一个 Python 模块,而不是一个类。你只能继承类。

因此,你应该在自己的自定义类中利用它的方法/函数。

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

我上面写的只是一个例子,让你开始工作。

直接使用...然后,我想我会在__init__()中做类似于self.session = requests.session()的事情,然后执行像self.login()这样的方法,调用例如self.session.get()并执行更多操作...
  • 谢谢!
- Jeflopo
@JesúsFlores 是的,完全正确。 - rantanplan

4
一个好的方法是从 requests 中的一个 Session 对象继承子类。以下是一个基本示例:

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 包含免费的Session (request) api,您还可以添加任何其他想要的内容。

一个实际的例子:假设客户端在运行时需要指定身份验证标头(在这种情况下,身份验证需要当前时间戳)。以下是一个子类 Session 和子类化后的AuthBase 实现的示例客户端(此代码需要为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

1

我想给你一个完整的例子:

    # ----example.py----
    from locust import HttpUser, task, between
    import requests

    # Create fake api endpoint POST https://mocki.io/fake-json-api 
    class MyClient():
        def __init__(self, host):
            self.session = requests.session()
            self.host = host

        def create_user(self, *args, **kwargs):
            return self.session.post('{}/v1/9b021e1a'.format(self.host), json={"name":"something"})

    class QuickstartUser(HttpUser):
        wait_time = between(1, 2)

        @task
        def api(self):
            my_client = MyClient('https://api.mocki.io')
            my_client.session = self.client
            print(my_client.create_user().status_code)

    print('Executing client normally')
    client = MyClient('https://api.mocki.io')
    print(client.create_user().status_code)

您可以执行客户端代码:

python example.py

您也可以使用 locust 执行客户端:

locust --host https://api.mocki.io --users 5 --spawn-rate 1 --locustfile example.py

在这两种执行方式中,您都使用了相同的客户端。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接