Blog‎ > ‎

Drupal XMLRPC: Create Nodes with Python

posted Nov 9, 2012, 10:20 AM by Pasi Orovuo   [ updated Nov 9, 2012, 10:21 AM ]
As a part of another project, I needed to create a lot (hundreds) of nodes in Python programmatically. The key to this is Service API, available in here: http://drupal.org/node/109782. Links on the page led me to this tutorial which uses a cookie aware transport available from here.

To my disappointment, the CookieTransport code doesn't work on Python 2.7. I got an error about missing getreply() method. Inspection of the code made me wonder if there would be a better way to implement the same functionality, but without copying large chunks of the parent class code to the subclass. A solution which appeared to me as rather non-oop... Below you'll find the code which works nicely on Python 2.7.

Otherwise the linked tutorial is very useful. Another thing to note is that when using Services API, I needed to grant access to Services API for Anonymous user. API itself requires authentication regardless.

#!/usr/bin/python

import xmlrpclib

class CookieTransport( xmlrpclib.Transport ):
    def __init__( self ):
        xmlrpclib.Transport.__init__( self )
        self.cookies = {}
        
    def set_cookie( self, key, value ):
        self.cookies[key] = value
        
    def unset_cookie( self, key ):
        if self.cookies.haskey( key ):
            del self.cookies[key]
    
    def get_cookies( self ):
        cookies = []
        for key in self.cookies.keys():
            cookies += [ '%s=%s' % ( key, self.cookies[key] ) ]
        return cookies
        
    def get_http_cookies( self ):
        cookies = self.get_cookies()
        return '; '.join( cookies ) if len( cookies ) > 0 else None
    
    def send_host( self, connection, host ):
        cookies = self.get_http_cookies()
        if cookies != None:
            connection.putheader( 'Cookie', cookies )
        return xmlrpclib.Transport.send_host( self, connection, host )

    def parse_response( self, response ):
        for header in response.getheaders():
            if header[0] == 'set-cookie':
                cookie = header[1].split( ';' )[0].strip()
                key, value = cookie.split( '=' )
                self.cookies[key] = value
        return xmlrpclib.Transport.parse_response( self, response )

Comments