LiveImport API
- liveimport.register(namespace: dict[str, Any], importstmts: str, *, package: str = '', clear: bool = False, allow_other_statements: bool = False) None
Register import statements for syncing.
All modules referenced by the import statements must already be loaded and have associated source files, and all names mentioned must already exist in namespace. If an associated source file is later modified, then a sync will reload the corresponding module and update names from the module.
- Parameters:
namespace – The import statement target, usually the caller’s value of
globals().importstmts – Python code consisting of zero or more import statements. The application should have already executed these or equivalent imports.
package – Context for interpreting relative import statements. When given, package is usually the caller’s immediate parent package, accessible as
__spec__.parentif it exists. If no package is specified, relative imports are not allowed. Relative imports are only useful when using LiveImport outside a notebook, since notebook code is not in a package.clear – If and only if true, discard all prior registrations targeting namespace before registering the given import statements.
allow_other_statements – If true, non-import statements are allowed in importstmts and ignored. Otherwise, only import statements are allowed.
- Raises:
SyntaxError – importstmts is not syntactically valid.
ImportError – importstmts includes an improper relative import.
ValueError – importstmts includes a non-import statement and allow_other_statements is false, a referenced module is not loaded or has no associated source file, or an included name does not already exist.
ModuleError – The content of a module referenced by an import statement is erroneous.
Example:
liveimport.register(globals(),""" import printmath as pm from simulator import stop as halt from verify import * """)
If
verify.pyis modified, a sync will reloadverifyand create or update bindings in namespace for the same names that executingfrom verify import *would. Similarly, ifsimulator.pyis modified, a sync will reload the module and create or update a binding forhaltwith the value ofstopinsimulator.Using multiline strings to specify multiple import statements, each on its own line as shown above is convenient and easy to read, but statements must have identical indentation.
# Raises a SyntaxError because "import green" has leading whitespace # while "import red" does not. liveimport.register(globals(),"""import red import green""") # This works. liveimport.register(globals(),"""import red import green""") # And so does this. liveimport.register(globals(),""" import red import green""")
Since the statements given are Python code, you can also use semicolons to separate statements.
liveimport.register(globals(),"import red; import green")
Registration is idempotent, multiple registrations are allowed, and overlapping registrations such as
liveimport.register(globals(),"from symcode import x, hermite_poly") liveimport.register(globals(),"from symcode import x, lagrange_poly") liveimport.register(globals(),"from symcode import lagrange_poly as lp") liveimport.register(globals(),"from symcode import *") liveimport.register(globals(),"import symcode")
are perfectly fine.
- liveimport.sync(*, observer: Callable[[ReloadEvent], None] | None = None) None
Bring all registered imports up to date. This includes reloading out-of-date tracked modules and rebinding imported names. A tracked module is out-of-date if either the module has changed since registration or last sync, or the module depends on an out-of-date tracked module.
“Depends on” is a strict partial order LiveImport computes between tracked modules based on the top level import statements in those modules. In most cases, those imports naturally define a strict partial order. If they do not (meaning there is an import cycle), LiveImport ignores the imports by more recently tracked modules that prevent it.
sync()guarantees that reload order is consistent with the “depends on” partial order, so if A depends on B, then B will reload before A.sync()uses source file modification times to determine if a module has changed. Any change triggers a reload, including being reset to an older time. (So reverted modules reload.)- Parameters:
observer – If given,
sync()calls observer with aReloadEventdescribing each successful reload.- Raises:
ModuleError – The content of a tracked module is erronous or raised an exception when executed during a reload.
Note
Unless automatic syncing is disabled, calling
sync()in a notebook should not be necessary.
- liveimport.workspace(*directories: str | PathLike) None
Define the workspace, a set of directories.
LiveImport tracks modules that either are imported by a registered import statement, or are imported by a tracked module and have a source file in the workspace. A source file is in the workspace if and only if it’s under a workspace directory.
The default workspace is the current working directory when the LiveImport module is imported. Thus, when LiveImport is used in a notebook, the workspace is the directory containing the notebook.
- Parameters:
directories – Zero or more path strings or path-like objects. Each path must identify an existing directory.
- Raises:
ValueError – One of the specified paths does not exist or exists but is not a directory.
Example: After calling
liveimport.workspace("src", "/opt/notebook-utils")
the workspace is the directory
srcin the current working directory and the directory/opt/notebook-utils.If you call
liveimport.workspace() # No paths given
the workspace is empty, so only modules referenced by registered imports will be tracked.
Note
Changing the workspace does not alter tracking decisions LiveImport has already made. It only affects future decisions. If you want a non-default workspace, its best to change it before registering any imports.
Configure hidden cell magic.
- Parameters:
enabled – Notebook cells that begin with
#_%%liveimportrun as if they began with%%livemagicif and only if enabled is true. This makes LiveImport cell magic transparent to IDEs like Visual Studio Code, yet still function as desired. Hidden cell magic is enabled by default.
- liveimport.auto_sync(enabled: bool | None = None, *, grace: float | None = None, report: bool | None = None) None
Configure automatic sync behavior. By default, automatic syncing is enabled with a grace period of 1.0 seconds and reloads are reported.
- Parameters:
enabled – LiveImport syncs whenever a notebook cell runs if and only if enabled is true and a grace period since the end of the last cell execution has expired.
grace – The minimum time in seconds that must pass between the end of one cell execution and the beginning of the another before LiveImport will sync. The grace period inhibits syncing between cell executions during a multi-cell run, such as running the entire notebook.
report – Use Markdown console blocks to report when modules are reloaded by automatic syncing.
- class liveimport.ReloadEvent(module: str, reason: str, mtime: float, after: list[str])
Describes a successful reload. Attributes:
- mtime: float
The modification time of the module source file last seen by LiveImport. If reason is
"modified", this time changed since LiveImport began tracking or last reloaded module.
- after: list[str]
Modules on which module depends which LiveImport has already reloaded as part of the same sync. If reason is
"dependent", LiveImport reloaded module solely because it reloaded these modules.
The string representation of a
ReloadEventis an English-language description similar toReloaded printmath modified 18 seconds agoor
Reloaded simulator because printmath reloaded
- exception liveimport.ModuleError(module: str, phase: str)
LiveImport has determined there is an issue with the content of a module.
- phase: str
Phase of processing during which LiveImport detected the erroneous condition, currently either
"analysis"or"reload".
- __cause__: BaseException
The issue LiveImport encountered. This could be a source error, such as a
SyntaxError, or an exception raised while the module is executing during a reload.