以下は、 Webfaction XML-RPC APIを使用してデータベースを作成するための django テスト スイート ランナーです。API を使用したデータベースのセットアップには 1 分ほどかかる場合があり、スクリプトが一時的に停止しているように見える場合があります。しばらくお待ちください。
注: Webfaction サーバーでコントロール パネルのパスワードを使用すると、セキュリティ上のリスクがあります。これは、誰かが Web サーバーの SSH に侵入して Webfaction アカウントを乗っ取る可能性があるためです。それが懸念される場合は、USE_SESSKEY を True に設定し、このスクリプトの下にあるファブリック スクリプトを使用してセッション ID をサーバーに渡します。セッション キーは、最後の API 呼び出しから1 時間で期限切れになります。
ファイル test_runner.py: サーバーで、WebfactionTestRunner を使用するように ./manage.py テストを構成する必要があります。
"""
This test runner uses Webfaction XML-RPC API to create and destroy database
"""
# you can put your control panel username and password here.
# NOTE: there is a security risk of having control panel password in
# the webfaction server, because someone breaching into your web server
# SSH could take over your Webfaction account. If that is a concern,
# set USE_SESSKEY to True and use the fabric script below this script to
# generate a session.
USE_SESSKEY = True
# CP_USERNAME = 'webfactionusername' # required if and only if USE_SESSKEY is False
# CP_PASSWORD = 'webfactionpassword' # required if and only if USE_SESSKEY is False
import sys
import os
from django.test.simple import DjangoTestSuiteRunner
from django import db
from webfaction import Webfaction
def get_sesskey():
    f = os.path.expanduser("~/sesskey")
    sesskey = open(f).read().strip()
    os.remove(f)
    return sesskey
if USE_SESSKEY:
    wf = Webfaction(get_sesskey())
else:
    wf = Webfaction()
    wf.login(CP_USERNAME, CP_PASSWORD)
def get_db_user_and_type(connection):
    db_types = {
        'django.db.backends.postgresql_psycopg2': 'postgresql',
        'django.db.backends.mysql': 'mysql',
    }
    return (
        connection.settings_dict['USER'],
        db_types[connection.settings_dict['ENGINE']],
    )
def _create_test_db(self, verbosity, autoclobber):
    """
    Internal implementation - creates the test db tables.
    """
    test_database_name = self._get_test_db_name()
    db_user, db_type = get_db_user_and_type(self.connection)
    try:
        wf.create_db(db_user, test_database_name, db_type)
    except Exception as e:
        sys.stderr.write(
            "Got an error creating the test database: %s\n" % e)
        if not autoclobber:
            confirm = raw_input(
                "Type 'yes' if you would like to try deleting the test "
                "database '%s', or 'no' to cancel: " % test_database_name)
        if autoclobber or confirm == 'yes':
            try:
                if verbosity >= 1:
                    print("Destroying old test database '%s'..."
                        % self.connection.alias)
                wf.delete_db(test_database_name, db_type)
                wf.create_db(db_user, test_database_name, db_type)
            except Exception as e:
                sys.stderr.write(
                    "Got an error recreating the test database: %s\n" % e)
                sys.exit(2)
        else:
            print("Tests cancelled.")
            sys.exit(1)
    db.close_connection()
    return test_database_name
def _destroy_test_db(self, test_database_name, verbosity):
    """
    Internal implementation - remove the test db tables.
    """
    db_user, db_type = get_db_user_and_type(self.connection)
    wf.delete_db(test_database_name, db_type)
    self.connection.close()
class WebfactionTestRunner(DjangoTestSuiteRunner):
    def __init__(self, *args, **kwargs):
        # Monkey patch BaseDatabaseCreation with our own version
        from django.db.backends.creation import BaseDatabaseCreation
        BaseDatabaseCreation._create_test_db = _create_test_db
        BaseDatabaseCreation._destroy_test_db = _destroy_test_db
        return super(WebfactionTestRunner, self).__init__(*args, **kwargs)
ファイル webfaction.py: これは Webfaction API のシン ラッパーです。test_runner.py (リモート サーバー内) と fabfile.py (ローカル マシン内) の両方でインポート可能である必要があります。
import xmlrpclib
class Webfaction(object):
    def __init__(self, sesskey=None):
        self.connection = xmlrpclib.ServerProxy("https://api.webfaction.com/")
        self.sesskey = sesskey
    def login(self, username, password):
        self.sesskey, _ = self.connection.login(username, password)
    def create_db(self, db_user, db_name, db_type):
        """ Create a database owned by db_user """
        self.connection.create_db(self.sesskey, db_name, db_type, 'unused')
        # deletes the default user created by Webfaction API
        self.connection.make_user_owner_of_db(self.sesskey, db_user, db_name, db_type)
        self.connection.delete_db_user(self.sesskey, db_name, db_type)
    def delete_db(self, db_name, db_type):
        try:
            self.connection.delete_db_user(self.sesskey, db_name, db_type)
        except xmlrpclib.Fault as e:
            print 'ignored error:', e
        try:
            self.connection.delete_db(self.sesskey, db_name, db_type)
        except xmlrpclib.Fault as e:
            print 'ignored error:', e
ファイル fabfile.py: セッション キーを生成するためのサンプル ファブリック スクリプト。USE_SESSKEY=True の場合にのみ必要です。
from fabric.api import *
from fabric.operations import run, put
from webfaction import Webfaction
import io
env.hosts = ["webfactionusername@webfactionusername.webfactional.com"]
env.password = "webfactionpassword"
def run_test():
    wf = Webfaction()
    wf.login(env.hosts[0].split('@')[0], env.password)
    sesskey_file = '~/sesskey'
    sesskey = wf.sesskey
    try:
        put(io.StringIO(unicode(sesskey)), sesskey_file, mode='0600')
        # put your test code here
        # e.g. run('DJANGO_SETTINGS_MODULE=settings /path/to/virtualenv/python /path/to/manage.py test --testrunner=test_runner.WebfactionTestRunner')
        raise Exception('write your test here')
    finally:
        run("rm -f %s" % sesskey_file)