Skip to content
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

5.3b2 #670

Merged
merged 5 commits into from
Sep 10, 2024
Merged

5.3b2 #670

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
4 changes: 3 additions & 1 deletion HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Change Log
This document records all notable changes to `SQL Explorer <https://github.com/explorerhq/sql-explorer>`_.
This project adheres to `Semantic Versioning <https://semver.org/>`_.

`5.3.0 (beta)`_ (2024-08-29)
`5.3.0 (beta 2)`_ (2024-09-10)
===========================
* `#664`_: Improvements to the AI SQL Assistant:

Expand Down Expand Up @@ -41,6 +41,8 @@ This project adheres to `Semantic Versioning <https://semver.org/>`_.

* Fixed a bug when validating connections to uploaded files. Also added basic locking when downloading files from S3.

* On-boarding UI; if no connections or queries are created, the UI walks the user through it a bit.

* Keyboard shortcut for formatting the SQL in the editor.

- Cmd+Shift+F (Windows: Ctrl+Shift+F)
Expand Down
2 changes: 1 addition & 1 deletion explorer/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"minor": 3,
"patch": 0,
"releaselevel": "beta",
"serial": 1
"serial": 2
}


Expand Down
2 changes: 2 additions & 0 deletions explorer/app_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,8 @@
# 500mb default max
EXPLORER_MAX_UPLOAD_SIZE = getattr(settings, "EXPLORER_MAX_UPLOAD_SIZE", 500 * 1024 * 1024)

EXPLORER_HOSTED = getattr(settings, "EXPLORER_HOSTED", False)


def has_assistant():
return EXPLORER_AI_API_KEY is not None
Expand Down
1 change: 0 additions & 1 deletion explorer/ee/db_connections/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,6 @@ def save(self, *args, **kwargs):
DatabaseConnection.objects.filter(default=True).update(default=False)
else:
# If there is no default set yet, make this newly created one the default.
# Effectively this is for first-time installations.
has_default = DatabaseConnection.objects.filter(default=True).exists()
if not has_default:
self.default = True
Expand Down
1 change: 0 additions & 1 deletion explorer/ee/db_connections/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ def post(self, request): # noqa

class DatabaseConnectionsListView(PermissionRequiredMixin, ExplorerContextMixin, ListView):

context_object_name = "sqlite_uploads"
permission_required = "connections_permission"
template_name = "connections/connections.html"
model = DatabaseConnection
Expand Down
7 changes: 6 additions & 1 deletion explorer/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields["database_connection"].widget.choices = self.connections
if not self.instance.database_connection:
self.initial["database_connection"] = default_db_connection().alias
default_db = default_db_connection()
self.initial["database_connection"] = default_db_connection().alias if default_db else None
self.fields["database_connection"].widget.attrs["class"] = "form-select"

def clean(self):
Expand All @@ -66,6 +67,10 @@ def created_at_time(self):

@property
def connections(self):
default_db = default_db_connection()
if default_db is None:
return []

# Ensure the default connection appears first in the dropdown in the form
result = DatabaseConnection.objects.annotate(
custom_order=Case(
Expand Down
4 changes: 2 additions & 2 deletions explorer/permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def view_permission(request, **kwargs):
# And token auth does not give you permission to view the list.


def view_permission_list(request):
def view_permission_list(request, *args, **kwargs):
return app_settings.EXPLORER_PERMISSION_VIEW(request)\
or allowed_query_pks(request.user.id)

Expand All @@ -25,5 +25,5 @@ def change_permission(request, *args, **kwargs):
return app_settings.EXPLORER_PERMISSION_CHANGE(request)


def connections_permission(request, **kwargs):
def connections_permission(request, *args, **kwargs):
return app_settings.EXPLORER_PERMISSION_CONNECTIONS(request)
21 changes: 16 additions & 5 deletions explorer/src/js/assistant.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ function setupTableList() {
removeItemButton: true,
searchEnabled: true,
shouldSort: false,
position: 'bottom'
position: 'bottom',
placeholderValue: "Click to search for relevant tables"
});

// TODO - nasty. Should be refactored. Used by submitAssistantAsk to get relevant tables.
Expand All @@ -66,6 +67,16 @@ function setupTableList() {
});
});

const refreshTables = document.getElementById('refresh_tables_button');
refreshTables.addEventListener('click', (e) => {
e.preventDefault();
keys.forEach(k => {
choices.removeActiveItemsByValue(k);
});
selectRelevantTablesSql(choices, keys)
selectRelevantTablesRequest(choices, keys)
});

selectRelevantTablesSql(choices, keys);

document.addEventListener('docChanged', debounce(
Expand All @@ -81,16 +92,16 @@ function setupTableList() {
}

function selectRelevantTablesSql(choices, keys) {
const textContent = window.editor.state.doc.toString();
const textContent = window.editor.state.doc.toString().toLowerCase();
const textWords = new Set(textContent.split(/\s+/));
const hasKeys = keys.filter(key => textWords.has(key));
const hasKeys = keys.filter(key => textWords.has(key.toLowerCase()));
choices.setChoiceByValue(hasKeys);
}

function selectRelevantTablesRequest(choices, keys) {
const textContent = document.getElementById("id_assistant_input").value
const textWords = new Set(textContent.split(/\s+/));
const hasKeys = keys.filter(key => textWords.has(key));
const textWords = new Set(textContent.toLowerCase().split(/\s+/));
const hasKeys = keys.filter(key => textWords.has(key.toLowerCase()));
choices.setChoiceByValue(hasKeys);
}

Expand Down
5 changes: 3 additions & 2 deletions explorer/templates/assistant/table_description_list.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
{% block sql_explorer_content %}
<div class="container">
<h3>Table Annotations</h3>
<p>These will be injected into any AI assistant prompts that reference the annotated table.</p>
<p>Write some notes about your tables to help the AI Assistant do its job. Relevant annotations will be automatically injected into AI assistant requests.</p>
<p>Good annotations may describe the purposes of columns that are not obvious from their name alone, common joins to other tables, or the semantic meaning of enum values.</p>
<div class="mt-3">
<a href="{% url 'table_description_create' %}" class="btn btn-primary mb-3">Create New</a>
<a href="{% url 'table_description_create' %}" class="btn btn-primary mb-3">Create Annotation</a>
<table class="table table-striped table-hover">
<thead>
<tr>
Expand Down
13 changes: 5 additions & 8 deletions explorer/templates/connections/connection_upload.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,21 @@
{% block sql_explorer_content %}
<div class="container mt-5">
<div class="pt-3">
<h4>Upload a file</h4>
<h4>Create a connection from an uploaded file</h4>
<p>Supports .csv, .json, .db, and .sqlite files. JSON files with one JSON document per line are also supported. CSV/JSON data will be parsed and converted to SQLite. SQLite databases must <i>not</i> be password protected.</p>
<p></p>

<p>Appending to an existing connection will add a new table to the SQLite database, named after the uploaded file. If a table with the filename already exists, it will be replaced with the uploaded data.</p>
<form id="upload-form">
<div class="form-floating mb-3">
<select id="append" name="append" class="form-select">
<option value="" selected>-- Create new connection --</option>
<option value="" selected></option>
{% for connection in valid_connections %}
<option value="{{ connection.id }}">{{ connection.alias }}</option>
{% endfor %}
</select>
<label for="append">Append to existing connection:</label>
<span class="form-text text-muted">When appending, if a table with the filename already exists, it will be replaced with the uploaded data.</span>
<label for="append">Optional: Append to existing connection:</label>
</div>

<div id="drop-area" class="p-3 mb-4 bg-light border rounded" style="cursor: pointer">
<p class="lead mb-0">Drag and drop, or click to upload .csv, .json, .db, .sqlite.</p>
<p class="lead mb-0"><span class="fw-bold">Upload: </span>Drag and drop, or click to upload .csv, .json, .db, .sqlite.</p>
<input type="file" id="fileElem" style="display:none" accept=".db,.csv,.sqlite,.json">
<div class="progress mt-3" style="height: 20px;">
<div id="progress-bar" class="progress-bar" role="progressbar" style="width: 0;" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">0%</div>
Expand Down
11 changes: 9 additions & 2 deletions explorer/templates/connections/connections.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,15 @@
<div class="container">
<h3>Connections</h3>
<div class="mt-3">
<a href="{% url 'explorer_connection_create' %}" class="btn btn-primary mb-3">Add New Connection</a>
<a href="{% url 'explorer_upload_create' %}" class="btn btn-primary mb-3">Upload File</a>
<div class="d-flex align-items-center gap-2 mb-3">
<a href="{% url 'explorer_connection_create' %}" class="btn btn-primary">Add New Connection</a>
<a href="{% url 'explorer_upload_create' %}" class="btn btn-primary">Upload File</a>
{% if object_list|length == 0 %}
<span class="text-secondary d-flex align-items-center fw-bold">
<i class="bi-arrow-left me-1"></i>Connect to an existing database, or upload a csv, json, or sqlite file.
</span>
{% endif %}
</div>
<table class="table table-striped" id="connections_table">
<thead>
<tr>
Expand Down
5 changes: 4 additions & 1 deletion explorer/templates/explorer/assistant.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,14 @@
</div>
<div class="assistant-icons" style="">
<div>
<i class="bi-plus-circle" id="select_all_button" style="cursor: pointer;" data-bs-toggle="tooltip" data-bs-placement="top" data-bs-title="Select all"></i>
<i class="bi-check-all" id="select_all_button" style="cursor: pointer;" data-bs-toggle="tooltip" data-bs-placement="top" data-bs-title="Add all"></i>
</div>
<div>
<i class="bi-trash" id="deselect_all_button" style="cursor: pointer;" data-bs-toggle="tooltip" data-bs-placement="top" data-bs-title="Remove all"></i>
</div>
<div>
<i class="bi-repeat" id="refresh_tables_button" style="cursor: pointer;" data-bs-toggle="tooltip" data-bs-placement="top" data-bs-title="Refresh autodetect"></i>
</div>
<div>
<i class="bi-card-list" id="assistant_history" style="cursor: pointer;" data-bs-toggle="tooltip" data-bs-placement="top" data-bs-title="History"></i>
</div>
Expand Down
6 changes: 6 additions & 0 deletions explorer/templates/explorer/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,12 @@ <h2>This is easy to fix, I promise!</h2>
<a class="nav-link{% if not query and view_name == 'query_favorites' %} active{% endif %}"
href="{% url 'query_favorites' %}"><i class="small me-1 bi-heart"></i>{% translate "Favorites" %}</a>
</li>
{% if hosted %}
<li class="nav-item">
<a class="nav-link"
href="/"><i class="small me-1 bi-arrow-return-left"></i>Manage</a>
</li>
{% endif %}
</ul>
</div>
</nav>
Expand Down
3 changes: 1 addition & 2 deletions explorer/templates/explorer/play.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ <h2>{% translate "Playground" %}</h2>
<div class="alert alert-danger db-error">{{ error|escape }}</div>
{% endif %}
{{ form.non_field_errors }}
{% if form.connections|length > 1 and can_change %}
{% if can_change %}
<div class="mb-3 form-floating">
{{ form.database_connection }}
<label for="id_database_connection" class="form-label">{% translate "Connection" %}</label>
Expand All @@ -26,7 +26,6 @@ <h2>{% translate "Playground" %}</h2>
<div class="d-none">
{{ form.database_connection }}
</div>
<div>{{ form.database_connection.value }}</div>
{% endif %}
<div class="row">
<div class="col">
Expand Down
7 changes: 5 additions & 2 deletions explorer/templates/explorer/query.html
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ <h2>
<div class="alert alert-danger">{{ error|escape }}</div>
{% endfor %}{% endif %}
</div>
{% if form.connections|length > 1 and can_change %}
{% if can_change %}
<div class="mb-3 form-floating">
{{ form.database_connection }}
<label for="id_database_connection" class="form-label">{% translate "Connection" %}</label>
Expand Down Expand Up @@ -96,6 +96,10 @@ <h2>
{% if query %}
<div class="position-relative float-end">
<small>
<span class="pe-3">
{% if query and can_change and assistant_enabled %}{{ form.few_shot }} {% translate "Assistant Example" %}{% endif %}
<i class="bi-question-circle" style="cursor: pointer;" data-bs-toggle="tooltip" data-bs-placement="top" data-bs-title="Queries marked as examples will be sent, when relevant, to the AI Assistant as few-shot examples of how certain tables are used."></i>
</span>
<a href="#" title="Open in playground" id="playground_button">
<i class="bi-arrow-up-right-square"></i>
</a>
Expand Down Expand Up @@ -150,6 +154,5 @@ <h2>
</div>
<div class="container mt-1 text-end small">
{% if query and can_change and tasks_enabled %}{{ form.snapshot }} {% translate "Snapshot" %}{% endif %}
{% if query and can_change and assistant_enabled %}{{ form.few_shot }} {% translate "Assistant Example" %}{% endif %}
</div>
{% endblock %}
Loading
Loading