-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
e97baac
commit fb2979e
Showing
14 changed files
with
294 additions
and
106 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,36 @@ | ||
# igogo | ||
# igogo 🐎🏎️ | ||
|
||
--- | ||
|
||
Execute several jupyter cells at the same time | ||
|
||
> Have you ever just sited and watched a long-running jupyter cell? | ||
> **Now, you can continue to work in the same notebook freely** | ||
## Wait, isn't it just a background job? No. | ||
|
||
- No multithreading, no data races, no locks. | ||
You can freely operate with your notebook variables without the risk of corrupting them. | ||
- Beautiful output. When several cells execute in parallel, | ||
all printed data is displayed in corresponding cell's output. No more twisted and messed out concurrent outputs. | ||
- Easily cancel jobs, wait for completion, and start the new ones. | ||
|
||
## Use cases | ||
1) You have a long-running cell, and you need to check something. | ||
You can just start the second cell without interrupting a long-running cell. | ||
> **Example:** you run a machine learning train loop and want to immediately save model's weights or check metrics. | ||
> With `igogo` you can do so without interrupting the training. | ||
2) If you need to compare score of some function with different parameters, you can run several | ||
functions at the same time and monitor results. | ||
> **Example:** you have several sets of hyperparameters and want to compare them. | ||
> You can start training two models, monitoring two loss graphs at the same time. | ||
## Install | ||
|
||
Igogo is available through PyPi: | ||
|
||
```bash | ||
pip install igogo | ||
``` | ||
|
||
## Usage |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,26 +1,35 @@ | ||
from .output import OutputStream | ||
from typing import List | ||
import asyncio | ||
import contextvars | ||
|
||
from .output import OutputStreamsSetter, OutputObject | ||
from .exceptions import IgogoInvalidContext | ||
|
||
|
||
class IgogoContext(object): | ||
out_stream: OutputStream | ||
out_stream: OutputStreamsSetter | ||
task: asyncio.Task | ||
additional_outputs: List[OutputObject] | ||
|
||
def __init__(self, task: asyncio.Task, out_stream: OutputStream): | ||
def __init__(self, task: asyncio.Task, out_stream: OutputStreamsSetter, additional_outputs: List[OutputObject]): | ||
self.out_stream = out_stream | ||
self.task = task | ||
self.additional_outputs = additional_outputs | ||
|
||
|
||
_context: contextvars.ContextVar[IgogoContext | None] = contextvars.ContextVar("igogo_context", default=None) | ||
|
||
|
||
def get_context_or_none() -> IgogoContext: | ||
return _context.get() | ||
|
||
|
||
def get_context_or_fail() -> IgogoContext: | ||
value = _context.get() | ||
value = get_context_or_none() | ||
if value is None: | ||
raise IgogoInvalidContext() | ||
return value | ||
|
||
|
||
def set_context(context: IgogoContext): | ||
_context.set(context) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,17 @@ | ||
import io | ||
class IgogoInvalidContext(Exception): | ||
... | ||
def __init__(self): | ||
from .core import _log_error | ||
file = io.StringIO() | ||
_log_error('Igogo command invoked from invalid context', file=file) | ||
super().__init__(file.getvalue()) | ||
file.close() | ||
|
||
|
||
class IgogoAdditionalOutputsExhausted(Exception): | ||
def __init__(self): | ||
from .core import _log_error | ||
file = io.StringIO() | ||
_log_error('Igogo invoked display function, but cell has not enough display capabilities', file=file) | ||
super().__init__(file.getvalue()) | ||
file.close() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,24 @@ | ||
import IPython | ||
from IPython.core.magic import (Magics, magics_class, cell_magic) | ||
from .output import Output | ||
|
||
@magics_class | ||
class IgogoMagic(Magics): | ||
@cell_magic | ||
def igogo(self, line, cell): | ||
ip = IPython.get_ipython() | ||
args: dict = eval(f"dict({line})") | ||
args.setdefault('update_globals', False) | ||
update_globals = args['update_globals'] | ||
args.pop('update_globals') | ||
prefix = "def __igogo_magic_wrapper():\n" \ | ||
" import igogo\n" \ | ||
f" @igogo.job(**dict({line}))\n" \ | ||
" async def execute():\n" | ||
f" @igogo.job(**dict({args}))\n" \ | ||
" async def execute():\n"\ | ||
" global " + ', '.join(list(IPython.get_ipython().user_ns.keys())) + '\n' | ||
cell = prefix + '\n'.join([' ' + line for line in cell.split('\n')]) | ||
cell += "\n" \ | ||
cell += "\n" + \ | ||
(" globals().update(locals())\n" if update_globals else "") + \ | ||
" return execute()\n" \ | ||
"__igogo_magic_wrapper()" | ||
ip.ex(cell) | ||
ip.run_cell(cell, silent=True) | ||
|
Oops, something went wrong.