Last updated 17 January 2012. Created on 17 January 2012.
Edited by josepvalls. Log in to edit this page.

After you have exposed the node and user resources you can first log in a user and perform an action with the session cookie returned. To keep the session cookie I am using some code from Roberto Rocco Angeloni:
http://www.roccoangeloni.it/wp/2008/06/13/xmlrpclib-with-cookie-aware-tr...

Then:

tr = CookieTransport()
server = xmlrpclib.Server(url, transport=tr)
server.system.connect()
user = server.user.login('user','password')
tr.SESSION_ID_STRING = user['session_name']
tr.mysessid = user['sessid']
new_node = {'body': 'Ordenar bibliotecas es ejercer de un modo silencioso el arte de la critica.\n-- Jorge Luis Borges. (1899-1986) Escritor argentino.', 'type': 'page', 'title': 'Just a little test'}
server.node.create(new_node)
server.node.retrieve(10)['uid']

Looking for support? Visit the Drupal.org forums, or join #drupal-support in IRC.

Comments

josepvalls’s picture

I wrote this page after I found out that the linked drupal_services.py project was outdated.
I found an updated project on github and I've updated the documentation in http://drupal.org/node/763066
https://github.com/dgtlmoon/python_drupal_services/blob/master/drupal_se...

k-nar’s picture

hello I launched the updated drupal_services.py (node creation test) with Service 3.1 and I get "Access denied for user anonymous" even though I'm using admin credentials, does it work for you ?

k-nar’s picture

my quick fix for drupal_services.py
line 57
- result = re.search('.+(SESS.*?;)', response.getheader("Set-Cookie", 0), re.IGNORECASE)
- if result is not None:
- self.cookie = result.group(1)
+ self.cookie = response.getheader("Set-Cookie", 0)

also line 97
- return getattr(self, method_name)(args[0])
+ return getattr(self, method_name)(*args)

00trav’s picture

I am pretty new to python, do you mind giving some example code of how to use this class.
Thank you in advance.

mozodan’s picture

With Services 3 and Drupal 7 I have to use a token to avoid an error: "401 CSRF Invalid". This is the code that worked for me:

# Clase que permite modificar las cabeceras de lo que se va a enviar al servidor XML-RPC 
# Basicamente lo que hace es añadir el parametro Cookie y el token X-CSRF-Token 

class CookieTransport(xmlrpclib.Transport):
   def send_content(self, connection, request_body):
     if hasattr(self,'cookiename'):
       connection.putheader('Cookie', "%s=%s" % (self.cookiename, self.cookievalue))
     if hasattr(self,'token'):
       connection.putheader('X-CSRF-Token', "%s" % (self.token))
     return xmlrpclib.Transport.send_content(self, connection, request_body)

# Se crea un transporte del tipo creado anteriormente
transport=CookieTransport()

# Se crea el proxy de nuestro servidor XML-RPC para las llamadas a procedimiento remoto. 
# Hay que pasarle el transporte creado para poder modificar las cabeceras 
server=xmlrpclib.ServerProxy('http://10.82.12.222/gesweb/test_xmlrpcserver',transport)

# Validamos el usuario con el que queremos crear el contenido 
login=server.user.login('myuser','mypassword')

# Una vez validado, moficamos los valores de la cookie e invocamos al token para recuperar el valor X-CSRF que será 
# el que utilice el servidor XML-RPC para validar las peticiones 
transport.cookievalue=login['sessid']
transport.cookiename=login['session_name']


token=server.user.token()
transport.token=token['token']

nodo_nuevo={'type': 'article', 'title': 'Titulo de prueba','body':{'und':{'0':{'value':'Articulo creado con el usuario myuser'}}}}

server.contenido.create(nodo_nuevo)

Hope this helps!

mozodan’s picture

With Services 3 and Drupal 7 I have to use a token to avoid an error: "401 CSRF Invalid". This is the code that worked for me:

# Clase que permite modificar las cabeceras de lo que se va a enviar al servidor XML-RPC 
# Basicamente lo que hace es añadir el parametro Cookie y el token X-CSRF-Token 

class CookieTransport(xmlrpclib.Transport):
   def send_content(self, connection, request_body):
     if hasattr(self,'cookiename'):
       connection.putheader('Cookie', "%s=%s" % (self.cookiename, self.cookievalue))
     if hasattr(self,'token'):
       connection.putheader('X-CSRF-Token', "%s" % (self.token))
     return xmlrpclib.Transport.send_content(self, connection, request_body)

# Se crea un transporte del tipo creado anteriormente
transport=CookieTransport()

# Se crea el proxy de nuestro servidor XML-RPC para las llamadas a procedimiento remoto. 
# Hay que pasarle el transporte creado para poder modificar las cabeceras 
server=xmlrpclib.ServerProxy('http://10.82.12.222/gesweb/test_xmlrpcserver',transport)

# Validamos el usuario con el que queremos crear el contenido 
login=server.user.login('myuser','mypassword')

# Una vez validado, moficamos los valores de la cookie e invocamos al token para recuperar el valor X-CSRF que será 
# el que utilice el servidor XML-RPC para validar las peticiones 
transport.cookievalue=login['sessid']
transport.cookiename=login['session_name']


token=server.user.token()
transport.token=token['token']

nodo_nuevo={'type': 'article', 'title': 'Titulo de prueba','body':{'und':{'0':{'value':'Articulo creado con el usuario myuser'}}}}

server.contenido.create(nodo_nuevo)

Hope this helps!

Mark aka Dark’s picture

I'm working with python 3.x and found out that things work somewhat differently. Eventually I figured it out. I'm posting the result here.

only thing i can't get to work is extra fields (custom fields).
But hopefully someone can use this.

import xmlrpc.client

class CookieTransport(xmlrpc.client.Transport):
    def send_content(self, connection, request_body):
        if hasattr(self,'cookiename'):
            connection.putheader('Cookie', "%s=%s" % (self.cookiename, self.cookievalue))
            if hasattr(self,'token'):
                connection.putheader('X-CSRF-Token', "%s" % (self.token))
        return xmlrpc.client.Transport.send_content(self, connection, request_body)

transport = CookieTransport()
url = "http://url.com/to/your/endpoint"
uname = 'Drupal username'
passwd = 'itsasecret'
proxy = xmlrpc.client.ServerProxy(url, transport)
login = proxy.user.login(uname,passwd)
transport.cookievalue=login['sessid']
transport.cookiename=login['session_name']
transport.token = login['token']

new_node={
               'type': 'benchmark',
               'title': 'benchmark result',
               'field_device': 'Nvidia 630M', 
               'field_operating_system':'Windhoos',
               'field_blender_version':'2.71a', 
               'field_render_time': '00.00.01', 
               }
bmresult = proxy.benchmarks.create(new_benchmark)