Jump to content

Calling an IronPython script on DataTable Refresh: Function called by ExternalEventManager does not know Application or Document context


Nicolas Alend

Recommended Posts

Hello,

The following is under Spotfire 10.3.3.

In my Spotfire Document, I need to execute an IronPython script everytime my "Dataset" DataTable is refreshed.

This script will reorder the columns and change some columns type. I have this script working on its own, it is not my concern.

To do so, I create another IronPython script that is executed when the Spotfire Document is opened (See here) and that creates a Trigger and ExternalEventManager that listens to the Refreshing event of DataTable "Dataset" and calls a IronPython function that calls the IronPython script I want to execute.

 

from Spotfire.Dxp.Data import *

from Spotfire.Dxp.Framework.ApplicationModel import NotificationService

from Spotfire.Dxp.Framework.DocumentModel import *

notify = Application.GetService[NotificationService]()

notify.AddInformationNotification("Script executed at Document opening", "", "")

 

def myTriggerFunction():

from Spotfire.Dxp.Framework.ApplicationModel import NotificationService

from Spotfire.Dxp.Application.Scripting import ScriptDefinition

from Spotfire.Dxp.Application.Scripting import ScriptManager

from System.Collections.Generic import Dictionary

import clr

notify = Application.GetService[NotificationService]()

notify.AddInformationNotification("myTriggerFunction being executed", "", "")

scriptDef = clr.Reference[scriptDefinition]()

scriptManager = Document.ScriptManager

scriptExists = scriptManager.TryGetScript("onDataTableRefresh", scriptDef)

#notify.AddInformationNotification("Script exists", scriptExists.ToString(), "")

params = Dictionary[str, object]()

scriptManager.ExecuteScript(scriptDef.Value, params)

 

### uncomment next line to test function "myTriggerFunction" when document is opened => is works: the IronPython script is executed

#myTriggerFunction()

 

from Spotfire.Dxp.Framework.DocumentModel import *

def getMyTrigger():

return Trigger.CreatePropertyTrigger(

Document.Data.Tables["Dataset"],

DataTable.PropertyNames.Refreshing

)

 

externalEventManager = ExternalEventManager()

externalEventManager.AddEventHandler(

myTriggerFunction,

getMyTrigger()

)When I open the Document and refresh the DataTables (In the Analyst for exemple: Data > Reload all data), I have the following error message:

UnboundNameException at System.Windows.Forms:

global name 'Application' is not defined (HRESULT: 80131500)

 

Stack Trace:

at System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate method, Object[] args, Boolean synchronous)

at System.Windows.Forms.Control.Invoke(Delegate method, Object[] args)

at System.Windows.Forms.WindowsFormsSynchronizationContext.Send(SendOrPostCallback d, Object state)

at Spotfire.Dxp.Forms.Application.FormsApplicationThread.InvokeOnUIThreadAndTransferTransactionStartPermission(ApplicationInvocation method)

at Spotfire.Dxp.Framework.Commands.CommandHistory.EndTransactionAndRaiseEventsOnUiThread(Object busyProof)

at Spotfire.Dxp.Framework.Commands.CommandHistory.CommitOutermostTransaction(Object busyProof, Boolean oldHiding, Boolean sticky, Guid stickyGuid, Boolean isHighlight)

at Spotfire.Dxp.Framework.Commands.CommandHistory.OutermostTransactionHandle.PerformCommit()

at Spotfire.Dxp.Framework.Commands.CommandHistory.OutermostTransactionHandle.Dispose(Boolean disposing)

at Spotfire.Dxp.Framework.Commands.CommandHistory.InternalTransactionHandle.PerformCommit()

at Spotfire.Dxp.Data.DataTableCollection.d__57.MoveNext()

at Spotfire.Dxp.Forms.Data.DataFormsUtilities.c__DisplayClass6_0.b__2()

at Spotfire.Dxp.Forms.Application.FormsProgressService.ProgressThread.DoOperationLoop()It seems that the function called by the ExternalEventManager when the Trigger is fired does not know the Application context (nor the Document itself based on my other tests).

That is my concern!

So my questions are:

 

How can I have my IronPython script executed when my DataTable "Dataset" is refreshed (tht is what I want to do, no matter how)

What context does the function "myTriggerFunction" have access to when it is executed after the trigger is fired Why does it NOT know the Application nor Document

 

 

For your information:

 

the function "myTriggerFunction" works fine and does call the IronPython script "onDataTableRefresh" when it is called at the Document opening (see commented line in code exemple above).

the function "myTriggerFunction" must have 0 arguments (see Spotfire API Documentation). As a consequence:

 

 

I can not pass the Document as an argument.

I can not call a function of a Class I would have instanciated using the Document since this function would have at least 1 argument: self.

 

 

Thanks a lot for your help!

Nicolas

Link to comment
Share on other sites

  • 2 weeks later...

Hi Nicolas,

Maybe not an answer to why the script is failing, but you can also use a data function to kick off the iron python script.

Here is an example of such a data function set up: https://spotfired.blogspot.com/2015/10/update-doc-property-trigger-ironp...

If you set the iron python script to be kicked off everytome a document property changes, the best way to do so is add a sys.time() in the data function as an output parameter. Connect the script to this document property and it will ensure the script is triggered whenever the data time property has changed. This is normally done when you open the dashboard.

If it has to be an iron python script, you can also check out this post: https://spotfired.blogspot.com/2016/05/trigger-script-after-data-table-l....

Kind regards,

David

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...