Skip to content

Commit 73cd874

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

File tree

2 files changed

+116
-0
lines changed

2 files changed

+116
-0
lines changed

run_files/__init__.py

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

run_files/magic.py

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import os
2+
import uuid
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+
36+
local_filename = f'{personal_file}_{uuid.uuid4()}'
37+
sql_command = f'DOWNLOAD PERSONAL FILE {personal_file} TO {local_filename}'
38+
39+
# Execute the SQL command
40+
self.shell.run_line_magic('sql', sql_command)
41+
# Run the downloaded file
42+
self.shell.run_line_magic('run', local_filename)
43+
44+
# Delete the local file after running it
45+
if os.path.exists(local_filename):
46+
os.remove(local_filename)
47+
48+
49+
@magics_class
50+
class RunSharedMagic(Magics):
51+
def __init__(self, shell: InteractiveShell):
52+
Magics.__init__(self, shell=shell)
53+
54+
@no_var_expand
55+
@needs_local_scope
56+
@line_magic('run_shared')
57+
def run_shared(self, line: str, local_ns: Any = None) -> Any:
58+
"""
59+
Downloads a shared file using the %sql magic and then runs it using %run.
60+
61+
Examples::
62+
63+
# Line usage
64+
65+
%run_shared shared_file.ipynb
66+
67+
"""
68+
shared_file = line.strip()
69+
if not shared_file:
70+
raise ValueError('No shared file specified.')
71+
72+
local_filename = f'{shared_file}_{uuid.uuid4()}'
73+
sql_command = f'DOWNLOAD SHARED FILE {shared_file} TO {local_filename}'
74+
75+
# Execute the SQL command
76+
self.shell.run_line_magic('sql', sql_command)
77+
# Run the downloaded file
78+
self.shell.run_line_magic('run', local_filename)
79+
80+
# Delete the local file after running it
81+
if os.path.exists(local_filename):
82+
os.remove(local_filename)
83+
84+
# In order to actually use these magics, you must register them with a
85+
# running IPython.
86+
87+
88+
def load_ipython_extension(ip: InteractiveShell) -> None:
89+
"""
90+
Any module file that define a function named `load_ipython_extension`
91+
can be loaded via `%load_ext module.path` or be configured to be
92+
autoloaded by IPython at startup time.
93+
"""
94+
95+
# Load jupysql extension
96+
# This is necessary for jupysql to initialize internal state
97+
# required to render messages
98+
assert ip.extension_manager is not None
99+
result = ip.extension_manager.load_extension('sql')
100+
if result == 'no load function':
101+
raise RuntimeError('Could not load sql extension. Is jupysql installed?')
102+
103+
# Check if %run magic command is defined
104+
if ip.find_line_magic('run') is None:
105+
raise RuntimeError(
106+
'%run magic command is not defined. '
107+
'Is it available in your IPython environment?',
108+
)
109+
110+
# Register run_personal and run_shared
111+
ip.register_magics(RunPersonalMagic(ip))
112+
ip.register_magics(RunSharedMagic(ip))

0 commit comments

Comments
 (0)