How can I add a callback to a ThreadedKernelClient in IPython? - ipython

Currently I'm getting my hands on a ThreadedKernelClient by:
kernel_manager = KernelManager(client_class='IPython.kernel.threaded.ThreadedKernelClient')
kernel_manager.start_kernel()
kernel_client = kernel_manager.client()
However, I'm not sure how I can register a callback for incoming messages (after I run execute). Can anyone point me in the right direction?

What I've done is subclass ThreadedZMQSocketChannel and ThreadedKernelClient, and overwrote call_handlers, eg:
class TestChannel(ThreadedZMQSocketChannel):
def call_handlers(self, msg):
# do something
class TestClient(ThreadedKernelClient):
iopub_channel_class = Type(TestChannel)
shell_channel_class = Type(TestChannel)
stdin_channel_class = Type(TestChannel)
Your manager then looks like:
kernel_manager = KernelManager(kernel_name='python', client_class='__main__.TestClient')
Once you start_channels, your call_handlers method will be called with results from methods such as execute.

Related

Log4cplus setproperty function usage

I use the following configuration for my logger, in the conf file :
log4cplus.appender.TestLogAppender = log4cplus::TimeBasedRollingFileAppender
log4cplus.appender.TestLogAppender.FilenamePattern = %d{yyyyMMdd}.log
log4cplus.appender.TestLogAppender.MaxHistory = 365
log4cplus.appender.TestLogAppender.Schedule = DAILY
log4cplus.appender.TestLogAppender.RollOnClose = false
log4cplus.appender.TestLogAppender.layout = log4cplus::PatternLayout
log4cplus.appender.TestLogAppender.layout.ConversionPattern = %m%n
And in my code, I have the following initializing function for my logger, in which first, I load the configuration file, and then I wish to set the 'FilenamePattern' property to a new value, so that when I run multiple applications, each application will write to it's own log file:
void InitLogger()
{
ProperyConfigurator::doConfigure (L"LogConf.conf");
helpers:Properties prop(L"LogConf.conf");
props.setPropery(L"log4cplus.appender.TestLogAppender.FilenamePattern" ,
"Log/AppLogName.log.%d{yyyy-MM-dd}");
}
The problem is that when I run even one application, the log messages are written to the file as given in the original configuration file (in the 'FilenamePattern' property).
It seems the 'setproperty' didn't set the new value I gave it.
Is there a problem with my initializing logger function?
Have I used the setProperty method wrong?
You are obviously changing the properties after you have already configured the system, so your changes will be ignored. Do this instead:
helpers:Properties props(L"LogConf.conf");
props.setPropery(L"log4cplus.appender.TestLogAppender.FilenamePattern" ,
"Log/AppLogName.log.%d{yyyy-MM-dd}");
ProperyConfigurator propConf (props);
propConf.configure();

Passing variables between classes in Tkinter, Python 3

I'm kind of a newbie to Python, and I'm writing some code to take data via a user input and put it into a .csv file. To do that, the program needs to pass data from class to class.
To teach myself how to pass data, I took code from here. I did have to alter the code a bit to get it to start up, making sure that the make_widget and print_it functions can pull the "name" variable stored in self.app_data data structure properly.
from tkinter import *
from tkinter import ttk
class MyApp(Tk):
def __init__(self):
Tk.__init__(self)
self.app_data={'name': StringVar}
container = ttk.Frame(self)
container.pack(side="top", fill="both", expand = True)
self.frames = {}
for F in (PageOne, PageTwo):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky = NSEW)
self.show_frame(PageOne)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class PageOne(ttk.Frame):
def __init__(self, parent, controller):
ttk.Frame.__init__(self, parent)
self.controller=controller
ttk.Label(self, text='PageOne').grid(padx=(20,20), pady=(20,20))
self.make_widget(controller)
def make_widget(self, controller):
self.controller=controller
self.some_entry = ttk.Entry(self, textvariable=self.controller.app_data['name'], width=8)
self.some_entry.grid()
button1 = ttk.Button(self, text='Next Page',command=lambda: controller.show_frame(PageTwo))
button1.grid()
class PageTwo(ttk.Frame):
def __init__(self, parent, controller):
ttk.Frame.__init__(self, parent)
self.controller=controller
ttk.Label(self, text='PageTwo').grid(padx=(20,20), pady=(20,20))
button1 = ttk.Button(self, text='Previous Page',command=lambda: controller.show_frame(PageOne))
button1.grid()
button2 = ttk.Button(self, text='press to print', command= self.print_it())
button2.grid()
def print_it(self):
value=self.controller.app_data['name'].get()
print ('The value stored in StartPage some_entry = ', value)#What do I put here
#to print the value of some_input from PageOne
When I run this program, it does start up, and I can move from frame to frame, but it does not print the "name" variable.
When I close the window, I get the error:
TypeError: get() missing 1 required positional argument: 'self'
Which the traceback blames on the line:
value=self.controller.app_data['name'].get()
What am I doing wrong? For what it's worth, I'm writing the code in Python 3.5.
I really appreciate any help that you guys could give me.

MongoEngine not saving embedded doc second time around

When I use MongoEngine to add an embedded doc to a doc, it works the first time when the list is empty but fails with subsequent tries saying: mongoengine.errors.OperationError: Could not save document (Cannot update 'sensorlist.1.alert_list.0._cls' and 'sensorlist.1.alert_list' at the same time)
The following test code demonstrates the issue: If you run it once you will see a new collection/document in foo that has an S2 embedded Sensor with qty 2 embedded Alerts. If you run it again it blows up - Any ideas?
Thx Bill
import mongoengine as ME
ME.connect('foo')
class Sensor(ME.EmbeddedDocument):
name = ME.StringField()
alert_list = ME.ListField()
class Alert(ME.EmbeddedDocument):
name = ME.StringField(default = 'new alert')
class SiteConfig(ME.Document):
siteid = ME.StringField()
sensorlist = ME.ListField(ME.EmbeddedDocumentField(Sensor))
if not SiteConfig.objects(siteid = '123456'):
newsite = SiteConfig(siteid = '123456')
newsite.save()
print("saved new site")
site = SiteConfig.objects(siteid = '123456').first()
newsensor = Sensor(name='S1')
site.sensorlist.append(newsensor)
site.save()
print("added sensor S1")
newsensor = Sensor(name='S2')
site.sensorlist.append(newsensor)
site.save()
print("added sensor S2")
for sensor in site.sensorlist:
if sensor.name =='S2':
alert = Alert()
sensor.alert_list.append(alert)
site.save()
print('added first alert to S2')
for sensor in site.sensorlist:
if sensor.name =='S2':
alert = Alert()
sensor.alert_list.append(alert)
site.save()
print('added second alert to S1')
I solved this by reproducing the code in MongoAlchemy which is very similar. That also failed but actually gave me useful exception info that pointed me to the problem which was that my Sensor class Alert_list definition needed to specify the class it contains.
So the fix is to define Sensor like this:
class Sensor(ME.DynamicEmbeddedDocument):
name = ME.StringField()
alert_list = ME.ListField(ME.EmbeddedDocumentField(Alert))
After all that pain over such a small issue I will probably stick with MongoAlchemy!

What am I doing wrong with this Python class? AttributeError: 'NoneType' object has no attribute 'usernames'

Hey there I am trying to make my first class my code is as follows:
class Twitt:
def __init__(self):
self.usernames = []
self.names = []
self.tweet = []
self.imageurl = []
def twitter_lookup(self, coordinents, radius):
twitter = Twitter(auth=auth)
coordinents = coordinents + "," + radius
print coordinents
query = twitter.search.tweets(q="", geocode='33.520661,-86.80249,50mi', rpp=10)
print query
for result in query["statuses"]:
self.usernames.append(result["user"]["screen_name"])
self.names.append(result['user']["name"])
self.tweet.append(h.unescape(result["text"]))
self.imageurl.append(result['user']["profile_image_url_https"])
What I am trying to be able to do is then use my class like so:
test = Twitt()
hello = test.twitter_lookup("38.5815720,-121.4944000","1m")
print hello.usernames
This does not work and I keep getting: "AttributeError: 'NoneType' object has no attribute 'usernames'"
Maybe I just misunderstood the tutorial or am trying to use this wrong. Any help would be appreciated thanks.
I see the error is test.twitter_lookup("38.5815720,-121.4944000","1m") return nothing. If you want the usernames, you need to do
test = Twitt()
test.twitter_lookup("38.5815720,-121.4944000","1m")
test.usernames
Your function twitter_lookup is modifying the Twitt object in-place. You didn't make it return any kind of value, so when you call hello = test.twitter_lookup(), there's no return value to assign to hello, and it ends up as None. Try test.usernames instead.
Alternatively, have the twitter_lookup function put its results in some new object (perhaps a dictionary?) and return it. This is probably the more sensible solution.
Also, the function accepts a coordinents (it's 'coordinates') argument, but then throws it away and uses a hard-coded value instead.

Call TYPO3 plugin from other plugin's body

I need to call typo3 plugin from other plugin's body and pass its result to template. This is pseudo-code that describes what I want to achieve doing this:
$data['###SOME_VARIABLE###'] = $someOtherPlugin->main();
$this->cObj->substituteMarkerArray($someTemplate, $data);
Is it possible?
Thanks!
It doenst work if you use the whole pi construct, e.g. for links, marker function etc, and the TSFE Data can be corrupted.
Dmitry said:
http://lists.typo3.org/pipermail/typo3-english/2008-August/052259.html
$cObjType = $GLOBALS['TSFE']->tmpl->setup['plugin.']['tx_rgsmoothgallery_pi1'];
$conf = $GLOBALS['TSFE']->tmpl->setup['plugin.']['tx_rgsmoothgallery_pi1.'];
$cObj = t3lib_div::makeInstance('tslib_cObj');
$cObj->start(array(), '_NO_TABLE');
$conf['val'] = 1;
$content = $cObj->cObjGetSingle($cObjType, $conf); //calling the main method
You should use t3lib_div:makeInstance method.
There is a working example from TYPO3's "powermail" extension.
function getGeo() {
// use geo ip if loaded
if (t3lib_extMgm::isLoaded('geoip')) {
require_once( t3lib_extMgm::extPath('geoip').'/pi1/class.tx_geoip_pi1.php');
$this->media = t3lib_div::makeInstance('tx_geoip_pi1');
if ($this->conf['geoip.']['file']) { // only if file for geoip is set
$this->media->init($this->conf['geoip.']['file']); // Initialize the geoip Ext
$this->GEOinfos = $this->media->getGeoIP($this->ipOverride ? $this->ipOverride : t3lib_div::getIndpEnv('REMOTE_ADDR')); // get all the infos of current user ip
}
}
}
The answer of #mitchiru is nice and basically correct.
If you have created your outer extension with Kickstarter and you are using pi_base then there is already an instance of tslib_cObj and the whole construct becomes simpler:
// get type of inner extension, eg. USER or USER_INT
$cObjType = $GLOBALS['TSFE']->tmpl->setup['plugin.']['tx_innerextension_pi1'];
// get configuration array of inner extension
$cObjConf = $GLOBALS['TSFE']->tmpl->setup['plugin.']['tx_innerextension_pi1.'];
// add own parameters to configuration array if needed - otherwise skip this line
$cObjConf['myparam'] = 'myvalue';
// call main method of inner extension, using cObj of outer extension
$content = $this->cObj->cObjGetSingle($cObjType, $cObjConf);
Firstly, you have to include your plugin class, before using, or outside your class:
include_once(t3lib_extMgm::extPath('myext').'pi1/class.tx_myext_pi1.php');
Secondly in your code (in the main as example)
$res = tx_myext_pi1::myMethod();
This will work for sure (I've checked this): http://lists.typo3.org/pipermail/typo3-english/2008-August/052259.html.
Probably Fedir's answer is correct too but I didn't have a chance to try it.
Cheers!