IronPython is an implementation of the Python language for the .NET framework,
using the new Dynamic Language Runtime (DLR) as language services layer on top
of the Common Language Runtime (CLR). The DLR's reusable hosting model makes it
extremely suitable to add scripting capabilities to existing products.
In this post we'll create an ADAM command line utility that will allow us to run
IronPython scripts against an ADAM application.
Getting IronPython
IronPython can be downloaded from its CodePlex project page:
http://ironpython.codeplex.com/.
For this post we're using version 2.6 RC3. After downloading, installation is
pretty straight-forward.
Setting up a console application project
Using Visual Studio 2008, create a new console project named
Adam.Scripting.CommandLine and add references to the following assemblies (the
IronPython assemblies can be found in the IronPython installation directory,
which defaults to C:\Program Files\IronPython-2.6):
- Adam.Core.dll
- Adam.Tools.dll
- IronPython.dll
- Microsoft.Scripting.dll
- Microsoft.Scripting.Core.dll
The Adam.Tools assembly contains a set of classes that make life simpeler for
console application developers, and this is a nice occassion to elaborate on
some of these helpers. The
Arguments
class exposes
methods for parsing command line parameters and executing commands, much like
the standard Adam.Core.CommandLine.exe and Adam.Core.DatabaseManager.exe work.
Our command line tool will expose a single command, RunScript, that will take in
ADAM connection information and a path to a Python file to execute:
| C# |
1
2
3
4
|
static readonly Command[] ProgramCommands =
{
new Command("RunScript", RunScript, RunScriptHelp)
};
|
As you can see, a Command
is defined by a command name (which is used to identify the command passed
through the command line), and two delegates: one that handles the execution of
the command, and one that displays the help information for the command. These
delegates are automatically invoked when calling the
Arguments.ExecuteCommand(Command[], DisplayHelpDelegate) method.
Hosting the IronPython engine
In the RunScript command, we allow the user to specify the location of a Python
script file, which will then be executed by the IronPython engine. For this to
work, we need to initialize an IronPython hosting environment within our command line tool:
| C# |
1
2
3
4
5
6
7
8
9
10
11
|
// Initialize the IronPython engine.
ScriptEngine engine = Python.CreateEngine();
// Preparing the scope for the script.
ScriptScope scope = engine.CreateScope();
scope.Engine.Runtime.LoadAssembly(typeof(Application).Assembly);
scope.SetVariable("adamApp", app);
// Loading the script file.
ScriptSource source = engine.CreateScriptSourceFromFile(path);
source.Execute(scope);
|
First of all, we're creating an instance of the IronPython engine, which is a
factory for all IronPython-related work. As a side-note, the ScriptEngine class
is really a part of the DLR, and can be used to host other dynamic languages as
well (such as IronScheme, IronRuby, ...).
Next, we're creating and initializing a ScriptScope for the file we're going to
execute. This involves preparing the assembly references and global variables
that should be available to the script. In this case, we're adding a reference
to the Adam.Core assembly, and pass the logged on Application object as the adamApp variable.
Your very first ADAM IronPython Script
At this point we have a command line utility that can be run like this:
Adam.Scripting.CommandLine.exe -path=C:\Temp\ListUsers.py
-registration=AdamTest -userName=Administrator
-password=password
And now to test this, let's create a Python script that lists all users known to
ADAM. Open your favorite Python editor, and enter the following:
| Python |
1
2
3
4
5
6
7
|
import Adam.Core
users = Adam.Core.Management.UserCollection(adamApp)
users.Load(Adam.Core.Search.SearchExpression('*'))
for user in users:
print user.Name
|
Now, if we save the file to ListUsers.py, and run the script using our command
line tool, the output should list all ADAM users. Please note that the adamApp
variable is available in the script (as passed through the scope), and the
import Adam.Core statement is required to make the Adam.Core namespaces
available.
Wrapping it up
And now it is up to you to experiment. Go nuts. You could use this little
application to create import scripts (yes, you can add records, users and
other ADAM objects using script), create maintenance jobs, or even, given some
modifications, execute workflows using script. Feel free to share your
experiences in the comments. Happy coding!