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']

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)