Connect to Tryton with JSON-RPC and PHP


(Vincenzo Ferraro) #21

Hi Ebdo,
what do you mean by http-header?
In rpc calls after login I get error 401:
User id and session returned from the server I added them in “params”.
Where am I doing wrong?


(Vincenzo Ferraro) #22

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???


(Cédric Krier) #23

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.


(Vincenzo Ferraro) #24

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 …


(Cédric Krier) #25

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.


(Sergio Morillo) #26

Have you initialized the database?


(Vincenzo Ferraro) #27

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?


(Sergio Morillo) #28

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


(Cédric Krier) #29

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


(Vincenzo Ferraro) #30

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'

(Vincenzo Ferraro) #31

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?


(Cédric Krier) #32

It looks like your context is not a dictionary.


(Vincenzo Ferraro) #33

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?


(Cédric Krier) #34

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.


(Vincenzo Ferraro) #35

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)


(Cédric Krier) #36

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


(Vincenzo Ferraro) #37

I will be happy to share my experience!


(albert) #39

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!


(Vincenzo Ferraro) #40

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?


(Vincenzo Ferraro) #41

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));