duckdb-assistant 0.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- duckdb_assistant-0.0.1/LICENSE +21 -0
- duckdb_assistant-0.0.1/PKG-INFO +144 -0
- duckdb_assistant-0.0.1/README.md +129 -0
- duckdb_assistant-0.0.1/pyproject.toml +22 -0
- duckdb_assistant-0.0.1/setup.cfg +4 -0
- duckdb_assistant-0.0.1/src/duckdb_assistant/__init__.py +1 -0
- duckdb_assistant-0.0.1/src/duckdb_assistant/assistant.py +68 -0
- duckdb_assistant-0.0.1/src/duckdb_assistant/gemini_api.py +38 -0
- duckdb_assistant-0.0.1/src/duckdb_assistant.egg-info/PKG-INFO +144 -0
- duckdb_assistant-0.0.1/src/duckdb_assistant.egg-info/SOURCES.txt +10 -0
- duckdb_assistant-0.0.1/src/duckdb_assistant.egg-info/dependency_links.txt +1 -0
- duckdb_assistant-0.0.1/src/duckdb_assistant.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Sundaresh Sankaran
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: duckdb-assistant
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: A package containing a Python class and associated methods to generate and execute DuckDB queries.
|
|
5
|
+
Author-email: Sundaresh Sankaran <sundaresh.sankaran@gmail.com>
|
|
6
|
+
Project-URL: Homepage, https://github.com/SundareshSankaran/duckdb-assistant
|
|
7
|
+
Project-URL: Issues, https://github.com/SundareshSankaran/duckdb-assistant/issues
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Requires-Python: >=3.10
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Dynamic: license-file
|
|
15
|
+
|
|
16
|
+
# duckdb-assistant: Generate & Execute DuckDB SQL
|
|
17
|
+
|
|
18
|
+
This repository provides a Python class and associated methods to generate and execute DuckDB SQL.
|
|
19
|
+
|
|
20
|
+
[DuckDB](https://duckdb.org) is an open-source, low-footprint, in-process query processing engine which provides access to several data stores and structures like Parquet, CSV, JSON and data located in conventional Relational Database Management Systems (RDBMS). This package uses the [`duckdb`](https://pypi.org/project/duckdb/) Python package along with methods to call a Large Language Model (LLM) from Google Gemini to generate code in a convenient and conversational manner.
|
|
21
|
+
|
|
22
|
+
A wiki of this repo has been generated using DeepWiki and is available here: [](https://deepwiki.com/SundareshSankaran/duckdb-assistant)
|
|
23
|
+
|
|
24
|
+
Refer this [doc](https://github.com/SundareshSankaran/duckdb-assistant/blob/main/docs/VISION.md) for more details on how this project will evolve.
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
## Installation
|
|
28
|
+
1. Clone this repository
|
|
29
|
+
2. To install locally in editable mode, refer [here](https://github.com/SundareshSankaran/duckdb-assistant/blob/main/build/local_install_quick_start.md)
|
|
30
|
+
|
|
31
|
+
Run the following command for a pip installation of the package from PyPi.
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
> [!WARNING]
|
|
35
|
+
> This package is not yet registered on PyPi. The following command shall be valid once it's made available.
|
|
36
|
+
|
|
37
|
+
```shell
|
|
38
|
+
|
|
39
|
+
pip install --upgrade duckdb-assistant
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Usage - quick example
|
|
44
|
+
|
|
45
|
+
To initialise the DuckDBAssistant class:
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
from duckdb_assistant import DuckDBAssistant
|
|
49
|
+
|
|
50
|
+
dda = DuckDBAssistant()
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Then, to generate a query in natural language,
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
duckdb_query = dda.generate("Create an empty customer table.")
|
|
57
|
+
print(duckdb_query)
|
|
58
|
+
```
|
|
59
|
+
**Result:**
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
>>> duckdb_query = dda.generate("Create an empty customer table.")
|
|
63
|
+
>>> print(duckdb_query)
|
|
64
|
+
CREATE TABLE IF NOT EXISTS customer (
|
|
65
|
+
customer_id INTEGER PRIMARY KEY,
|
|
66
|
+
first_name VARCHAR,
|
|
67
|
+
last_name VARCHAR,
|
|
68
|
+
email VARCHAR,
|
|
69
|
+
phone VARCHAR,
|
|
70
|
+
address VARCHAR,
|
|
71
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
72
|
+
);
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Then, you execute the generated query either through a DuckDB connection or through the inbuilt duckdb Python connection object as follows:
|
|
76
|
+
|
|
77
|
+
```python
|
|
78
|
+
dda.dd.execute(duckdb_query)
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
which is another way of running
|
|
83
|
+
|
|
84
|
+
```python
|
|
85
|
+
import duckdb as dd
|
|
86
|
+
dd.execute(duckdb_query)
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Or, you can choose to call the execute and sql methods available with the class that directly call duckdb's execute and sql methods after generation.
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
|
|
93
|
+
dda.execute("Create an empty customer table.")
|
|
94
|
+
|
|
95
|
+
dda.sql("Print Hello World through SQL")
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
**Result:**
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
>>> dda.execute("Create an empty customer table.")
|
|
103
|
+
<_duckdb.DuckDBPyConnection object at 0x10c194af0>
|
|
104
|
+
>>>
|
|
105
|
+
>>> dda.sql("Print Hello World through SQL")
|
|
106
|
+
┌───────────────┐
|
|
107
|
+
│ 'Hello World' │
|
|
108
|
+
│ varchar │
|
|
109
|
+
├───────────────┤
|
|
110
|
+
│ Hello World │
|
|
111
|
+
└───────────────┘
|
|
112
|
+
|
|
113
|
+
>>>
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Documentation
|
|
117
|
+
Refer this [page](https://github.com/SundareshSankaran/duckdb-assistant/tree/main/docs/DOCUMENTATION.md) for a list of all available methods and attributes.
|
|
118
|
+
|
|
119
|
+
## Generative AI usage
|
|
120
|
+
Core functions (described in [Documentation](https://github.com/SundareshSankaran/duckdb-assistant/tree/main/docs/DOCUMENTATION.md)) use Large Language Models (LLM, starting with Gemini 3.6 Flash) from the Google Gemini family. While you are free to modify the code to accommodate other LLMs, these are at present the only LLMs supported. Read this important note regarding functions that make use of Generative AI.
|
|
121
|
+
|
|
122
|
+
**IMPORTANT**: All outputs returned from Generative AI tools such as LLMs should be carefully reviewed prior to actual use. Quality of Generative AI outputs are determined by the Large Language Model in use and may be incorrect. Always review the same.
|
|
123
|
+
|
|
124
|
+
Add the following environmental variable to a .env file supplying variables to your environment. Get your Gemini API key from [Google AI Studio](https://aistudio.google.com/welcome).
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
GEMINI_API_KEY = <your_key>
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
An example env file ([sample.env](https://github.com/SundareshSankaran/duckdb-assistant/blob/main/sample.env)) is provided for this purpose. Rename this to `.env` and use.
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
## Convenience: tasks.json
|
|
134
|
+
This repository contains a `tasks.json` meant for use in Visual Studio Code which helps clean up temporary files and stands up a virtual environment for quick development and exploration. Remove this file if you do not want to have Visual Studio Code run the tasks in `tasks.json`.
|
|
135
|
+
|
|
136
|
+
## Change Log
|
|
137
|
+
* Version: 0.0.1 (30JUL2026)
|
|
138
|
+
- Initial push to GitHub
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
Refer [`CHANGELOG.md`](https://github.com/SundareshSankaran/duckdb-assistant/blob/main/docs/CHANGELOG.md) for other changes.
|
|
142
|
+
|
|
143
|
+
## Contact
|
|
144
|
+
* [Sundaresh Sankaran](mailto:sundaresh.sankaran@gmail.com)
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# duckdb-assistant: Generate & Execute DuckDB SQL
|
|
2
|
+
|
|
3
|
+
This repository provides a Python class and associated methods to generate and execute DuckDB SQL.
|
|
4
|
+
|
|
5
|
+
[DuckDB](https://duckdb.org) is an open-source, low-footprint, in-process query processing engine which provides access to several data stores and structures like Parquet, CSV, JSON and data located in conventional Relational Database Management Systems (RDBMS). This package uses the [`duckdb`](https://pypi.org/project/duckdb/) Python package along with methods to call a Large Language Model (LLM) from Google Gemini to generate code in a convenient and conversational manner.
|
|
6
|
+
|
|
7
|
+
A wiki of this repo has been generated using DeepWiki and is available here: [](https://deepwiki.com/SundareshSankaran/duckdb-assistant)
|
|
8
|
+
|
|
9
|
+
Refer this [doc](https://github.com/SundareshSankaran/duckdb-assistant/blob/main/docs/VISION.md) for more details on how this project will evolve.
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
1. Clone this repository
|
|
14
|
+
2. To install locally in editable mode, refer [here](https://github.com/SundareshSankaran/duckdb-assistant/blob/main/build/local_install_quick_start.md)
|
|
15
|
+
|
|
16
|
+
Run the following command for a pip installation of the package from PyPi.
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
> [!WARNING]
|
|
20
|
+
> This package is not yet registered on PyPi. The following command shall be valid once it's made available.
|
|
21
|
+
|
|
22
|
+
```shell
|
|
23
|
+
|
|
24
|
+
pip install --upgrade duckdb-assistant
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Usage - quick example
|
|
29
|
+
|
|
30
|
+
To initialise the DuckDBAssistant class:
|
|
31
|
+
|
|
32
|
+
```python
|
|
33
|
+
from duckdb_assistant import DuckDBAssistant
|
|
34
|
+
|
|
35
|
+
dda = DuckDBAssistant()
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Then, to generate a query in natural language,
|
|
39
|
+
|
|
40
|
+
```python
|
|
41
|
+
duckdb_query = dda.generate("Create an empty customer table.")
|
|
42
|
+
print(duckdb_query)
|
|
43
|
+
```
|
|
44
|
+
**Result:**
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
>>> duckdb_query = dda.generate("Create an empty customer table.")
|
|
48
|
+
>>> print(duckdb_query)
|
|
49
|
+
CREATE TABLE IF NOT EXISTS customer (
|
|
50
|
+
customer_id INTEGER PRIMARY KEY,
|
|
51
|
+
first_name VARCHAR,
|
|
52
|
+
last_name VARCHAR,
|
|
53
|
+
email VARCHAR,
|
|
54
|
+
phone VARCHAR,
|
|
55
|
+
address VARCHAR,
|
|
56
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
57
|
+
);
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Then, you execute the generated query either through a DuckDB connection or through the inbuilt duckdb Python connection object as follows:
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
dda.dd.execute(duckdb_query)
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
which is another way of running
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
import duckdb as dd
|
|
71
|
+
dd.execute(duckdb_query)
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Or, you can choose to call the execute and sql methods available with the class that directly call duckdb's execute and sql methods after generation.
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
|
|
78
|
+
dda.execute("Create an empty customer table.")
|
|
79
|
+
|
|
80
|
+
dda.sql("Print Hello World through SQL")
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**Result:**
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
>>> dda.execute("Create an empty customer table.")
|
|
88
|
+
<_duckdb.DuckDBPyConnection object at 0x10c194af0>
|
|
89
|
+
>>>
|
|
90
|
+
>>> dda.sql("Print Hello World through SQL")
|
|
91
|
+
┌───────────────┐
|
|
92
|
+
│ 'Hello World' │
|
|
93
|
+
│ varchar │
|
|
94
|
+
├───────────────┤
|
|
95
|
+
│ Hello World │
|
|
96
|
+
└───────────────┘
|
|
97
|
+
|
|
98
|
+
>>>
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Documentation
|
|
102
|
+
Refer this [page](https://github.com/SundareshSankaran/duckdb-assistant/tree/main/docs/DOCUMENTATION.md) for a list of all available methods and attributes.
|
|
103
|
+
|
|
104
|
+
## Generative AI usage
|
|
105
|
+
Core functions (described in [Documentation](https://github.com/SundareshSankaran/duckdb-assistant/tree/main/docs/DOCUMENTATION.md)) use Large Language Models (LLM, starting with Gemini 3.6 Flash) from the Google Gemini family. While you are free to modify the code to accommodate other LLMs, these are at present the only LLMs supported. Read this important note regarding functions that make use of Generative AI.
|
|
106
|
+
|
|
107
|
+
**IMPORTANT**: All outputs returned from Generative AI tools such as LLMs should be carefully reviewed prior to actual use. Quality of Generative AI outputs are determined by the Large Language Model in use and may be incorrect. Always review the same.
|
|
108
|
+
|
|
109
|
+
Add the following environmental variable to a .env file supplying variables to your environment. Get your Gemini API key from [Google AI Studio](https://aistudio.google.com/welcome).
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
GEMINI_API_KEY = <your_key>
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
An example env file ([sample.env](https://github.com/SundareshSankaran/duckdb-assistant/blob/main/sample.env)) is provided for this purpose. Rename this to `.env` and use.
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
## Convenience: tasks.json
|
|
119
|
+
This repository contains a `tasks.json` meant for use in Visual Studio Code which helps clean up temporary files and stands up a virtual environment for quick development and exploration. Remove this file if you do not want to have Visual Studio Code run the tasks in `tasks.json`.
|
|
120
|
+
|
|
121
|
+
## Change Log
|
|
122
|
+
* Version: 0.0.1 (30JUL2026)
|
|
123
|
+
- Initial push to GitHub
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
Refer [`CHANGELOG.md`](https://github.com/SundareshSankaran/duckdb-assistant/blob/main/docs/CHANGELOG.md) for other changes.
|
|
127
|
+
|
|
128
|
+
## Contact
|
|
129
|
+
* [Sundaresh Sankaran](mailto:sundaresh.sankaran@gmail.com)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "duckdb-assistant"
|
|
7
|
+
version = "0.0.1"
|
|
8
|
+
authors = [
|
|
9
|
+
{ name="Sundaresh Sankaran", email="sundaresh.sankaran@gmail.com" },
|
|
10
|
+
]
|
|
11
|
+
description = "A package containing a Python class and associated methods to generate and execute DuckDB queries."
|
|
12
|
+
readme = "README.md"
|
|
13
|
+
requires-python = ">=3.10"
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Programming Language :: Python :: 3",
|
|
16
|
+
"License :: OSI Approved :: Apache Software License",
|
|
17
|
+
"Operating System :: OS Independent",
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
[project.urls]
|
|
21
|
+
Homepage = "https://github.com/SundareshSankaran/duckdb-assistant"
|
|
22
|
+
Issues = "https://github.com/SundareshSankaran/duckdb-assistant/issues"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from duckdb_assistant.assistant import DuckDBAssistant
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
class DuckDBAssistant:
|
|
2
|
+
"""This initialises a class to help you generate and execute DuckDB queries."""
|
|
3
|
+
def __init__(self, additional_system_prompt: str = None, name: str = None, creationTimeStamp: str = None, createdBy: str = None, dd: duckdb.DuckDBPyConnection = None, initial_sql: str = None) -> object:
|
|
4
|
+
import json
|
|
5
|
+
import duckdb as dd
|
|
6
|
+
|
|
7
|
+
system_prompt = "You are a DuckDB SQL expert. You will be provided with a user request and additionally a database, table or view schema as part of context. Your task is to use this context to generate a DuckDB SQL query. The query should be optimised for the task at hand and should take into account the facts provided in each user prompt's context. At a minimum, your task is to return just the SQL query without additional text or commentary. But if the user asks for the additional informaiton such as a summary, an executive report or simply information, do so."
|
|
8
|
+
if additional_system_prompt:
|
|
9
|
+
system_prompt += f" {additional_system_prompt}"
|
|
10
|
+
|
|
11
|
+
# Initialisation of attributes
|
|
12
|
+
self.id = None
|
|
13
|
+
self.name=None
|
|
14
|
+
self.creationTimeStamp=None
|
|
15
|
+
self.createdBy=None
|
|
16
|
+
self.dd = None
|
|
17
|
+
self.last_query = None
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
# Assign attributes which have been provided
|
|
21
|
+
import uuid
|
|
22
|
+
self.id=uuid.uuid4() if not self.id else self.id
|
|
23
|
+
self.name=name if name else f"Auto_Generated_{self.id}"
|
|
24
|
+
self.creationTimeStamp=creationTimeStamp if creationTimeStamp else self.creationTimeStamp
|
|
25
|
+
self.createdBy=createdBy if createdBy else self.createdBy
|
|
26
|
+
self.system_prompt = system_prompt if system_prompt else self.system_prompt
|
|
27
|
+
self.dd = dd if dd else duckdb.connect()
|
|
28
|
+
|
|
29
|
+
self.dd.execute(initial_sql) if initial_sql else None
|
|
30
|
+
|
|
31
|
+
def __setitem__(self, key, value):
|
|
32
|
+
setattr(self, key, value)
|
|
33
|
+
|
|
34
|
+
def generate(self, prompt:str) -> str:
|
|
35
|
+
"""This function generates a DuckDB SQL query based on a given prompt using Gemini API. Provide the prompt as an argument."""
|
|
36
|
+
from .gemini_api import generate_duckdb_query
|
|
37
|
+
try:
|
|
38
|
+
duckdb_query = generate_duckdb_query(system_prompt = self.system_prompt,user_prompt = f"User prompt: {prompt}")
|
|
39
|
+
self.last_query = {"user_prompt": prompt,"result": duckdb_query}
|
|
40
|
+
return duckdb_query
|
|
41
|
+
except Exception as e:
|
|
42
|
+
return f"Error occurred: {e}"
|
|
43
|
+
|
|
44
|
+
def change_name(self, new_name: str) -> str:
|
|
45
|
+
"""This function changes the name of a DuckDBAssistant. Provide the new name as an argument."""
|
|
46
|
+
try:
|
|
47
|
+
self["name"] = new_name
|
|
48
|
+
return f"Name changed to {new_name}"
|
|
49
|
+
except Exception as e:
|
|
50
|
+
return f"Error occurred: {e}"
|
|
51
|
+
|
|
52
|
+
def execute(self, prompt:str) -> DuckDBPyConnection:
|
|
53
|
+
"""This function executes a DuckDB SQL query based on a given prompt using Gemini API. Provide the prompt as an argument."""
|
|
54
|
+
try:
|
|
55
|
+
duckdb_query = self.generate(prompt)
|
|
56
|
+
result = self.dd.execute(duckdb_query)
|
|
57
|
+
return result
|
|
58
|
+
except Exception as e:
|
|
59
|
+
return f"Error occurred: {e}"
|
|
60
|
+
|
|
61
|
+
def sql(self, prompt:str) -> DuckDBPyRelation:
|
|
62
|
+
"""This function lazily executes a DuckDB SQL query based on a given prompt using Gemini API. Provide the prompt as an argument."""
|
|
63
|
+
try:
|
|
64
|
+
duckdb_query = self.generate(prompt)
|
|
65
|
+
result = self.dd.sql(duckdb_query)
|
|
66
|
+
return result
|
|
67
|
+
except Exception as e:
|
|
68
|
+
return f"Error occurred: {e}"
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
def generate_duckdb_query(system_prompt: str,user_prompt: str) -> str:
|
|
2
|
+
"""This function generates DuckDB SQL based on a given user prompt using the Gemini API."""
|
|
3
|
+
import os
|
|
4
|
+
import json
|
|
5
|
+
import time
|
|
6
|
+
import random
|
|
7
|
+
import re
|
|
8
|
+
from google import genai
|
|
9
|
+
from google.genai import errors
|
|
10
|
+
from dotenv import load_dotenv
|
|
11
|
+
load_dotenv() # Load environment variables from .env file
|
|
12
|
+
|
|
13
|
+
client = genai.Client(api_key=os.environ["GEMINI_API_KEY"])
|
|
14
|
+
|
|
15
|
+
FALLBACK_MODELS = ["gemini-3.6-flash", "gemini-3.5-flash-lite", "gemini-3.5-flash", "gemini-3.1-pro-preview","gemini-3.1-flash-lite", "gemini-2.5-flash"]
|
|
16
|
+
|
|
17
|
+
for model in FALLBACK_MODELS:
|
|
18
|
+
try:
|
|
19
|
+
response = client.models.generate_content(
|
|
20
|
+
model=model,
|
|
21
|
+
contents=system_prompt + "\n\n" + user_prompt
|
|
22
|
+
)
|
|
23
|
+
break
|
|
24
|
+
except Exception as e:
|
|
25
|
+
print(errors)
|
|
26
|
+
print(f"Error with model {model}: {e}")
|
|
27
|
+
time_delay = random.uniform(1, 3) # Random delay between 1 and 3 seconds
|
|
28
|
+
print(f"Retrying with next model after {time_delay:.2f} seconds...")
|
|
29
|
+
time.sleep(time_delay)
|
|
30
|
+
continue
|
|
31
|
+
|
|
32
|
+
duckdb_query = response.text
|
|
33
|
+
pattern = r"```(?:sql)?\s*\n(.*?)\n```"
|
|
34
|
+
m = re.search(pattern, duckdb_query, re.DOTALL | re.IGNORECASE)
|
|
35
|
+
|
|
36
|
+
if m:
|
|
37
|
+
duckdb_query = m.group(1).strip()
|
|
38
|
+
return duckdb_query
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: duckdb-assistant
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: A package containing a Python class and associated methods to generate and execute DuckDB queries.
|
|
5
|
+
Author-email: Sundaresh Sankaran <sundaresh.sankaran@gmail.com>
|
|
6
|
+
Project-URL: Homepage, https://github.com/SundareshSankaran/duckdb-assistant
|
|
7
|
+
Project-URL: Issues, https://github.com/SundareshSankaran/duckdb-assistant/issues
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Requires-Python: >=3.10
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Dynamic: license-file
|
|
15
|
+
|
|
16
|
+
# duckdb-assistant: Generate & Execute DuckDB SQL
|
|
17
|
+
|
|
18
|
+
This repository provides a Python class and associated methods to generate and execute DuckDB SQL.
|
|
19
|
+
|
|
20
|
+
[DuckDB](https://duckdb.org) is an open-source, low-footprint, in-process query processing engine which provides access to several data stores and structures like Parquet, CSV, JSON and data located in conventional Relational Database Management Systems (RDBMS). This package uses the [`duckdb`](https://pypi.org/project/duckdb/) Python package along with methods to call a Large Language Model (LLM) from Google Gemini to generate code in a convenient and conversational manner.
|
|
21
|
+
|
|
22
|
+
A wiki of this repo has been generated using DeepWiki and is available here: [](https://deepwiki.com/SundareshSankaran/duckdb-assistant)
|
|
23
|
+
|
|
24
|
+
Refer this [doc](https://github.com/SundareshSankaran/duckdb-assistant/blob/main/docs/VISION.md) for more details on how this project will evolve.
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
## Installation
|
|
28
|
+
1. Clone this repository
|
|
29
|
+
2. To install locally in editable mode, refer [here](https://github.com/SundareshSankaran/duckdb-assistant/blob/main/build/local_install_quick_start.md)
|
|
30
|
+
|
|
31
|
+
Run the following command for a pip installation of the package from PyPi.
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
> [!WARNING]
|
|
35
|
+
> This package is not yet registered on PyPi. The following command shall be valid once it's made available.
|
|
36
|
+
|
|
37
|
+
```shell
|
|
38
|
+
|
|
39
|
+
pip install --upgrade duckdb-assistant
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Usage - quick example
|
|
44
|
+
|
|
45
|
+
To initialise the DuckDBAssistant class:
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
from duckdb_assistant import DuckDBAssistant
|
|
49
|
+
|
|
50
|
+
dda = DuckDBAssistant()
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Then, to generate a query in natural language,
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
duckdb_query = dda.generate("Create an empty customer table.")
|
|
57
|
+
print(duckdb_query)
|
|
58
|
+
```
|
|
59
|
+
**Result:**
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
>>> duckdb_query = dda.generate("Create an empty customer table.")
|
|
63
|
+
>>> print(duckdb_query)
|
|
64
|
+
CREATE TABLE IF NOT EXISTS customer (
|
|
65
|
+
customer_id INTEGER PRIMARY KEY,
|
|
66
|
+
first_name VARCHAR,
|
|
67
|
+
last_name VARCHAR,
|
|
68
|
+
email VARCHAR,
|
|
69
|
+
phone VARCHAR,
|
|
70
|
+
address VARCHAR,
|
|
71
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
72
|
+
);
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Then, you execute the generated query either through a DuckDB connection or through the inbuilt duckdb Python connection object as follows:
|
|
76
|
+
|
|
77
|
+
```python
|
|
78
|
+
dda.dd.execute(duckdb_query)
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
which is another way of running
|
|
83
|
+
|
|
84
|
+
```python
|
|
85
|
+
import duckdb as dd
|
|
86
|
+
dd.execute(duckdb_query)
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Or, you can choose to call the execute and sql methods available with the class that directly call duckdb's execute and sql methods after generation.
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
|
|
93
|
+
dda.execute("Create an empty customer table.")
|
|
94
|
+
|
|
95
|
+
dda.sql("Print Hello World through SQL")
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
**Result:**
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
>>> dda.execute("Create an empty customer table.")
|
|
103
|
+
<_duckdb.DuckDBPyConnection object at 0x10c194af0>
|
|
104
|
+
>>>
|
|
105
|
+
>>> dda.sql("Print Hello World through SQL")
|
|
106
|
+
┌───────────────┐
|
|
107
|
+
│ 'Hello World' │
|
|
108
|
+
│ varchar │
|
|
109
|
+
├───────────────┤
|
|
110
|
+
│ Hello World │
|
|
111
|
+
└───────────────┘
|
|
112
|
+
|
|
113
|
+
>>>
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Documentation
|
|
117
|
+
Refer this [page](https://github.com/SundareshSankaran/duckdb-assistant/tree/main/docs/DOCUMENTATION.md) for a list of all available methods and attributes.
|
|
118
|
+
|
|
119
|
+
## Generative AI usage
|
|
120
|
+
Core functions (described in [Documentation](https://github.com/SundareshSankaran/duckdb-assistant/tree/main/docs/DOCUMENTATION.md)) use Large Language Models (LLM, starting with Gemini 3.6 Flash) from the Google Gemini family. While you are free to modify the code to accommodate other LLMs, these are at present the only LLMs supported. Read this important note regarding functions that make use of Generative AI.
|
|
121
|
+
|
|
122
|
+
**IMPORTANT**: All outputs returned from Generative AI tools such as LLMs should be carefully reviewed prior to actual use. Quality of Generative AI outputs are determined by the Large Language Model in use and may be incorrect. Always review the same.
|
|
123
|
+
|
|
124
|
+
Add the following environmental variable to a .env file supplying variables to your environment. Get your Gemini API key from [Google AI Studio](https://aistudio.google.com/welcome).
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
GEMINI_API_KEY = <your_key>
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
An example env file ([sample.env](https://github.com/SundareshSankaran/duckdb-assistant/blob/main/sample.env)) is provided for this purpose. Rename this to `.env` and use.
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
## Convenience: tasks.json
|
|
134
|
+
This repository contains a `tasks.json` meant for use in Visual Studio Code which helps clean up temporary files and stands up a virtual environment for quick development and exploration. Remove this file if you do not want to have Visual Studio Code run the tasks in `tasks.json`.
|
|
135
|
+
|
|
136
|
+
## Change Log
|
|
137
|
+
* Version: 0.0.1 (30JUL2026)
|
|
138
|
+
- Initial push to GitHub
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
Refer [`CHANGELOG.md`](https://github.com/SundareshSankaran/duckdb-assistant/blob/main/docs/CHANGELOG.md) for other changes.
|
|
142
|
+
|
|
143
|
+
## Contact
|
|
144
|
+
* [Sundaresh Sankaran](mailto:sundaresh.sankaran@gmail.com)
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
src/duckdb_assistant/__init__.py
|
|
5
|
+
src/duckdb_assistant/assistant.py
|
|
6
|
+
src/duckdb_assistant/gemini_api.py
|
|
7
|
+
src/duckdb_assistant.egg-info/PKG-INFO
|
|
8
|
+
src/duckdb_assistant.egg-info/SOURCES.txt
|
|
9
|
+
src/duckdb_assistant.egg-info/dependency_links.txt
|
|
10
|
+
src/duckdb_assistant.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
duckdb_assistant
|