Cassini API
Core
- class cassini.core.Meta(file: Path)
Like a dictionary, except linked to a json file on disk. Caches the value of the json in itself.
- Parameters:
file (Path) – File Meta object stores information about.
- property age: float
time in secs since last fetch
- fetch() Dict[str, dict | list | tuple | str | int | float | bool | None]
Fetches values from the meta file and updates them into self._cache.
Notes
This doesn’t overwrite self._cache with meta contents, but updates it. Meaning new stuff to file won’t be overwritten, it’ll just be loaded.
- get(key: str, default: Any | None = None) Any
Like dict.get
- keys() KeysView[str]
like dict.keys
- refresh() None
Check age of cache, if stale then re-fetch
- write() None
Overwrite contents of cache into file
- class cassini.core.TierBase(*args: str, **kwargs: Dict[str, Any])
Base class for creating Tiers
- Parameters:
*identifiers (str) – sequence of strings that identify this tier. With the final identifier being unique.
- rank
Class attribute, specifying the rank of this Tier
- Type:
int
- id_regex
Class attribute, regex that defines a group that matches the id of a Tier object from a name… except the name isn’t the full name, but with parent names stripped, see examples basically!
- Type:
str
- description
returns the description found in a Tier _instance’s meta file
- Type:
str
- started
return a datetime parsed using config.DATE_FORMAT found in meta file
- Type:
datetime
- conclusion
return the conclusion found in a Tier _instance’s meta file.
- Type:
str
- rank
(class attribute) rank of this Tier class (not to be set directly)
- Type:
int
- id_regex
(class attribute) regex used to restrict form of Tier object ids. Should contain 1 group that captures the id.
- Type:
str
- gui_cls
- (class attribute) The class called upon initialisation to use as gui for this object. Constructor should take self
as first argument.
- Type:
Any
- add_highlight(name: str, data: List[Dict[str, Dict[str, Any]]], overwrite: bool = True) None
Add a highlight to self.highlights_file.
This is usually done behind the scenes using the %%hlt My Title magic.
- Parameters:
name (str) – Name of highlight (also taken as the title).
data (list) – list of data and metadata that can be passed to IPython.display.publish_display_data to render.
overwrite (bool) – If False will raise an exception if a highlight of the same name exists. Default is True
- cache_file
Path to where cache file for this Tier object will be.
- Returns:
cache_file – Defaults to self.parent.folder / self._meta_folder_name / (self.name + ‘.cache’)
- Return type:
Path
- cache_result(name: str, data: List[Dict[str, Dict[str, Any]]], overwrite: bool = True) None
Cache a result in self.cache_file.
This is usually done behind the scenes using the %%cache magic.
- Parameters:
name (str) – name used as key in JSON for this cached result. When using %%cache this is a hash of the cell text
data (dict) – list of data and metadata that can be passed to IPython.display.publish_display_data to render.
overwrite (bool) – If False will raise an exception if a cached result of the same name exists. Default is True
- children_df(*, include: List[str] | None = None, exclude: List[str] | None) DataFrame | None
Build an UnescapedDataFrame containing rows from each child of this Tier. Columns are inferred from contents of meta files.
- Parameters:
include (Sequence[str]) – names of columns to include in children DataFrame
exclude (Sequence[str]) – names of columns to drop from children DataFrame
Notes
Parameters include and exclude are mutually exclusive.
- Returns:
df – DataFrame containing Tier’s children. If no children then returns None.
- Return type:
UnescapedDataFrame, None
- exists() bool
returns True if this Tier object has already been setup (e.g. by self.setup_files)
- file
Path to where .ipynb file for this Tier instance will be.
- Returns:
file – Defaults to self.parent.folder / (self.name + ‘.ipynb’).
- Return type:
Path
- folder
Path to folder where the contents of this Tier lives.
Defaults to self.parent.folder / self.name.
- get_cached() Dict[str, List[Dict[str, Dict[str, Any]]]] | None
Retrieve cached output from self.cache_file.
Keys are a hash of text from cell that created this output.
- Returns:
cached – dictionary with all the cached outputs. In the same form as self.get_highlights(). Returns an empty dict if no cache_file exists.
- Return type:
dict
- get_child(id: str) TierBase
Get a child according to the given id.
- Parameters:
id (str) – id to add self.identifiers to form new Tier object of tier below.
- Returns:
child – child Tier object.
- Return type:
Type[TierBase]
- get_highlights() Dict[str, List[Dict[str, Dict[str, Any]]]] | None
Get dictionary of highlights for this Tier _instance.
This dictionary is in a form that can be rendered in the notebook using IPython.display.publish_display_data see Examples.
This is implemented for you with self.display_highlights().
- Returns:
highlights – Get dictionary of highlights for this Tier _instance. If the highlights file doesn’t exist, just returns an empty dict.
- Return type:
dict
Examples
>>> wp = project['WP1'] >>> for title, outputs in wp.get_highlights(): ... print("Displaying Highlight:", title) ... for output in outputs: ... IPython.display.publish_display_data(**output)
- classmethod get_templates() List[Path]
Get all the templates for this Tier.
- gui_cls
alias of
BaseTierGui
- highlights_file
Path to where highlights file for this Tier object should be.
- Returns:
highlights_file – Defaults to self.parent.folder / self._meta_folder_name / (self.name + ‘.hlts’)
- Return type:
Path
- href
href usable in notebook HTML giving link to self.file.
Assumes that os.getcwd() reflects the directory of the currently opened .ipynb (usually true, unless you’re changing working dir).
Does do escaping on the HTML, but is maybe pointless!
- Returns:
href – href usable in notebook HTML.
- Return type:
str
- id
Shortcut for getting final identifier.
Examples
>>> from my_project import project >>> smpl = project.env('WP2.3c') >>> smpl.identifiers ['2', '3', 'c'] >>> smpl.id 'c'
- identifiers
Read only copy of identifiers that make up this Tier object.
- meta_file
Path to where meta file for this Tier object should be.
- Returns:
meta_file – Defaults to self.parent.folder / self._meta_folder_name / (self.name + ‘.json’)
- Return type:
Path
- name
Full name of Tier object. Made by concatenating each parent’s self.name_part_template filled with each parent’s self.id.
Examples
>>> wp = WorkPackage('2') >>> exp = Experiment('2', '3') >>> smpl = Sample('2', '3', 'c') >>> wp.name_part_template.format(wp.id) WP2 >>> exp.name_part_template.format(exp.id) .3 >>> smpl.name_part_template.format(smpl.id) c >>> smpl.name # all 3 joined together WP2.3c
- open_folder() None
Open self.folder in explorer
Notes
Only works on Windows machines.
Window is opened via the Jupyter server, not the browser, so if you are not accessing jupyter on localhost then the window won’t open for you!
- parent
‘(
- Type:
Parent of this Tier _instance, None if has no parent
- classmethod parse_name(name: str) Tuple[str, ...]
Ask env.project to parse name.
- remove_cached(name: str) None
Remove cached output according to the name provided.
- remove_files() None
Deletes files associated with a Tier
- remove_highlight(name: str) None
Remove highlight from highlight file. Performed by calling get_highlights(), then deleting the key name from the dictionary, then re-writing the highlights… if you’re interested!
- render_template(template_path: Path) str
Render template file passing self as self.short_type and as tier.
- Parameters:
template (Path) – path to template file. Must be relative to project.template_folder
- Returns:
rendered_text – template rendered with self.
- Return type:
str
- setup_files(template: Path | None = None, meta: Dict[str, dict | list | tuple | str | int | float | bool | None] | None = None) None
Create all the files needed for a valid Tier object to exist.
This includes its .ipynb file, its parent folder, its own folder and its Meta file.
Will render .ipynb file as Jinja template engine, passing to the template self with names given by self.short_type and tier.
- Parameters:
template (Path) – path to template file to render to create .ipynb file.
meta (MetaDict) – Initial meta values to create the tier with.
Environment
- class cassini.environment.CassiniLabApp(**kwargs: Any)
Subclass of jupyterlab.labapp.LabApp that ensures ContentsManager.allow_hidden = True (needed for jupyter_cassini_server)
- classmethod initialize_server(argv: Any | None = None) LabServerApp
Patch serverapp to ensure hidden files are allowed, needed for jupyter_cassini_server
- class cassini.environment.PathLibEnv(block_start_string: str = '{%', block_end_string: str = '%}', variable_start_string: str = '{{', variable_end_string: str = '}}', comment_start_string: str = '{#', comment_end_string: str = '#}', line_statement_prefix: str | None = None, line_comment_prefix: str | None = None, trim_blocks: bool = False, lstrip_blocks: bool = False, newline_sequence: te.Literal['\n', '\r\n', '\r'] = '\n', keep_trailing_newline: bool = False, extensions: ~typing.Sequence[str | ~typing.Type[Extension]] = (), optimized: bool = True, undefined: ~typing.Type[~jinja2.runtime.Undefined] = <class 'jinja2.runtime.Undefined'>, finalize: ~typing.Callable[[...], ~typing.Any] | None = None, autoescape: bool | ~typing.Callable[[str | None], bool] = False, loader: BaseLoader | None = None, cache_size: int = 400, auto_reload: bool = True, bytecode_cache: BytecodeCache | None = None, enable_async: bool = False)
Subclass of jinja2.Environment to enable using pathlib.Path for template names.
- get_template(name: Path | str, parent: str | None = None, globals: MutableMapping[str, Any] | None = None) Template
Load a template by name with
loader
and return aTemplate
. If the template does not exist aTemplateNotFound
exception is raised.- Parameters:
name – Name of the template to load. When loading templates from the filesystem, “/” is used as the path separator, even on Windows.
parent – The name of the parent template importing this template.
join_path()
can be used to implement name transformations with this.globals – Extend the environment
globals
with these extra variables available for all renders of this template. If the template has already been loaded and cached, its globals are updated with any new items.
Changed in version 3.0: If a template is loaded from cache,
globals
will update the template’s globals instead of ignoring the new values.Changed in version 2.4: If
name
is aTemplate
object it is returned unchanged.
- class cassini.environment.Project(*args: Any, **kwargs: Any)
Represents your project. Understands your naming convention, and your project hierarchy.
- Parameters:
hierarchy (List[Type[BaseTier]]) – Sequence of TierBase subclasses representing the hierarchy for this project. i.e. earlier entries are stored in higher level directories.
project_folder (Union[str, Path]) – path to home directory. Note this also accepts a path to a file, but will take project_folder.parent in that case. This enables __file__ to be used if you want project_folder to be based in the same dir.
Notes
This class is a singleton i.e. only 1 instance per interpreter can be created.
- env(name: str) TierBase
Initialise the global environment to a particular Tier that is retrieved by parsing name.
This will set the value of env.o.
Warning
This should only really be called once (or only with 1 name). Otherwise this could create some unexpected behaviour.
- launch(app: LabApp | None = None, patch_pythonpath: bool = True) LabApp
Jump off point for a cassini project.
Sets up required files for your project, monkeypatches PYTHONPATH to make your project available throughout and launches a jupyterlab server.
This explicitly associates an instance of the Jupyter server with a particular project.
- Parameters:
app (LabApp) – A ready made Jupyter Lab app (By defuault will just create a new one).
patch_pythonpath (bool) – Add self.project_folder to the PYTHONPATH? (defaults to True)
- parse_name(name: str) Tuple[str, ...]
Parses a string that corresponds to a Tier and returns a list of its identifiers.
returns an empty tuple if not a valid name.
- Parameters:
name (str) – name to parse
- Returns:
identifiers – identifiers extracted from name, empty tuple if None found
- Return type:
tuple
Notes
This works in a slightly strange - but robust way!
e.g.
>>> name = 'WP2.3c'
it will loop through each entry in cls.hierarchy (skipping home!), and then perform a search on name with that regex:
>>> WorkPackage.name_part_regex WP(\d+) >>> match = re.search(WorkPackage.name_part_regex, name)
If there’s no match, it will return (), if there is, it stores the id part:
>>> wp_id = match.group(1) # in python group 0 is the whole match >>> wp_id 2
Then it removes the whole match from the name:
>>> name = name[match.end(0):] >>> name .3c
Then it moves on to the next tier
>>> Experiment.name_part_regex '\.(\d+)' >>> match = re.search(WorkPackage.name_part_regex, name)
If there’s a match it extracts the id, and substracts the whole string from name and moves on, continuing this loop until it’s gone through the whole hierarchy.
The whole name has to be a valid id, or it will return () e.g.
>>> TierBase.parse_name('WP2.3') ('2', '3') >>> TierBase.parse_name('WP2.u3') ()
- setup_files() TierBase
Setup files needed for this project.
Will put everything you need in project_folder to get going.
- template_folder()
Overwritable property providing where templates will be stored for this project.
IPyGui
- class cassini.ipygui.BaseTierGui(tier: T)
Mixin to provide nice notebook outputs for Jupyter Notebooks.
- children_df(*, include: List[str] | None = None, exclude: List[str] | None = None) UnescapedDataFrame | None
Calls tier.children_df but returns an UnescapedDataFrame instead.
- display_highlights() None
Display an ipywidgets.Accordian with this Tier’s highlights.
- header(*, include: List[str] | None = None, exclude: List[str] | None = None) DOMWidget
Builds header widget from its components.
- Parameters:
include (Sequence[str]) – names of components to render in header widget.
exclude (Sequence[str]) – names of components not to render in header widget.
Notes
Parameters include and exclude are mutually exclusive.
- Returns:
header – Widget that can be displayed containing all the components of this Tier’s header.
- Return type:
DOMWidget
- new_child() DOMWidget
Widget for creating new child for this Tier.
- class cassini.ipygui.InputSequence(done_action: Callable[[...], Any], *children: DOMWidget)
Helper class for creating ‘input sequences’ i.e. a sequency of widgets that you fill in, and then click confirm.
- Parameters:
done_action (callable) – function to call when confirm is clicked. Each child (see next parameter!) is passed to done_action
*children (ipywidget) – widgets to display in order. When confirm clicked, these widget objects are passed to done_action.
- as_widget() DOMWidget
Build self into ipywidget
- Returns:
widget – widget form of self.
- Return type:
DOMWidget
- child_updated(change: Any) None
Called when a child is updated, meant to stop you pressing confirm until you’ve entered something into every widget… don’t think it actually works tho!
- display() Output
Displays self.as_widget().
- Returns:
output – output widget which we displayed into…
- Return type:
Output
- reset(change: Any) None
Reset the state of the InputSequence. Called when new button clicked.
- class cassini.ipygui.UnescapedDataFrame(data=None, index: Axes | None = None, columns: Axes | None = None, dtype: Dtype | None = None, copy: bool | None = None)
Subclass of pd.DataFrame that slightly dangerously does not escape any html in its self._repr_html_ method.
Warning
This class deliberately does not escape HTML for objects it contains. This means you need to trust these objects.
- static try_html_repr(obj: object) str
Get text form of obj, first try obj._repr_html_, fallback on str(obj).
Warning
This method does not escape obj._repr_html_. So make sure your reprs are trustworthy!
- class cassini.ipygui.WHTML(html: str)
Magic class that takes html text and creates an object that is rendered with that text.
ipywidget.HTML widgets do not get their links XSRF protected, but obj._repr_html_ does!
Warning
This HTML is not escaped, so could do bad stuff!
- cassini.ipygui.widgetify(obj: Any) Output
Allows any object to be treated like an ipywidget so it can be used in ipywidget layouts - handy!
- cassini.ipygui.widgetify_html(html: str) Output
Required for html which has links rather than ipywidgets HTML widget.
- Parameters:
html (str) – HTML to render
- Return type:
Output widget containing the HTML
Defaults
- class cassini.defaults.tiers.DataSet(*args: str, **kwargs: Dict[str, Any])
DataSet Tier.
The final tier, intended to represent a folder containing a collection of files relating to a particular Sample.
- default_template = None
- exists() bool
returns True if this Tier object has already been setup (e.g. by self.setup_files)
- folder
- classmethod get_templates() List[Path]
Datasets have no templates.
- href
- setup_files(template: Path | None = None, meta=None) None
Create all the files needed for a valid Tier object to exist.
This includes its .ipynb file, its parent folder, its own folder and its Meta file.
Will render .ipynb file as Jinja template engine, passing to the template self with names given by self.short_type and tier.
- Parameters:
template (Path) – path to template file to render to create .ipynb file.
meta (MetaDict) – Initial meta values to create the tier with.
- class cassini.defaults.tiers.Experiment(*args: str, **kwargs: Dict[str, Any])
Experiment Tier.
Just below WorkPackage, experiments are intended to be collections of samples and datasets that work towards the goal of the parent WorkPackage.
Each Experiment has a number of samples.
- children_df(include: List[str] | None = None, exclude: List[str] | None = None) DataFrame | None
Build an UnescapedDataFrame containing rows from each child of this Tier. Columns are inferred from contents of meta files.
- Parameters:
include (Sequence[str]) – names of columns to include in children DataFrame
exclude (Sequence[str]) – names of columns to drop from children DataFrame
Notes
Parameters include and exclude are mutually exclusive.
- Returns:
df – DataFrame containing Tier’s children. If no children then returns None.
- Return type:
UnescapedDataFrame, None
- gui_cls
alias of
ExperimentGui
- setup_technique(name: str) None
Convenience method for adding a new technique to this experiment.
Essentially just creates a new folder for it in the appropriate location.
This folder can then be filled with `DataSet`s
- property techniques: List[str]
Convenience property for looking up all the techniques that have been performed on samples in this experiment.
Notes
This just checks for the existence of DataSet folders, and not if they have anything in them!
- class cassini.defaults.tiers.ExperimentGui(tier: T)
- new_dataset() DOMWidget
A handy widget for creating new DataSets.
- class cassini.defaults.tiers.Home(*args: str, **kwargs: Dict[str, Any])
Home Tier.
This, or a subclass of this should generally be the first entry in your hierarchy, essentially represents the top level folder in your hierarchy.
Creates the Home.ipynb notebook that allows easy navigation of your project.
- exists() bool
returns True if this Tier object has already been setup (e.g. by self.setup_files)
- file
- folder
- highlights_file
- meta_file
- name
- setup_files(template: Path | None = None, meta=None) None
Create all the files needed for a valid Tier object to exist.
This includes its .ipynb file, its parent folder, its own folder and its Meta file.
Will render .ipynb file as Jinja template engine, passing to the template self with names given by self.short_type and tier.
- Parameters:
template (Path) – path to template file to render to create .ipynb file.
meta (MetaDict) – Initial meta values to create the tier with.
- class cassini.defaults.tiers.HomeGui(tier: T)
- class cassini.defaults.tiers.Sample(*args: str, **kwargs: Dict[str, Any])
Sample Tier.
A Sample is intended to represent some object that you collect data on.
As such, each sample has its own `DataSet`s.
Notes
A Sample id can’t start with a number and can’t contain ‘-’ (dashes), as these confuse the name parser.
- folder
- class cassini.defaults.tiers.SampleGui(tier: T)
- new_child() DOMWidget
Widget for creating new child for this Tier.