# More Pythonic VTK wrapping

**URL:** https://discourse.vtk.org/t/more-pythonic-vtk-wrapping/13092
**Category:** Development
**Created:** [January 17, 2024, 10:23pm UTC](https://discourse.vtk.org/t/more-pythonic-vtk-wrapping/13092 "2024-01-17T22:23:14Z")
**Posts on this page:** 20
**Page:** 3

<div class="post-metadata">

### Author: ![berk.geveci](https://discourse.vtk.org/user_avatar/discourse.vtk.org/berk.geveci/32/3146_2.png) [@berk.geveci](https://discourse.vtk.org/u/berk.geveci)
#### Post date: [January 28, 2024, 1:44pm UTC](https://discourse.vtk.org/t/more-pythonic-vtk-wrapping/13092/41 "2024-01-28T13:44:31Z")

</div>

How about `eval()` or `evaluate()`? When used in the context of functions, these imply returning a value.

I don’t like overloading `get_output` any further since it has meant getting the output without execution from the beginning. `run()` has the same issue as `execute()` in that it does not imply returning a value.

---

<div class="post-metadata">

### Author: ![toddy](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/t/edb3f5/32.png) [@toddy](https://discourse.vtk.org/u/toddy)
#### Post date: [January 28, 2024, 11:51pm UTC](https://discourse.vtk.org/t/more-pythonic-vtk-wrapping/13092/42 "2024-01-28T23:51:40Z")

</div>

Perhaps it should have been done the other way around whereby the default behaviour of **GetOutput()** was to always perform an evaluation but supplemented by a caching mechanism to return a stored value when the filter/reader was unmodified.

---

<div class="post-metadata">

### Author: ![amaclean](https://discourse.vtk.org/user_avatar/discourse.vtk.org/amaclean/32/224_2.png) [@amaclean](https://discourse.vtk.org/u/amaclean)
#### Post date: [January 29, 2024, 3:22am UTC](https://discourse.vtk.org/t/more-pythonic-vtk-wrapping/13092/43 "2024-01-29T03:22:02Z")

</div>

I really don’t see any issues with execute() … to my mind the pipelines are normally executed or evaluated. execute() doesn’t imply that no value is returned. I would normally expect a result … Null, Pass, Fail, the pipeline …

---

<div class="post-metadata">

### Author: ![berk.geveci](https://discourse.vtk.org/user_avatar/discourse.vtk.org/berk.geveci/32/3146_2.png) [@berk.geveci](https://discourse.vtk.org/u/berk.geveci)
#### Post date: [January 29, 2024, 6:59pm UTC](https://discourse.vtk.org/t/more-pythonic-vtk-wrapping/13092/44 "2024-01-29T18:59:06Z")

</div>

Hi folks,

Here is an update:

> <https://gist.github.com/berkgeveci/5dadcd8c08490a735c385c93be0ccdee>

Highlights:

- No more need to create a `Pipeline` object explicitly. Now `>>` returns a pipeline object that enables reuse of pipelines (and composition)
- I went with the `select_ports(input_port, algorithm, output_port)` way of selecting ports.
- I went with `execute()` as the alternatives suggested are not better.

---

<div class="post-metadata">

### Author: ![ahernsean](https://discourse.vtk.org/user_avatar/discourse.vtk.org/ahernsean/32/5874_2.png) [@ahernsean](https://discourse.vtk.org/u/ahernsean)
#### Post date: [January 29, 2024, 7:02pm UTC](https://discourse.vtk.org/t/more-pythonic-vtk-wrapping/13092/45 "2024-01-29T19:02:34Z")

</div>

`eval()` and `evaluate()` are pretty good. They’re both better than `execute()`. I’m still partial to `generate()`. It’s the best I’ve heard suggested so far. It implies something being produced as a result.

---

<div class="post-metadata">

### Author: ![berk.geveci](https://discourse.vtk.org/user_avatar/discourse.vtk.org/berk.geveci/32/3146_2.png) [@berk.geveci](https://discourse.vtk.org/u/berk.geveci)
#### Post date: [January 29, 2024, 7:20pm UTC](https://discourse.vtk.org/t/more-pythonic-vtk-wrapping/13092/46 "2024-01-29T19:20:35Z")

</div>

Can we get some votes for eval(), execute(), and generate()?

I vote for eval().

---

<div class="post-metadata">

### Author: ![cory.quammen](https://discourse.vtk.org/user_avatar/discourse.vtk.org/cory.quammen/32/6751_2.png) [@cory.quammen](https://discourse.vtk.org/u/cory.quammen)
#### Post date: [January 29, 2024, 7:21pm UTC](https://discourse.vtk.org/t/more-pythonic-vtk-wrapping/13092/47 "2024-01-29T19:21:43Z")

</div>

_Poll ([view on site](https://discourse.vtk.org/t/more-pythonic-vtk-wrapping/13092/47))_

---

<div class="post-metadata">

### Author: ![banesullivan](https://discourse.vtk.org/user_avatar/discourse.vtk.org/banesullivan/32/7143_2.png) [@banesullivan](https://discourse.vtk.org/u/banesullivan)
#### Post date: [January 29, 2024, 7:54pm UTC](https://discourse.vtk.org/t/more-pythonic-vtk-wrapping/13092/48 "2024-01-29T19:54:53Z")

</div>

i have a strong aversion to eval since it is a Python built in [Built-in Functions — Python 3.12.1 documentation](https://docs.python.org/3/library/functions.html#eval)

---

<div class="post-metadata">

### Author: ![will.schroeder](https://discourse.vtk.org/user_avatar/discourse.vtk.org/will.schroeder/32/233_2.png) [@will.schroeder](https://discourse.vtk.org/u/will.schroeder)
#### Post date: [January 29, 2024, 8:01pm UTC](https://discourse.vtk.org/t/more-pythonic-vtk-wrapping/13092/49 "2024-01-29T20:01:45Z")

</div>

I agree with Bane (eval bad). I also like to use VTK terminology (i.e., execute()).

---

<div class="post-metadata">

### Author: ![Zach\_Mullen](https://discourse.vtk.org/user_avatar/discourse.vtk.org/zach_mullen/32/8358_2.png) [@Zach\_Mullen](https://discourse.vtk.org/u/Zach_Mullen)
#### Post date: [January 29, 2024, 8:04pm UTC](https://discourse.vtk.org/t/more-pythonic-vtk-wrapping/13092/50 "2024-01-29T20:04:00Z")

</div>

Would it be possible to not have to explicitly call `execute` on the pipeline at all? Rather, if you try to read an output property, the internals would know that it needs to execute the pipeline and then do so?

---

<div class="post-metadata">

### Author: ![berk.geveci](https://discourse.vtk.org/user_avatar/discourse.vtk.org/berk.geveci/32/3146_2.png) [@berk.geveci](https://discourse.vtk.org/u/berk.geveci)
#### Post date: [January 29, 2024, 8:05pm UTC](https://discourse.vtk.org/t/more-pythonic-vtk-wrapping/13092/51 "2024-01-29T20:05:57Z")

</div>

> Would it be possible to not have to explicitly call `execute` on the pipeline at all? Rather, if you try to read an output property, the internals would know that it needs to execute the pipeline and then do so?

Yes, but that would be a change of behavior for VTK. I am not willing to take that on. Our goal here is to simplify / integrate but not change / improve behavior necessarily.

---

<div class="post-metadata">

### Author: ![will.schroeder](https://discourse.vtk.org/user_avatar/discourse.vtk.org/will.schroeder/32/233_2.png) [@will.schroeder](https://discourse.vtk.org/u/will.schroeder)
#### Post date: [January 29, 2024, 8:06pm UTC](https://discourse.vtk.org/t/more-pythonic-vtk-wrapping/13092/52 "2024-01-29T20:06:13Z")

</div>

Some filters have multiple inputs / outputs, and in some cases these are optional. In most cases they all need to be connected before execution makes sense.

---

<div class="post-metadata">

### Author: ![cory.quammen](https://discourse.vtk.org/user_avatar/discourse.vtk.org/cory.quammen/32/6751_2.png) [@cory.quammen](https://discourse.vtk.org/u/cory.quammen)
#### Post date: [January 29, 2024, 8:22pm UTC](https://discourse.vtk.org/t/more-pythonic-vtk-wrapping/13092/53 "2024-01-29T20:22:17Z")

</div>

> [@berk.geveci](#):
>
> Yes, but that would be a change of behavior for VTK. I am not willing to take that on. Our goal here is to simplify / integrate but not change / improve behavior necessarily.

If you implemented this in ` __getattr__ ` it shouldn’t require a change in VTK itself. Let’s say instead of invoking `execute()` you simply access a `output` attribute. ` __getattr__ ` could perform the update on the pipeline when it the attribute `output` is requested and give you the result. The implementation would, I suspect, be very similar to the implementation of an `execute()` function. It’s mainly a syntactic preference in my view. The main advantage of an attribute is it is perhaps easier to name - you don’t have to find a verb that also indicates a noun is returned.

> [@will.schroeder](#):
>
> Some filters have multiple inputs / outputs

That’s a good point about multiple outputs. How would this be handled with either an `execute()` or a `output` attribute? Return a tuple of VTK objects?

---

<div class="post-metadata">

### Author: ![berk.geveci](https://discourse.vtk.org/user_avatar/discourse.vtk.org/berk.geveci/32/3146_2.png) [@berk.geveci](https://discourse.vtk.org/u/berk.geveci)
#### Post date: [January 29, 2024, 8:34pm UTC](https://discourse.vtk.org/t/more-pythonic-vtk-wrapping/13092/54 "2024-01-29T20:34:25Z")

</div>

> [@cory.quammen](#):
>
> If you implemented this in ` __getattr__ ` it shouldn’t require a change in VTK itself. Let’s say instead of invoking `execute()` you simply access a `output` attribute. ` __getattr__ ` could perform the update on the pipeline when it the attribute `output` is requested and give you the result. The implementation would, I suspect, be very similar to the implementation of an `execute()` function. It’s mainly a syntactic preference in my view. The main advantage of an attribute is it is perhaps easier to name - you don’t have to find a verb that also indicates a noun is returned.

This is still a behavior change. Given how we create properties, I would expect `.output` to call `GetOutput()` on the algorithm, which does not execute. This is the current behavior.

> [@cory.quammen](#):
>
> That’s a good point about multiple outputs. How would this be handled with either an `execute()` or a `output` attribute? Return a tuple of VTK objects?

I did not think of returning a tuple of data objects. That’s doable. This currently returns the 2nd output:

```auto
select_ports(alg, 1).execute()

```

but if you want the other input after executing, you have to do:

```auto
alg.GetOutputDataObject(0)

```

Because of the way Python properties work, we cannot do:

```auto
alg.output(0)

```

We can implement that as a custom function if requested though.

---

<div class="post-metadata">

### Author: ![berk.geveci](https://discourse.vtk.org/user_avatar/discourse.vtk.org/berk.geveci/32/3146_2.png) [@berk.geveci](https://discourse.vtk.org/u/berk.geveci)
#### Post date: [January 29, 2024, 11:33pm UTC](https://discourse.vtk.org/t/more-pythonic-vtk-wrapping/13092/55 "2024-01-29T23:33:00Z")

</div>

One more thing: many of the multiple output algorithms have specific Get methods for their other outputs. For example, the clip filter has the method `GetClippedOutput()` which would have a corresponding property called 'clipped\_output` so the following is always possible:

```auto
output = (source >> clip).execute()
c_output = clip.clipped_output

```

But I am starting to like this idea a lot:

```auto
output, c_output = (source >> clip).execute()

```

---

<div class="post-metadata">

### Author: ![marcomusy](https://discourse.vtk.org/user_avatar/discourse.vtk.org/marcomusy/32/95_2.png) [@marcomusy](https://discourse.vtk.org/u/marcomusy)
#### Post date: [January 30, 2024, 9:24am UTC](https://discourse.vtk.org/t/more-pythonic-vtk-wrapping/13092/56 "2024-01-30T09:24:45Z")

</div>

How about this

```python
p = vtkRTAnalyticSource() >> vtkContourFilter(contour_values=[100])
p.update() # returns self (or None)
print(p.output.number_of_points)

```

where now `output` is a python property returning `None` before `update()` is called.  
In case of multiple outputs `output` can be a tuple and you can still do

```py
output, c_output = (source >> clip).update().output

```

isn’t this the most similar sequence of actions to what we normally do in vtk?

```python
algo = SomeSource()
algo.Update()
out = algo.GetOutput()

```

---

<div class="post-metadata">

### Author: ![ahernsean](https://discourse.vtk.org/user_avatar/discourse.vtk.org/ahernsean/32/5874_2.png) [@ahernsean](https://discourse.vtk.org/u/ahernsean)
#### Post date: [January 30, 2024, 12:41pm UTC](https://discourse.vtk.org/t/more-pythonic-vtk-wrapping/13092/57 "2024-01-30T12:41:04Z")

</div>

I love the idea of a multi-output filter returning a tuple by default. Very Pythonic!

---

<div class="post-metadata">

### Author: ![Aashish\_Chaudhary](https://discourse.vtk.org/user_avatar/discourse.vtk.org/aashish_chaudhary/32/8377_2.png) [@Aashish\_Chaudhary](https://discourse.vtk.org/u/Aashish_Chaudhary)
#### Post date: [January 30, 2024, 4:44pm UTC](https://discourse.vtk.org/t/more-pythonic-vtk-wrapping/13092/58 "2024-01-30T16:44:40Z")

</div>

I’m not seeing the entire thread, but having the () “function call” operator would be better to execute the pipeline, as then we could treat pipeline reference as lambda. Another option is run() - it is shorter than eval and execute. I can understand why most of the members here voted for the execute option. That is probably most familiar to VTK experts, though run() might be a better, shorter, and more familiar option for newcomers.

---

<div class="post-metadata">

### Author: ![MicK7](https://discourse.vtk.org/user_avatar/discourse.vtk.org/mick7/32/3362_2.png) [@MicK7](https://discourse.vtk.org/u/MicK7)
#### Post date: [January 31, 2024, 1:06pm UTC](https://discourse.vtk.org/t/more-pythonic-vtk-wrapping/13092/59 "2024-01-31T13:06:43Z")

</div>

As a vtk pipeline is more or less a graph, it would be nice to have a pythonic API coherent with networkx or other graph package that would allow plotting the pipeline graph in matplotlib. This may need to create a dedicated pipeline class.

---

<div class="post-metadata">

### Author: ![berk.geveci](https://discourse.vtk.org/user_avatar/discourse.vtk.org/berk.geveci/32/3146_2.png) [@berk.geveci](https://discourse.vtk.org/u/berk.geveci)
#### Post date: [January 31, 2024, 1:08pm UTC](https://discourse.vtk.org/t/more-pythonic-vtk-wrapping/13092/60 "2024-01-31T13:08:56Z")

</div>

I would be happy to add support for that once the core infrastructure is completed. There is already a Pipeline class in the current implementation (which I am working to add to the MR) so it should not be hard. Contributions are welcome too 🙂

[Previous page](https://discourse.vtk.org/t/more-pythonic-vtk-wrapping/13092.md?page=2)

[Next page](https://discourse.vtk.org/t/more-pythonic-vtk-wrapping/13092.md?page=4)
