Connect to Tryton with JSON-RPC and PHP

I update you on my tests on json-rpc:

  • Login on http: // localhost: 8001 / <db_name> /
    return values: call_id, user_id and session_id.

  • Get User Preferences:
    on http: // localhost: 8001 / (if I add the db_name in the url I have 401 error)

JSON.stringify ({'method': 'model.res.user.get_preferences', 'id': 3, 'params': [userId, session, true, {}]})

But I get this error:

u'model.res.user.get_preferences', Traceback (most recent call last):
   File "/site-packages/trytond/wsgi.py", line 71, in dispatch_request
     return endpoint (request, ** request.view_args)
   File "/site-packages/trytond/protocols/dispatcher.py", line 82, in root
     return methods [request.rpc_method] (request, * request.rpc_params)
KeyError: u'model.res.user.get_preferences'

Who helps me???

The user and session should not be passed as parameters. They must be set in ‘Authorization’ header as "Session " + base64("<login>:<user id>:<session>").
But you can also not use a session but just the basic HTTP authentication with user/password.

Thanks for the reply.

I modified the call in:

$ .ajax ({
'contentType': 'application / json',
'data': JSON.stringify ({'method': 'model.res.user.get_preferences', 'id': 3, 'params': [true, {}]}),
'dataType': 'json',
'url': 'http://<user>:<pass>@localhost:8001/tryton/',
'type': 'post'}

and I get the 401 error from the server.

If I edit the url to
http://<user>:<pass>@localhost:8001/
(without db_name), i get the following error:

‘model.res.user.get_preferences’, Traceback (most recent call last):
File “/site-packages/trytond/wsgi.py”, line 71, in dispatch_request
return endpoint (request, ** request.view_args)
File “/site-packages/trytond/protocols/dispatcher.py”, line 82, in root
return methods [request.rpc_method] (request, * request.rpc_params)
KeyError: u’model.res.user.get_preferences’

I am discouraged …

I doubt that jQuery support such URL format.

Why? If you do not define a database name, trytond can not know which one to use.

Have you initialized the database?

Yes, sergyo.

I used the authorization header. Now the call at model.res.user.get_preferences is ok!

I would now like to try to modify an existing party.category with:

{'id': 4, 'method': 'model.party.category.write', 'params': [[3], {'active': true, 'name': 'newCategory', 'parent': null }, true, context]}

  • context is the answer to the call model.res.user.get_preferences.

I get the following error:

Traceback (most recent call last):
  File "/site-packages/trytond/wsgi.py", line 71, in dispatch_request
    return endpoint (request, ** request.view_args)
  File "/site-packages/trytond/protocols/dispatcher.py", line 41, in rpc
    request, database_name, * request.rpc_params)
  File "/site-packages/trytond/wsgi.py", line 42, in auth_required
    return wrapped (* args, ** kwargs)
  File "/site-packages/trytond/protocols/wrappers.py", line 122, in wrapper
    return func (request, pool, * args, ** kwargs)
  File "/site-packages/trytond/protocols/dispatcher.py", line 167, in _dispatch
    result = rpc.result (meth (* c_args, ** c_kwargs))
  File "/site-packages/trytond/model/modelsql.py", line 926, in write
    assert not len ​​(args)% 2
AssertionError

Where am I wrong?

Please check the params. Write method needs pairs of list of records ids and dict of changes.

Why do you put an extra argument true? The write method does not have such extra argument.

Sorry,
I looked for examples on the net and I’m not sure the syntax is correct.
Also to get the user preferences on the net I found only examples in which userId and SessionId were inserted in “params”.

Is the “context” variable correct (user preferences)?

With this configuration:

{'id': 4, 'method': 'model.party.category.write', 'params': [[3], {'active': true, 'name': 'newCategory', 'parent': null }, context]}

I have this error:

'NoneType' object has no 'keys' attribute, Traceback (most recent call last):
  File "/site-packages/trytond/wsgi.py", line 71, in dispatch_request
    return endpoint (request, ** request.view_args)
  File "/site-packages/trytond/protocols/dispatcher.py", line 41, in rpc
    request, database_name, * request.rpc_params)
  File "/site-packages/trytond/wsgi.py", line 42, in auth_required
    return wrapped (* args, ** kwargs)
  File "/site-packages/trytond/protocols/wrappers.py", line 122, in wrapper
    return func (request, pool, * args, ** kwargs)
  File "/site-packages/trytond/protocols/dispatcher.py", line 162, in _dispatch
    = rpc.convert (obj, * args, ** kwargs)
  File "/site-packages/trytond/rpc.py", line 41, in convert
    for key in context.keys ():
AttributeError: 'NoneType' object has no attribute 'keys'

What can this error depend on?

'unicode' object has no 'keys' attribute, Traceback (most recent call last):
   File "/site-packages/trytond/wsgi.py", line 71, in dispatch_request
     return endpoint (request, ** request.view_args)
   File "/site-packages/trytond/protocols/dispatcher.py", line 41, in rpc
     request, database_name, * request.rpc_params)
   File "/site-packages/trytond/wsgi.py", line 42, in auth_required
     return wrapped (* args, ** kwargs)
   File "/site-packages/trytond/protocols/wrappers.py", line 122, in wrapper
     return func (request, pool, * args, ** kwargs)
   File "/site-packages/trytond/protocols/dispatcher.py", line 162, in _dispatch
     = rpc.convert (obj, * args, ** kwargs)
   File "/site-packages/trytond/rpc.py", line 41, in convert
     for key in context.keys ():
AttributeError: 'unicode' object has no attribute 'keys'

Is it possible that it is related to user preferences?

It looks like your context is not a dictionary.

Good morning,
the answer of the server is:

{“company”:1,“groups”:[5,6,18,1,11,4,9,31,30,2,15,8,3,22,23,7,17,16,20,35,26,25,32,34,33,29,36,27,28,21,13,12,14,24,19,37,10],“language”:“en”,“employee”:null,“language_direction”:“ltr”,“company_work_time”:{“M”:576000,“d”:28800,“h”:3600,“m”:60,“s”:1,“w”:144000,“Y”:6912000},“company.rec_name”:“Simpool”}

Is this a dictionary?

Maybe or maybe not.

Shows that in this case it is None (null).

Shows that int this case it is a string instead of a dictionary.

Thanks a lot ced! :+1::+1::+1:

Summary my progress in Json-Rpc:

  • Access to tryton
  • Get user preferences
  • Create a new category (party.category)
  • Edit an existing category (party.category)
  • Delete an existing category (party.category)

I have yet to test the reading of existing categories (with and without search filters)

Then it will be great to provide improvement to Remote Procedure Call — trytond 5.3 documentation

I will be happy to share my experience!

Sorry for joining so late to the discussion.

We’ve already done some work in order to connect to Tryton using JSONRPC with PHP.

I created this snippet where you can find a library (modified version of an existing one) as well as a command line example (works with both HTTP & HTTPS):

https://bitbucket.org/snippets/nantic/Le9Mnj

Hope it helps!

Thank you so much!
in jsonRPCClient.php I get an error and I think I understand the cause.
The correct format for login is that username and password are sent in this format:

[user, {'password': password}]

while in the jsonRPCClient.php file username and password are sent in the format:

[Username, password]

This generates an error:

Fatal error: Uncaught Exception: Request error: ["LoginException", ["password", "Password", "password"]] in /Users/ivinci/Desktop/php/jsonRPCClient.php:189
Stack trace:
# 0 /Users/ivinci/Desktop/php/jsonRPCClient.php(103): jsonRPCClient -> __ call ('common.db.login', Array)
# 1 /Users/ivinci/Desktop/php/jsonRPCClient.php(91): jsonRPCClient-> cl ('common.db.login', Array)
# 2 /Users/ivinci/Desktop/php/client.php(63): jsonRPCClient-> login ('<user>', '<pass>')
# 3 {main}
   thrown in /Users/ivinci/Desktop/php/jsonRPCClient.php online 189

How could the array be written in order to have that format?

Login Function

Change:

$session = $this->cl('common.db.login', array($username, $password));

To:

if ($this->version > 38) {
            $password = array('password' => $password);
        }
$session = $this->cl('common.db.login', array($username, $password));

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.