traitlets.config: common or global parameters?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

traitlets.config: common or global parameters?

G Jones
Hello,

I am working on using traitlets.config in my project. The application has this structure:

class Writer(Configurable):
    writer_trait = Int(4).tag(config=True)
    common_dir = Unicode('').tag(config=True)

class Acquire(Configurable):
    acquire_trait = Int(55).tag(config=True)
    common_dir = Unicode('').tag(config=True)

class Pipeline(Configurable):
    common_dir = Unicode('').tag(config=True)
    def initialize(self):
        self.writer = Writer()
        self.acquire = Acquire()

class PipelineApp(Application):
    classes = [Pipeline, Acquire, Writer]
    def initialize(self,argv=None):
        self.pipeline = Pipeline(config=self.config)
        self.pipeline.initialize()


The idea is that the common_dir traits should be all the same. The code works as written, but results in three possible lines in the settings file. Since the settings file is just python, it's not too bad to do
c.Pipeline.common_dir = '/output'
c.Acquire.common_dir = c.Pipeline.common_dir
c.Writer.common_dir = c.Pipeline.common_dir

But it seems like there should be a better way.

I see that I could pass in a parent and access it that way:
self.writer = Writer(parent=self)

and then in writer:
self.parent.common_dir

But then if I want to use Writer on its own, I need to do a check if self.parent.... or something.

Is there a better way? I hope the intent is clear, please let me know if not.

Thanks,
Glenn

_______________________________________________
IPython-dev mailing list
[hidden email]
https://mail.scipy.org/mailman/listinfo/ipython-dev
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: traitlets.config: common or global parameters?

Matthias Bussonnier
Hi Glenn,

I think the idea is to make a Common dummy subclass:

class MyConfigurable(configurable):
    # class can be empty, or you can move the
    # common_dir = Unicode('').tag(config=True)
    # in it, up to you.
    pass


Then just inherit from it:

  class Writer(MyConfigurable):
      writer_trait = Int(4).tag(config=True)
      common_dir = Unicode('').tag(config=True)

  class Acquire(MyConfigurable):
      acquire_trait = Int(55).tag(config=True)
      common_dir = Unicode('').tag(config=True)

  class Pipeline(MyConfigurable):
      common_dir = Unicode('').tag(config=True)
      def initialize(self):
          self.writer = Writer()
          self.acquire = Acquire()

  class PipelineApp(Application):
      classes = [Pipeline, Acquire, Writer]
      def initialize(self,argv=None):
          self.pipeline = Pipeline(config=self.config)
          self.pipeline.initialize()
>
>
> The idea is that the common_dir traits should be all the same. The code works as
> written, but results in three possible lines in the settings file. Since the
> settings file is just python, it's not too bad to do
>
> c.Pipeline.common_dir = '/output'
> c.Acquire.common_dir = c.Pipeline.common_dir
> c.Writer.common_dir = c.Pipeline.common_dir


Now you just need to configure MyConfigurable for it to affect all classes.

    c.MyConfigurable.common_dir = '/output'

You can target one class in particular with what you do above.

If you add parent=self

    self.pipeline = Pipeline(config=self.config, parent=self)

Then you can narrow down configuration by using parent/child selector;

    c.PipelineApp.MyConfigurable.common_dir = '/output'

It will target only MyConfigurable where `parent=self` is passed and
parent is an
instance of PipelineApp. (This is a rare case use in nbconvert to allow
configuration of each exporter independently)

Does that answer your questions ?

--

Matthias

On Tue, Feb 21, 2017 at 7:01 AM, G Jones <[hidden email]> wrote:

> Hello,
>
> I am working on using traitlets.config in my project. The application has
> this structure:
>
> class Writer(Configurable):
>     writer_trait = Int(4).tag(config=True)
>     common_dir = Unicode('').tag(config=True)
>
> class Acquire(Configurable):
>     acquire_trait = Int(55).tag(config=True)
>     common_dir = Unicode('').tag(config=True)
>
> class Pipeline(Configurable):
>     common_dir = Unicode('').tag(config=True)
>     def initialize(self):
>         self.writer = Writer()
>         self.acquire = Acquire()
>
> class PipelineApp(Application):
>     classes = [Pipeline, Acquire, Writer]
>     def initialize(self,argv=None):
>         self.pipeline = Pipeline(config=self.config)
>         self.pipeline.initialize()
>
>
> The idea is that the common_dir traits should be all the same. The code
> works as written, but results in three possible lines in the settings file.
> Since the settings file is just python, it's not too bad to do
> c.Pipeline.common_dir = '/output'
> c.Acquire.common_dir = c.Pipeline.common_dir
> c.Writer.common_dir = c.Pipeline.common_dir
>
> But it seems like there should be a better way.
>
> I see that I could pass in a parent and access it that way:
> self.writer = Writer(parent=self)
>
> and then in writer:
> self.parent.common_dir
>
> But then if I want to use Writer on its own, I need to do a check if
> self.parent.... or something.
>
> Is there a better way? I hope the intent is clear, please let me know if
> not.
>
> Thanks,
> Glenn
>
> _______________________________________________
> IPython-dev mailing list
> [hidden email]
> https://mail.scipy.org/mailman/listinfo/ipython-dev
>
_______________________________________________
IPython-dev mailing list
[hidden email]
https://mail.scipy.org/mailman/listinfo/ipython-dev
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: traitlets.config: common or global parameters?

G Jones
Hi Matthias,
Thanks for the reply; I think that makes sense.
It might also answer my next question too: Suppose I have another application PipelineMonitor and I want to connect PipelineApp to PipelineMonitor via a common socket. The question is how to share that common socket information (i.e. port number) between the applications using the config file. It sounds like the idea would be to do something like
common_configuration.py:
class GlobalConfiguration(configurable):
    common_port_number = Int(55555).tag(config=True)

pipeline.py:
from common_configuration import GlobalConfiguration
class PipelineConfiguration(GlobalConfiguration):
    common_dir = Unicode('').tag(config=True)

pipeline_monitor.py:
from common_configuration import GlobalConfiguration
class PipelineMonitorConfiguration(GlobalCOnfiguration):
    some_param = Int(34).tag(config=True)

and then inherit PipelineConfiguration and PipelineMonitorConfiguration in the respective application classes.

Then I should be able to have a global_config.py configuration file with the common_port_number, and then use load_subconfig(global_config.py) in each of the application specific config files.

Does that sound like the right idea?

Thank you again,
Glenn


On Tue, Feb 21, 2017 at 11:39 AM, Matthias Bussonnier <[hidden email]> wrote:
Hi Glenn,

I think the idea is to make a Common dummy subclass:

class MyConfigurable(configurable):
    # class can be empty, or you can move the
    # common_dir = Unicode('').tag(config=True)
    # in it, up to you.
    pass


Then just inherit from it:

  class Writer(MyConfigurable):
      writer_trait = Int(4).tag(config=True)
      common_dir = Unicode('').tag(config=True)

  class Acquire(MyConfigurable):
      acquire_trait = Int(55).tag(config=True)
      common_dir = Unicode('').tag(config=True)

  class Pipeline(MyConfigurable):
      common_dir = Unicode('').tag(config=True)
      def initialize(self):
          self.writer = Writer()
          self.acquire = Acquire()

  class PipelineApp(Application):
      classes = [Pipeline, Acquire, Writer]
      def initialize(self,argv=None):
          self.pipeline = Pipeline(config=self.config)
          self.pipeline.initialize()
>
>
> The idea is that the common_dir traits should be all the same. The code works as
> written, but results in three possible lines in the settings file. Since the
> settings file is just python, it's not too bad to do
>
> c.Pipeline.common_dir = '/output'
> c.Acquire.common_dir = c.Pipeline.common_dir
> c.Writer.common_dir = c.Pipeline.common_dir


Now you just need to configure MyConfigurable for it to affect all classes.

    c.MyConfigurable.common_dir = '/output'

You can target one class in particular with what you do above.

If you add parent=self

    self.pipeline = Pipeline(config=self.config, parent=self)

Then you can narrow down configuration by using parent/child selector;

    c.PipelineApp.MyConfigurable.common_dir = '/output'

It will target only MyConfigurable where `parent=self` is passed and
parent is an
instance of PipelineApp. (This is a rare case use in nbconvert to allow
configuration of each exporter independently)

Does that answer your questions ?

--

Matthias

On Tue, Feb 21, 2017 at 7:01 AM, G Jones <[hidden email]> wrote:
> Hello,
>
> I am working on using traitlets.config in my project. The application has
> this structure:
>
> class Writer(Configurable):
>     writer_trait = Int(4).tag(config=True)
>     common_dir = Unicode('').tag(config=True)
>
> class Acquire(Configurable):
>     acquire_trait = Int(55).tag(config=True)
>     common_dir = Unicode('').tag(config=True)
>
> class Pipeline(Configurable):
>     common_dir = Unicode('').tag(config=True)
>     def initialize(self):
>         self.writer = Writer()
>         self.acquire = Acquire()
>
> class PipelineApp(Application):
>     classes = [Pipeline, Acquire, Writer]
>     def initialize(self,argv=None):
>         self.pipeline = Pipeline(config=self.config)
>         self.pipeline.initialize()
>
>
> The idea is that the common_dir traits should be all the same. The code
> works as written, but results in three possible lines in the settings file.
> Since the settings file is just python, it's not too bad to do
> c.Pipeline.common_dir = '/output'
> c.Acquire.common_dir = c.Pipeline.common_dir
> c.Writer.common_dir = c.Pipeline.common_dir
>
> But it seems like there should be a better way.
>
> I see that I could pass in a parent and access it that way:
> self.writer = Writer(parent=self)
>
> and then in writer:
> self.parent.common_dir
>
> But then if I want to use Writer on its own, I need to do a check if
> self.parent.... or something.
>
> Is there a better way? I hope the intent is clear, please let me know if
> not.
>
> Thanks,
> Glenn
>
> _______________________________________________
> IPython-dev mailing list
> [hidden email]
> https://mail.scipy.org/mailman/listinfo/ipython-dev
>
_______________________________________________
IPython-dev mailing list
[hidden email]
https://mail.scipy.org/mailman/listinfo/ipython-dev


_______________________________________________
IPython-dev mailing list
[hidden email]
https://mail.scipy.org/mailman/listinfo/ipython-dev
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: traitlets.config: common or global parameters?

MinRK

On Tue, Feb 21, 2017 at 6:51 PM, G Jones <[hidden email]> wrote:

Hi Matthias,
Thanks for the reply; I think that makes sense.
It might also answer my next question too: Suppose I have another application PipelineMonitor and I want to connect PipelineApp to PipelineMonitor via a common socket. The question is how to share that common socket information (i.e. port number) between the applications using the config file. It sounds like the idea would be to do something like
common_configuration.py:
class GlobalConfiguration(configurable):
    common_port_number = Int(55555).tag(config=True)

pipeline.py:
from common_configuration import GlobalConfiguration
class PipelineConfiguration(GlobalConfiguration):
    common_dir = Unicode('').tag(config=True)

pipeline_monitor.py:
from common_configuration import GlobalConfiguration
class PipelineMonitorConfiguration(GlobalCOnfiguration):
    some_param = Int(34).tag(config=True)

and then inherit PipelineConfiguration and PipelineMonitorConfiguration in the respective application classes.

Yup, this is a patten that has shown up in a few cases, and works pretty well.


Then I should be able to have a global_config.py configuration file with the common_port_number, and then use load_subconfig(global_config.py) in each of the application specific config files.

If your different Applications are relatively small and closely related, you can probably get away with using a single configuration file for your whole application. Set config_file_name on all your applications to the same value (e.g. 'myapp_config'.

-MinRK


Does that sound like the right idea?

Thank you again,
Glenn


On Tue, Feb 21, 2017 at 11:39 AM, Matthias Bussonnier <[hidden email]> wrote:
Hi Glenn,

I think the idea is to make a Common dummy subclass:

class MyConfigurable(configurable):
    # class can be empty, or you can move the
    # common_dir = Unicode('').tag(config=True)
    # in it, up to you.
    pass


Then just inherit from it:

  class Writer(MyConfigurable):
      writer_trait = Int(4).tag(config=True)
      common_dir = Unicode('').tag(config=True)

  class Acquire(MyConfigurable):
      acquire_trait = Int(55).tag(config=True)
      common_dir = Unicode('').tag(config=True)

  class Pipeline(MyConfigurable):
      common_dir = Unicode('').tag(config=True)
      def initialize(self):
          self.writer = Writer()
          self.acquire = Acquire()

  class PipelineApp(Application):
      classes = [Pipeline, Acquire, Writer]
      def initialize(self,argv=None):
          self.pipeline = Pipeline(config=self.config)
          self.pipeline.initialize()
>
>
> The idea is that the common_dir traits should be all the same. The code works as
> written, but results in three possible lines in the settings file. Since the
> settings file is just python, it's not too bad to do
>
> c.Pipeline.common_dir = '/output'
> c.Acquire.common_dir = c.Pipeline.common_dir
> c.Writer.common_dir = c.Pipeline.common_dir


Now you just need to configure MyConfigurable for it to affect all classes.

    c.MyConfigurable.common_dir = '/output'

You can target one class in particular with what you do above.

If you add parent=self

    self.pipeline = Pipeline(config=self.config, parent=self)

Then you can narrow down configuration by using parent/child selector;

    c.PipelineApp.MyConfigurable.common_dir = '/output'

It will target only MyConfigurable where `parent=self` is passed and
parent is an
instance of PipelineApp. (This is a rare case use in nbconvert to allow
configuration of each exporter independently)

Does that answer your questions ?

--

Matthias

On Tue, Feb 21, 2017 at 7:01 AM, G Jones <[hidden email]> wrote:
> Hello,
>
> I am working on using traitlets.config in my project. The application has
> this structure:
>
> class Writer(Configurable):
>     writer_trait = Int(4).tag(config=True)
>     common_dir = Unicode('').tag(config=True)
>
> class Acquire(Configurable):
>     acquire_trait = Int(55).tag(config=True)
>     common_dir = Unicode('').tag(config=True)
>
> class Pipeline(Configurable):
>     common_dir = Unicode('').tag(config=True)
>     def initialize(self):
>         self.writer = Writer()
>         self.acquire = Acquire()
>
> class PipelineApp(Application):
>     classes = [Pipeline, Acquire, Writer]
>     def initialize(self,argv=None):
>         self.pipeline = Pipeline(config=self.config)
>         self.pipeline.initialize()
>
>
> The idea is that the common_dir traits should be all the same. The code
> works as written, but results in three possible lines in the settings file.
> Since the settings file is just python, it's not too bad to do
> c.Pipeline.common_dir = '/output'
> c.Acquire.common_dir = c.Pipeline.common_dir
> c.Writer.common_dir = c.Pipeline.common_dir
>
> But it seems like there should be a better way.
>
> I see that I could pass in a parent and access it that way:
> self.writer = Writer(parent=self)
>
> and then in writer:
> self.parent.common_dir
>
> But then if I want to use Writer on its own, I need to do a check if
> self.parent.... or something.
>
> Is there a better way? I hope the intent is clear, please let me know if
> not.
>
> Thanks,
> Glenn
>
> _______________________________________________
> IPython-dev mailing list
> [hidden email]
> https://mail.scipy.org/mailman/listinfo/ipython-dev
>
_______________________________________________
IPython-dev mailing list
[hidden email]
https://mail.scipy.org/mailman/listinfo/ipython-dev


_______________________________________________
IPython-dev mailing list
[hidden email]
https://mail.scipy.org/mailman/listinfo/ipython-dev


_______________________________________________
IPython-dev mailing list
[hidden email]
https://mail.scipy.org/mailman/listinfo/ipython-dev
Loading...