<commit_before>#
# Kiwi: a Framework and Enhanced Widgets for Python
#
# Copyright (C) 2003-2006 Async Open Source
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
# USA
#
# Author(s): Christian Reis <kiko@async.com.br>
#            Lorenzo Gil Sanchez <lgs@sicem.biz>
#            Johan Dahlin <jdahlin@async.com.br>
#            Gustavo Rahal <gustavo@async.com.br>
#            Daniel Saran R. da Cunha <daniel@async.com.br>
#            Evandro Vale Miquelito <evandro@async.com.br>
#

"""GtkComboBox and GtkComboBoxEntry support for the Kiwi Framework.

The GtkComboBox and GtkComboBoxEntry classes here are also slightly extended
they contain methods to easily insert and retrieve data from combos.
"""

import gobject
import gtk
from gtk import keysyms

from kiwi import ValueUnset
from kiwi.datatypes import number
from kiwi.python import deprecationwarn
from kiwi.ui.comboboxentry import BaseComboBoxEntry
from kiwi.ui.comboentry import ComboEntry
from kiwi.ui.combomixin import COL_COMBO_LABEL, COMBO_MODE_STRING, \
     COMBO_MODE_DATA, COMBO_MODE_UNKNOWN, ComboMixin
from kiwi.ui.proxywidget import ProxyWidgetMixin, ValidatableProxyWidgetMixin
from kiwi.ui.widgets.entry import ProxyEntry
from kiwi.utils import PropertyObject, gproperty

class ProxyComboBox(PropertyObject, gtk.ComboBox, ComboMixin, ProxyWidgetMixin):

    __gtype_name__ = 'ProxyComboBox'
    allowed_data_types = (basestring, object) + number

    def __init__(self):
        gtk.ComboBox.__init__(self)
        ComboMixin.__init__(self)
        ProxyWidgetMixin.__init__(self)
        PropertyObject.__init__(self)
        self.connect('changed', self._on__changed)

        renderer = gtk.CellRendererText()
        self.pack_start(renderer)
        self.add_attribute(renderer, 'text', COL_COMBO_LABEL)

    # GtkComboBox is a GtkContainer subclass which implements __len__ in
    # PyGTK in 2.8 and higher. Therefor we need to provide our own
    # implementation to be backwards compatible and override the new
    # behavior in 2.8
    def __len__(self):
        return len(self.get_model())

    def _on__changed(self, combo):
        self.emit('content-changed')

    def read(self):
        if self.mode == COMBO_MODE_UNKNOWN:
            return ValueUnset

        data = self.get_selected()
        if self.mode == COMBO_MODE_STRING:
            data = self._from_string(data)

        return data

    def update(self, data):
        # We dont need validation because the user always
        # choose a valid value

        if data is None:
            return

        if self.mode == COMBO_MODE_STRING:
            data = self._as_string(data)

        self.select(data)

    def prefill(self, itemdata, sort=False):
        ComboMixin.prefill(self, itemdata, sort)

        # we always have something selected, by default the first item
        self.set_active(0)
        self.emit('content-changed')

    def clear(self):
        ComboMixin.clear(self)
        self.emit('content-changed')

class ProxyComboBoxEntry(PropertyObject, BaseComboBoxEntry, ComboMixin,
                         ValidatableProxyWidgetMixin):
    allowed_data_types = (basestring, object) + number
    __gtype_name__ = 'ProxyComboBoxEntry'
    # it doesn't make sense to connect to this signal
    # because we want to monitor the entry of the combo
    # not the combo box itself.

    gproperty("list-editable", bool, True, "Editable")

    def __init__(self, **kwargs):
        deprecationwarn(
            'ProxyComboBoxEntry is deprecated, use ProxyComboEntry instead',
            stacklevel=3)
        BaseComboBoxEntry.__init__(self)
        ComboMixin.__init__(self)
        ValidatableProxyWidgetMixin.__init__(self, widget=self.entry)
        PropertyObject.__init__(self, **kwargs)

        self.set_text_column(COL_COMBO_LABEL)

        # here we connect the expose-event signal directly to the entry
        self.child.connect('changed', self._on_child_entry__changed)

        # HACK! we force a queue_draw because when the window is first
        # displayed the icon is not drawn.
        gobject.idle_add(self.queue_draw)

        self.set_events(gtk.gdk.KEY_RELEASE_MASK)
        self.connect("key-release-event", self._on__key_release_event)

    def prop_set_list_editable(self, value):
        if self.mode == COMBO_MODE_DATA:
            return

        self.entry.set_editable(value)

        return value

    def _update_selection(self, text=None):
        if text is None:
            text = self.entry.get_text()

        self.select_item_by_label(text)

    def _add_text_to_combo_list(self):
        text = self.entry.get_text()
        if not text.strip():
            return

        if text in self.get_model_strings():
            return

        self.entry.set_text('')
        self.append_item(text)
        self._update_selection(text)

    def _on__key_release_event(self, widget, event):
        """Checks for "Enter" key presses and add the entry text to
        the combo list if the combo list is set as editable.
        """
        if not self.list_editable:
            return

        if event.keyval in (keysyms.KP_Enter,
                            keysyms.Return):
            self._add_text_to_combo_list()

    def _on_child_entry__changed(self, widget):
        """Called when something on the entry changes"""
        if not widget.get_text():
            return

        self.emit('content-changed')

    def set_mode(self, mode):
        # If we're in the transition to go from
        # unknown->label set editable to False
        if (self.mode == COMBO_MODE_UNKNOWN and mode == COMBO_MODE_DATA):
            self.entry.set_editable(False)

        ComboMixin.set_mode(self, mode)

    def read(self):
        if self.mode == COMBO_MODE_UNKNOWN:
            return ValueUnset
        return self.get_selected()

    def update(self, data):
        if data is ValueUnset or data is None:
            self.entry.set_text("")
        else:
            self.select(data)

    def prefill(self, itemdata, sort=False, clear_entry=False):
        ComboMixin.prefill(self, itemdata, sort)
        if clear_entry:
            self.entry.set_text("")

        # setup the autocompletion
        auto = gtk.EntryCompletion()
        auto.set_model(self.get_model())
        auto.set_text_column(COL_COMBO_LABEL)
        self.entry.set_completion(auto)

    def clear(self):
        """Removes all items from list and erases entry"""
        ComboMixin.clear(self)
        self.entry.set_text("")

class ProxyComboEntry(PropertyObject, ComboEntry, ComboMixin,
                      ValidatableProxyWidgetMixin):
    __gtype_name__ = 'ProxyComboEntry'
    allowed_data_types = (basestring, object) + number

    gproperty("list-editable", bool, True, "Editable")

    def __init__(self):
        entry = ProxyEntry()
        ComboEntry.__init__(self, entry=entry)
        ComboMixin.__init__(self)
        ValidatableProxyWidgetMixin.__init__(self)
        PropertyObject.__init__(self)
        entry.connect('content-changed', self._on_entry__content_changed)

    # We only need to listen for changes in the entry, it's updated
    # even if you select something in the popup list
    def _on_entry__content_changed(self, entry):
        self.emit('content-changed')

    def prop_set_list_editable(self, value):
        self.entry.set_editable(value)
        return value

    def read(self):
        return self.get_selected()

    def update(self, data):
        if data is ValueUnset or data is None:
            self.entry.set_text("")
        else:
            self.select(data)

    def clear(self):
        """Removes all items from list and erases entry"""
        ComboMixin.clear(self)
        self.entry.set_text("")

    def set_tooltip(self, text):
        self.entry.set_tooltip(text)

    def prefill(self, data, sort=False):
        return ComboEntry.prefill(self, data, sort)
<commit_msg>Add documentation references<commit_after>#
# Kiwi: a Framework and Enhanced Widgets for Python
#
# Copyright (C) 2003-2006 Async Open Source
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
# USA
#
# Author(s): Christian Reis <kiko@async.com.br>
#            Lorenzo Gil Sanchez <lgs@sicem.biz>
#            Johan Dahlin <jdahlin@async.com.br>
#            Gustavo Rahal <gustavo@async.com.br>
#            Daniel Saran R. da Cunha <daniel@async.com.br>
#            Evandro Vale Miquelito <evandro@async.com.br>
#

"""GtkComboBox and GtkComboBoxEntry support for the Kiwi Framework.

The GtkComboBox and GtkComboBoxEntry classes here are also slightly extended
they contain methods to easily insert and retrieve data from combos.
"""

import gobject
import gtk
from gtk import keysyms

from kiwi import ValueUnset
from kiwi.datatypes import number
from kiwi.python import deprecationwarn
from kiwi.ui.comboboxentry import BaseComboBoxEntry
from kiwi.ui.comboentry import ComboEntry
from kiwi.ui.combomixin import COL_COMBO_LABEL, COMBO_MODE_STRING, \
     COMBO_MODE_DATA, COMBO_MODE_UNKNOWN, ComboMixin
from kiwi.ui.proxywidget import ProxyWidgetMixin, ValidatableProxyWidgetMixin
from kiwi.ui.widgets.entry import ProxyEntry
from kiwi.utils import PropertyObject, gproperty

class ProxyComboBox(PropertyObject, gtk.ComboBox, ComboMixin, ProxyWidgetMixin):

    __gtype_name__ = 'ProxyComboBox'
    allowed_data_types = (basestring, object) + number

    def __init__(self):
        gtk.ComboBox.__init__(self)
        ComboMixin.__init__(self)
        ProxyWidgetMixin.__init__(self)
        PropertyObject.__init__(self)
        self.connect('changed', self._on__changed)

        renderer = gtk.CellRendererText()
        self.pack_start(renderer)
        self.add_attribute(renderer, 'text', COL_COMBO_LABEL)

    # GtkComboBox is a GtkContainer subclass which implements __len__ in
    # PyGTK in 2.8 and higher. Therefor we need to provide our own
    # implementation to be backwards compatible and override the new
    # behavior in 2.8
    def __len__(self):
        return len(self.get_model())

    def _on__changed(self, combo):
        self.emit('content-changed')

    def read(self):
        if self.mode == COMBO_MODE_UNKNOWN:
            return ValueUnset

        data = self.get_selected()
        if self.mode == COMBO_MODE_STRING:
            data = self._from_string(data)

        return data

    def update(self, data):
        # We dont need validation because the user always
        # choose a valid value

        if data is None:
            return

        if self.mode == COMBO_MODE_STRING:
            data = self._as_string(data)

        self.select(data)

    def prefill(self, itemdata, sort=False):
        """
        See L{kiwi.ui.combomixin.ComboMixin.prefill}
        """
        ComboMixin.prefill(self, itemdata, sort)

        # we always have something selected, by default the first item
        self.set_active(0)
        self.emit('content-changed')

    def clear(self):
        ComboMixin.clear(self)
        self.emit('content-changed')

class ProxyComboBoxEntry(PropertyObject, BaseComboBoxEntry, ComboMixin,
                         ValidatableProxyWidgetMixin):
    allowed_data_types = (basestring, object) + number
    __gtype_name__ = 'ProxyComboBoxEntry'
    # it doesn't make sense to connect to this signal
    # because we want to monitor the entry of the combo
    # not the combo box itself.

    gproperty("list-editable", bool, True, "Editable")

    def __init__(self, **kwargs):
        deprecationwarn(
            'ProxyComboBoxEntry is deprecated, use ProxyComboEntry instead',
            stacklevel=3)
        BaseComboBoxEntry.__init__(self)
        ComboMixin.__init__(self)
        ValidatableProxyWidgetMixin.__init__(self, widget=self.entry)
        PropertyObject.__init__(self, **kwargs)

        self.set_text_column(COL_COMBO_LABEL)

        # here we connect the expose-event signal directly to the entry
        self.child.connect('changed', self._on_child_entry__changed)

        # HACK! we force a queue_draw because when the window is first
        # displayed the icon is not drawn.
        gobject.idle_add(self.queue_draw)

        self.set_events(gtk.gdk.KEY_RELEASE_MASK)
        self.connect("key-release-event", self._on__key_release_event)

    def prop_set_list_editable(self, value):
        if self.mode == COMBO_MODE_DATA:
            return

        self.entry.set_editable(value)

        return value

    def _update_selection(self, text=None):
        if text is None:
            text = self.entry.get_text()

        self.select_item_by_label(text)

    def _add_text_to_combo_list(self):
        text = self.entry.get_text()
        if not text.strip():
            return

        if text in self.get_model_strings():
            return

        self.entry.set_text('')
        self.append_item(text)
        self._update_selection(text)

    def _on__key_release_event(self, widget, event):
        """Checks for "Enter" key presses and add the entry text to
        the combo list if the combo list is set as editable.
        """
        if not self.list_editable:
            return

        if event.keyval in (keysyms.KP_Enter,
                            keysyms.Return):
            self._add_text_to_combo_list()

    def _on_child_entry__changed(self, widget):
        """Called when something on the entry changes"""
        if not widget.get_text():
            return

        self.emit('content-changed')

    def set_mode(self, mode):
        # If we're in the transition to go from
        # unknown->label set editable to False
        if (self.mode == COMBO_MODE_UNKNOWN and mode == COMBO_MODE_DATA):
            self.entry.set_editable(False)

        ComboMixin.set_mode(self, mode)

    def read(self):
        if self.mode == COMBO_MODE_UNKNOWN:
            return ValueUnset
        return self.get_selected()

    def update(self, data):
        if data is ValueUnset or data is None:
            self.entry.set_text("")
        else:
            self.select(data)

    def prefill(self, itemdata, sort=False, clear_entry=False):
        """
        See L{kiwi.ui.combomixin.ComboMixin.prefill}
        """
        ComboMixin.prefill(self, itemdata, sort)
        if clear_entry:
            self.entry.set_text("")

        # setup the autocompletion
        auto = gtk.EntryCompletion()
        auto.set_model(self.get_model())
        auto.set_text_column(COL_COMBO_LABEL)
        self.entry.set_completion(auto)

    def clear(self):
        """Removes all items from list and erases entry"""
        ComboMixin.clear(self)
        self.entry.set_text("")

class ProxyComboEntry(PropertyObject, ComboEntry, ComboMixin,
                      ValidatableProxyWidgetMixin):
    __gtype_name__ = 'ProxyComboEntry'
    allowed_data_types = (basestring, object) + number

    gproperty("list-editable", bool, True, "Editable")

    def __init__(self):
        entry = ProxyEntry()
        ComboEntry.__init__(self, entry=entry)
        ComboMixin.__init__(self)
        ValidatableProxyWidgetMixin.__init__(self)
        PropertyObject.__init__(self)
        entry.connect('content-changed', self._on_entry__content_changed)

    # We only need to listen for changes in the entry, it's updated
    # even if you select something in the popup list
    def _on_entry__content_changed(self, entry):
        self.emit('content-changed')

    def prop_set_list_editable(self, value):
        self.entry.set_editable(value)
        return value

    def read(self):
        return self.get_selected()

    def update(self, data):
        if data is ValueUnset or data is None:
            self.entry.set_text("")
        else:
            self.select(data)

    def clear(self):
        """Removes all items from list and erases entry"""
        ComboMixin.clear(self)
        self.entry.set_text("")

    def set_tooltip(self, text):
        self.entry.set_tooltip(text)

    def prefill(self, data, sort=False):
        return ComboEntry.prefill(self, data, sort)
<|endoftext|>


<commit_before>import logging
import pprint
from klue.swagger.apipool import ApiPool
from klue_microservice.utils import get_container_version

log = logging.getLogger(__name__)

def do_ping():
    log.debug("Replying ping:ok")
    v = ApiPool.ping.model.Version()
    return v

def do_version():
    """Return version details of the running server api"""
    v = ApiPool.ping.model.Version(
        name=ApiPool().current_server_name,
        version=ApiPool().current_server_api.get_version(),
        container=get_container_version(),
    )
    log.info("/version: " + pprint.pformat(v))
    return v
<commit_msg>Duh. Ping returned wrong datatype...<commit_after>import logging
import pprint
from klue.swagger.apipool import ApiPool
from klue_microservice.utils import get_container_version

log = logging.getLogger(__name__)

def do_ping():
    log.debug("Replying ping:ok")
    v = ApiPool.ping.model.Ok()
    return v

def do_version():
    """Return version details of the running server api"""
    v = ApiPool.ping.model.Version(
        name=ApiPool().current_server_name,
        version=ApiPool().current_server_api.get_version(),
        container=get_container_version(),
    )
    log.info("/version: " + pprint.pformat(v))
    return v
<|endoftext|>


<commit_before>import utils
import numpy as np
import utils_heart
from pathfinder import SUBMISSION_PATH

def read_submission(file_path):
    pid2cdf0, pid2cdf1 = {}, {}
    csv_file = open(file_path)
    lines = csv_file.readlines()
    for l in lines[1:]:
        row = l.split(',')
        pid, target = row[0].split('_')
        cdf_string = row[1:]
        if all(x == '' for x in cdf_string[:-1]) or all(x == 'nan' for x in cdf_string[:-1]):
            cdf = None
        else:
            cdf = np.float64(cdf_string)
        pid = int(pid)
        if target == 'Systole':
            pid2cdf0[pid] = cdf
        if target == 'Diastole':
            pid2cdf1[pid] = cdf

    return pid2cdf0, pid2cdf1

def fix_submission(submission_path_meta, submission_path_ss, submission_path_mix, threshold=0.03):
    pid2cdf0_meta, pid2cdf1_meta = read_submission(submission_path_meta)
    pid2cdf0_ss, pid2cdf1_ss = read_submission(submission_path_ss)
    pid2cdf0_mix, pid2cdf1_mix = read_submission(submission_path_mix)
    pid2cdf0_fixed, pid2cdf1_fixed = {}, {}

    patient_ids = pid2cdf0_meta.keys()
    assert patient_ids == pid2cdf0_ss.keys()
    assert patient_ids == pid2cdf0_mix.keys()

    # no prediction from metamodel -> take prediction from slice model
    for pid in patient_ids:
        pid2cdf0_fixed[pid] = pid2cdf0_ss[pid] if pid2cdf0_meta[pid] is None else pid2cdf0_meta[pid]
        pid2cdf1_fixed[pid] = pid2cdf1_ss[pid] if pid2cdf1_meta[pid] is None else pid2cdf1_meta[pid]

    # metamodel disagrees with slice model -> take prediction from mixture ensemble
    for pid in patient_ids:
        crps0 = utils_heart.crps(pid2cdf0_fixed[pid], pid2cdf0_ss[pid])
        if crps0 > threshold:
            print 'sys', pid, crps0
        pid2cdf0_fixed[pid] = pid2cdf0_mix[pid] if crps0 > threshold else pid2cdf0_fixed[pid]

        crps1 = utils_heart.crps(pid2cdf1_fixed[pid], pid2cdf1_ss[pid])
        if crps1 > threshold:
            print 'dst', pid, crps1
        pid2cdf1_fixed[pid] = pid2cdf1_mix[pid] if crps1 > threshold else pid2cdf1_fixed[pid]

    fixed_predictions = {}
    for pid in patient_ids:
        fixed_predictions[pid] = [pid2cdf0_fixed[pid], pid2cdf1_fixed[pid]]

    meta_expid = submission_path_meta.split('-')[-1].replace('.csv', '')
    ss_expid = submission_path_ss.split('-')[-1].replace('.csv', '')
    mix_expid = submission_path_mix.split('-')[-1].replace('.csv', '')
    fixed_submission_path = SUBMISSION_PATH + 'ira_%s-%s-%s.csv' % (meta_expid, ss_expid, mix_expid)
    utils.save_submission(fixed_predictions, fixed_submission_path)
    print 'Submission save to', fixed_submission_path

if __name__ == '__main__':
    # TODO here I will fill my final ensemble
    submission_path_meta = SUBMISSION_PATH + 'final_submission-1457307421.35.csv'
    submission_path_ss = SUBMISSION_PATH + 'final_submission-1457306840.7.csv'
    submission_path_mix = SUBMISSION_PATH + 'final_submission-1457307792.6.csv'

    fix_submission(submission_path_meta, submission_path_ss, submission_path_mix)
<commit_msg>experimental submission<commit_after>import utils
import numpy as np
import utils_heart
from pathfinder import SUBMISSION_PATH

def read_submission(file_path):
    pid2cdf0, pid2cdf1 = {}, {}
    csv_file = open(file_path)
    lines = csv_file.readlines()
    for l in lines[1:]:
        row = l.split(',')
        pid, target = row[0].split('_')
        cdf_string = row[1:]
        if all(x == '' for x in cdf_string[:-1]) or all(x == 'nan' for x in cdf_string[:-1]):
            cdf = None
        else:
            cdf = np.float64(cdf_string)
        pid = int(pid)
        if target == 'Systole':
            pid2cdf0[pid] = cdf
        if target == 'Diastole':
            pid2cdf1[pid] = cdf

    return pid2cdf0, pid2cdf1

def fix_submission(submission_path_meta, submission_path_ss, submission_path_mix, threshold=0.03):
    pid2cdf0_meta, pid2cdf1_meta = read_submission(submission_path_meta)
    pid2cdf0_ss, pid2cdf1_ss = read_submission(submission_path_ss)
    pid2cdf0_mix, pid2cdf1_mix = read_submission(submission_path_mix)
    pid2cdf0_fixed, pid2cdf1_fixed = {}, {}

    patient_ids = pid2cdf0_meta.keys()
    assert patient_ids == pid2cdf0_ss.keys()
    assert patient_ids == pid2cdf0_mix.keys()

    # no prediction from metamodel -> take prediction from slice model
    for pid in patient_ids:
        pid2cdf0_fixed[pid] = pid2cdf0_ss[pid] if pid2cdf0_meta[pid] is None else pid2cdf0_meta[pid]
        pid2cdf1_fixed[pid] = pid2cdf1_ss[pid] if pid2cdf1_meta[pid] is None else pid2cdf1_meta[pid]

    # metamodel disagrees with slice model -> take prediction from mixture ensemble
    for pid in patient_ids:
        crps0 = utils_heart.crps(pid2cdf0_fixed[pid], pid2cdf0_ss[pid])
        if crps0 > threshold:
            print 'sys', pid, crps0
        pid2cdf0_fixed[pid] = pid2cdf0_mix[pid] if crps0 > threshold else pid2cdf0_fixed[pid]

        crps1 = utils_heart.crps(pid2cdf1_fixed[pid], pid2cdf1_ss[pid])
        if crps1 > threshold:
            print 'dst', pid, crps1
        pid2cdf1_fixed[pid] = pid2cdf1_mix[pid] if crps1 > threshold else pid2cdf1_fixed[pid]

    fixed_predictions = {}
    for pid in patient_ids:
        fixed_predictions[pid] = [pid2cdf0_fixed[pid], pid2cdf1_fixed[pid]]

    meta_expid = submission_path_meta.split('-')[-1].replace('.csv', '')
    ss_expid = submission_path_ss.split('-')[-1].replace('.csv', '')
    mix_expid = submission_path_mix.split('-')[-1].replace('.csv', '')
    fixed_submission_path = SUBMISSION_PATH + 'ira_%s-%s-%s.csv' % (meta_expid, ss_expid, mix_expid)
    utils.save_submission(fixed_predictions, fixed_submission_path)
    print 'Submission save to', fixed_submission_path

if __name__ == '__main__':
    # TODO here I will fill my final ensemble
    submission_path_meta = SUBMISSION_PATH + 'final_submission-1457786956.36.csv'
    submission_path_ss = SUBMISSION_PATH + 'final_submission-1457790522.0.csv'
    submission_path_mix = SUBMISSION_PATH + 'final_submission-1457794389.54.csv'

    fix_submission(submission_path_meta, submission_path_ss, submission_path_mix)
<|endoftext|>


<commit_before># specifically use concurrent.futures for threadsafety
# asyncio Futures cannot be used across threads
import asyncio
import json
import threading
import time
from concurrent.futures import Future
from functools import partial

from kubernetes_asyncio import config
from kubernetes_asyncio import watch
from traitlets import Any
from traitlets import Bool
from traitlets import Dict
from traitlets import Int
from traitlets import Unicode
from traitlets.config import LoggingConfigurable
from urllib3.exceptions import ReadTimeoutError

from .clients import shared_client

# This is kubernetes client implementation specific, but we need to know
# whether it was a network or watch timeout.

class ResourceReflector(LoggingConfigurable):
    """Base class for keeping a local up-to-date copy of a set of
    kubernetes resources.

    Must be subclassed once per kind of resource that needs watching.

    Creating a reflector should be done with the create() classmethod,
    since that, in addition to creating the instance, initializes the
    Kubernetes configuration, acquires a K8s API client, and starts the
    watch task.

    Shutting down a reflector should be done by awaiting its stop() method.
    JupyterHub does not currently do this, so the watch task runs until the
    Hub exits.
    """

    labels = Dict(
        {},
        config=True,
        help="""
        Labels to reflect onto local cache
        """,
    )

    fields = Dict(
        {},
        config=True,
        help="""
        Fields to restrict the reflected objects
        """,
    )

    resources = Dict(
        {},
        help="""
        Dictionary of resource names to the appropriate resource objects.

        This can be accessed across threads safely.
        """,
    )

    kind = Unicode(
        'resource',
        help="""
        Human readable name for kind of object we're watching for.

        Used for diagnostic messages.
        """,
    )

    omit_namespace = Bool(
        False,
        config=True,
        help="""
        Set this to true if the reflector is to operate across
        multiple namespaces.
        """,
    )

    namespace = Unicode(
        None,
        allow_none=True,
        help="""
        Namespace to watch for resources in; leave at 'None' for
        multi-namespace reflectors.
        """,
    )

    list_method_name = Unicode(
        "",
        help="""
        Name of function (on apigroup respresented by
        `api_group_name`) that is to be called to list resources.

        This will be passed a a label selector.

        If self.omit_namespace is False you want something of the form
        list_namespaced_<resource> - for example,
        `list_namespaced_pod` will give you a PodReflector.  It will
        take its namespace from self.namespace (which therefore should
        not be None).

        If self.omit_namespace is True, you want
        list_<resource>_for_all_namespaces.

        This must be set by a subclass.

        It is not necessary to set it for pod or event reflectors, because
        __init__ will figure it out.  If you create your own reflector
        subclass you probably want to add the logic to choose the method
        name to that class's __init__().
        """,
    )

    api_group_name = Unicode(
        'CoreV1Api',
        help="""
        Name of class that represents the apigroup on which
        `list_method_name` is to be found.

        Defaults to CoreV1Api, which has everything in the 'core' API group. If you want to watch Ingresses,
        for example, you would have to use ExtensionsV1beta1Api
        """,
    )

    request_timeout = Int(
        60,
        config=True,
        help="""
        Network timeout for kubernetes watch.

        Trigger watch reconnect when a given request is taking too long,
        which can indicate network issues.
        """,
    )

    timeout_seconds = Int(
        10,
        config=True,
        help="""
        Timeout for kubernetes watch.

        Trigger watch reconnect when no watch event has been received.
        This will cause a full reload of the currently existing resources
        from the API server.
        """,
    )

    restart_seconds = Int(
        30,
        config=True,
        help="""
        Maximum time before restarting a watch.

        The watch will be restarted at least this often,
        even if events are still arriving.
        Avoids trusting kubernetes watch to yield all events,
        which seems to not be a safe assumption.
        """,
    )

    on_failure = Any(help="""Function to be called when the reflector gives up.""")

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # Client configuration for kubernetes, as done via the load_config
        # function, has already taken place in KubeSpawner or KubeIngressProxy
        # initialization steps.
        self.api = shared_client(self.api_group_name)

        # FIXME: Protect against malicious labels?
        self.label_selector = ','.join(
            ['{}={}'.format(k, v) for k, v in self.labels.items()]
        )
        self.field_selector = ','.join(
            ['{}={}'.format(k, v) for k, v in self.fields.items()]
        )

        self.first_load_future = Future()
        self._stop_event = threading.Event()

        # Make sure that we know kind, whether we should omit the
        #  namespace, and what our list_method_name is.  For the things
        #  we already know about, we can derive list_method_name from
        #  those two things.  New reflector types should also update
        #  their __init__() methods to derive list_method_name, but you
        #  could just set it directly in the subclass.
        if not self.list_method_name:
            plural_to_singular = {
                "endpoints": "endpoints",
                "events": "event",
                "ingresses": "ingress",
                "pods": "pod",
                "services": "service",
            }

            if self.kind in plural_to_singular:
                if self.omit_namespace:
                    self.list_method_name = (
                        f"list_{plural_to_singular[self.kind]}_for_all_namespaces"
                    )
                else:
                    self.list_method_name = (
                        f"list_namespaced_{plural_to_singular[self.kind]}"
                    )

        # Make sure we have the required values.
        if not self.kind:
            raise RuntimeError("Reflector kind must be set!")
        if not self.list_method_name:
            raise RuntimeError("Reflector list_method_name must be set!")

        self.watch_task = None  # Test this rather than absence of the attr

        # Note that simply instantiating the class does not load
        # Kubernetes config, acquire an API client, or start the
        # watch task.

    @classmethod
    async def create(cls, *args, **kwargs):
        """
        This is a workaround: `__init__` cannot be async, but we want
        to call async methods to instantiate a reflector in a usable state.

        This method creates the reflector, and then loads Kubernetes config,
        acquires an API client, and starts the watch task.

        Use it to create a new Reflector object.
        """
        inst = cls(*args, **kwargs)
        await inst.start()
        return inst

    async def _list_and_update(self):
        """
        Update current list of resources by doing a full fetch.

        Overwrites all current resource info.
        """
        initial_resources = None
        kwargs = dict(
            label_selector=self.label_selector,
            field_selector=self.field_selector,
            _request_timeout=self.request_timeout,
            _preload_content=False,
        )
        if not self.omit_namespace:
            kwargs["namespace"] = self.namespace

        list_method = getattr(self.api, self.list_method_name)
        initial_resources_raw = await list_method(**kwargs)
        # This is an atomic operation on the dictionary!
        initial_resources = json.loads(await initial_resources_raw.read())
        self.resources = {
            f'{p["metadata"]["namespace"]}/{p["metadata"]["name"]}': p
            for p in initial_resources["items"]
        }
        # return the resource version so we can hook up a watch
        return initial_resources["metadata"]["resourceVersion"]

    async def _watch_and_update(self):
        """
        Keeps the current list of resources up-to-date

        We first fetch the list of current resources, and store that. Then we
        register to be notified of changes to those resources, and keep our
        local store up-to-date based on these notifications.

        We also perform exponential backoff, giving up after we hit 32s
        wait time. This should protect against network connections dropping
        and intermittent unavailability of the api-server. Every time we
        recover from an exception we also do a full fetch, to pick up
        changes that might've been missed in the time we were not doing
        a watch.

        Since the resources are read-only in the Spawner (where they are
        used), then this is safe.  The Spawner's view of the world might be
        out-of-date, but it's not going to corrupt any data.
        """
        selectors = []
        log_name = ""
        if self.label_selector:
            selectors.append("label selector=%r" % self.label_selector)
        if self.field_selector:
            selectors.append("field selector=%r" % self.field_selector)
        log_selector = ', '.join(selectors)

        cur_delay = 0.1

        if self.omit_namespace:
            ns_str = "all namespaces"
        else:
            ns_str = "namespace {}".format(self.namespace)

        self.log.info(
            "watching for %s with %s in %s",
            self.kind,
            log_selector,
            ns_str,
        )
        while True:
            self.log.debug("Connecting %s watcher", self.kind)
            start = time.monotonic()
            w = watch.Watch()
            try:
                resource_version = await self._list_and_update()
                if not self.first_load_future.done():
                    # signal that we've loaded our initial data
                    self.first_load_future.set_result(None)
                watch_args = {
                    "label_selector": self.label_selector,
                    "field_selector": self.field_selector,
                    "resource_version": resource_version,
                }
                if not self.omit_namespace:
                    watch_args["namespace"] = self.namespace
                if self.request_timeout:
                    # set network receive timeout
                    watch_args['_request_timeout'] = self.request_timeout
                if self.timeout_seconds:
                    # set watch timeout
                    watch_args['timeout_seconds'] = self.timeout_seconds
                # This is a little hack to defeat the Kubernetes client
                # deserializing the objects it gets, which can use a lot
                # of CPU in busy clusters.  cf
                # https://github.com/jupyterhub/kubespawner/pull/424
                method = partial(
                    getattr(self.api, self.list_method_name), _preload_content=False
                )
                async with w.stream(method, **watch_args) as stream:
                    async for watch_event in stream:
                        # in case of timeout_seconds, the w.stream just exits (no exception thrown)
                        # -> we stop the watcher and start a new one
                        # Remember that these events are k8s api related WatchEvents
                        # objects, not k8s Event or Pod representations, they will
                        # reside in the WatchEvent's object field depending on what
                        # kind of resource is watched.
                        #
                        # ref: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.20/#watchevent-v1-meta
                        # ref: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.20/#event-v1-core
                        cur_delay = 0.1
                        resource = watch_event['raw_object']
                        ref_key = "{}/{}".format(
                            resource["metadata"]["namespace"],
                            resource["metadata"]["name"],
                        )
                        if watch_event['type'] == 'DELETED':
                            # This is an atomic delete operation on the dictionary!
                            self.resources.pop(ref_key, None)
                        else:
                            # This is an atomic operation on the dictionary!
                            self.resources[ref_key] = resource
                        if self.stopped():
                            self.log.info("%s watcher stopped: inner", self.kind)
                            break
                        watch_duration = time.monotonic() - start
                        if watch_duration >= self.restart_seconds:
                            self.log.debug(
                                "Restarting %s watcher after %i seconds",
                                self.kind,
                                watch_duration,
                            )
                            break

            except ReadTimeoutError:
                # network read time out, just continue and restart the watch
                # this could be due to a network problem or just low activity
                self.log.warning("Read timeout watching %s, reconnecting", self.kind)
                continue
            except Exception:
                cur_delay = cur_delay * 2
                if cur_delay > 30:
                    self.log.exception("Watching resources never recovered, giving up")
                    if self.on_failure:
                        self.on_failure()
                    return
                self.log.exception(
                    "Error when watching resources, retrying in %ss", cur_delay
                )
                await asyncio.sleep(cur_delay)
                continue
            else:
                # no events on watch, reconnect
                self.log.debug("%s watcher timeout", self.kind)
            finally:
                w.stop()
                if self.stopped():
                    self.log.info("%s watcher stopped: outer", self.kind)
                    break
        self.log.warning("%s watcher finished", self.kind)

    async def start(self):
        """
        Start the reflection process!

        We'll do a blocking read of all resources first, so that we don't
        race with any operations that are checking the state of the pod
        store - such as polls. This should be called only once at the
        start of program initialization (when the singleton is being created),
        and not afterwards!
        """
        if self.watch_task and not self.watch_task.done():
            raise RuntimeError('Task watching for resources is already running')

        await self._list_and_update()
        self.watch_task = asyncio.create_task(self._watch_and_update())

    async def stop(self):
        """
        Cleanly shut down the watch task.
        """
        self._stop_event.set()
        # The watch task should now be in the process of terminating.  Give
        # it a bit...
        if self.watch_task and not self.watch_task.done():
            try:
                timeout = 5
                await asyncio.wait_for(self.watch_task, timeout)
            except asyncio.TimeoutError:
                # Raising the TimeoutError will cancel the task.
                self.log.warning(
                    f"Watch task did not finish in {timeout}s and was cancelled"
                )
        self.watch_task = None

    def stopped(self):
        return self._stop_event.is_set()

class NamespacedResourceReflector(ResourceReflector):
    """
    Watches for resources in a particular namespace.  The list_methods
    want both a method name and a namespace.
    """

    omit_namespace = False

class MultiNamespaceResourceReflector(ResourceReflector):
    """
    Watches for resources across all namespaces.  The list_methods
    want only a method name.  Note that this requires the service account
    to be significantly more powerful, since it must be bound to ClusterRoles
    rather than just Roles, and therefore this is inherently more
    dangerous.
    """

    omit_namespace = True
<commit_msg>Update kubespawner/reflector.py<commit_after># specifically use concurrent.futures for threadsafety
# asyncio Futures cannot be used across threads
import asyncio
import json
import threading
import time
from concurrent.futures import Future
from functools import partial

from kubernetes_asyncio import config
from kubernetes_asyncio import watch
from traitlets import Any
from traitlets import Bool
from traitlets import Dict
from traitlets import Int
from traitlets import Unicode
from traitlets.config import LoggingConfigurable
from urllib3.exceptions import ReadTimeoutError

from .clients import shared_client

# This is kubernetes client implementation specific, but we need to know
# whether it was a network or watch timeout.

class ResourceReflector(LoggingConfigurable):
    """Base class for keeping a local up-to-date copy of a set of
    kubernetes resources.

    Must be subclassed once per kind of resource that needs watching.

    Creating a reflector should be done with the create() classmethod,
    since that, in addition to creating the instance, initializes the
    Kubernetes configuration, acquires a K8s API client, and starts the
    watch task.

    Shutting down a reflector should be done by awaiting its stop() method.
    JupyterHub does not currently do this, so the watch task runs until the
    Hub exits.
    """

    labels = Dict(
        {},
        config=True,
        help="""
        Labels to reflect onto local cache
        """,
    )

    fields = Dict(
        {},
        config=True,
        help="""
        Fields to restrict the reflected objects
        """,
    )

    resources = Dict(
        {},
        help="""
        Dictionary of resource names to the appropriate resource objects.

        This can be accessed across threads safely.
        """,
    )

    kind = Unicode(
        'resource',
        help="""
        Human readable name for kind of object we're watching for.

        Used for diagnostic messages.
        """,
    )

    omit_namespace = Bool(
        False,
        config=True,
        help="""
        Set this to true if the reflector is to operate across
        multiple namespaces.
        """,
    )

    namespace = Unicode(
        None,
        allow_none=True,
        help="""
        Namespace to watch for resources in; leave at 'None' for
        multi-namespace reflectors.
        """,
    )

    list_method_name = Unicode(
        "",
        help="""
        Name of function (on apigroup respresented by
        `api_group_name`) that is to be called to list resources.

        This will be passed a a label selector.

        If self.omit_namespace is False you want something of the form
        list_namespaced_<resource> - for example,
        `list_namespaced_pod` will give you a PodReflector.  It will
        take its namespace from self.namespace (which therefore should
        not be None).

        If self.omit_namespace is True, you want
        list_<resource>_for_all_namespaces.

        This must be set by a subclass.

        It is not necessary to set it for pod or event reflectors, because
        __init__ will figure it out.  If you create your own reflector
        subclass you probably want to add the logic to choose the method
        name to that class's __init__().
        """,
    )

    api_group_name = Unicode(
        'CoreV1Api',
        help="""
        Name of class that represents the apigroup on which
        `list_method_name` is to be found.

        Defaults to CoreV1Api, which has everything in the 'core' API group. If you want to watch Ingresses,
        for example, you would have to use ExtensionsV1beta1Api
        """,
    )

    request_timeout = Int(
        60,
        config=True,
        help="""
        Network timeout for kubernetes watch.

        Trigger watch reconnect when a given request is taking too long,
        which can indicate network issues.
        """,
    )

    timeout_seconds = Int(
        10,
        config=True,
        help="""
        Timeout for kubernetes watch.

        Trigger watch reconnect when no watch event has been received.
        This will cause a full reload of the currently existing resources
        from the API server.
        """,
    )

    restart_seconds = Int(
        30,
        config=True,
        help="""
        Maximum time before restarting a watch.

        The watch will be restarted at least this often,
        even if events are still arriving.
        Avoids trusting kubernetes watch to yield all events,
        which seems to not be a safe assumption.
        """,
    )

    on_failure = Any(help="""Function to be called when the reflector gives up.""")

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # Client configuration for kubernetes, as done via the load_config
        # function, has already taken place in KubeSpawner or KubeIngressProxy
        # initialization steps.
        self.api = shared_client(self.api_group_name)

        # FIXME: Protect against malicious labels?
        self.label_selector = ','.join(
            ['{}={}'.format(k, v) for k, v in self.labels.items()]
        )
        self.field_selector = ','.join(
            ['{}={}'.format(k, v) for k, v in self.fields.items()]
        )

        self.first_load_future = Future()
        self._stop_event = threading.Event()

        # Make sure that we know kind, whether we should omit the
        #  namespace, and what our list_method_name is.  For the things
        #  we already know about, we can derive list_method_name from
        #  those two things.  New reflector types should also update
        #  their __init__() methods to derive list_method_name, but you
        #  could just set it directly in the subclass.
        if not self.list_method_name:
            plural_to_singular = {
                "endpoints": "endpoints",
                "events": "event",
                "ingresses": "ingress",
                "pods": "pod",
                "services": "service",
            }

            if self.kind in plural_to_singular:
                if self.omit_namespace:
                    self.list_method_name = (
                        f"list_{plural_to_singular[self.kind]}_for_all_namespaces"
                    )
                else:
                    self.list_method_name = (
                        f"list_namespaced_{plural_to_singular[self.kind]}"
                    )

        # Make sure we have the required values.
        if not self.kind:
            raise RuntimeError("Reflector kind must be set!")
        if not self.list_method_name:
            raise RuntimeError("Reflector list_method_name must be set!")

        self.watch_task = None  # Test this rather than absence of the attr

        # Note that simply instantiating the class does not load
        # Kubernetes config, acquire an API client, or start the
        # watch task.

    @classmethod
    async def create(cls, *args, **kwargs):
        """
        This is a workaround: `__init__` cannot be async, but we want
        to call async methods to instantiate a reflector in a usable state.

        This method creates the reflector, and then loads Kubernetes config,
        acquires an API client, and starts the watch task.

        Use it to create a new Reflector object.
        """
        inst = cls(*args, **kwargs)
        await inst.start()
        return inst

    async def _list_and_update(self):
        """
        Update current list of resources by doing a full fetch.

        Overwrites all current resource info.
        """
        initial_resources = None
        kwargs = dict(
            label_selector=self.label_selector,
            field_selector=self.field_selector,
            _request_timeout=self.request_timeout,
            _preload_content=False,
        )
        if not self.omit_namespace:
            kwargs["namespace"] = self.namespace

        list_method = getattr(self.api, self.list_method_name)
        initial_resources_raw = await list_method(**kwargs)
        # This is an atomic operation on the dictionary!
        initial_resources = json.loads(await initial_resources_raw.read())
        self.resources = {
            f'{p["metadata"]["namespace"]}/{p["metadata"]["name"]}': p
            for p in initial_resources["items"]
        }
        # return the resource version so we can hook up a watch
        return initial_resources["metadata"]["resourceVersion"]

    async def _watch_and_update(self):
        """
        Keeps the current list of resources up-to-date

        We first fetch the list of current resources, and store that. Then we
        register to be notified of changes to those resources, and keep our
        local store up-to-date based on these notifications.

        We also perform exponential backoff, giving up after we hit 32s
        wait time. This should protect against network connections dropping
        and intermittent unavailability of the api-server. Every time we
        recover from an exception we also do a full fetch, to pick up
        changes that might've been missed in the time we were not doing
        a watch.

        Since the resources are read-only in the Spawner (where they are
        used), then this is safe.  The Spawner's view of the world might be
        out-of-date, but it's not going to corrupt any data.
        """
        selectors = []
        log_name = ""
        if self.label_selector:
            selectors.append("label selector=%r" % self.label_selector)
        if self.field_selector:
            selectors.append("field selector=%r" % self.field_selector)
        log_selector = ', '.join(selectors)

        cur_delay = 0.1

        if self.omit_namespace:
            ns_str = "all namespaces"
        else:
            ns_str = "namespace {}".format(self.namespace)

        self.log.info(
            "watching for %s with %s in %s",
            self.kind,
            log_selector,
            ns_str,
        )
        while True:
            self.log.debug("Connecting %s watcher", self.kind)
            start = time.monotonic()
            w = watch.Watch()
            try:
                resource_version = await self._list_and_update()
                if not self.first_load_future.done():
                    # signal that we've loaded our initial data
                    self.first_load_future.set_result(None)
                watch_args = {
                    "label_selector": self.label_selector,
                    "field_selector": self.field_selector,
                    "resource_version": resource_version,
                }
                if not self.omit_namespace:
                    watch_args["namespace"] = self.namespace
                if self.request_timeout:
                    # set network receive timeout
                    watch_args['_request_timeout'] = self.request_timeout
                if self.timeout_seconds:
                    # set watch timeout
                    watch_args['timeout_seconds'] = self.timeout_seconds
                # Calling the method with _preload_content=False is a performance
                # optimization making the Kubernetes client do less work. See
                # https://github.com/jupyterhub/kubespawner/pull/424.
                method = partial(
                    getattr(self.api, self.list_method_name), _preload_content=False
                )
                async with w.stream(method, **watch_args) as stream:
                    async for watch_event in stream:
                        # in case of timeout_seconds, the w.stream just exits (no exception thrown)
                        # -> we stop the watcher and start a new one
                        # Remember that these events are k8s api related WatchEvents
                        # objects, not k8s Event or Pod representations, they will
                        # reside in the WatchEvent's object field depending on what
                        # kind of resource is watched.
                        #
                        # ref: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.20/#watchevent-v1-meta
                        # ref: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.20/#event-v1-core
                        cur_delay = 0.1
                        resource = watch_event['raw_object']
                        ref_key = "{}/{}".format(
                            resource["metadata"]["namespace"],
                            resource["metadata"]["name"],
                        )
                        if watch_event['type'] == 'DELETED':
                            # This is an atomic delete operation on the dictionary!
                            self.resources.pop(ref_key, None)
                        else:
                            # This is an atomic operation on the dictionary!
                            self.resources[ref_key] = resource
                        if self.stopped():
                            self.log.info("%s watcher stopped: inner", self.kind)
                            break
                        watch_duration = time.monotonic() - start
                        if watch_duration >= self.restart_seconds:
                            self.log.debug(
                                "Restarting %s watcher after %i seconds",
                                self.kind,
                                watch_duration,
                            )
                            break

            except ReadTimeoutError:
                # network read time out, just continue and restart the watch
                # this could be due to a network problem or just low activity
                self.log.warning("Read timeout watching %s, reconnecting", self.kind)
                continue
            except Exception:
                cur_delay = cur_delay * 2
                if cur_delay > 30:
                    self.log.exception("Watching resources never recovered, giving up")
                    if self.on_failure:
                        self.on_failure()
                    return
                self.log.exception(
                    "Error when watching resources, retrying in %ss", cur_delay
                )
                await asyncio.sleep(cur_delay)
                continue
            else:
                # no events on watch, reconnect
                self.log.debug("%s watcher timeout", self.kind)
            finally:
                w.stop()
                if self.stopped():
                    self.log.info("%s watcher stopped: outer", self.kind)
                    break
        self.log.warning("%s watcher finished", self.kind)

    async def start(self):
        """
        Start the reflection process!

        We'll do a blocking read of all resources first, so that we don't
        race with any operations that are checking the state of the pod
        store - such as polls. This should be called only once at the
        start of program initialization (when the singleton is being created),
        and not afterwards!
        """
        if self.watch_task and not self.watch_task.done():
            raise RuntimeError('Task watching for resources is already running')

        await self._list_and_update()
        self.watch_task = asyncio.create_task(self._watch_and_update())

    async def stop(self):
        """
        Cleanly shut down the watch task.
        """
        self._stop_event.set()
        # The watch task should now be in the process of terminating.  Give
        # it a bit...
        if self.watch_task and not self.watch_task.done():
            try:
                timeout = 5
                await asyncio.wait_for(self.watch_task, timeout)
            except asyncio.TimeoutError:
                # Raising the TimeoutError will cancel the task.
                self.log.warning(
                    f"Watch task did not finish in {timeout}s and was cancelled"
                )
        self.watch_task = None

    def stopped(self):
        return self._stop_event.is_set()

class NamespacedResourceReflector(ResourceReflector):
    """
    Watches for resources in a particular namespace.  The list_methods
    want both a method name and a namespace.
    """

    omit_namespace = False

class MultiNamespaceResourceReflector(ResourceReflector):
    """
    Watches for resources across all namespaces.  The list_methods
    want only a method name.  Note that this requires the service account
    to be significantly more powerful, since it must be bound to ClusterRoles
    rather than just Roles, and therefore this is inherently more
    dangerous.
    """

    omit_namespace = True
<|endoftext|>


<commit_before>
from twisted.trial import unittest
from twisted.internet import defer
from twisted.internet.error import ConnectionDone
from foolscap import Tub
from foolscap.referenceable import RemoteReference
from foolscap.test.common import HelperTarget

def ignoreConnectionDone(f):
    f.trap(ConnectionDone)
    return None

class Gifts(unittest.TestCase):
    # Here we test the three-party introduction process as depicted in the
    # classic Granovetter diagram. Alice has a reference to Bob and another
    # one to Carol. Alice wants to give her Carol-reference to Bob, by
    # including it as the argument to a method she invokes on her
    # Bob-reference.

    debug = False

    def setUp(self):
        self.services = [Tub(), Tub(), Tub()]
        self.tubA, self.tubB, self.tubC = self.services
        for s in self.services:
            s.startService()
            l = s.listenOn("tcp:0:interface=127.0.0.1")
            s.setLocation("localhost:%d" % l.getPortnum())

    def tearDown(self):
        return defer.DeferredList([s.stopService() for s in self.services])

    def createCharacters(self):
        self.alice = HelperTarget("alice")
        self.bob = HelperTarget("bob")
        self.bob_url = self.tubB.registerReference(self.bob)
        self.carol = HelperTarget("carol")
        self.carol_url = self.tubC.registerReference(self.carol)

    def createInitialReferences(self):
        # we must start by giving Alice a reference to both Bob and Carol.
        if self.debug: print "Alice gets Bob"
        d = self.tubA.getReference(self.bob_url)
        def _aliceGotBob(abob):
            if self.debug: print "Alice got bob"
            self.abob = abob # Alice's reference to Bob
            if self.debug: print "Alice gets carol"
            d = self.tubA.getReference(self.carol_url)
            return d
        d.addCallback(_aliceGotBob)
        def _aliceGotCarol(acarol):
            if self.debug: print "Alice got carol"
            self.acarol = acarol # Alice's reference to Carol
        d.addCallback(_aliceGotCarol)
        return d

    def testGift(self):
        #defer.setDebugging(True)
        self.createCharacters()
        d = self.createInitialReferences()
        def _introduce(res):
            d2 = self.bob.waitfor()
            if self.debug: print "Alice introduces Carol to Bob"
            # send the gift. This might not get acked by the time the test is
            # done and everything is torn down, so explicitly silence any
            # ConnectionDone error that might result. When we get
            # callRemoteOnly(), use that instead.
            d3 = self.abob.callRemote("set", obj=(self.alice, self.acarol))
            d3.addErrback(ignoreConnectionDone)
            return d2 # this fires with the gift that bob got
        d.addCallback(_introduce)
        def _bobGotCarol((balice,bcarol)):
            if self.debug: print "Bob got Carol"
            self.bcarol = bcarol
            if self.debug: print "Bob says something to Carol"
            d2 = self.carol.waitfor()
            # handle ConnectionDone as described before
            d3 = self.bcarol.callRemote("set", obj=12)
            d3.addErrback(ignoreConnectionDone)
            return d2
        d.addCallback(_bobGotCarol)
        def _carolCalled(res):
            if self.debug: print "Carol heard from Bob"
            self.failUnlessEqual(res, 12)
        d.addCallback(_carolCalled)
        return d

    def testOrdering(self):
        self.createCharacters()
        self.bob.calls = []
        d = self.createInitialReferences()
        def _introduce(res):
            # we send three messages to Bob. The second one contains the
            # reference to Carol.
            self.abob.callRemote("append", obj=1)
            self.abob.callRemote("append", obj=self.acarol)
            d2 = self.abob.callRemote("append", obj=3)
            return d2
        d.addCallback(_introduce)
        def _checkBob(res):
            # this runs after all three messages have been acked by Bob
            self.failUnlessEqual(len(self.bob.calls), 3)
            self.failUnlessEqual(self.bob.calls[0], 1)
            self.failUnless(isinstance(self.bob.calls[1], RemoteReference))
            self.failUnlessEqual(self.bob.calls[2], 3)
        d.addCallback(_checkBob)
        return d

    # this was used to alice's reference to carol (self.acarol) appeared in
    # alice's gift table at the right time, to make sure that the
    # RemoteReference is kept alive while the gift is in transit. The whole
    # introduction pattern is going to change soon, so it has been disabled
    # until I figure out what the new scheme ought to be asserting.

    def OFF_bobGotCarol(self, (balice,bcarol)):
        if self.debug: print "Bob got Carol"
        # Bob has received the gift
        self.bcarol = bcarol

        # wait for alice to receive bob's 'decgift' sequence, which was sent
        # by now (it is sent after bob receives the gift but before the
        # gift-bearing message is delivered). To make sure alice has received
        # it, send a message back along the same path.
        def _check_alice(res):
            if self.debug: print "Alice should have the decgift"
            # alice's gift table should be empty
            brokerAB = self.abob.tracker.broker
            self.failUnlessEqual(brokerAB.myGifts, {})
            self.failUnlessEqual(brokerAB.myGiftsByGiftID, {})
        d1 = self.alice.waitfor()
        d1.addCallback(_check_alice)
        # the ack from this message doesn't always make it back by the time
        # we end the test and hang up the connection. That connectionLost
        # causes the deferred that this returns to errback, triggering an
        # error, so we must be sure to discard any error from it. TODO: turn
        # this into balice.callRemoteOnly("set", 39), which will have the
        # same semantics from our point of view (but in addition it will tell
        # the recipient to not bother sending a response).
        balice.callRemote("set", 39).addErrback(lambda ignored: None)

        if self.debug: print "Bob says something to Carol"
        d2 = self.carol.waitfor()
        d = self.bcarol.callRemote("set", obj=12)
        d.addCallback(lambda res: d2)
        d.addCallback(self._carolCalled)
        d.addCallback(lambda res: d1)
        return d

<commit_msg>[foolscap @ improve the ordering test] Do it in such a way that if it does fail, it fails more cleanly.<commit_after>
from twisted.trial import unittest
from twisted.internet import defer
from twisted.internet.error import ConnectionDone
from foolscap import Tub
from foolscap.referenceable import RemoteReference
from foolscap.test.common import HelperTarget

def ignoreConnectionDone(f):
    f.trap(ConnectionDone)
    return None

class Gifts(unittest.TestCase):
    # Here we test the three-party introduction process as depicted in the
    # classic Granovetter diagram. Alice has a reference to Bob and another
    # one to Carol. Alice wants to give her Carol-reference to Bob, by
    # including it as the argument to a method she invokes on her
    # Bob-reference.

    debug = False

    def setUp(self):
        self.services = [Tub(), Tub(), Tub()]
        self.tubA, self.tubB, self.tubC = self.services
        for s in self.services:
            s.startService()
            l = s.listenOn("tcp:0:interface=127.0.0.1")
            s.setLocation("localhost:%d" % l.getPortnum())

    def tearDown(self):
        return defer.DeferredList([s.stopService() for s in self.services])

    def createCharacters(self):
        self.alice = HelperTarget("alice")
        self.bob = HelperTarget("bob")
        self.bob_url = self.tubB.registerReference(self.bob)
        self.carol = HelperTarget("carol")
        self.carol_url = self.tubC.registerReference(self.carol)

    def createInitialReferences(self):
        # we must start by giving Alice a reference to both Bob and Carol.
        if self.debug: print "Alice gets Bob"
        d = self.tubA.getReference(self.bob_url)
        def _aliceGotBob(abob):
            if self.debug: print "Alice got bob"
            self.abob = abob # Alice's reference to Bob
            if self.debug: print "Alice gets carol"
            d = self.tubA.getReference(self.carol_url)
            return d
        d.addCallback(_aliceGotBob)
        def _aliceGotCarol(acarol):
            if self.debug: print "Alice got carol"
            self.acarol = acarol # Alice's reference to Carol
        d.addCallback(_aliceGotCarol)
        return d

    def testGift(self):
        #defer.setDebugging(True)
        self.createCharacters()
        d = self.createInitialReferences()
        def _introduce(res):
            d2 = self.bob.waitfor()
            if self.debug: print "Alice introduces Carol to Bob"
            # send the gift. This might not get acked by the time the test is
            # done and everything is torn down, so explicitly silence any
            # ConnectionDone error that might result. When we get
            # callRemoteOnly(), use that instead.
            d3 = self.abob.callRemote("set", obj=(self.alice, self.acarol))
            d3.addErrback(ignoreConnectionDone)
            return d2 # this fires with the gift that bob got
        d.addCallback(_introduce)
        def _bobGotCarol((balice,bcarol)):
            if self.debug: print "Bob got Carol"
            self.bcarol = bcarol
            if self.debug: print "Bob says something to Carol"
            d2 = self.carol.waitfor()
            # handle ConnectionDone as described before
            d3 = self.bcarol.callRemote("set", obj=12)
            d3.addErrback(ignoreConnectionDone)
            return d2
        d.addCallback(_bobGotCarol)
        def _carolCalled(res):
            if self.debug: print "Carol heard from Bob"
            self.failUnlessEqual(res, 12)
        d.addCallback(_carolCalled)
        return d

    def testOrdering(self):
        self.createCharacters()
        self.bob.calls = []
        d = self.createInitialReferences()
        def _introduce(res):
            # we send three messages to Bob. The second one contains the
            # reference to Carol.
            dl = []
            dl.append(self.abob.callRemote("append", obj=1))
            dl.append(self.abob.callRemote("append", obj=self.acarol))
            dl.append(self.abob.callRemote("append", obj=3))
            return defer.DeferredList(dl)
        d.addCallback(_introduce)
        def _checkBob(res):
            # this runs after all three messages have been acked by Bob
            self.failUnlessEqual(len(self.bob.calls), 3)
            self.failUnlessEqual(self.bob.calls[0], 1)
            self.failUnless(isinstance(self.bob.calls[1], RemoteReference))
            self.failUnlessEqual(self.bob.calls[2], 3)
        d.addCallback(_checkBob)
        return d

    # this was used to alice's reference to carol (self.acarol) appeared in
    # alice's gift table at the right time, to make sure that the
    # RemoteReference is kept alive while the gift is in transit. The whole
    # introduction pattern is going to change soon, so it has been disabled
    # until I figure out what the new scheme ought to be asserting.

    def OFF_bobGotCarol(self, (balice,bcarol)):
        if self.debug: print "Bob got Carol"
        # Bob has received the gift
        self.bcarol = bcarol

        # wait for alice to receive bob's 'decgift' sequence, which was sent
        # by now (it is sent after bob receives the gift but before the
        # gift-bearing message is delivered). To make sure alice has received
        # it, send a message back along the same path.
        def _check_alice(res):
            if self.debug: print "Alice should have the decgift"
            # alice's gift table should be empty
            brokerAB = self.abob.tracker.broker
            self.failUnlessEqual(brokerAB.myGifts, {})
            self.failUnlessEqual(brokerAB.myGiftsByGiftID, {})
        d1 = self.alice.waitfor()
        d1.addCallback(_check_alice)
        # the ack from this message doesn't always make it back by the time
        # we end the test and hang up the connection. That connectionLost
        # causes the deferred that this returns to errback, triggering an
        # error, so we must be sure to discard any error from it. TODO: turn
        # this into balice.callRemoteOnly("set", 39), which will have the
        # same semantics from our point of view (but in addition it will tell
        # the recipient to not bother sending a response).
        balice.callRemote("set", 39).addErrback(lambda ignored: None)

        if self.debug: print "Bob says something to Carol"
        d2 = self.carol.waitfor()
        d = self.bcarol.callRemote("set", obj=12)
        d.addCallback(lambda res: d2)
        d.addCallback(self._carolCalled)
        d.addCallback(lambda res: d1)
        return d

<|endoftext|>


<commit_before>from django.conf import settings
from vendor.django_beanstalkd import beanstalk_job

from forecasts.handlers import send_forecast_email
from registrations.models import Registration

beanstalk_options = {
    "workers": {"forecasts": 3}
}

def log(job_name, message):

    log_msg = "%s\t%s\t%s" % (datetime.datetime.now(), job_name, message)
    print log_msg

    f = open(settings.BEANSTALK_LOG_FILE, 'a')
    f.write(log_msg + "\n")
    f.close()

@beanstalk_job(worker='forecasts')
def job_send_forecast_email(arg):

    try:
        registration = Registration.objects.get(id=int(arg))
    except Registration.DoesNotExist:
        log("job_send_forecast_email", "Could not find registration id %d" % int(arg))
        return False

    success = send_forecast_email(registration)
    log("job_send_forecast_email_link", "Sent forecast email to %s" % registration.email)
    return success
<commit_msg>Added missing datetime import<commit_after>import datetime

from django.conf import settings
from vendor.django_beanstalkd import beanstalk_job

from forecasts.handlers import send_forecast_email
from registrations.models import Registration

beanstalk_options = {
    "workers": {"forecasts": 3}
}

def log(job_name, message):

    log_msg = "%s\t%s\t%s" % (datetime.datetime.now(), job_name, message)
    print log_msg

    f = open(settings.BEANSTALK_LOG_FILE, 'a')
    f.write(log_msg + "\n")
    f.close()

@beanstalk_job(worker='forecasts')
def job_send_forecast_email(arg):

    try:
        registration = Registration.objects.get(id=int(arg))
    except Registration.DoesNotExist:
        log("job_send_forecast_email", "Could not find registration id %d" % int(arg))
        return False

    success = send_forecast_email(registration)
    log("job_send_forecast_email_link", "Sent forecast email to %s" % registration.email)
    return success
<|endoftext|>


<commit_before>"""A module for defining WORKSPACE dependencies required for rules_foreign_cc"""

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe")
load("//foreign_cc/private/framework:toolchain.bzl", "register_framework_toolchains")
load("//toolchains:toolchains.bzl", "built_toolchains", "prebuilt_toolchains", "preinstalled_toolchains")

# buildifier: disable=unnamed-macro
def rules_foreign_cc_dependencies(
        native_tools_toolchains = [],
        register_default_tools = True,
        cmake_version = "3.23.2",
        make_version = "4.3",
        ninja_version = "1.11.0",
        register_preinstalled_tools = True,
        register_built_tools = True,
        register_toolchains = True):
    """Call this function from the WORKSPACE file to initialize rules_foreign_cc \
    dependencies and let neccesary code generation happen \
    (Code generation is needed to support different variants of the C++ Starlark API.).

    Args:
        native_tools_toolchains: pass the toolchains for toolchain types
            '@rules_foreign_cc//toolchains:cmake_toolchain' and
            '@rules_foreign_cc//toolchains:ninja_toolchain' with the needed platform constraints.
            If you do not pass anything, registered default toolchains will be selected (see below).

        register_default_tools: If True, the cmake and ninja toolchains, calling corresponding
            preinstalled binaries by name (cmake, ninja) will be registered after
            'native_tools_toolchains' without any platform constraints. The default is True.

        cmake_version: The target version of the cmake toolchain if `register_default_tools`
            or `register_built_tools` is set to `True`.

        make_version: The target version of the default make toolchain if `register_built_tools`
            is set to `True`.

        ninja_version: The target version of the ninja toolchain if `register_default_tools`
            or `register_built_tools` is set to `True`.

        register_preinstalled_tools: If true, toolchains will be registered for the native built tools
            installed on the exec host

        register_built_tools: If true, toolchains that build the tools from source are registered

        register_toolchains: If true, registers the toolchains via native.register_toolchains. Used by bzlmod
    """

    register_framework_toolchains(register_toolchains = register_toolchains)

    if register_toolchains:
        native.register_toolchains(*native_tools_toolchains)

        native.register_toolchains(
            "@rules_foreign_cc//toolchains:preinstalled_autoconf_toolchain",
            "@rules_foreign_cc//toolchains:preinstalled_automake_toolchain",
            "@rules_foreign_cc//toolchains:preinstalled_m4_toolchain",
            "@rules_foreign_cc//toolchains:preinstalled_pkgconfig_toolchain",
        )

    if register_default_tools:
        prebuilt_toolchains(cmake_version, ninja_version, register_toolchains)

    if register_built_tools:
        built_toolchains(
            cmake_version = cmake_version,
            make_version = make_version,
            ninja_version = ninja_version,
            register_toolchains = register_toolchains,
        )

    if register_preinstalled_tools:
        preinstalled_toolchains()

    maybe(
        http_archive,
        name = "bazel_skylib",
        # `main` as of 2021-10-27
        # Release request: https://github.com/bazelbuild/bazel-skylib/issues/336
        urls = [
            "https://github.com/bazelbuild/bazel-skylib/archive/6e30a77347071ab22ce346b6d20cf8912919f644.zip",
        ],
        strip_prefix = "bazel-skylib-6e30a77347071ab22ce346b6d20cf8912919f644",
        sha256 = "247361e64b2a85b40cb45b9c071e42433467c6c87546270cbe2672eb9f317b5a",
    )
<commit_msg>Use bazel_skylib 1.2.1 (#920)<commit_after>"""A module for defining WORKSPACE dependencies required for rules_foreign_cc"""

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe")
load("//foreign_cc/private/framework:toolchain.bzl", "register_framework_toolchains")
load("//toolchains:toolchains.bzl", "built_toolchains", "prebuilt_toolchains", "preinstalled_toolchains")

# buildifier: disable=unnamed-macro
def rules_foreign_cc_dependencies(
        native_tools_toolchains = [],
        register_default_tools = True,
        cmake_version = "3.23.2",
        make_version = "4.3",
        ninja_version = "1.11.0",
        register_preinstalled_tools = True,
        register_built_tools = True,
        register_toolchains = True):
    """Call this function from the WORKSPACE file to initialize rules_foreign_cc \
    dependencies and let neccesary code generation happen \
    (Code generation is needed to support different variants of the C++ Starlark API.).

    Args:
        native_tools_toolchains: pass the toolchains for toolchain types
            '@rules_foreign_cc//toolchains:cmake_toolchain' and
            '@rules_foreign_cc//toolchains:ninja_toolchain' with the needed platform constraints.
            If you do not pass anything, registered default toolchains will be selected (see below).

        register_default_tools: If True, the cmake and ninja toolchains, calling corresponding
            preinstalled binaries by name (cmake, ninja) will be registered after
            'native_tools_toolchains' without any platform constraints. The default is True.

        cmake_version: The target version of the cmake toolchain if `register_default_tools`
            or `register_built_tools` is set to `True`.

        make_version: The target version of the default make toolchain if `register_built_tools`
            is set to `True`.

        ninja_version: The target version of the ninja toolchain if `register_default_tools`
            or `register_built_tools` is set to `True`.

        register_preinstalled_tools: If true, toolchains will be registered for the native built tools
            installed on the exec host

        register_built_tools: If true, toolchains that build the tools from source are registered

        register_toolchains: If true, registers the toolchains via native.register_toolchains. Used by bzlmod
    """

    register_framework_toolchains(register_toolchains = register_toolchains)

    if register_toolchains:
        native.register_toolchains(*native_tools_toolchains)

        native.register_toolchains(
            "@rules_foreign_cc//toolchains:preinstalled_autoconf_toolchain",
            "@rules_foreign_cc//toolchains:preinstalled_automake_toolchain",
            "@rules_foreign_cc//toolchains:preinstalled_m4_toolchain",
            "@rules_foreign_cc//toolchains:preinstalled_pkgconfig_toolchain",
        )

    if register_default_tools:
        prebuilt_toolchains(cmake_version, ninja_version, register_toolchains)

    if register_built_tools:
        built_toolchains(
            cmake_version = cmake_version,
            make_version = make_version,
            ninja_version = ninja_version,
            register_toolchains = register_toolchains,
        )

    if register_preinstalled_tools:
        preinstalled_toolchains()

    maybe(
        http_archive,
        name = "bazel_skylib",
        urls = [
            "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.2.1/bazel-skylib-1.2.1.tar.gz",
            "https://github.com/bazelbuild/bazel-skylib/releases/download/1.2.1/bazel-skylib-1.2.1.tar.gz",
        ],
        sha256 = "f7be3474d42aae265405a592bb7da8e171919d74c16f082a5457840f06054728",
    )
<|endoftext|>


<commit_before>__author__ = "Christian Kongsgaard"

# -------------------------------------------------------------------------------------------------------------------- #
# IMPORTS

# Modules:
import os
import sys

source_folder = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
sys.path.insert(0, source_folder)

# RiBuild Modules:
from delphin_6_automation.backend import *

# -------------------------------------------------------------------------------------------------------------------- #
# BACKEND

if __name__ == "__main__":
    main()
<commit_msg>started with logging<commit_after>__author__ = "Christian Kongsgaard"
__license__ = 'MIT'

# -------------------------------------------------------------------------------------------------------------------- #
# IMPORTS

# Modules:
import os
import sys
import logging

source_folder = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
sys.path.insert(0, source_folder)

# RiBuild Modules:
from delphin_6_automation.backend import *

# -------------------------------------------------------------------------------------------------------------------- #
# BACKEND

if __name__ == "__main__":
    logging.basicConfig(filename='simulation_worker.log', level=logging.DEBUG)
    logging.info('Started')
    main()
<|endoftext|>


<commit_before>from Pyblosxom.renderers.base import RendererBase
from Pyblosxom import tools
import types

class Renderer(RendererBase):
    def render(self, header = 1):
        pyhttp = self._request.getHttp()
        config = self._request.getConfiguration()
        data = self._request.getData()
        printout = self.write

        self.addHeader('Content-type', 'text/plain')
        self.showHeaders()
        printout("Welcome to debug mode!\n")
        printout("You wanted the %(flavour)s flavour if I support flavours\n" % data)

        printout("------------------------------------------------------\n")
        printout("The HTTP Return codes are:\n")
        printout("------------------------------------------------------\n")
        for key in self._header.keys():
            printout("%s -> %s\n" % (key, self._header[key]))

        printout("------------------------------------------------------\n")
        printout("The OS environment contains:\n")
        printout("------------------------------------------------------\n")
        import os
        for key in os.environ.keys():
            printout("%s -> %s\n" % (key, os.environ[key]))

        printout("------------------------------------------------------\n")
        printout("Request.getHttp() dict contains:\n")
        printout("------------------------------------------------------\n")
        for key in pyhttp.keys():
            printout("%s -> %s\n" % (key, pyhttp[key]))

        printout("------------------------------------------------------\n")
        printout("Request.getConfiguration() dict contains:\n")
        printout("------------------------------------------------------\n")
        for key in config.keys():
            printout("%s -> %s\n" % (key, config[key]))

        printout("------------------------------------------------------\n")
        printout("Request.getData() dict contains:\n")
        printout("------------------------------------------------------\n")
        for key in data.keys():
            printout("%s -> %s\n" % (key, data[key]))

        printout("------------------------------------------------------\n")
        printout("Entries to process:\n")
        printout("------------------------------------------------------\n")
        for content in self._content:
            if type(content) != types.StringType:
                printout("%s\n" % content.get('filename', 'No such file\n'))

        printout("------------------------------------------------------\n")
        printout("Cached Titles:\n")
        printout("------------------------------------------------------\n")
        cache = tools.get_cache()
        for content in self._content:
            if type(content) != types.StringType:
                filename = content['filename']

                if cache.has_key(filename):
                    printout("%s" % cache[filename]['title'])
                cache.close()

        printout("------------------------------------------------------\n")
        printout("Cached Entry Bodies:\n")
        printout("------------------------------------------------------\n")
        for content in self._content:
            if type(content) != types.StringType:
                filename = content['filename']
                if cache.has_key(filename):
                    printout("%s\n" % cache[filename]['title'])
                    printout("==================================================\n")
                    printout("%s\n" % cache[filename]['body'])
                else:
                    printout("Contents of %s is not cached\n" % filename)
                cache.close()
                printout("------------------------------------------------------\n")
<commit_msg>Allow the debug renderer to display a lot more keys that are available to the user<commit_after>from Pyblosxom.renderers.base import RendererBase
from Pyblosxom import tools
import types

class Renderer(RendererBase):
    def render(self, header = 1):
        pyhttp = self._request.getHttp()
        config = self._request.getConfiguration()
        data = self._request.getData()
        printout = self.write

        self.addHeader('Content-type', 'text/plain')
        self.showHeaders()
        printout("Welcome to debug mode!\n")
        printout("You wanted the %(flavour)s flavour if I support flavours\n" % data)

        printout("------------------------------------------------------\n")
        printout("The HTTP Return codes are:\n")
        printout("------------------------------------------------------\n")
        for key in self._header.keys():
            printout("%s -> %s\n" % (key, self._header[key]))

        printout("------------------------------------------------------\n")
        printout("The OS environment contains:\n")
        printout("------------------------------------------------------\n")
        import os
        for key in os.environ.keys():
            printout("%s -> %s\n" % (key, os.environ[key]))

        printout("------------------------------------------------------\n")
        printout("Request.getHttp() dict contains:\n")
        printout("------------------------------------------------------\n")
        for key in pyhttp.keys():
            printout("%s -> %s\n" % (key, pyhttp[key]))

        printout("------------------------------------------------------\n")
        printout("Request.getConfiguration() dict contains:\n")
        printout("------------------------------------------------------\n")
        for key in config.keys():
            printout("%s -> %s\n" % (key, config[key]))

        printout("------------------------------------------------------\n")
        printout("Request.getData() dict contains:\n")
        printout("------------------------------------------------------\n")
        for key in data.keys():
            printout("%s -> %s\n" % (key, data[key]))

        printout("------------------------------------------------------\n")
        printout("Entries to process:\n")
        printout("------------------------------------------------------\n")
        for content in self._content:
            if type(content) != types.StringType:
                printout("%s\n" % content.get('filename', 'No such file\n'))

        printout("------------------------------------------------------\n")
        printout("Entries processed:\n")
        printout("------------------------------------------------------\n")
        for content in self._content:
            if type(content) != types.StringType:
                printout("------------------------------------------------------\n")
                printout("Items for %s:\n" % content.get('filename', 'No such file\n'))
                printout("------------------------------------------------------\n")
                for item in content.keys():
                    printout("%s -> %s\n" % (item, content[item]))

                #printout("%s\n" % content.get('filename', 'No such file\n'))

        printout("------------------------------------------------------\n")
        printout("Cached Titles:\n")
        printout("------------------------------------------------------\n")
        cache = tools.get_cache()
        for content in self._content:
            if type(content) != types.StringType:
                filename = content['filename']

                if cache.has_key(filename):
                    printout("%s\n" % cache[filename]['title'])
                cache.close()

        printout("------------------------------------------------------\n")
        printout("Cached Entry Bodies:\n")
        printout("------------------------------------------------------\n")
        for content in self._content:
            if type(content) != types.StringType:
                filename = content['filename']
                if cache.has_key(filename):
                    printout("%s\n" % cache[filename]['title'])
                    printout("==================================================\n")
                    printout("%s\n" % cache[filename]['body'])
                else:
                    printout("Contents of %s is not cached\n" % filename)
                cache.close()
                printout("------------------------------------------------------\n")
<|endoftext|>


<commit_before>from __future__ import division, print_function
import numpy as np

from Quaternions import utils
from Quaternions import functions as qf

shape = (4, 4)
quaternions_array = utils.random_quaternions_array(shape, 5)
print(quaternions_array.shape)
print(qf.exp(qf.log(quaternions_array)) == quaternions_array + np.eye(min(shape)))
print(qf.log(qf.exp(quaternions_array)) == quaternions_array)
<commit_msg>Quaternions arrays demo<commit_after>from __future__ import division, print_function
import numpy as np

from Quaternions import utils
from Quaternions import functions as qf

shape = (4, 4)
quaternions_array = utils.random_quaternions_array(shape, 5)
print(quaternions_array.shape)
print(qf.exp(qf.log(quaternions_array)) == quaternions_array + np.eye(min(shape)))
print(qf.log(qf.exp(quaternions_array)) == quaternions_array)

print(quaternions_array * utils.random_quaternion())
<|endoftext|>