Example: file.save, node.save via XML-RPC in Python

Last updated on
30 April 2025

Sample code for using the Services API via XML-RPC

Includes system.connect, user.login, file.save, file.get, node.save (with file attachment and CCK text field) and node.get.

#! /usr/bin/python

import os.path, sys, time, mimetypes, xmlrpclib, pprint, base64
pp = pprint.PrettyPrinter()

config = {
  'url': 'http://example.com/services/xmlrpc',
  'username': 'developer',
  'password': 'password',
}

# Make initial connection to service, then login as developer
server = xmlrpclib.Server(config['url'], allow_none=True);
connection = server.system.connect();
session = server.user.login(connection['sessid'], config['username'], config['password']);
sessid = session['sessid'];
user = session['user'];

timestamp = str(int(time.time()))

## Load a movie file
filename = 'testfile.MOV'
filesize = os.stat(filename).st_size
filemime = mimetypes.guess_type(filename)
fd = open(filename, 'rb')
video_file = fd.read()
fd.close()

# Create a file_obj dict with encoded file data
file_obj = {
    'file': base64.b64encode(video_file),
    'filename': filename,
    'filepath': 'sites/default/files/' + filename,
    'filesize': filesize,
    'timestamp': timestamp,
    'uid': user['uid'],
    'filemime': filemime,
}

# Save the file to the server
try:
    f = server.file.save(sessid, file_obj)

except xmlrpclib.Fault, err:
    print "A fault occurred"
    print "Fault code: %d" % err.faultCode
    print "Fault string: %s" % err.faultString

else:
    pp.pprint(f) # DEBUG print new file id (fid)

'''
# Get the new file from the server (verify)  DEBUG - not needed - but shows how to retrieve a file based on fid
try:
    ff = server.file.get(sessid, f)

except xmlrpclib.Fault, err:
    print "A fault occurred"
    print "Fault code: %d" % err.faultCode
    print "Fault string: %s" % err.faultString

else:
    # pp.pprint(ff) # DEBUG - dump the file structure - including the file data
'''

# Create the node object and reference the new fid just created
node = {
  'type': 'video_local',
  'status': 1,
  'type': 'video_local',
  'title': 'Remote Test ' + timestamp,
  'body': 'This is a test created from a remote app',
  'uid': user['uid'],
  'name': user['name'],
  'changed': timestamp,
  'files': { f: {
    'new': 1, # Required to insert the referenced file->fid as new attachment!
    'fid': f, # f is fid from uploaded video file
    'list': 1, # Or 1, depending on whether you want the attachment listed on node view.
    'description': 'Video File', # Any text description
    'weight': 0,
    }
  },
  'field_video_overlay' : [
    {'value': 'CCK Text Goes Here'},
  ],
}

pp.pprint(node) # DEBUG - dump the node - shows exact format to use in other languages

try:
    n = server.node.save(sessid, node)
    # nn = server.node.get(sessid,int(n),[])  # DEBUG - get the final node - not needed now that we know it works

except xmlrpclib.Fault, err:
    print "A fault occurred"
    print "Fault code: %d" % err.faultCode
    print "Fault string: %s" % err.faultString

else:
    pp.pprint(n) # DEBUG
    # pp.pprint(nn) # DEBUG - dump the final node - not needed now that we know it works

Help improve this page

Page status: Not set

You can: