ESAPI Programming with Python

      22 Comments on ESAPI Programming with Python

I’m used to programming in C# when creating Eclipse scripts with ESAPI. But there’s a lot of ceremony in that—opening Visual Studio, creating a new solution and project, referencing the ESAPI assemblies, creating a new program class, etc. That’s all fine if I’m creating a script that will be used by others.

But sometimes I just want to quickly get some information about a patient or patients and be done. It turns out that one can use Python to do this. Python is a general-purpose scripting language that’s easy to learn and use. Python was added to the family of .NET languages as IronPython. This is good because, as you may know, ESAPI is based on the .NET framework and therefore requires a .NET language to use it.

To get started, download and install IronPython. You can also install additional tools to integrate Python into Visual Studio, but I haven’t tried that yet. I’m just going to use a plain text editor.

Here’s the basic template of an ESAPI script in Python:

First, you tell it where the ESAPI assemblies are, and then you reference the required assemblies. You then create the application object (passing it your username and password). After your code, you dispose of the application object. (If you don’t dispose of it, you’ll get an annoying error before the program exists.)

Let’s use this template in an example. I’d like to output the multileaf collimator (MLC) leaf positions of all control points in a beam for a patient. Each output line will contain the control point index, the control point’s meterset weight, the jaw positions, and the positions of a leaf pair. Here’s the code:

As another example, I’d like to output the plan sums that contain plans with different structure set images. Here’s the code:

Each of these examples were coded in a single file—no need for solutions, projects, classes, etc. The code itself is also fairly easy to read because the language is streamlined and devoid of unnecessary syntax.

The IronPython Documentation website contains several useful links, including the Python language documentation and a reference on how IronPython integrates with the .NET framework.

22 thoughts on “ESAPI Programming with Python

  1. Joseph Bradshaw

    Hi Carlos,

    With all this in mind, do you feel you will be making the switch to using python now you can use it in the .NET framework or stick to c# for the time being? I’m still learning to program and have a much better understanding of c# but had decided to learn python with the intention of using it with Django for a work based project. I’m kind of torn between the two now having read your article. Any suggestions to which one I should devote my time?

    Thanks,
    Joseph.

    Reply
    1. Carlos Anderson Post author

      Hi Joseph,

      Personally, I use Python for simple scripts and C# for richer applications. The Python examples in the blog post simply pull data and display it as text. I use C# for anything more complex than that, especially if the script requires a user interface. The main reason for my choice is that I’m more comfortable with C# in non-trivial applications. For example, I know how to use NUnit to test my C# classes, I know how to concisely manipulate collections using LINQ, I know how to create and use C# class libraries, and I know how to use WPF and the MVVM pattern in C#.

      Of course, since IronPython is a .NET language you should be able to do all of the above with Python as well. But you’ll probably have to work a little harder to make it all work. For example, if you want Visual Studio to work well with Python you’ll need to install a plug-in. I’ve also read that you need to do additional steps to make it work with WPF.

      Since you already know C#, I would stick with C#. I think you’ll have an easier time developing complex applications that way. But since you’re also learning Python, you could give it a try in developing ESAPI scripts and see how that works for you. I know, I’m not providing a definite answer to your question. I really think it depends on the kinds of applications you’ll develop and on the familiarity you have with the language and the “ecosystem” around the language.

      Reply
  2. Matthew Schmidt

    Hi Carlos,

    Do you have an IDE you would recommend for IronPython? A few members on my time and I currently use Spyder, but it is my understanding that there is no Spyder support for IronPython…

    Thanks,

    Reply
    1. Carlos Anderson Post author

      There is Visual Studio support for IronPython: http://ironpython.net/tools. I haven’t personally used it, though, so I can’t comment on whether it’s actually good. Since my Python scripts have been pretty simple and all in one file, I just use vim. If you try the VS plug-in, please let me know if it’s good.

      Reply
  3. Joseph Bradshaw

    Thanks for the reply Carlos, I think I’ll stick to using C# for the time being then. I can’t seem to find a contact button on this site so hope you don’t mind me asking a question here. In terms of scripts, have you ever wrote anything which allows you to find the centre of an image series and set the user origin to that point? Is that even possible?

    Any info would be brilliant.

    Keep up the good work,

    Joseph.

    Reply
    1. Carlos Anderson Post author

      ESAPI is currently read-only, so you can’t change anything. You can only get information. If you look at the Image class, it has a read-only property called UserOrigin.

      Reply
  4. Todd S.

    Hi Carlos,
    Thanks for your tip on using IronPython with the ESAPI. From your example above, I occasionally run into an issue when trying to use CreateApplication — “Unable to cast object of type ‘VMS.TPS.Common.Model.Application’ to type ‘VMS.TPS.Common.Model.IApplication”. It seems sporadic — perhaps related to HIPPA logging? Any ideas?
    Thanks!

    Reply
    1. Carlos Anderson Post author

      Hi Todd,
      I don’t know what could be causing that error. I’ve asked other people and they’re not sure, either. Do you have multiple versions of Eclipse installed?

      Reply
      1. TJ

        Hello Carlos, I just came across your blog yesterday and it’s full of excellent information. Keep up the good work! I’ve tried to implement this example as well as the other example using IronPython with ESAPI, and both scripts give me the same error Todd encountered, however, my error is persistent rather than sporadic. I only have one version of Eclipse installed (11.0). Any ideas/suggestions?
        Thanks again!

        Reply
        1. Carlos Anderson Post author

          Hi TJ,
          Thanks for the encouragement! Unfortunately, it’s hard for me to know what the problem is when I can’t replicate it. My best guess is that the wrong version of IApplication is being loaded, which is why I asked about whether multiple Eclipse versions were installed. In your case, you only have one, so that’s confusing! Are you using Visual Studio to write the code? Visual Studio may be able to provide you with more details on the error itself, such as the versions of the assemblies it’s trying to load.

          Reply
          1. TJ

            Hey Carlos,
            I ended up solving the problem by switching the folder from ‘…/bin64’ to ‘…/bin.’ Does that mean that there are indeed two installations? I’m a (novice) medical physicist and admittedly not very knowledgeable about programming beyond algorithmic stuff. However, I am trying to learn, and I greatly appreciate your blog–I discovered it earlier this week from a link on reddit.

          2. Carlos Anderson Post author

            Hi TJ,
            It’s the same installation but it comes in two architectures (64-bit and 32-bit). Are you running ipy64.exe or ipy.exe? Also, is your operating system 64-bit or 32-bit? I’m glad you’re finding my blog helpful! If you haven’t already, I recommend that you check out the Varian Developers Forum, especially the Discussions.

        2. J

          Hi,

          I’m currently experiencing the same error while running my code, whereas it was working fine just a couple of weeks ago. However, switching to the /bin folder rather than the /bin64 folder did not solve my issue. Had you changed anything else in your code to solve the problem?

          Thanks!

          Reply
  5. Robin

    Hi Carlos, I can see this would be a nice alternative to developing standalone applications using C#, which I have done for a data mining project. Presumably this could even be performed in an jupyter notebook? That would be useful for research and teaching purposes.

    Moving on to the main question. My colleagues require scripts that they can use whilst planning, from the Tools>Scripts menu. I believe we are still restricted to C# for these scripts? However a possible workaround is to create a script that then runs a separate .py, passing the required arguments from the plan. The script would then need to display the output of the .py within Eclipse. Have you tried this out?
    Cheers
    Robin

    Reply
      1. Robin

        HI Carlos, a follow up question. I have request to install IronPython on our terminal but the IT support have refused the request, since officially Varian do not support python on their terminals. I take it you have a free hand to do this at your institute? Is there a workaround, where I could develop on my own PC and somehow connect to the database?
        Thanks
        Robin

        Reply
  6. Kris V.

    Hi Carlos,

    Thanks for this blog post. I’m wondering if you’ve seen an error that I’m having when I try to access the Eclipse API via Python. The error occurs at the line

    app = application.CreateApplication(“username”, “password”)

    I get a “System.NullReferenceException: Object Reference not set to an instance of an object.” It seems like it wants “app” to be instantiated as an Application, but I don’t think there’s a constructor in ESAPI.

    Background info:
    I’ve tried with Eclipse 13.6 and 13.7. I’ve tried using both Anaconda 4.3 and IronPython 2.7 (64-bit) both within the VisualStudio IDE and through the individual executables (python.exe and ipy64.exe respectively). Each time I get the same error. When accessing the api through C#, a login window pops up that allows me to enter my credentials and continue with the rest of the script, this does not happen when using python.

    Any ideas?

    Reply
    1. Carlos Anderson Post author

      Hi Kris,

      The only thing I can think of right now is that you have “application” instead of “Application” (capitalized). But when I tried using “application” I got a different error: “NameError: global name ‘application’ is not defined.” Have you tried running the template code I have above as-is?

      Reply
  7. Matt Schmidt

    Hi Carlos,

    Do you think it would be possible to perform this script against the ESAPI Portal Dosimetry libraries? When I make the code target Portal Dosimetry, for instance:

    import sys
    import clr
    import System
    #Add Varian’s path when referencing assemblies
    sys.path.append(‘C:/Program Files (X86)/Varian/portaldosimetry/1.4/’)
    clr.AddReferenceToFile(‘VMS.CA.Scripting.dll’)
    clr.AddReferenceToFile(‘VMS.DV.PD.Scripting.dll’)

    from VMS.CA.Scripting import *
    from VMS.DV.PD.Scripting import *

    app = Application.CreateApplication(“Physicist”,”Physicist”)

    # Add Code here — Below is an example for me.
    patient = app.OpenPatientById(“US-PD-004”)
    print(patient.Id)
    app.Dispose()

    I get an error that the program “could not load file or assembly ‘C:/Program File (X86)/portaldosimetry/1.4/VMS.DV.PD.Scripting.dll’ or one of its dependencies. It is not a valid Win32 application.” From this error, it feels like maybe the x64 architecture of PD is not capable to be accessed by IronPython? Do you have any suggestions that may make this more helpful to run?

    Thank you,

    Reply
      1. Matt Schmidt

        Hi Carlos, you were right. I did have the change my python environment from IronPython x64-2.7 to IronPython 2.7. Also, the CreateApplication method requires an app.config file that states the location of the PortalDosimetry assemblies. I had a hard time creating such a file in python, but found that I could add it directly with the following code.
        import System.Configuration
        clr.AddReference(‘System.Configuration’)
        from System.Configuration import ConfigurationManager

        ConfigurationManager.AppSettings[“AssemblyPath”] = ‘C:/Program Files (X86)/Varian/portaldosimetry/1.4/’

        After adding this, everything else from above worked fine.

        Thank you,

        Reply

Leave a Reply

Your email address will not be published. Required fields are marked *