Python «запросов» с декоратором - PullRequest
1 голос
/ 19 февраля 2020

Вот мой код, который я пытаюсь сделать:

import json
import requests

class Request(object):
  def __init__(self, method, path):
    self.method = method
    ## Q1
    self.url = ''.join([***MyClass.host***, path])
    self.h = {
      "Content-Type": "application/json;charset=UTF-8"
    }

  def __call__(self, f):
    def wrapper(*args, **kwargs):
      # Q2
      getattr(requests, self.method)(url = self.url, headers = h***, data = json.dumps(body)***)
    return wrapper

class MyClass(object):
  def __init__(self, host):
    self.host = host

  @Request(method = "post", path = "/add_mission")
  def AddMission(self, mission):
    body = {
      "mission_id": mission
    }

  @Request(method = "get", path = "/system_info")
  def GetInfo(self):
    print("I want get info")

Есть несколько вопросов, надеюсь, кто-то может решить мои проблемы:
1. Как мой декоратор "Запрос" получить переменную " хост "от" MyClass "? (В комментарии ## Q1)
2. Как я могу передать переменную функции "body" декоратору, возможно ли это? (В комментарии ## Q2)

Поскольку мне нужно получить доступ к другому URL (хост + путь) с помощью [post, get, delete]. Я не уверен, что декоратор не соответствует этому делу? Или, может быть, есть лучшие способы разобраться с этим делом?

1 Ответ

1 голос
/ 20 февраля 2020

Хост доступен после вызова украшенной функции через атрибут host вызывающего объекта, поэтому подождите, пока вы на самом деле не вызовете метод для создания URL. Вам нужно вызвать базовую функцию, чтобы получить значение, если оно есть, для использования в качестве полезной нагрузки.

import json
import requests

class Request(object):
    def __init__(self, method, path):
        self.method = method.upper()
        self.h = {
            "Content-Type": "application/json;charset=UTF-8"
        }

  def __call__(self, f):
      def wrapper(obj, *args, **kwargs):
          payload = f(*args, **kwargs)
          args = {
              'method': self.method,
              'url': 'http://{}/{}'.format(obj.host, self.path)
              'headers': self.h
          }
          if payload is not None:
              args['json'] = payload
          return requests.request(**args)
      return wrapper


class MyClass(object):
    def __init__(self, host):
        self.host = host

    @Request(method="post", path="/add_mission")
    def AddMission(self, mission):
        return {"mission_id": mission}

    @Request(method="get", path="/system_info")
    def GetInfo(self):
        print("I want get info")

Затем вы можете написать, например,

api = MyClass("www.example.com")
add_response = api.AddMission("mars")
info_response = api.GetInfo()

Каждая декорированная функция возвращает объект Response, созданный при вызове requests.request.

Вы можете рассмотреть подклассы Request для каждого метода:

class GetRequest(Request):
    def __init__(self, path):
        super().__init__("GET", path)

class PostRequest(Request):
    def __init__(self, path):
        super().__init__("POST", path)

# etc
...