Nodezator

Latest version: v1.5.1

Safety actively analyzes 675368 Python packages for vulnerabilities to keep your Python projects secure.

Scan your dependencies

Page 1 of 2

1.5.1

This is an impromptu patch that came to be because of some experimentation I did with a solution to make it easier to interact with sockets using the mouse to establish new connections. I call this solution socket proximity detection. It consists in detecting nearby sockets whenever:

- clicking near them in order to establish a new connection
- releasing the mouse dragging the new connection near the other socket

In other words, now doing both things is easier, because the mouse doesn't need to be exactly over the sockets for any of those actions to take place.

Additionally, special graphics/shapes are drawn on the screen when dragging a new connection to another socket in order to signal the detection to the user.

For instance, here's what it looks like when the socket detection graphics are "reaching hands":

![socket_proximity_detection](https://github.com/user-attachments/assets/fb56d14e-f778-49ef-84e6-da06326295be)

In the image, the mouse cursor becomes a hand that extends from the first socket. The second socket is detected due to its proximity, so a hand also extends from it to meet the hand cursor. Granted, a static image doesn't do justice to the usefulness of the feature nor to how smooth the movement is.

There's also no risk of the wrong socket connecting by mistake by moving the mouse accidentally close to another socket because the connection is only established when the mouse button is released, so you can move the cursor freely and only release it when there's visual confirmation that the socket you intend to connect to was properly detected and is in range (for this particular graphics used, we know the socket is in range when the hands hold each other at the cursor).

The user can even customize the experience by:

- picking one of the following graphics to be used:
- assisting line
- reaching hands
- hands and eyes
- baseball elements
- baseball elements and eyes
- setting the distance at which a target socket is detected when the mouse is dragging a new connection
- setting the distance at which a connection can be established with the detected socket

A few key content pieces were update as well. The first chapter of the user manual now has a new subsection on [sharing resources among nodes](https://manual.nodezator.com/ch-defining-your-first-node.html#sharing-resources-among-nodes). A very useful and long needed resource. In addition to that, a few other parts of the chapter were improved for clarity.

The [README](https://github.com/IndiePython/nodezator/blob/main/README.md) file of the repository is much more informative now and makes usage of more images and animated GIFs to showcase Nodezator features and capabilities. Like the first chapter of the manual, the README file also had several parts of its text improved for clarity.

We also made sure to include important information and warnings to avoid common misconceptions people tend to have when learning about Nodezator for the first time. For instance, some people seem to have a hard time telling whether Nodezator is an application or a framework/GUI library at first, so in the text we made sure to emphasize what Nodezator is and what it is not.

Finally, made a few small changes to the `menu` subpackage to make it easier to use widgets like checkbuttons and radiobuttons on the menus. The menu subpackage always had such widgets available, but we never needed to use them before. Now we use radiobuttons to allow users to choose their preferred socket detection graphics, so it was a great opportunity to improve their back end a bit. The appearance of the radiobuttons was improved as well. They are now rendered from SVG text.

1.5.0

The scheduled work for this release consisted of 02 features, but we delivered additional QOL (quality-of-life) features and other changes as well. The scheduled features were:

- Finishing and releasing the automated system testing service
- Replacing the makeshift graph execution algorithm by topological sorting

Among the additional QOL features, we highlight:

- Birds eye view
- The ability to jump to any node in the graph by providing its id

The remaining changes will be presented futher ahead, in a dedicated section.

In addition to the information presented in this release text, you can find much of the development process documented in this GitHub discussion: https://github.com/IndiePython/nodezator/discussions/72. It was used as a development log (devlog) detailing changes and related decisions.


New automated system testing service

This release was focused on providing a new key feature to aid in development of Nodezator: an automated system testing service.

Nodezator, being a node editor, is a software with many features, tools and a varied workflow. There are innumerable actions that users can take and underlying systems supporting it. Additionally, being an open-source software project, it is subject to external development work being merged into it. Even if there was only my own work being merged into it, the use-cases/systems are just too many to be manually tested by a single person.

In the past, despite my careful testing hundreds of times, I still couldn't manually test every possible action and it resulted in some nasty bugs being introduced in some past releases (bugs that were already solved). Although we also have unit tests, the coverage is still low and, even if it was high, the tests would only be able to ensure the isolated units work. This means we needed a tool that could test the entire system, ensuring every part works in tandem to perform each and every task the user can perform in Nodezator.

In other words, we needed a tool that ensured that, given the same actions performed by a user like clicking some element, typing something, pressing specific keys and key combinations, in order to perform a specific task, the app would be able to successfully perform that task, resulting in specific outputs and/or state.

This tool is called <a href="https://en.wikipedia.org/wiki/System_testing">System testing</a>. At the beginning, because it relies on GUI automation, we were mistakenly calling it automated GUI testing. However, because we are interested in testing the entire system, not only the graphical user interface, <b>system testing</b> is indeed the right term.

Performing system tests

Since version 1.4, Nodezator featured a <b>Playback</b> submenu on the menubar, although none of its options were available to users. In 1.5, this submenu was renamed to <b>GUI automation</b> and its <b>Automated GUI tests</b> option was renamed to <b>System testing</b>. This System testing submenu has all the options needed to set and perform an automated system testing session, with some keybindings assigned to the most common ones. Here's an image depicting the GUI automation submenu as well as the options available in the System testing submenu inside it:

![GUI automation submenu and its System testing submenu in the menubar](https://github.com/IndiePython/nodezator/assets/18728298/b8a8bae3-c978-4872-8031-3e4d7323e6ab)

Among the options within the System testing submenu, there's one that presents a form where a custom testing session can be set and triggered. The form is presented in the image below:

![Form to set and trigger custom system testing session](https://github.com/IndiePython/nodezator/assets/18728298/a4811f1a-dd19-4a39-a324-c7a818a1e846)

The form can be used to pick which test cases must be executed and the speed used. There's an speed option because although most people will usually want the tests to run in top speed, it might be useful to run specific tests in normal or slower speed in order to careful observe the execution of the task to help spot possible errors/mistakes.

Once an automated system testing session begins, the app starts moving by itself, executing each task. During the session, there are several controls that can be used to perform tasks like pausing/resuming the session or aborting it. You can check such controls in the general controls page (that you can access in the <b>Help &gt; General controls</b> menubar option).

Once a system testing session ends, a report is presented. Here's what the initial portion of the report looks like:

![Initial portion of system testing report](https://github.com/IndiePython/nodezator/assets/18728298/2829bf94-9949-4db1-af04-d7cc84ad52a9)

The actual report is much larger since it has details about the system and each test case executed.

On the bottom of the report there are also buttons to export it to other useful formats like <b>.html</b>, <b>.png</b> and <b>.pyl</b> (a Python file containing only literals).


Remaining work for system testing and Nodezator in general

All that remains is to populate the system testing service with all the needed test cases, which is expected to be done in the next patch or so.

In order to aid in development of not only of the system testing feature, but the whole app, a holistic view of its design is needed. Each and every task and feature must be listed. This is specially important for system testing because we need such information in order to define and implement all the needed test cases.

Because of that, since the beginning of our scheduled work for this version, we also started producing a <a href="https://en.wikipedia.org/wiki/Software_design_description">Software Design Document</a> (SDD) for Nodezator, which you can find in this dedicated repository: <a href="https://github.com/IndiePython/nodezator-sdd">https://github.com/IndiePython/nodezator-sdd</a>

A system testing document is also being produced. It is kept in a separate repository although it is considered part of Nodezator's SDD: <a href="https://github.com/IndiePython/nodezator-system-testing">https://github.com/IndiePython/nodezator-system-testing</a>. It is used to help manage system testing for Nodezator and to document its test cases. It is kept as a separate repository so changes to system testing can be managed and tracked separately from the rest of the SDD.

Finishing those documents is important not only for system testing, but also for Nodezator in general. For instance, once these documents are ready, we'll be able to organize the missing features in a sensible order for scheduling and implementation. We'll also be able to present a proper roadmap to users of the app and followers of the project.


Breadth-first-search-based topological sorting for graph execution

Replacing our makeshift graph execution solution by one based on the topological sorting algorithm/technique was a feature request made by Mr. <a href="https://github.com/OlegAlexander">Alexander</a> and accepted after considering the merits of the request.

Although other materials on the topic were researched, the most concise and straightforward definition for the topological sorting technique/algorithm was found on Quora (A Questions &amp; Answers platform):

> Topological sort is a fundamental technique in graph theory that organizes the nodes of a directed acyclic graph (DAG) while maintaining the edge direction. The significance of topological sort stems from its ability to offer a linear ordering of nodes, which may be used to address a range of issues such as scheduling, job sequencing, and dependency resolution. (<a href="https://www.quora.com/What-is-the-importance-of-topological-sort-in-graph-theory-What-are-its-applications-and-examples/answer/M-Pappa-John">source</a>)

In summary, topological sorting has many applications in computer science and software engineering and is an established key technique to solve many different kinds of problems. The specific algorithm picked was one based on a breadth-first search algorithm and also recommended by Mr. Alexander. This means nodes which don't require inputs are listed first, gathered in groups called generations, then the nodes immediately fed by their outputs are also listed as their own generation and so on until all the existing nodes are listed.

It should be particularly useful to us in the future when we implement parallel execution, since the algorithm groups together nodes which don't depend on each other and can thus be executed in parallel.

We implemented a custom solution adapted from <a href="https://en.wikipedia.org/wiki/Topological_sorting#Kahn's_algorithm">this pseudocode</a> and with insight from other researched materials. Our solution presented the same output but superior speed to an alternative solution using an established 3rd-party library for manipulating graphs, the <a href="https://networkx.org/">NetworkX</a> library. Specifically, this <a href="https://networkx.org/documentation/stable/reference/algorithms/generated/networkx.algorithms.dag.topological_generations.html#networkx.algorithms.dag.topological_generations">NetworkX tool</a> was used.

For the record, we don't fault NetworkX for its inferior speed in this specific case, since, being a library, we assume its offers a general solution designed to meet the requirements of many environments, whereas our custom solution is free to take advantage of local services and existing data structures to achieve top performance. NetworkX actually helped us validate our custom solution, that is, because NetworkX is a renowned library and our custom solution produced the same output as its solution.

In the distant future we intend to research NetworkX further, as well as other graph manipulation libraries like <a href="https://igraph.org/">igraph</a>. This would be done in order to learn even more about our problem space and see if we can improve our solution somehow, although we already have a validated working solution that produces the same output as an established library like NetworkX.

We assume a solution based on igraph may be faster, for instance, due to the library being written in C. However, we avoided further research in that direction for now and a possible adoption of igraph because:

- We don't have speed requirements nor performance complaints, only functional requirements
- We consider our functional requirements met, since our solution produces the same output as a solution based on the renowned NetworkX library
- Despite not having speed requirements, we managed to come up with a solution faster than a solution based on the renowned NetworkX library
- Avoiding the adoption of external dependencies as much as possible is a principle followed in Nodezator's maintenance and development
- We can't properly assess the merits of the adoption of external libraries until we implement parallelism and other asynchronous paradigms for graph execution. Only then we'll be able to fully assess the pros and cons of each solution.


Birds eye view and navigation

The bird's eye view feature displays a representation of the entire graph that fits the screen. It allows you to see the whole graph at once. You can also use it for navigation, as keeping the mouse pressed while hovering the view will cause the screen to scroll to the respective spot in the actual graph. That is, that spot will appear centered on the screen. Here's what the feature look like:

![Screenshot of the bird's eye view](https://github.com/IndiePython/nodezator/assets/18728298/698f35cf-4374-4590-8609-579ca464162c)

Note that the icons depicted in the view are not scaled down in the same proportion as the whole graph. They are just miniatures representing the center of each object. This is why in very small graphs they make the view look as though the objects were not positioned accurately, when in fact the view works just fine and navigation is very accurate, as holding the mouse button while hovering over each miniature will accurately position the screen centered on the specific miniature under the mouse. Additionally, this "illusion of inaccuracy" is only perceptible is small graphs anyway.

You can find access the feature in the <b>Graph &gt; toggle bird's eye view</b> menubar command or by pressing <b>B</b> (pressing <b>B</b> again or <b>Escape</b> exits the view). This will help people working on large graphs, as they'll be able to instantly jump to and inspect any spot on the graph.


Jump to specific node by providing its id

This version also offers the ability to jump to an existing node by providing its id. You can do this via small dialog that allows you to type the id of the node to which you want to jump. Here's what it looks like:

![Dialog to jump to node of given id.](https://github.com/IndiePython/nodezator/assets/18728298/4876f176-3619-4ff6-a59d-ed5257a16a20)

Typing an inexistent id will just briefly show a message informing the user that a node of the specified id doesn't exist.

You can find it in the <b>Graph &gt; Jump to node by id</b> menubar option or by pressing <b>Shift+J</b>. This will help people working on large graphs to find problematic nodes. That is, whenever a graph raises an error during execution, Nodezator informs the id of the problematic node. Users can now easily find that node using this feature by providing the id.


Improvements in user experience

Several interactions of the user with the GUI were improved by adopting one or more of these measures:

- Providing better default values
- Similar behaviour to what is observed in other apps

An example of providing better default values is the fact that the default name used when exporting files is now the name of the .ndz file loaded plus the extension of the corresponding format being exported. Before that, we used a generic file name plus the extension ("exported_graph" + extension). This meant users had to rename the file every time they were exporting the graph if they wanted a more meaningful/distinct name.

An example of adopting behaviours that are similar to what is observed in other apps is the fact that when navigating the file browser in order to select a file, clicking a folder won't cause its name to appear in the entry at the bottom of the file browser. After all, when we navigate in search of a file, we want only the names of files we click to appear in that entry, not the name of the folders. When we click a folder while looking for a file, we do so because we want to double-click it to access its location or inspect its contents, not to select it.

Now it is also possible to close a file without closing the app. Before, a file would only be closed when creating a new one, loading an existing one or quitting the app altogether. This distinction between the actions of closing a file and quitting the app is important for when we implement the ability to load multiple files at the same time, since then we may want to close a file while keeping the app running in order to keep editing other loaded files.


Improved "Not-found" drawings with SVG

We also improved the appearance of the "not-found" drawings. They are used to indicate visual content that wasn't found, obtained or loaded yet. It is used in viewer nodes that weren't executed yet (thus didn't generate any visuals) and path preview widgets that show visual content (the ones used to visualize images, fonts and videos).

They are now generated with SVG, resulting in smooth strokes/shapes. Check the difference in the image below that shows how the "not-found" drawing used in a viewer node:

![Comparison between appearances of the not-found drawings.](https://github.com/IndiePython/nodezator/assets/18728298/129ae068-04d9-42db-a841-f5db26f3d6b1)

The portion on the left shows how the "not-found" drawing appears in previous versions and on the right we have the same drawing as it appears now, with smooth strokes/shapes since it uses SVG.


Fixes and other back-end changes

Among the fixes performed, there was one that would cause the app to crash whenever trying to visualize an invalid font path on the font path preview widget.

There was also a bug in the int float entry widget. After editing the contents of an int float entry by typing the value in it, the intfloat entry was executing its custom update operation a second time needlessly. In other words, it was trying to update the .ndz file twice. This bug in particular was harmless cause we already had checks in place to prevent unnecessary updates which means the second execution had no effect besides being unnecessary. Even so, unnecessary executions must be avoided regardless and if this bug persisted in the system it could evolve into a more harmful one as a result of changes in the related systems.

A back-end change that will go unnoticed by users but will make data management a bit easier is the usage of <a href="https://pyga.me/docs/ref/system.html#pygame.system.get_pref_path">pygame.system.get_pref_path()</a> to define a central writeable path for files holding data like configuration, recent opened files, etc. It now replaces a custom makeshift solution we were using.

As a result, the app now stores such files in a new location.

Proper mechanisms were also employed to guarantee data in the old locations is copied into the new locations. In other words, your current configuration data and other important data saved in the old locations are not lost.

1.4.6

Among the many changes/additions for this patch release, we have:

- code contributed by Mr. sefgit via pull request, that consists of:
- mousewheel pan feature
- the addition of a .gitattributes file
- code contributed by me (KennedyRichard):
- the ability to confirm/dismiss/navigate the dialog using the keyboard
- a bug fix for a dialog that was growing past the screen


The mousewheel pan feature is the ability to pan/move the graph with the mousewheel. The .gitattributes file added is a simple text file that is used to define attributes to paths. Certain operations by Git can be influenced by assigning particular attributes to paths, which is what this file is used for. Some additional changes already discussed with the contributor were also made by me.

I also added/set the ability to confirm/dismiss dialogs with the keyboard using the **Enter** and **Escape** keys, respectively (though, often, confirming will also dismiss the dialog when it is the only action available). I use the terms "added/set" because part of the feature was already implemented and just needed to be properly set in the existing dialogs defined throughout the source. Naturally, some dialogs may not offer the option to be so casually dismissed like that when the consequences of the action cannot be reversed. Currently, though, we don't have any dialog like that.

The user can now also navigate the available dialog buttons/options using **arrow keys** or the **Tab** and **Shift+Tab** keys.

The bug fix consisted in preventing a specific dialog from growing past the screen.

In this specific bug, we were allowing text from error reports to be displayed on the dialog. The right practice, however, would be to just use known predefined text and record the error report in a more appropriate place for the user to check. Text from error reports can grow a lot when there are too many errors, so we must not use such text in dialogs. That's what was causing the problem.

Now, instead of reporting the error(s) on the dialog, we just display an informative small message and log the errors in both the default logger and our custom user logger. This way the user can check the error report using the log files or the user log that can be accessed on the app's GUI. The user log can be accessed by pressing **Ctrl+Shift+j** when you are on the graph/canvas or by selecting the **Help > Show user log** option on the menubar.

1.4.5

New unit tests for the function used to load nodes were provided by Mr. BMaxV via pull request. I KennedyRichard also refactored and complemented them.

I also used the opportunity to make some small improvements in the doctests and to fix one of them.

In order to make it more convenient to store test data, **.zip** files found in Nodezator's source are now also included in the source distribution. That is, they are downloaded in conjunction with the Python modules when someone installs Nodezator.

1.4.4

The bug in SVG exporting was fixed by removing unused code. The unused code was causing a name error because it was made from repurposed pre-existing code and was trying to access a variable that didn't exist in the new spot. Since HTML exporting relies on SVG exporting, HTML exporting was also being affected.

Some other lines that weren't causing errors but were not needed either were also removed to avoid confusion and needless maintenance.

The other bug fixed is related to change checking, that is, checking whether a change in a widget's value took place. Change checking was causing errors due to missing type checks. Such type checks were missing in different modules in the source and are now implemented.

More specifically, when a number changed, if the value was the same, even though the type was different, that change wasn't being treated properly, because the app was only checking the value and reaching the conclusion that nothing changed, because the value was the same in the end. However, this is not the right thing to do. That is, we must also take the type into account, because numeric values may have the same value and still have different types.

For instance, `0`, `0.0` and `0j` all have the same value, although they are an integer, a float and a complex number respectively. Because of that, wherever a value was being checked to determine whether a change took place, we also added a type check so this kind of change is also taken into account.

1.4.3

The error was caused by using the wrong attribute when retrieving the existing sockets from an operation node. Using the correct attribute name, by including an if/else clause that picked the appropriate attribute when needed, fixed the error.

The error was causing execution of the graph to fail altogether whenever operation nodes were present.

Page 1 of 2

© 2024 Safety CLI Cybersecurity Inc. All Rights Reserved.