Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Slack bot integration #427

Merged
merged 8 commits into from
Jun 15, 2017

Conversation

nulinspiratie
Copy link
Contributor

This pull request adds a QCoDeS slack bot that provides information about current measurements.
The user can communicate with the Slack bot via instant messaging (see image below).
The slack bot currently has the following functionality:

  • Give information about the current measurement (percentage done, print of dataset).
  • Upload the most recent plot
  • Notify when measurement is done
  • Adding custom commands and periodically-executed tasks

A few notes

  • I added the class attributes DataSet.latest_dataset and BasePlot.latest_plot. Every time a dataset/plot is instantiated, this attribute points to that object. This allows the slack bot to determine the latest dataset/plot.
  • I added to slack bot to qcodes/widgets, but I was not sure if this is the right place. If not, where should it go?
  • Periodic calls to Slack.update() must be made, and so the Slack bot works best as a widget in multiprocessing.
  • The package 'tempfile' is used to determine a temporary store location for any plot file. This isn't currently in the package requirements

@giulioungaretti @AdriaanRol

slack

@nulinspiratie nulinspiratie changed the title Slack bot integration Feat: Slack bot integration Dec 27, 2016
@giulioungaretti
Copy link
Contributor

lol this is super cool! May need more massaging though, as dataset.sync() may disappear soon, and same goes for the hiddenupdatewidget !

We can definitely work a way to insert the slack class into the code base, I have the feeling that this should rather be a daemon-like process (such as monitoring) than a widget like thing :D

Terrific contribution !

@nulinspiratie
Copy link
Contributor Author

nulinspiratie commented Jan 3, 2017

@giulioungaretti I wasn't aware that dataset.sync() would disappear, will it not be necessary later on?

And I was initially also thinking of a subprocess, but with the current multiprocessing architecture I ran into problems with retrieving the latest plot. Also, I noticed some cool things you can do when the Slack bot is a widget instead of a subprocess. For instance, you can create a cell, fill it with a chunk of code, and then execute it. I'm using this to run measurements from Slack atm, although I'm not sure if this functionality should be part of the QCoDeS package

@nulinspiratie
Copy link
Contributor Author

@giulioungaretti I realized this code doesn't need widgets nor multiprocessing. Instantiating it in a different thread is sufficient. Would this PR be useful for qcodes? If so I can make the changes. What folder would now be a good location for the code?

@giulioungaretti
Copy link
Contributor

We can definitely add this! I would make an extra folder next to utils.

The new version of slack is a thread, and so does not need a ipython
widget. Furthermore, the active_loop and active_data_set functions
have been added, since slack needs access to the active loop and data_set.
active_loop() will point to the active loop. this is set when calling
loop.run(set_active=True), where set_active is True by default.
In some cases a measurement can itself consist of measurements.
For instance, a complex parameter could perform an entire measurement.
To avoid that the active_loop is overwritten, the kwarg set_active=False
can be added.
@nulinspiratie
Copy link
Contributor Author

nulinspiratie commented Jun 6, 2017

@giulioungaretti I upgraded the Slack class, it now is a subclass of threading.Thread. The main advantage here is that it operates as a separate thread without depending on ipython widgets.

Starting the Slack client is very easy, namely as such:

from qcodes.utils.slack import Slack
slack = Slack(**optional_commands)

optional_commands are commands that can also be executed aside from the standard ones. For instance, it could be a parameter, which we can then perform get/set operations on via Slack.

Since the Slack class needs access to the latest measurement and plot, I also added some functionality to BasePlot and loops.py. BasePlot now has the class attribute BasePlot.latest_plot, which is updated every time a new BasePlot object is created. This way, latest_plot always refers to the latest created plot.

For loops I did something similar: I created ActiveLoop.active_loop. Using this, I added the two functions active_loop() and active_data_set(), which calls active_loop(). When running a loop with kwarg set_active=True (True by default), it will set ActiveLoop.active_loop to itself for the duration of the measurement. This also works with Measure. In the cases where you have a Loop in which a complex parameter itself creates a Loop or Measure, you can avoid overwriting active_loop by adding set_active = False.

I noticed that active_loop and active_data_set are also useful in other ways. For instance, you can use the folder of the active dataset as a base folder, and any parameters that create Loops can create subfolders in the base dataset folder. I added the two functions to qcodes init, so they can be accessed easier.

I finally also added slacker as an optional package in the setup

@giulioungaretti
Copy link
Contributor

looks good to me! @jenshnielsen @WilliamHPNielsen ?

@jenshnielsen
Copy link
Collaborator

Looks good to me

@giulioungaretti
Copy link
Contributor

great will review the code and merge//ask for changes today !

@giulioungaretti giulioungaretti self-assigned this Jun 8, 2017
Copy link
Contributor

@giulioungaretti giulioungaretti left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nulinspiratie small comments, the ready to merge!

from qcodes import active_loop, active_data_set


def convert_command(text):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure why this? Isn't there one extra def () ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what you mean, the try_convert_str is a function that's only called within convert_command, so I made it a subfunction.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nulinspiratie shut, never mind I totally misread the code. Just catch the right Value error and then I can merge!

try:
val = float(string)
return val
except:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just catch: ValueError here :D

try:
val = int(string)
return val
except:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just catch: ValueError here :D

@giulioungaretti giulioungaretti merged commit 77f2d1c into microsoft:master Jun 15, 2017
giulioungaretti pushed a commit that referenced this pull request Jun 15, 2017
Author: Serwan Asaad <serwan.asaad@gmail.com>

    Feat: Slack bot integration (#427)
@nulinspiratie nulinspiratie deleted the slack-bot branch June 21, 2017 02:02
Dominik-Vogel pushed a commit to Dominik-Vogel/Qcodes that referenced this pull request Aug 9, 2017
* Added slack bot

* Added latest_dataset/latest_plot

* refactor: moved slack.py to utils

* feat: upgraded slack, added active_loop, active_data_set

The new version of slack is a thread, and so does not need a ipython
widget. Furthermore, the active_loop and active_data_set functions
have been added, since slack needs access to the active loop and data_set.
active_loop() will point to the active loop. this is set when calling
loop.run(set_active=True), where set_active is True by default.
In some cases a measurement can itself consist of measurements.
For instance, a complex parameter could perform an entire measurement.
To avoid that the active_loop is overwritten, the kwarg set_active=False
can be added.

* added slacker to extra packages

* Removed .idea from PyCharm

* fix: Added catching of ValueError
peendebak pushed a commit to VandersypenQutech/Qcodes that referenced this pull request Aug 11, 2017
* Added slack bot

* Added latest_dataset/latest_plot

* refactor: moved slack.py to utils

* feat: upgraded slack, added active_loop, active_data_set

The new version of slack is a thread, and so does not need a ipython
widget. Furthermore, the active_loop and active_data_set functions
have been added, since slack needs access to the active loop and data_set.
active_loop() will point to the active loop. this is set when calling
loop.run(set_active=True), where set_active is True by default.
In some cases a measurement can itself consist of measurements.
For instance, a complex parameter could perform an entire measurement.
To avoid that the active_loop is overwritten, the kwarg set_active=False
can be added.

* added slacker to extra packages

* Removed .idea from PyCharm

* fix: Added catching of ValueError
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants