##// END OF EJS Templates
Backport PR #2384: Adapt inline backend to changes in matplotlib...
Backport PR #2384: Adapt inline backend to changes in matplotlib Matplotlib recently merged https://github.com/matplotlib/matplotlib/pull/1125 that makes it simpler to use objective oriented figure creation by automatically creating the right canvas for the backend. To solve that all backends must provide a backend_xxx.FigureCanvas. This is obviosly missing from the inline backend. The change is needed to make the inline backend work with mpl's 1.2.x branch which is due to released soon. Simply setting the default canvas equal to a Agg canvas appears to work for both svg and png figures but I'm not sure weather that is the right approach. Should the canvas depend on the figure format and provide a svg canvas for a svg figure? (Note that before this change to matplotlib the canvas from a plt.figure call seams to be a agg type in all cases) Edit: I made the pull request against 0.13.1 since it would be good to have this in the stable branch for when mpl is released. Just let me know and I can rebase it against master

File last commit:

r7509:56c97fc4
r8562:7d16877a
Show More
dictdb.py
220 lines | 6.3 KiB | text/x-python | PythonLexer
Bernardo B. Marques
remove all trailling spaces
r4872 """A Task logger that presents our DB interface,
MinRK
Started DB backend with mongoDB support.
r3579 but exists entirely in memory and implemented with dicts.
MinRK
update recently changed modules with Authors in docstring
r4018 Authors:
* Min RK
MinRK
Started DB backend with mongoDB support.
r3579 TaskRecords are dicts of the form:
{
'msg_id' : str(uuid),
'client_uuid' : str(uuid),
'engine_uuid' : str(uuid) or None,
'header' : dict(header),
'content': dict(content),
'buffers': list(buffers),
'submitted': datetime,
'started': datetime or None,
'completed': datetime or None,
'resubmitted': datetime or None,
'result_header' : dict(header) or None,
'result_content' : dict(content) or None,
'result_buffers' : list(buffers) or None,
}
With this info, many of the special categories of tasks can be defined by query:
pending: completed is None
client's outstanding: client_uuid = uuid && completed is None
MIA: arrived is None (and completed is None)
etc.
EngineRecords are dicts of the form:
{
'eid' : int(id),
'uuid': str(uuid)
}
This may be extended, but is currently.
We support a subset of mongodb operators:
$lt,$gt,$lte,$gte,$ne,$in,$nin,$all,$mod,$exists
"""
#-----------------------------------------------------------------------------
MinRK
update recently changed modules with Authors in docstring
r4018 # Copyright (C) 2010-2011 The IPython Development Team
MinRK
Started DB backend with mongoDB support.
r3579 #
# Distributed under the terms of the BSD License. The full license is in
# the file COPYING, distributed as part of this software.
#-----------------------------------------------------------------------------
MinRK
further fix/tests for record edits clobbering DictDB
r7261 from copy import deepcopy as copy
MinRK
Started DB backend with mongoDB support.
r3579 from datetime import datetime
MinRK
add LoggingConfigurable base class
r4016 from IPython.config.configurable import LoggingConfigurable
MinRK
Add SQLite backend, DB backends are Configurable...
r3646
MinRK
use 'timestamp' datatype for timestamps in sqlitedb
r4009 from IPython.utils.traitlets import Dict, Unicode, Instance
MinRK
Add SQLite backend, DB backends are Configurable...
r3646
MinRK
Started DB backend with mongoDB support.
r3579 filters = {
'$lt' : lambda a,b: a < b,
'$gt' : lambda a,b: b > a,
MinRK
cleanup pass
r3644 '$eq' : lambda a,b: a == b,
'$ne' : lambda a,b: a != b,
MinRK
Started DB backend with mongoDB support.
r3579 '$lte': lambda a,b: a <= b,
'$gte': lambda a,b: a >= b,
'$in' : lambda a,b: a in b,
'$nin': lambda a,b: a not in b,
MinRK
cleanup pass
r3644 '$all': lambda a,b: all([ a in bb for bb in b ]),
MinRK
Started DB backend with mongoDB support.
r3579 '$mod': lambda a,b: a%b[0] == b[1],
'$exists' : lambda a,b: (b and a is not None) or (a is None and not b)
}
class CompositeFilter(object):
"""Composite filter for matching multiple properties."""
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
Started DB backend with mongoDB support.
r3579 def __init__(self, dikt):
self.tests = []
self.values = []
for key, value in dikt.iteritems():
self.tests.append(filters[key])
self.values.append(value)
def __call__(self, value):
for test,check in zip(self.tests, self.values):
if not test(value, check):
return False
return True
MinRK
add LoggingConfigurable base class
r4016 class BaseDB(LoggingConfigurable):
MinRK
Refactor newparallel to use Config system...
r3604 """Empty Parent class so traitlets work on DB."""
MinRK
Add SQLite backend, DB backends are Configurable...
r3646 # base configurable traits:
MinRK
cleanup parallel traits...
r3988 session = Unicode("")
MinRK
Refactor newparallel to use Config system...
r3604
class DictDB(BaseDB):
MinRK
Started DB backend with mongoDB support.
r3579 """Basic in-memory dict-based object for saving Task Records.
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
Started DB backend with mongoDB support.
r3579 This is the first object to present the DB interface
for logging tasks out of memory.
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
Started DB backend with mongoDB support.
r3579 The interface is based on MongoDB, so adding a MongoDB
backend should be straightforward.
"""
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
Add SQLite backend, DB backends are Configurable...
r3646 _records = Dict()
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
Started DB backend with mongoDB support.
r3579 def _match_one(self, rec, tests):
"""Check if a specific record matches tests."""
for key,test in tests.iteritems():
if not test(rec.get(key, None)):
return False
return True
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
General improvements to database backend...
r3780 def _match(self, check):
MinRK
Started DB backend with mongoDB support.
r3579 """Find all the matches for a check dict."""
MinRK
General improvements to database backend...
r3780 matches = []
MinRK
Started DB backend with mongoDB support.
r3579 tests = {}
for k,v in check.iteritems():
if isinstance(v, dict):
tests[k] = CompositeFilter(v)
else:
tests[k] = lambda o: o==v
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
General improvements to database backend...
r3780 for rec in self._records.itervalues():
MinRK
Started DB backend with mongoDB support.
r3579 if self._match_one(rec, tests):
MinRK
dictdb queries should [shallow] copy records...
r6323 matches.append(copy(rec))
MinRK
General improvements to database backend...
r3780 return matches
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
General improvements to database backend...
r3780 def _extract_subdict(self, rec, keys):
"""extract subdict of keys"""
d = {}
d['msg_id'] = rec['msg_id']
for key in keys:
d[key] = rec[key]
MinRK
further fix/tests for record edits clobbering DictDB
r7261 return copy(d)
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
Started DB backend with mongoDB support.
r3579 def add_record(self, msg_id, rec):
"""Add a new Task Record, by msg_id."""
if self._records.has_key(msg_id):
raise KeyError("Already have msg_id %r"%(msg_id))
self._records[msg_id] = rec
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
Started DB backend with mongoDB support.
r3579 def get_record(self, msg_id):
"""Get a specific Task Record, by msg_id."""
MinRK
dictdb queries should [shallow] copy records...
r6323 if not msg_id in self._records:
MinRK
Started DB backend with mongoDB support.
r3579 raise KeyError("No such msg_id %r"%(msg_id))
MinRK
dictdb queries should [shallow] copy records...
r6323 return copy(self._records[msg_id])
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
Started DB backend with mongoDB support.
r3579 def update_record(self, msg_id, rec):
"""Update the data in an existing record."""
self._records[msg_id].update(rec)
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
Started DB backend with mongoDB support.
r3579 def drop_matching_records(self, check):
"""Remove a record from the DB."""
MinRK
General improvements to database backend...
r3780 matches = self._match(check)
MinRK
Started DB backend with mongoDB support.
r3579 for m in matches:
MinRK
various db backend fixes...
r3875 del self._records[m['msg_id']]
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
Started DB backend with mongoDB support.
r3579 def drop_record(self, msg_id):
"""Remove a record from the DB."""
del self._records[msg_id]
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
General improvements to database backend...
r3780 def find_records(self, check, keys=None):
"""Find records matching a query dict, optionally extracting subset of keys.
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
General improvements to database backend...
r3780 Returns dict keyed by msg_id of matching records.
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
General improvements to database backend...
r3780 Parameters
----------
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
General improvements to database backend...
r3780 check: dict
mongodb-style query argument
keys: list of strs [optional]
if specified, the subset of keys to extract. msg_id will *always* be
included.
"""
matches = self._match(check)
if keys:
return [ self._extract_subdict(rec, keys) for rec in matches ]
else:
return matches
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
General improvements to database backend...
r3780 def get_history(self):
"""get all msg_ids, ordered by time submitted."""
msg_ids = self._records.keys()
return sorted(msg_ids, key=lambda m: self._records[m]['submitted'])
MinRK
add NoDB for non-recording Hub...
r5892
MinRK
Use NoDB by default...
r7509 NODATA = KeyError("NoDB backend doesn't store any data. "
"Start the Controller with a DB backend to enable resubmission / result persistence."
)
MinRK
add NoDB for non-recording Hub...
r5892 class NoDB(DictDB):
"""A blackhole db backend that actually stores no information.
Provides the full DB interface, but raises KeyErrors on any
method that tries to access the records. This can be used to
minimize the memory footprint of the Hub when its record-keeping
functionality is not required.
"""
def add_record(self, msg_id, record):
pass
def get_record(self, msg_id):
MinRK
Use NoDB by default...
r7509 raise NODATA
MinRK
add NoDB for non-recording Hub...
r5892
def update_record(self, msg_id, record):
pass
def drop_matching_records(self, check):
pass
def drop_record(self, msg_id):
pass
def find_records(self, check, keys=None):
MinRK
Use NoDB by default...
r7509 raise NODATA
MinRK
add NoDB for non-recording Hub...
r5892
def get_history(self):
MinRK
Use NoDB by default...
r7509 raise NODATA
MinRK
add NoDB for non-recording Hub...
r5892