GP SoftwareTwitter
Opus FAQsManualCommandsObjects

Python proxy development thread

For whom is it for?

  • People interested in scripting Opus with python
  • And currently for people who at the same time would like to play a bit with scripting and report errors.

What is it?
A very early alpha version of code that should (in the future):

  • Eliminate the need for _FlagAsMethod
  • Enable using () for all method calls
  • Enable using [] for accessing any collections
  • Do anything else that appears handy

How should I use it?

  • Place the code below in <python_install_dir>\Python3\Lib\site-packages\dopus_proxy.py
  • For example create this button and run it (output goes to script log panel):
from dopus_proxy import DOpusProxy

def OnClick(clickData):

    dp = DOpusProxy(DOpus)
    result = dp.Create().Command().CommandList('i')
    for cmd in result:
        DOpus.Output(cmd)
  • Generally, you wrap any DOpus object in DOpusProxy, do all the calling command stuff, and then it either unwraps itself automatically to a "real" value, like in the sample button, or you need to unwrap it yourself using ".obj" notation. For example the line "result = dp.Create().Command().CommandList('i').obj" also works in the above button. I suspect that if you pass an object as an Opus command parameter, you always have to unwrap.
  • Some technical stuff: usage of DOpusProxy is very similar to using Builder objects, but in fact it is a Proxy (to CDispatch object, which is via COM interface also a proxy to DOpus).

What should I know?

  • When scripting in Opus, do not use any scripting features/objects that are not specific strictly to Opus, unless you feel comfortable with them (for example file metadata handling). Python equivalents have more capabilities and are easier to use (exceptions probably exist).
  • I did all my Opus integration a few years ago and I am really not up to date with Opus scripting, fe. I have not touched script dialogs.

What should I do now?

  • Please try the code so that it fails in a few ways with your scripts (crash with red stop sign at the status bar OR unexpected behaviour OR lack of expected behaviour)
  • Report here: context (re. button/script command), any parameters/input used, some code lines that trigger the problem, text from script log panel (if applies) and any other relevant data
  • I will attempt to resolve all reported issues, and hopefully with time build some more complete solution.

Have fun.

class DOpusProxy:

    def __init__(self, obj, name='<top parent object>', parent=None):
        self._obj = obj
        self._name = name
        self._parent = parent if parent else obj

    def __getattr__(self, item):
        return DOpusProxy(getattr(self._obj, item), item, self._obj)

    def __getitem__(self, key):	
        #return DOpusProxy(self._obj(key), '<iterable member>', self._obj)		
        return self._obj[key]

    def __call__(self, *args, **kwargs):
        if args == () and kwargs == {}:
            return self
        else:
            self._parent._FlagAsMethod(self._name)
            call_result = getattr(self._parent, self._name)(*args, *kwargs)
            return DOpusProxy(call_result, '<call result>', call_result)

    def __str__(self):
        return str(self._obj)

    def __int__(self):
        return int(self._obj)

    @property
    def obj(self):
        return self._obj
2 Likes

v0.01 alpha

  • added __setitem__
  • added retrying with () syntax in __getitem__
  • added debug info and win32traceutil loading
  • added unit tests

dopv0.01.zip (1.6 KB)

v0.02 alpha

  • added __setattr__
  • refactor related to __setattr__
  • started building test case library
  • (not working & commented out) DOpus datatypes conversion functions

dopv0.02.zip (3.2 KB)

v0.03 alpha

  • added Vector/list, Map/dict conversion functions

dopv0.03.zip (4.0 KB)