Skip to content

dry #53

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 12, 2025
Merged

dry #53

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"image": "mcr.microsoft.com/devcontainers/universal:2",
"containerEnv": {
},
"hostRequirements": {
"cpus": 2
},
"waitFor": "onCreateCommand",
"updateContentCommand": "pip install -e ",
"postCreateCommand": "",
"postStartCommand": "git reset --hard && git clean -fd",
"customizations": {
"codespaces": {
"openFiles": [
"notebooks/demo.ipynb"
]
},
"vscode": {
"extensions": [
"ms-toolsai.jupyter",
"ms-python.python"
]
}
}
}
150 changes: 150 additions & 0 deletions notebooks/demo.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# PyStackQL Development Demo\n",
"\n",
"This notebook demonstrates how to use the development version of PyStackQL directly from the source code. Any changes you make to the PyStackQL code will be immediately reflected here."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# First, let's check what version of PyStackQL we're using\n",
"import pystackql\n",
"print(f\"PyStackQL Version: {pystackql.__version__}\")\n",
"\n",
"# Check the location of the package to confirm we're using the development version\n",
"print(f\"Package Location: {pystackql.__file__}\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Load the magic extension\n",
"%load_ext pystackql.magic"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Basic Query Test\n",
"\n",
"Let's run a simple query to test that everything is working:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%stackql SELECT 42 as answer"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## CSV Download Test\n",
"\n",
"Let's test the CSV download functionality:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%%stackql --csv-download\n",
"SELECT \n",
" 'Python' as language,\n",
" 'Development' as mode,\n",
" 'PyStackQL' as package"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Test Cloud Provider Functionality\n",
"\n",
"If you have credentials configured, you can test actual cloud provider queries:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Uncomment and run the appropriate provider query based on your available credentials\n",
"\n",
"# AWS Example\n",
"# %stackql DESCRIBE aws.ec2.instances\n",
"\n",
"# GitHub Example\n",
"# %stackql registry pull github\n",
"# %stackql SELECT login FROM github.users.followers WHERE username = 'stackql'"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Development Tips\n",
"\n",
"1. After modifying PyStackQL code, you don't need to reinstall the package - changes are reflected immediately\n",
"2. You can run tests from the terminal with `pytest tests/`\n",
"3. If you modify deep core functionality, you may need to restart the kernel\n",
"4. To debug issues, you can use Python's built-in debugging tools:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Example debugging a PyStackQL function\n",
"from pystackql.core import StackQL\n",
"\n",
"# Get instance properties\n",
"stackql = StackQL()\n",
"props = stackql.properties()\n",
"print(props)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python (PyStackQL Dev)",
"language": "python",
"name": "pystackql-dev"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.4"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
44 changes: 43 additions & 1 deletion pystackql/magic_ext/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,46 @@ def run_query(self, query):
if query.strip().lower().startswith("registry pull"):
return self.stackql_instance.executeStmt(query)

return self.stackql_instance.execute(query)
return self.stackql_instance.execute(query)

def _display_with_csv_download(self, df):
"""Display DataFrame with CSV download link.

:param df: The DataFrame to display and make downloadable.
"""
import IPython.display

try:
# Generate CSV data
import io
import base64
csv_buffer = io.StringIO()
df.to_csv(csv_buffer, index=False)
csv_data = csv_buffer.getvalue()

# Encode to base64 for data URI
csv_base64 = base64.b64encode(csv_data.encode()).decode()

# Create download link
download_link = f'data:text/csv;base64,{csv_base64}'

# Display the DataFrame first
IPython.display.display(df)

# Create and display the download button
download_html = f'''
<div style="margin-top: 10px;">
<a href="{download_link}" download="stackql_results.csv"
style="display: inline-block; padding: 8px 16px; background-color: #007cba;
color: white; text-decoration: none; border-radius: 4px;
font-family: Arial, sans-serif; font-size: 14px; border: none; cursor: pointer;">
📥 Download CSV
</a>
</div>
'''
IPython.display.display(IPython.display.HTML(download_html))

except Exception as e:
# If CSV generation fails, just display the DataFrame normally
IPython.display.display(df)
print(f"Error generating CSV download: {e}")
47 changes: 1 addition & 46 deletions pystackql/magic_ext/local.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,8 @@
"""

from IPython.core.magic import (magics_class, line_cell_magic)
from IPython.display import display, HTML
from .base import BaseStackqlMagic
import argparse
import base64
import io

@magics_class
class StackqlMagic(BaseStackqlMagic):
Expand Down Expand Up @@ -62,48 +59,6 @@ def stackql(self, line, cell=None):
elif not is_cell_magic:
return results

def _display_with_csv_download(self, df):
"""Display DataFrame with CSV download link.

:param df: The DataFrame to display and make downloadable.
"""
import IPython.display

try:
# Generate CSV data
import io
import base64
csv_buffer = io.StringIO()
df.to_csv(csv_buffer, index=False)
csv_data = csv_buffer.getvalue()

# Encode to base64 for data URI
csv_base64 = base64.b64encode(csv_data.encode()).decode()

# Create download link
download_link = f'data:text/csv;base64,{csv_base64}'

# Display the DataFrame first
IPython.display.display(df)

# Create and display the download button
download_html = f'''
<div style="margin-top: 10px;">
<a href="{download_link}" download="stackql_results.csv"
style="display: inline-block; padding: 8px 16px; background-color: #007cba;
color: white; text-decoration: none; border-radius: 4px;
font-family: Arial, sans-serif; font-size: 14px; border: none; cursor: pointer;">
📥 Download CSV
</a>
</div>
'''
IPython.display.display(IPython.display.HTML(download_html))

except Exception as e:
# If CSV generation fails, just display the DataFrame normally
IPython.display.display(df)
print(f"Error generating CSV download: {e}")

def load_ipython_extension(ipython):
"""Load the non-server magic in IPython.

Expand All @@ -114,4 +69,4 @@ def load_ipython_extension(ipython):
"""
# Create an instance of the magic class and register it
magic_instance = StackqlMagic(ipython)
ipython.register_magics(magic_instance)
ipython.register_magics(magic_instance)
47 changes: 1 addition & 46 deletions pystackql/magic_ext/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,8 @@
"""

from IPython.core.magic import (magics_class, line_cell_magic)
from IPython.display import display, HTML
from .base import BaseStackqlMagic
import argparse
import base64
import io

@magics_class
class StackqlServerMagic(BaseStackqlMagic):
Expand Down Expand Up @@ -64,50 +61,8 @@ def stackql(self, line, cell=None):
else:
return results

def _display_with_csv_download(self, df):
"""Display DataFrame with CSV download link.

:param df: The DataFrame to display and make downloadable.
"""
import IPython.display

try:
# Generate CSV data
import io
import base64
csv_buffer = io.StringIO()
df.to_csv(csv_buffer, index=False)
csv_data = csv_buffer.getvalue()

# Encode to base64 for data URI
csv_base64 = base64.b64encode(csv_data.encode()).decode()

# Create download link
download_link = f'data:text/csv;base64,{csv_base64}'

# Display the DataFrame first
IPython.display.display(df)

# Create and display the download button
download_html = f'''
<div style="margin-top: 10px;">
<a href="{download_link}" download="stackql_results.csv"
style="display: inline-block; padding: 8px 16px; background-color: #007cba;
color: white; text-decoration: none; border-radius: 4px;
font-family: Arial, sans-serif; font-size: 14px; border: none; cursor: pointer;">
📥 Download CSV
</a>
</div>
'''
IPython.display.display(IPython.display.HTML(download_html))

except Exception as e:
# If CSV generation fails, just display the DataFrame normally
IPython.display.display(df)
print(f"Error generating CSV download: {e}")

def load_ipython_extension(ipython):
"""Load the server magic in IPython."""
# Create an instance of the magic class and register it
magic_instance = StackqlServerMagic(ipython)
ipython.register_magics(magic_instance)
ipython.register_magics(magic_instance)