Git Product home page Git Product logo

ryvencore's People

Contributors

amaury-anciaux avatar leon-thomm avatar sphh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

ryvencore's Issues

branches and publishing packages

main: should generally be working.

dev: is used for development and is expected to have breaking or incomplete changes.

v*: used for commits dedicated to specific legacy versions.

publishing pypi packages

New PyPI releases are published by creating a git tag, e.g.

git tag v0.4.0a9
git push v0.4.0a9

and then see Actions tab on GitHub


Feel free to suggest changes.

dtypes default not used

Hi @leon-thomm, I've been using ryvencore over on ironflow to build a jupyter-based gui to drive for our project pyiron and I'm absolutely loving it.

I discovered that the default values in the initial input channels were not being used. In addition to the dtypes, where default is actively solicited in the initializer, I thought it might be nice to allow specifying defaults for non-typed input using add_data['val'].

A MWE example is below with a little fix to put in NodeInput.__init__ if you'd like. I'd be happy to make a PR, but when I forked the repo I discovered that main here is way out of date compared to the conda-forge installation (v0.3.1.1). NodeInput.__init__ doesn't even take a dtypes: Dtypes = None kwarg. Where is the more up-to-date code coming from? The only branch ahead of main here doesn't have it, and unfortunately I don't have permissions to dig into the conda feedstock source to look there.

MWE:

import ryvencore as rc

class MyNode(rc.Node):
    title = 'mwe'
    init_inputs = [
        rc.NodeInputBP(type_='data', add_data={'val': 'towel'}),  # Without dtype
        rc.NodeInputBP(type_='data', dtype=rc.dtypes.Integer(default=42))
    ]
    
    def place_event(self):
        super().place_event()
        print(f"{self.__class__.__name__} got placed")
    
session = rc.Session()
session.register_node(MyNode)
script = session.create_script(title='mwe')
node = script.flow.create_node(MyNode)
print("Initialized?", node.initialized)
print("Values after initialization:", node.input(0), node.input(1))

def set_defaults(node_input):
    """Something like could be added to NodeInput.__init__"""
    if node_input.dtype is not None:
        node_input.update(node_input.dtype.default)
    elif 'val' in node_input.add_data.keys():
        node_input.update(node_input.add_data['val'])
        
set_defaults(node.inputs[0])
set_defaults(node.inputs[1])
print("Values after setting defaults:", node.input(0), node.input(1))

>>> MyNode got placed
>>> Initialized? True
>>> Values after initialization: None None
>>> Values after setting defaults: towel 42

edited for hyperlinks

Documentation ryvencore 0.4+

In the documentation of ryvencore, there is an example of Data flow.

It does not work as is. May I suggest the following code that implements the registration of the node in the session before using them?

import ryvencore as rc

class Producer(rc.Node):
    init_outputs = [rc.NodeOutputType()]

    def push_data(self, d):
        self.d = d
        self.update()
    def update_event(self, inp=-1):
        self.set_output_val(0, self.d)

class Consumer(rc.Node):
    init_inputs = [rc.NodeInputType()]
    def update_event(self, inp=-1):
        p = self.input(0).payload
        p.append(4)
        print(p)

def build_and_run(D):
    s = rc.Session()
    s.register_node(Producer)
    s.register_node(Consumer)
    f = s.create_flow('main')
    producer =  f.create_node(Producer)
    consumer1 = f.create_node(Consumer)
    consumer2 = f.create_node(Consumer)
    f.connect_nodes(producer.outputs[0], consumer1.inputs[0])
    f.connect_nodes(producer.outputs[0], consumer2.inputs[0])
    return producer.push_data(D)

build_and_run(rc.Data([1,2,3]))

Error not at the right location

When trying to create a node but not using a node that what previously register, the program prints a message but does not output an error. Thus the program fails at a later stage making it harder to debug.

In the following example, we want to create a node 'Producer' (string) which fails (we should use the class directly) but only creates an error 3 lines later.

import ryvencore as rc

class Producer(rc.Node):
    init_outputs = [rc.NodeOutputType()]

    def push_data(self, d):
        self.d = d
        self.update()
    def update_event(self, inp=-1):
        self.set_output_val(0, self.d)

class Consumer(rc.Node):
    init_inputs = [rc.NodeInputType()]
    def update_event(self, inp=-1):
        p = self.input(0).payload
        p.append(4)
        print(p)

def build_and_run(D):
    s = rc.Session()
    s.register_node(Producer)
    s.register_node(Consumer)
    f = s.create_flow('main')
    producer =  f.create_node('Producer')
    consumer1 = f.create_node(Consumer)
    consumer2 = f.create_node(Consumer)
    f.connect_nodes(producer.outputs[0], consumer1.inputs[0])
    f.connect_nodes(producer.outputs[0], consumer2.inputs[0])
    return producer.push_data(D)

build_and_run(rc.Data([1,2,3]))

Error message

Node class Producer not in session nodes

dangerous mutable defaults in List and Choice

On ryvencore 0.3.1.1.

By using mutable defaults, multiple input channels can impact each other. MWE:

import ryvencore as rc

l1 = rc.NodeInputBP(type_='data', dtype=rc.dtypes.List())
l2 = rc.NodeInputBP(type_='data', dtype=rc.dtypes.List())

l2.dtype.val.append('bar')
print(l2.dtype.default, l1.dtype.val, l1.dtype.default)

c1 = rc.NodeInputBP(type_='data', dtype=rc.dtypes.Choice())
c2 = rc.NodeInputBP(type_='data', dtype=rc.dtypes.Choice())

c2.dtype.items.append(str)
print(c1.dtype.items)

>>> ['bar'] ['bar'] ['bar']
>>> [<class 'str'>]

If I'm correctly understanding the typical use cases of dtypes, I can't imagine it's very likely someone would come in and mutate things like this, but I guess it's possible someone tries to get clever and update the items available to a choice and winds up updating more choices than they meant to. Adding the pattern self.items = items if items is not None else [] and changing the signature to items = None should clean it up (and similar for List and default), so even if it's unlikely to be problematic the fix is easy.

error: str object is not callable

This is really weird.

When trying to undo a paste command with a DrawingObject as content, the error from the title appears in the console. In several attempts, I have been able to locate the crash, but not the source for this

    def remove_drawing(self, drawing: DrawingObject):
        """Removes a drawing from the scene."""

        self.scene().removeItem(drawing)
        self.drawings.remove(drawing)

This method of FlowView does execute completely, however self.scene().removeItem(drawing) seems to have no effect. The debugger always crashes without error description anywhere in this method when undoing a paste command. I then tried to get more information using simple print statement but even things like this (!!):

    def remove_drawing(self, drawing: DrawingObject):
        """Removes a drawing from the scene."""
        print(drawing)
        # self.scene().removeItem(drawing)
        # self.drawings.remove(drawing)

results in a debugger crash when I try to break at the print line. I could not find any redefinitions of the word and methods str or print in any files, including the DrawingObject. I also don't overwrite builtin methods in DrawingObject.
It completely breaks the undo of the paste command (removing), however it doesn't break the delete command, which doesn't make any sense to me. The error is also printed when moving DrawingObjects. I've no idea what to do with this...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.