Skip to content

Commit 1821922

Browse files
authored
Merge pull request #57 from stackql/feature/refactor
v3.8.0
2 parents 895c586 + a8ccf8a commit 1821922

File tree

8 files changed

+237
-238
lines changed

8 files changed

+237
-238
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
# Changelog
22

3-
## v3.8.0 (2025-06-04)
3+
## v3.8.0 (2025-06-13)
44

55
### Updates
66

7+
- Added `--csv-download` argument for stackql magic commands
78
- Refactor
89
- Enhanced test coverage
910

README.rst

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ PyStackQL - Python Wrapper for StackQL
2222
StackQL is an open source developer tool which allows you to query and interact with cloud and SaaS provider APIs using SQL grammar.
2323
StackQL can be used for cloud inventory analysis, cloud cost optimization, cloud security and compliance, provisioning/IaC, assurance, XOps, and more.
2424

25-
PyStackQL is a Python wrapper for StackQL which allows you to use StackQL within Python applications and to use the power of Python to extend StackQL.
25+
`PyStackQL <https://pypi.org/project/pystackql/>`_ is a Python wrapper for StackQL which allows you to use StackQL within Python applications and to use the power of Python to extend StackQL.
2626
PyStackQL can be used with ``pandas``, ``matplotlib``, ``plotly``, ``jupyter`` and other Python libraries to create powerful data analysis and visualization applications.
2727

2828
For detailed documentation, including the API reference, see `Read the Docs <https://pystackql.readthedocs.io>`_.
@@ -52,19 +52,17 @@ The following example demonstrates how to run a query and return the results as
5252
::
5353

5454
from pystackql import StackQL
55-
import pandas as pd
5655
region = "ap-southeast-2"
57-
stackql = StackQL()
56+
stackql = StackQL(output='pandas')
5857
5958
query = """
60-
SELECT instanceType, COUNT(*) as num_instances
59+
SELECT instance_type, COUNT(*) as num_instances
6160
FROM aws.ec2.instances
6261
WHERE region = '%s'
63-
GROUP BY instanceType
62+
GROUP BY instance_type
6463
""" % (region)
6564
66-
res = stackql.execute(query)
67-
df = pd.read_json(res)
65+
df = stackql.execute(query)
6866
print(df)
6967

7068
Using PyStackQL with Jupyter Notebook
@@ -76,7 +74,7 @@ To use the integrated Jupyter magic commands provided by PyStackQL:
7674

7775
.. code-block:: python
7876
79-
%load_ext pystackql
77+
%load_ext pystackql.magic
8078
8179
2. **Execute a Query Using Line Magic**:
8280

@@ -111,12 +109,11 @@ Supported Python Versions
111109

112110
PyStackQL has been tested on:
113111

114-
- Python 3.7
115-
- Python 3.8
116112
- Python 3.9
117113
- Python 3.10
118114
- Python 3.11
119-
- Python 3.12 (MacOS and Linux only)
115+
- Python 3.12
116+
- Python 3.13
120117

121118
Licensing
122119
~~~~~~~~~

docs/source/conf.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,13 @@
2020
# -- Project information -----------------------------------------------------
2121

2222
project = 'pystackql'
23-
copyright = '2021-2024, StackQL Studios'
23+
copyright = '2021-2025, StackQL Studios'
2424
author = 'StackQL Studios'
2525

2626
# The short X.Y version
2727
version = ''
2828
# The full version, including alpha/beta/rc tags
29-
release = 'v3.6.6'
29+
release = 'v3.8.0'
3030

3131

3232
# -- General configuration ---------------------------------------------------

docs/source/examples.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,10 @@ StackQL can be used to collect, analyze, summarize, and report on cloud resource
4949
regions = ["ap-southeast-2", "us-east-1"]
5050
queries = [
5151
f"""
52-
SELECT '{region}' as region, instanceType, COUNT(*) as num_instances
52+
SELECT '{region}' as region, instance_type, COUNT(*) as num_instances
5353
FROM aws.ec2.instances
5454
WHERE region = '{region}'
55-
GROUP BY instanceType
55+
GROUP BY instance_type
5656
"""
5757
for region in regions
5858
]

docs/source/intro.rst

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -71,19 +71,17 @@ The following example demonstrates how to run a query and return the results as
7171
.. code-block:: python
7272
7373
from pystackql import StackQL
74-
import pandas as pd
7574
region = "ap-southeast-2"
76-
stackql = StackQL()
75+
stackql = StackQL(output='pandas')
7776
7877
query = """
79-
SELECT instanceType, COUNT(*) as num_instances
78+
SELECT instance_type, COUNT(*) as num_instances
8079
FROM aws.ec2.instances
8180
WHERE region = '%s'
82-
GROUP BY instanceType
81+
GROUP BY instance_type
8382
""" % (region)
8483
85-
res = stackql.execute(query)
86-
df = pd.read_json(res)
84+
df = stackql.execute(query)
8785
print(df)
8886
8987
Using ``UNION`` and ``JOIN`` operators
@@ -96,26 +94,25 @@ StackQL is a fully functional SQL programming environment, enabling the full set
9694
...
9795
regions = ["ap-southeast-2", "us-east-1"]
9896
query = """
99-
SELECT '%s' as region, instanceType, COUNT(*) as num_instances
97+
SELECT '%s' as region, instance_type, COUNT(*) as num_instances
10098
FROM aws.ec2.instances
10199
WHERE region = '%s'
102-
GROUP BY instanceType
100+
GROUP BY instance_type
103101
UNION
104-
SELECT '%s' as region, instanceType, COUNT(*) as num_instances
102+
SELECT '%s' as region, instance_type, COUNT(*) as num_instances
105103
FROM aws.ec2.instances
106104
WHERE region = '%s'
107-
GROUP BY instanceType
105+
GROUP BY instance_type
108106
""" % (regions[0], regions[0], regions[1], regions[1])
109107
110-
res = stackql.execute(query)
111-
df = pd.read_json(res)
108+
df = stackql.execute(query)
112109
print(df)
113110
114111
The preceding example will print a ``pandas.DataFrame`` which would look like this:
115112

116113
.. code-block:: sh
117114
118-
instanceType num_instances region
115+
instance_type num_instances region
119116
0 t2.medium 2 ap-southeast-2
120117
1 t2.micro 7 ap-southeast-2
121118
2 t2.small 4 ap-southeast-2
@@ -133,17 +130,15 @@ In addition to ``UNION`` DML operators, you can also run a batch (list) of queri
133130
134131
queries = [
135132
f"""
136-
SELECT '{region}' as region, instanceType, COUNT(*) as num_instances
133+
SELECT '{region}' as region, instance_type, COUNT(*) as num_instances
137134
FROM aws.ec2.instances
138135
WHERE region = '{region}'
139-
GROUP BY instanceType
136+
GROUP BY instance_type
140137
"""
141138
for region in regions
142139
]
143140
144-
res = stackql.executeQueriesAsync(queries)
145-
df = pd.read_json(json.dumps(res))
146-
141+
df = stackql.executeQueriesAsync(queries)
147142
print(df)
148143
149144
@@ -156,10 +151,9 @@ Here is an example of using the ``json_extract`` function to extract a field fro
156151
.. code-block:: python
157152
158153
from pystackql import StackQL
159-
import pandas as pd
160154
subscriptionId = "273769f6-545f-45b2-8ab8-2f14ec5768dc"
161155
resourceGroupName = "stackql-ops-cicd-dev-01"
162-
stackql = StackQL()
156+
stackql = StackQL() # output format defaults to 'dict'
163157
164158
query = """
165159
SELECT name,
@@ -172,8 +166,7 @@ Here is an example of using the ``json_extract`` function to extract a field fro
172166
""" % (resourceGroupName, subscriptionId)
173167
174168
res = stackql.execute(query)
175-
df = pd.read_json(res)
176-
print(df)
169+
print(res)
177170
178171
Using the Jupyter Magic Extension
179172
=================================
@@ -184,7 +177,7 @@ To get started with the magic extension, first load it into your Jupyter environ
184177

185178
.. code-block:: ipython
186179
187-
%load_ext pystackql
180+
%load_ext pystackql.magic
188181
189182
After loading the magic extension, you can use the `%%stackql` magic to execute StackQL commands in a dedicated Jupyter cell. The output will be displayed directly below the cell, just like any other Jupyter command output.
190183

@@ -196,3 +189,9 @@ Example:
196189
SHOW SERVICES in aws
197190
198191
This Jupyter magic extension provides a seamless integration of `pystackql` into your Jupyter workflows, allowing you to explore cloud and SaaS provider data interactively within your notebooks.
192+
193+
To use the magic extension to run queries against a StackQL server, you can use the following command:
194+
195+
.. code-block:: ipython
196+
197+
%load_ext pystackql.magics

docs/source/magic_ext.rst

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,25 +38,39 @@ The extension provides both line and cell magic functionalities:
3838
.. code-block:: python
3939
4040
%%stackql
41-
SELECT instanceType, COUNT(*) as num_instances
41+
SELECT instance_type, COUNT(*) as num_instances
4242
FROM aws.ec2.instances
43-
WHERE region = '$region' GROUP BY instanceType
43+
WHERE region = '$region' GROUP BY instance_type
4444
4545
Options
4646
-------
4747

4848
When using `StackqlMagic` as cell magic, you can pass in the following options:
4949

5050
- ``--no-display`` : Suppresses the display of the results. Even when this option is enabled, the results are still saved in the `stackql_df` Pandas DataFrame.
51+
- ``--csv-download`` : Adds a download button below the query results that allows you to download the data as a CSV file.
5152

52-
Example:
53+
Examples
54+
--------
55+
56+
Basic Query
57+
~~~~~~~~~~
5358

5459
.. code-block:: python
5560
5661
project = 'stackql-demo'
5762
zone = 'australia-southeast1-a'
5863
region = 'australia-southeast1'
5964
65+
%%stackql
66+
SELECT SPLIT_PART(machineType, '/', -1) as machine_type, count(*) as num_instances
67+
FROM google.compute.instances
68+
WHERE project = '$project' AND zone = '$zone'
69+
GROUP BY machine_type
70+
71+
Suppressing Display
72+
~~~~~~~~~~~~~~~~~~
73+
6074
.. code-block:: python
6175
6276
%%stackql --no-display
@@ -67,6 +81,38 @@ Example:
6781
6882
This will run the query but won't display the results in the notebook. Instead, you can later access the results via the `stackql_df` variable.
6983

84+
Downloading Results as CSV
85+
~~~~~~~~~~~~~~~~~~~~~~~~~
86+
87+
.. code-block:: python
88+
89+
%%stackql --csv-download
90+
SELECT
91+
'Python' as language,
92+
'Development' as mode,
93+
'PyStackQL' as package
94+
95+
This will display the query results in the notebook and add a download button below the results. Clicking the button will download the data as a CSV file named ``stackql_results.csv``.
96+
97+
Combining Options
98+
~~~~~~~~~~~~~~~
99+
100+
You can also combine options. For example, if you want to suppress the display but still want a download button:
101+
102+
.. code-block:: python
103+
104+
# First run the query with no display
105+
%%stackql --no-display
106+
SELECT instance_type, COUNT(*) as num_instances
107+
FROM aws.ec2.instances
108+
WHERE region = '$region' GROUP BY instance_type
109+
110+
# Then manually display with the download button
111+
from IPython.display import display
112+
display(stackql_df)
113+
from pystackql import StackqlMagic
114+
StackqlMagic(get_ipython())._display_with_csv_download(stackql_df)
115+
70116
.. note::
71117

72118
The results of the queries are always saved in a Pandas DataFrame named `stackql_df` in the notebook's current namespace. This allows you to further process or visualize the data as needed.
@@ -75,8 +121,8 @@ An example of visualizing the results using Pandas is shown below:
75121

76122
.. code-block:: python
77123
78-
stackql_df.plot(kind='pie', y='num_instances', labels=_['machine_type'], title='Instances by Type', autopct='%1.1f%%')
124+
stackql_df.plot(kind='pie', y='num_instances', labels=stackql_df['machine_type'], title='Instances by Type', autopct='%1.1f%%')
79125
80126
--------
81127

82-
This documentation provides a basic overview and usage guide for the `StackqlMagic` extension. For advanced usage or any additional features provided by the extension, refer to the source code or any other accompanying documentation.
128+
This documentation provides a basic overview and usage guide for the `StackqlMagic` extension. For advanced usage or any additional features provided by the extension, refer to the source code or any other accompanying documentation.

0 commit comments

Comments
 (0)