1
+ # # pystackql/magic_ext/local.py
2
+
3
+ # """
4
+ # Local Jupyter magic extension for PyStackQL.
5
+
6
+ # This module provides a Jupyter magic command for running StackQL queries
7
+ # using a local StackQL binary.
8
+ # """
9
+
10
+ # from IPython.core.magic import (magics_class, line_cell_magic)
11
+ # from IPython.display import display, HTML
12
+ # from .base import BaseStackqlMagic
13
+ # import argparse
14
+ # import base64
15
+ # import io
16
+
17
+ # @magics_class
18
+ # class StackqlMagic(BaseStackqlMagic):
19
+ # """Jupyter magic command for running StackQL queries in local mode."""
20
+
21
+ # def __init__(self, shell):
22
+ # """Initialize the StackqlMagic class.
23
+
24
+ # :param shell: The IPython shell instance.
25
+ # """
26
+ # super().__init__(shell, server_mode=False)
27
+
28
+ # @line_cell_magic
29
+ # def stackql(self, line, cell=None):
30
+ # """A Jupyter magic command to run StackQL queries.
31
+
32
+ # Can be used as both line and cell magic:
33
+ # - As a line magic: `%stackql QUERY`
34
+ # - As a cell magic: `%%stackql [OPTIONS]` followed by the QUERY in the next line.
35
+
36
+ # :param line: The arguments and/or StackQL query when used as line magic.
37
+ # :param cell: The StackQL query when used as cell magic.
38
+ # :return: StackQL query results as a named Pandas DataFrame (`stackql_df`).
39
+ # """
40
+ # is_cell_magic = cell is not None
41
+
42
+ # if is_cell_magic:
43
+ # parser = argparse.ArgumentParser()
44
+ # parser.add_argument("--no-display", action="store_true", help="Suppress result display.")
45
+ # parser.add_argument("--csv-download", action="store_true", help="Add CSV download link to output.")
46
+ # args = parser.parse_args(line.split())
47
+ # query_to_run = self.get_rendered_query(cell)
48
+ # else:
49
+ # args = None
50
+ # query_to_run = self.get_rendered_query(line)
51
+
52
+ # results = self.run_query(query_to_run)
53
+ # self.shell.user_ns['stackql_df'] = results
54
+
55
+ # if is_cell_magic and args and args.no_display:
56
+ # return None
57
+ # elif is_cell_magic and args and args.csv_download and not args.no_display:
58
+ # self._display_with_csv_download(results)
59
+ # return results
60
+ # elif is_cell_magic and args and not args.no_display:
61
+ # return results
62
+ # elif not is_cell_magic:
63
+ # return results
64
+
65
+ # def _display_with_csv_download(self, df):
66
+ # """Display DataFrame with CSV download link.
67
+
68
+ # :param df: The DataFrame to display and make downloadable.
69
+ # """
70
+ # import IPython.display
71
+
72
+ # try:
73
+ # # Generate CSV data
74
+ # import io
75
+ # import base64
76
+ # csv_buffer = io.StringIO()
77
+ # df.to_csv(csv_buffer, index=False)
78
+ # csv_data = csv_buffer.getvalue()
79
+
80
+ # # Encode to base64 for data URI
81
+ # csv_base64 = base64.b64encode(csv_data.encode()).decode()
82
+
83
+ # # Create download link
84
+ # download_link = f'data:text/csv;base64,{csv_base64}'
85
+
86
+ # # Display the DataFrame first
87
+ # IPython.display.display(df)
88
+
89
+ # # Create and display the download button
90
+ # download_html = f'''
91
+ # <div style="margin-top: 10px;">
92
+ # <a href="{download_link}" download="stackql_results.csv"
93
+ # style="display: inline-block; padding: 8px 16px; background-color: #007cba;
94
+ # color: white; text-decoration: none; border-radius: 4px;
95
+ # font-family: Arial, sans-serif; font-size: 14px; border: none; cursor: pointer;">
96
+ # 📥 Download CSV
97
+ # </a>
98
+ # </div>
99
+ # '''
100
+ # IPython.display.display(IPython.display.HTML(download_html))
101
+
102
+ # except Exception as e:
103
+ # # If CSV generation fails, just display the DataFrame normally
104
+ # IPython.display.display(df)
105
+ # print(f"Error generating CSV download: {e}")
106
+
107
+ # def load_ipython_extension(ipython):
108
+ # """Load the non-server magic in IPython.
109
+
110
+ # This is called when running %load_ext pystackql.magic in a notebook.
111
+ # It registers the %stackql and %%stackql magic commands.
112
+
113
+ # :param ipython: The IPython shell instance
114
+ # """
115
+ # # Create an instance of the magic class and register it
116
+ # magic_instance = StackqlMagic(ipython)
117
+ # ipython.register_magics(magic_instance)
118
+
119
+
1
120
# pystackql/magic_ext/local.py
2
121
3
122
"""
8
127
"""
9
128
10
129
from IPython .core .magic import (magics_class , line_cell_magic )
11
- from IPython .display import display , HTML
12
130
from .base import BaseStackqlMagic
13
131
import argparse
14
- import base64
15
- import io
16
132
17
133
@magics_class
18
134
class StackqlMagic (BaseStackqlMagic ):
@@ -62,48 +178,6 @@ def stackql(self, line, cell=None):
62
178
elif not is_cell_magic :
63
179
return results
64
180
65
- def _display_with_csv_download (self , df ):
66
- """Display DataFrame with CSV download link.
67
-
68
- :param df: The DataFrame to display and make downloadable.
69
- """
70
- import IPython .display
71
-
72
- try :
73
- # Generate CSV data
74
- import io
75
- import base64
76
- csv_buffer = io .StringIO ()
77
- df .to_csv (csv_buffer , index = False )
78
- csv_data = csv_buffer .getvalue ()
79
-
80
- # Encode to base64 for data URI
81
- csv_base64 = base64 .b64encode (csv_data .encode ()).decode ()
82
-
83
- # Create download link
84
- download_link = f'data:text/csv;base64,{ csv_base64 } '
85
-
86
- # Display the DataFrame first
87
- IPython .display .display (df )
88
-
89
- # Create and display the download button
90
- download_html = f'''
91
- <div style="margin-top: 10px;">
92
- <a href="{ download_link } " download="stackql_results.csv"
93
- style="display: inline-block; padding: 8px 16px; background-color: #007cba;
94
- color: white; text-decoration: none; border-radius: 4px;
95
- font-family: Arial, sans-serif; font-size: 14px; border: none; cursor: pointer;">
96
- 📥 Download CSV
97
- </a>
98
- </div>
99
- '''
100
- IPython .display .display (IPython .display .HTML (download_html ))
101
-
102
- except Exception as e :
103
- # If CSV generation fails, just display the DataFrame normally
104
- IPython .display .display (df )
105
- print (f"Error generating CSV download: { e } " )
106
-
107
181
def load_ipython_extension (ipython ):
108
182
"""Load the non-server magic in IPython.
109
183
@@ -114,4 +188,4 @@ def load_ipython_extension(ipython):
114
188
"""
115
189
# Create an instance of the magic class and register it
116
190
magic_instance = StackqlMagic (ipython )
117
- ipython .register_magics (magic_instance )
191
+ ipython .register_magics (magic_instance )
0 commit comments