Как позвонить в тритон из jsonrpc - PullRequest
0 голосов
/ 18 февраля 2020

Я пытаюсь подключиться через json -rp c к Trytond, используя этот класс

class HttpClient:
    """HTTP Client to make JSON RPC requests to Tryton server.
    User is logged in when an object is created.
    """

    def __init__(self, url, database_name, user, passwd):
        self._url = '{}/{}/'.format(url, database_name)
        self._user = user
        self._passwd = passwd
        self._login()
        self._id = 0

    def get_id(self):
        self._id += 1
        return self._id

    def _login(self):
        """
        Returns list, where
        0 - user id
        1 - session token
        """
        payload = json.dumps({
            'params': [self._user, {'password': self._passwd}],
            'jsonrpc': "2.0",
            'method': 'common.db.login',
            'id': 1,
        })
        headers = {'content-type': 'application/json'}
        result = requests.post(self._url, data=payload, headers=headers)
        if result.status_code in [500, 401]:
            raise Exception(result.text)

        if 'json' in result:
            self._session = result.json()['result']
        else:
            self._session = json.loads(result.text)

        return self._session

    def call(self, prefix, method, params=[[], {}]):
        """RPC Call
        """
        method = '{}.{}'.format(prefix, method)
        payload = json.dumps({
            'params': params,
            'method': method,
            'id': self.get_id(),

        })

        authorization = base64.b64encode(self._session[1].encode('utf-8'))
        headers = {
        'Content-Type': 'application/json',
        'Authorization': b'Session ' + authorization
        }

        response = requests.post(self._url, data=payload, headers=headers)
        if response.status_code in [500, 401]:
            raise Exception(response.text)
        return response.json()

    def model(self, model, method, args=[], kwargs={}):
        return self.call('model.%s' % model, method, [args, kwargs])

    def system(self, method):
        return self.call('system', method, params=[])

, и я называю его таким образом

def notifieToMainServer(self):
    url = "http://%s:%s" % (HOST, PORT)
    headers = {'content-type': 'application/json'}
    client = HttpClient(url, "tryton", CREDENTIALS[0], CREDENTIALS[1])   
    client.model('main.register',
                 'ActivateService', 
                 {'code': self.code,
                  'name': self.nome,
                  'surname': self.cognome,
                  'service_type': 'registry',
                  'service_url': '' # qui andra messa l'url di chimata
                  }
                 )

Создание HttpClient работает хорошо, и я могу войти в систему, но когда я пытаюсь вызвать метод ActivateService, я получаю ответ 401.

Я также добавляю ActivateService в класс rp c

@classmethod
def __setup__(cls):
    super(MainRegister, cls).__setup__()
    cls.__rpc__.update({    
            'ActivateService': RPC(instantiate=0)})  

и функция такая как

def ActivateService(self,
                    code,
                    name,
                    surname,
                    service_type,
                    service_url):
    """
        activate the service for the given code and the given service
    """

что я сделал не так?

с наилучшими пожеланиями, Маттео

Ответы [ 2 ]

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

Заголовок авторизации должен быть:

'Авторизация':: b'Bearer '+ авторизация

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

В конце концов я решаю проблему с этим изменяющим классом

class HttpClient:
    """HTTP Client to make JSON RPC requests to Tryton server.
    User is logged in when an object is created.
    """

    def __init__(self, url, database_name, user, passwd):
        self._url = '{}/{}/'.format(url, database_name)
        self._user = user
        self._passwd = passwd
        self._login()
        self._id = 0

    def get_id(self):
        self._id += 1
        return self._id

    def _login(self):
        """
        Returns list, where
        0 - user id
        1 - session token
        """
        payload = json.dumps({
            'params': [self._user, {'password': self._passwd}],
            'jsonrpc': "2.0",
            'method': 'common.db.login',
            'id': 1,
        })
        headers = {'content-type': 'application/json'}
        result = requests.post(self._url,
                               data=payload,
                               headers=headers)
        if result.status_code in [500, 401]:
            raise Exception(result.text)

        if 'json' in result:
            self._session = result.json()['result']
        else:
            self._session = json.loads(result.text)

        return self._session

    def call(self, prefix, method, params=[[], {}, {}]):
        """RPC Call
        """
        method = '{}.{}'.format(prefix, method)
        payload = json.dumps({
            'params': params,
            'method': method,
            'id': self.get_id(),
         })
        auth = "%s:%s:%s" % (self._user, self._session[0], self._session[1])
        authorization = base64.b64encode(auth.encode('utf-8'))
        headers = {
        'Content-Type': 'application/json',
        'Authorization': b'Session ' + authorization
        }

        response = requests.post(self._url,
                                 data=payload,
                                 headers=headers)
        if response.status_code in [500, 401]:
            raise Exception(response.text)
        return response.json()

    def model(self, model, method, args=[], kwargs={}):
        return self.call('model.%s' % model, method, (args, kwargs, {}))

    def system(self, method):
        return self.call('system', method, params=[])

ключевой момент - это вызов, который должен быть выполнен с контекстом, чтобы быть выполненным правильным образом !!

    def model(self, model, method, args=[], kwargs={}):
        return self.call('model.%s' % model, method, (args, kwargs, {}))

надеюсь, что это помогает с уважением

...