XFiles - Fabric extension

Nowadays, there are a lot of XML formatted files used for both configuration and other resources, and therefore having a method to work with them is must have.

XFiles is a Fabric extension that aims to provides a support for reading and writing XML files located on remote servers or in local filesystem.

Note

The current version does support only reading the XML files.

See Changelog to see the list of features per version.

Introduction

Short introduction to the extension, covering the installation and usage of the module.

Prerequisites

The extension is dependent on following solutions:

  • Python 2.5 or higher (Fabric requires py2.5)
  • Fabric and its requirements
Installation

Install the module by using following steps:

  1. Download and install Distribute:

    curl -O http://python-distribute.org/distribute_setup.py
    sudo python distribute_setup.py
    
  2. Install fabric-contrib.xfiles -module and Fabric (if not yet installed) using easy_install or pip:

    easy_install -U Fabric fabric-contrib.xfiles
    

OR:

pip install -U Fabric fabric-contrib.xfiles
Usage

Simple usage example

  1. Create Fabric configuration file fabfile.py, for example with following contents:

    from fabric.api import env, run
    from fabric.contrib import xfiles
    
    def test():
      for elem in xfiles.query('~/document.xml', '/root/item[id=test*]'):
        # List all the elements having the attribute 'id'
        # and it with value 'test', or something that starts with it
        print elem.text
    

    In this example, it is expected you have XML -document in your home directory (on remotehost -server), for example:

    <root>
      <item id="foo">value1</item>
      <item id="testing">value2</item>
      <item id="test">value3</item>
    </root>
    
  2. To see the outcome, run the command:

    fab --username hostaccount -H remotehost test
    

    Unless you have SSH private key provided for the remotehost, it’ll prompt for the password. After successful login, the XML file is read and text from all /root/item -elements is listed.

    Tip

    If the host parameter is not provided, or it is localhost, no SSH connection is needed/created and the file path is expected to be found from local filesystem. For example, following query reads the XML from same directory where the fabfile.py is:

    for elem in xfiles.query('test.xml', '/root/sub'):
      print elem
    

Usage

The example above shows only a one way how to use the extension. This shows additional and more advanced examples.

static xfiles.query(path, xquery, fail_on_error=True)

Makes query to remote XML file and returns the matching entries back

path
Path to remote XML document
xquery

XQuery -like selection for the elements/values in the XML document. Selection format:

path/to/elements            # <-- matches to elements -element
/root/path/to/elements      # <-- absolute selection example
path/to=value               # <-- matches with 'to' element when having text 'value' in it
path/to=val*                # <-- matches with 'to' element when having text starting with 'val'
path/to/elements[id]        # <-- matches to all elements having 'id' attribute
path/to/elements[@id]       # <-- same as above
path/to/elements[i?]        # <-- matches to all attributes with 'i'+something
path/to/elements[i*]        # <-- matches to all attributes with 'i'
path/to/elements[id=value]  # <-- matches to all elements having 'id' attribute with value 'value'
path/to/elements[@id=value] # <-- same as above
path/to/elements[id=val*]   # <-- matches to all elements having 'val'+something
path/to/elements[i?=val*]   # <-- combination from above
path/to[i?=val*]=val*       # <-- combination from all of the above

Note

Wildcard are not supported for paths - at least not yet. So, for example, following is not supported:

path/to/elem*
fail_on_error (default True)
If the document reading/parsing fails, an exception is raised. However, if this flag is set to False, and empty list is returned instead - silently.
returns
List of ElementTree -elements. Or empty list if silent fail flag is set

Example usage:

# fabfile.py
from fabric.contrib import xfiles

def mycommand():
  for elem in xfiles.query('path/to/remotedoc.xml', 'items/item'):
    print elem.text, elem.attrib

And to run fabfile:

fab mycommand
static xfiles.pprint(path, xquery)

Prints the matching entries (whereas query() only returns elements)

# fabfile.py
from fabric.contrib import xfiles

def mycommand(rpath):
  #Lists the elements of remote document.
  xfiles.pprint(rpath, 'items/item[attr=value]')

And to run fabfile:

fab mycommand:document.xml
static xfiles.validate(path, dtd=None, xmlschema=None, relaxng=None, fail_on_error=True)

Validates the given XML document, based on provided schema (if at all):

New in version 0.2.

dtd
Path to local DTD schema file. If provided, the XML document will be validated against it.
xmlschema
Path to local XMLSchema file. If provided, the XML document will be validated against it.
relaxng
Path to local RelaxNG file. If provided, the XML document will be validated against it.

If none of these schema files are provided, the basic XML document parsing is done to ensure the validity of the document.

If the validation fails, the exception is thrown, hopefully with descriptive message why the validation did not pass. If fail_on_error is set False, the function returns False on failure. Otherwise True.

Example

from fabric.contrib import xfiles

def check():
  #Checks the setup config validity
  dtd = 'server-config.dtd'
  xsd = 'config.xsd'

  try:
    xfiles.validate('/etc/appx/server.xml', dtd=dtd)
    xfiles.validate('/etc/appx/application.xml', xmlschema=xsd)
  except Exception as e:
    print 'Validation FAILED: %s' % e

Note

Schema validations requires lxml module to be installed on local environment.

http://codespeak.net/lxml/validation.html#xmlschema

Development

The source and issue management is hosted in Bitbucket mercurial repository: http://bitbucket.org/jmu/fabric-contrib/. With the addition of liberal MIT-license, the extension is free to use for both commercial and personal usage.

For the development, following additional modules are needed:

  • Nose - for unit testing
  • Fudge - for test mockups
  • Coverage - for test coverage measurement

Table Of Contents

Next topic

Changelog

This Page