Skip to content

Commit 2f899e2

Browse files
feat(magic): add run_personal and run_shared magic commands
1 parent 1b6131a commit 2f899e2

File tree

4 files changed

+169
-0
lines changed

4 files changed

+169
-0
lines changed

run_personal/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
from run_personal.magic import load_ipython_extension
2+
3+
4+
__all__ = ['load_ipython_extension']

run_personal/magic.py

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import os
2+
import time
3+
from typing import Any
4+
5+
from IPython.core.interactiveshell import InteractiveShell
6+
from IPython.core.magic import line_magic
7+
from IPython.core.magic import Magics
8+
from IPython.core.magic import magics_class
9+
from IPython.core.magic import needs_local_scope
10+
from IPython.core.magic import no_var_expand
11+
12+
13+
@magics_class
14+
class RunPersonalMagic(Magics):
15+
def __init__(self, shell: InteractiveShell):
16+
Magics.__init__(self, shell=shell)
17+
18+
@no_var_expand
19+
@needs_local_scope
20+
@line_magic('run_personal')
21+
def run_personal(self, line: str, local_ns: Any = None) -> Any:
22+
"""
23+
Downloads a personal file using the %sql magic and then runs it using %run.
24+
25+
Examples::
26+
27+
# Line usage
28+
29+
%run_personal personal_file.ipynb
30+
31+
"""
32+
personal_file = line.strip()
33+
if not personal_file:
34+
raise ValueError('No personal file specified.')
35+
if personal_file.startswith("'") and personal_file.endswith("'"):
36+
personal_file = personal_file[1:-1]
37+
if not personal_file:
38+
raise ValueError('No personal file specified.')
39+
40+
local_filename = (
41+
f'{int(time.time() * 1_000_000)}_{personal_file}'.replace(' ', '_')
42+
)
43+
sql_command = f"DOWNLOAD PERSONAL FILE '{personal_file}' TO '{local_filename}'"
44+
45+
# Execute the SQL command
46+
self.shell.run_line_magic('sql', sql_command)
47+
# Run the downloaded file
48+
self.shell.run_line_magic('run', local_filename)
49+
50+
# Delete the local file after running it
51+
if os.path.exists(local_filename):
52+
os.remove(local_filename)
53+
54+
55+
# In order to actually use these magics, you must register them with a
56+
# running IPython.
57+
58+
59+
def load_ipython_extension(ip: InteractiveShell) -> None:
60+
"""
61+
Any module file that define a function named `load_ipython_extension`
62+
can be loaded via `%load_ext module.path` or be configured to be
63+
autoloaded by IPython at startup time.
64+
"""
65+
66+
# Load jupysql extension
67+
# This is necessary for jupysql to initialize internal state
68+
# required to render messages
69+
assert ip.extension_manager is not None
70+
result = ip.extension_manager.load_extension('sql')
71+
if result == 'no load function':
72+
raise RuntimeError('Could not load sql extension. Is jupysql installed?')
73+
74+
# Check if %run magic command is defined
75+
if ip.find_line_magic('run') is None:
76+
raise RuntimeError(
77+
'%run magic command is not defined. '
78+
'Is it available in your IPython environment?',
79+
)
80+
81+
# Register run_personal and run_shared
82+
ip.register_magics(RunPersonalMagic(ip))

run_shared/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
from run_shared.magic import load_ipython_extension
2+
3+
4+
__all__ = ['load_ipython_extension']

run_shared/magic.py

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import os
2+
import time
3+
from typing import Any
4+
5+
from IPython.core.interactiveshell import InteractiveShell
6+
from IPython.core.magic import line_magic
7+
from IPython.core.magic import Magics
8+
from IPython.core.magic import magics_class
9+
from IPython.core.magic import needs_local_scope
10+
from IPython.core.magic import no_var_expand
11+
12+
13+
@magics_class
14+
class RunSharedMagic(Magics):
15+
def __init__(self, shell: InteractiveShell):
16+
Magics.__init__(self, shell=shell)
17+
18+
@no_var_expand
19+
@needs_local_scope
20+
@line_magic('run_shared')
21+
def run_shared(self, line: str, local_ns: Any = None) -> Any:
22+
"""
23+
Downloads a shared file using the %sql magic and then runs it using %run.
24+
25+
Examples::
26+
27+
# Line usage
28+
29+
%run_shared shared_file.ipynb
30+
31+
"""
32+
shared_file = line.strip()
33+
if not shared_file:
34+
raise ValueError('No shared file specified.')
35+
if shared_file.startswith("'") and shared_file.endswith("'"):
36+
shared_file = shared_file[1:-1]
37+
if not shared_file:
38+
raise ValueError('No personal file specified.')
39+
40+
local_filename = f'{int(time.time() * 1_000_000)}_{shared_file}'.replace(' ', '_')
41+
sql_command = f"DOWNLOAD SHARED FILE '{shared_file}' TO '{local_filename}'"
42+
43+
# Execute the SQL command
44+
self.shell.run_line_magic('sql', sql_command)
45+
# Run the downloaded file
46+
self.shell.run_line_magic('run', local_filename)
47+
48+
# Delete the local file after running it
49+
if os.path.exists(local_filename):
50+
os.remove(local_filename)
51+
52+
# In order to actually use these magics, you must register them with a
53+
# running IPython.
54+
55+
56+
def load_ipython_extension(ip: InteractiveShell) -> None:
57+
"""
58+
Any module file that define a function named `load_ipython_extension`
59+
can be loaded via `%load_ext module.path` or be configured to be
60+
autoloaded by IPython at startup time.
61+
"""
62+
63+
# Load jupysql extension
64+
# This is necessary for jupysql to initialize internal state
65+
# required to render messages
66+
assert ip.extension_manager is not None
67+
result = ip.extension_manager.load_extension('sql')
68+
if result == 'no load function':
69+
raise RuntimeError('Could not load sql extension. Is jupysql installed?')
70+
71+
# Check if %run magic command is defined
72+
if ip.find_line_magic('run') is None:
73+
raise RuntimeError(
74+
'%run magic command is not defined. '
75+
'Is it available in your IPython environment?',
76+
)
77+
78+
# Register run_personal and run_shared
79+
ip.register_magics(RunSharedMagic(ip))

0 commit comments

Comments
 (0)