Question

Getting published parameters from within a python caller nested in several custom transformers


I'm trying to use a python caller within a custom transformer that is nested inside another custom transformer.

With just a single custom transformer I'd use: 

paramVal = str(FME_MacroValues[MyCustomTransformerName_MyParameterName])

to get the parameter value inside the custom transformer. However when this custom transformer is nested inside another custom transformer, this naming convention doesn't work - I get a python exception

Python Exception <KeyError>: 'MyCustomTransformerName_MyParameterName'

The combination of both custom transformer names throws an error

paramVal = str(FME_MacroValues[MyContainingCustomTransformer_MyCustomTransformer_MyParameterName])

Using just the parameter name as follows gives me the value from the parent workspace

paramVal = str(FME_MacroValues[MyParameterName])

while using concatenating the name of the containing custom transformer gets parameters from within that transformer

paramVal = str(FME_MacroValues[MyContainingCustomTransformer_MyParameterName])

Is there a specific naming convention that will help me here? If not i'll probably just have to settle for getting values from the containing custom transformer.


9 replies

Userlevel 4

The problem you're seeing is that the prefix isn't the custom transformer name, but the custom transformer instance name. It just so happens that the first instance of a custom transformer name has the same name as its instance name.

You can use this pattern to first get the instance name inside the custom transformer at concatenante it with your parameter name:

custom_transformer_name = 'MyContainingCustomTransformer'
parameter_name = 'MyParameterName'
instance_name = FME_MacroValues[custom_transformer_name + '_WORKSPACE_NAME']
paramVal = FME_MacroValues[instance_name + '_' + parameter_name]

If you feel this ought to be easier, I totally agree.

@jdh, this is what I was talking about earlier today.

Badge +5

The problem you're seeing is that the prefix isn't the custom transformer name, but the custom transformer instance name. It just so happens that the first instance of a custom transformer name has the same name as its instance name.

You can use this pattern to first get the instance name inside the custom transformer at concatenante it with your parameter name:

custom_transformer_name = 'MyContainingCustomTransformer'
parameter_name = 'MyParameterName'
instance_name = FME_MacroValues[custom_transformer_name + '_WORKSPACE_NAME']
paramVal = FME_MacroValues[instance_name + '_' + parameter_name]

If you feel this ought to be easier, I totally agree.

@jdh, this is what I was talking about earlier today.

Hi @david_r, I was just looking at this today and it does not appear work in all situations. For example, if I have 2 instances of the same custom transformer in my workspace (which is entirely foreseeable, as custom transformers are supposed to be re-usable) then only the 2nd instance name is stored in the FME_MacroValues dict.

 

 

For example, if I have 2 custom transformers "test" and "test_2" and I print out the FME_MacroValues dict for each, the result is:

 

FME_MacroValues (test): {..., 'test_WORKSPACE_NAME': 'test_2'} FME_MacroValues (test_2): {..., 'test_WORKSPACE_NAME': 'test_2'}
This seems like a bug to me and I will see what Safe has to say.

 

 

Nic

 

Userlevel 4
Hi @david_r, I was just looking at this today and it does not appear work in all situations. For example, if I have 2 instances of the same custom transformer in my workspace (which is entirely foreseeable, as custom transformers are supposed to be re-usable) then only the 2nd instance name is stored in the FME_MacroValues dict.

 

 

For example, if I have 2 custom transformers "test" and "test_2" and I print out the FME_MacroValues dict for each, the result is:

 

FME_MacroValues (test): {..., 'test_WORKSPACE_NAME': 'test_2'} FME_MacroValues (test_2): {..., 'test_WORKSPACE_NAME': 'test_2'}
This seems like a bug to me and I will see what Safe has to say.

 

 

Nic

 

That's interesting. Could you perhaps upload a minimal workspace to reproduce the issue?

 

Note that you have very little leeway in how you implement this compared to what I posted above: FME tries very hard to be "intelligent" about automatically fixing your "mistakes" and therefore sometimes ends up mangling your string.

 

If you implement it exactly as I've done above, you should be able to work fly under the radar of this detection mechanism and it ought to work.
Badge +5
That's interesting. Could you perhaps upload a minimal workspace to reproduce the issue?

 

Note that you have very little leeway in how you implement this compared to what I posted above: FME tries very hard to be "intelligent" about automatically fixing your "mistakes" and therefore sometimes ends up mangling your string.

 

If you implement it exactly as I've done above, you should be able to work fly under the radar of this detection mechanism and it ought to work.
Hi @david_r,

 

I've submitted a support request to Safe to ask about this but haven't received a response yet. Here's the FME Workspace [published-param-in-custom-xform.fmw] that I sent to Safe. You'll notice that the instance name that gets printed out is the same for each instance of the custom transformer.

 

Nic

 

Userlevel 4
Hi @david_r,

 

I've submitted a support request to Safe to ask about this but haven't received a response yet. Here's the FME Workspace [published-param-in-custom-xform.fmw] that I sent to Safe. You'll notice that the instance name that gets printed out is the same for each instance of the custom transformer.

 

Nic

 

Hi Nic, thanks for the workspace, I can confirm that I couldn't get it to work in FME 2017.1 either. I'd appreciate if you'd post here if you hear back from Safe.
Badge +5
Hi Nic, thanks for the workspace, I can confirm that I couldn't get it to work in FME 2017.1 either. I'd appreciate if you'd post here if you hear back from Safe.
Safe support have filed a PR to investigate if this is possible, or possibly it's an enhancement. I'll update if I hear anything further.

 

 

Userlevel 4
Safe support have filed a PR to investigate if this is possible, or possibly it's an enhancement. I'll update if I hear anything further.

 

 

Thanks. Hopefully they'll extend the API to support a more elegant and pythonic solution. The workaround I posted above feels really hacky.
Hi @david_r,

 

I've submitted a support request to Safe to ask about this but haven't received a response yet. Here's the FME Workspace [published-param-in-custom-xform.fmw] that I sent to Safe. You'll notice that the instance name that gets printed out is the same for each instance of the custom transformer.

 

Nic

 

Safe support have confirmed that this is an issue and that there is currently no way of obtaining the instance name within Python (and TCL). They have opened PR for it.

 

 

The only solution at the moment is to obtain the parameter value prior to the PythonCaller (using a ParameterFetcher, AttributeCreator, etc.) and, if you have a large number of features and are worried about performance, only run getAttribute() on the first feature.

 

 

Userlevel 4
Safe support have confirmed that this is an issue and that there is currently no way of obtaining the instance name within Python (and TCL). They have opened PR for it.

 

 

The only solution at the moment is to obtain the parameter value prior to the PythonCaller (using a ParameterFetcher, AttributeCreator, etc.) and, if you have a large number of features and are worried about performance, only run getAttribute() on the first feature.

 

 

Thanks for the feedback!

Reply