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

Validating CLI arguments #561

Merged
merged 25 commits into from
Jun 8, 2023
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
ae2f54d
Validating CLI arguments
tl3119 May 31, 2023
2be9e6a
Merge branch 'master' of https://github.com/tl3119/jupysql
tl3119 May 31, 2023
38be8a0
Validating CLI arguments
tl3119 Jun 1, 2023
cd093c2
Merge pull request #1 from ploomber/master
tl3119 Jun 1, 2023
a52c5e6
remove rec_arguments array and add tests for line magic and cell magic
tl3119 Jun 1, 2023
acc2f06
Merge branch 'master' of https://github.com/tl3119/jupysql
tl3119 Jun 1, 2023
f06d7cc
Merge pull request #2 from ploomber/master
tl3119 Jun 1, 2023
08a540f
Update docs to use --alias
tl3119 Jun 2, 2023
3fca85d
Merge branch 'master' of https://github.com/tl3119/jupysql
tl3119 Jun 2, 2023
beec9e2
Remove pinned pydata version
tl3119 Jun 5, 2023
16f794f
Validating CLI arguments update
tl3119 Jun 5, 2023
3055c77
Update PR
tl3119 Jun 5, 2023
79efad6
Update PR, fix irrelevant issues
tl3119 Jun 6, 2023
7200eef
Update magic logic and test
tl3119 Jun 6, 2023
90ed427
Update test_magic.py
tl3119 Jun 7, 2023
219a47c
update PR
tl3119 Jun 7, 2023
553f49f
update PR
tl3119 Jun 7, 2023
43b35c3
Merge pull request #3 from ploomber/master
tl3119 Jun 7, 2023
7203acf
fix check only for cell magic
tl3119 Jun 7, 2023
468f365
Merge branch 'master' of https://github.com/tl3119/jupysql
tl3119 Jun 7, 2023
a410d91
Merge pull request #5 from ploomber/master
tl3119 Jun 7, 2023
68310ea
pass multiple arguments to pytest parameterized
tl3119 Jun 7, 2023
e5d4e9b
Merge branch 'master' of https://github.com/tl3119/jupysql
tl3119 Jun 7, 2023
cb8b636
Update PR
tl3119 Jun 7, 2023
42e4f24
Merge pull request #6 from ploomber/master
tl3119 Jun 7, 2023
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
2 changes: 0 additions & 2 deletions doc/environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ dependencies:
- pytest
# for %%sql --interact
- ipywidgets
# 0.13.2 is broken currently
# https://github.com/pydata/pydata-sphinx-theme/issues/1274
- pydata-sphinx-theme<0.13.2
tl3119 marked this conversation as resolved.
Show resolved Hide resolved
# needed to upload and download from/to S3 for notebook cache
- awscli
39 changes: 24 additions & 15 deletions doc/intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,25 +65,36 @@ After the first connection, connect info can be omitted::
%sql select count(*) from languages
```

Connections to multiple databases can be maintained. You can refer to
an existing connection by username@database
Connections to multiple databases can be maintained. You can switch connection using --alias
tl3119 marked this conversation as resolved.
Show resolved Hide resolved
Suppose we create two database, named one and two. Then, assign alias to both connections so we can switch them by name:

```sql
%%sql will@shakes
select charname, speechcount from character
where speechcount = (select max(speechcount)
from character);
%sql sqlite:///one.db --alias one
%sql sqlite:///two.db --alias two
```

```python
print(_)
```sql
%sql
```

+++
It will run query in "two" database

Pass the alias to make it the current connection:

```sql
%sql one
```

If no connect string is supplied, ``%sql`` will provide a list of existing connections;
however, if no connections have yet been made and the environment variable ``DATABASE_URL``
is available, that will be used.
You can pass an alias and query in the same cell:

```sql
%sql two
SELECT * FROM two
```

However, this isn’t supported with the line magic (e.g., `%sql one SELECT * FROM one`).

+++

For secure access, you may dynamically access your credentials (e.g. from your system environment or `getpass.getpass`) to avoid storing your password in the notebook itself. Use the `$` before any variable to access it in your `%sql` command.

Expand All @@ -98,9 +109,7 @@ connection_string = "postgresql://{user}:{password}@localhost/some_database".for

+++

You may use multiple SQL statements inside a single cell, but you will
only see any query results from the last of them, so this really only
makes sense for statements with no output
You may use multiple SQL statements inside a single cell, but you will only see any query results from the last of them, so this really only makes sense for statements with no output

+++

Expand Down
24 changes: 24 additions & 0 deletions src/sql/magic.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import sql.connection
import sql.parse
import sql.run
from sql.parse import _option_strings_from_parser
from sql import display, exceptions
from sql.store import store
from sql.command import SQLCommand
Expand Down Expand Up @@ -180,6 +181,26 @@ def _mutex_autopandas_autopolars(self, change):
setattr(self, other, False)
print(f"Disabled '{other}' since '{change['name']}' was enabled.")

def check_random_arguments(self, line="", cell=""):
# Split the line into tokens separated by whitespace
tokens = line.split()
arguments = []

# Iterate through the tokens to separate arguments and SQL code
tl3119 marked this conversation as resolved.
Show resolved Hide resolved
# If the token starts with "--", it is an argument
for token in tokens:
if token.startswith("--"):
arguments.append(token)

declared_argument = _option_strings_from_parser(SqlMagic.execute.parser)
# check only for cell magic
if cell is not None:
for check_argument in arguments:
if check_argument not in declared_argument:
raise exceptions.UsageError(
"Unrecognized argument(s): {}".format(check_argument)
)

@no_var_expand
@needs_local_scope
@line_magic("sql")
Expand Down Expand Up @@ -315,6 +336,9 @@ def interactive_execute_wrapper(**kwargs):

# %%sql {line}
# {cell}

self.check_random_arguments(line, cell)

if local_ns is None:
local_ns = {}

Expand Down
5 changes: 5 additions & 0 deletions src/tests/test_magic.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,11 @@ def test_persist_no_index(ip):
assert persisted == [(1, "foo"), (2, "bar")]


def test_unrecognized_arguments_cell_magic(ip):
result = ip.run_cell("%%sql --stuff \n SELECT * FROM test")
assert "Unrecognized argument(s)" in str(result.error_in_exec)

tl3119 marked this conversation as resolved.
Show resolved Hide resolved

def test_persist_invalid_identifier(ip):
result = ip.run_cell("%sql --persist sqlite:// not an identifier")
assert "not a valid identifier" in str(result.error_in_exec)
Expand Down