sqlsaber 0.9.0__tar.gz → 0.10.0__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.
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/CHANGELOG.md +9 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/PKG-INFO +8 -1
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/README.md +7 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/pyproject.toml +1 -1
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/src/sqlsaber/cli/commands.py +26 -7
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/uv.lock +1 -1
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/.github/workflows/publish.yml +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/.gitignore +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/.python-version +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/AGENT.md +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/CLAUDE.md +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/LICENSE +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/pytest.ini +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/sqlsaber.svg +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/src/sqlsaber/__init__.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/src/sqlsaber/__main__.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/src/sqlsaber/agents/__init__.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/src/sqlsaber/agents/anthropic.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/src/sqlsaber/agents/base.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/src/sqlsaber/agents/mcp.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/src/sqlsaber/agents/streaming.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/src/sqlsaber/cli/__init__.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/src/sqlsaber/cli/auth.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/src/sqlsaber/cli/completers.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/src/sqlsaber/cli/database.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/src/sqlsaber/cli/display.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/src/sqlsaber/cli/interactive.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/src/sqlsaber/cli/memory.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/src/sqlsaber/cli/models.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/src/sqlsaber/cli/streaming.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/src/sqlsaber/clients/__init__.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/src/sqlsaber/clients/anthropic.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/src/sqlsaber/clients/base.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/src/sqlsaber/clients/exceptions.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/src/sqlsaber/clients/models.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/src/sqlsaber/clients/streaming.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/src/sqlsaber/config/__init__.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/src/sqlsaber/config/api_keys.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/src/sqlsaber/config/auth.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/src/sqlsaber/config/database.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/src/sqlsaber/config/oauth_flow.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/src/sqlsaber/config/oauth_tokens.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/src/sqlsaber/config/settings.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/src/sqlsaber/database/__init__.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/src/sqlsaber/database/connection.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/src/sqlsaber/database/schema.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/src/sqlsaber/mcp/__init__.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/src/sqlsaber/mcp/mcp.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/src/sqlsaber/memory/__init__.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/src/sqlsaber/memory/manager.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/src/sqlsaber/memory/storage.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/src/sqlsaber/models/__init__.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/src/sqlsaber/models/events.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/src/sqlsaber/models/types.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/tests/__init__.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/tests/conftest.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/tests/test_agents/test_anthropic_oauth.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/tests/test_cli/__init__.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/tests/test_cli/test_commands.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/tests/test_clients/test_anthropic_client.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/tests/test_clients/test_streaming.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/tests/test_config/__init__.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/tests/test_config/test_database.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/tests/test_config/test_oauth.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/tests/test_config/test_settings.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/tests/test_database/__init__.py +0 -0
- {sqlsaber-0.9.0 → sqlsaber-0.10.0}/tests/test_database/test_connection.py +0 -0
|
@@ -4,6 +4,15 @@ All notable changes to SQLSaber will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.10.0] - 2025-07-08
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- Support for reading queries from stdin via pipe operator
|
|
12
|
+
- `echo 'show me all users' | saber` now works
|
|
13
|
+
- `cat query.txt | saber` reads query from file via stdin
|
|
14
|
+
- Allows integration with other command-line tools and scripts
|
|
15
|
+
|
|
7
16
|
## [0.9.0] - 2025-07-08
|
|
8
17
|
|
|
9
18
|
### Changed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sqlsaber
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.10.0
|
|
4
4
|
Summary: SQLSaber - Agentic SQL assistant like Claude Code
|
|
5
5
|
License-File: LICENSE
|
|
6
6
|
Requires-Python: >=3.12
|
|
@@ -139,6 +139,13 @@ Execute a single natural language query:
|
|
|
139
139
|
saber "show me all users created this month"
|
|
140
140
|
```
|
|
141
141
|
|
|
142
|
+
You can also pipe queries from stdin:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
echo "show me all users created this month" | saber
|
|
146
|
+
cat query.txt | saber
|
|
147
|
+
```
|
|
148
|
+
|
|
142
149
|
### Database Selection
|
|
143
150
|
|
|
144
151
|
Use a specific database connection:
|
|
@@ -118,6 +118,13 @@ Execute a single natural language query:
|
|
|
118
118
|
saber "show me all users created this month"
|
|
119
119
|
```
|
|
120
120
|
|
|
121
|
+
You can also pipe queries from stdin:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
echo "show me all users created this month" | saber
|
|
125
|
+
cat query.txt | saber
|
|
126
|
+
```
|
|
127
|
+
|
|
121
128
|
### Database Selection
|
|
122
129
|
|
|
123
130
|
Use a specific database connection:
|
|
@@ -51,9 +51,11 @@ def meta_handler(
|
|
|
51
51
|
Query your database using natural language.
|
|
52
52
|
|
|
53
53
|
Examples:
|
|
54
|
-
saber
|
|
55
|
-
saber "show me all users"
|
|
56
|
-
saber -d mydb "show me users"
|
|
54
|
+
saber # Start interactive mode
|
|
55
|
+
saber "show me all users" # Run a single query with default database
|
|
56
|
+
saber -d mydb "show me users" # Run a query with specific database
|
|
57
|
+
echo "show me all users" | saber # Read query from stdin
|
|
58
|
+
cat query.txt | saber # Read query from file via stdin
|
|
57
59
|
"""
|
|
58
60
|
# Store database in app context for commands to access
|
|
59
61
|
app.meta["database"] = database
|
|
@@ -64,7 +66,7 @@ def query(
|
|
|
64
66
|
query_text: Annotated[
|
|
65
67
|
str | None,
|
|
66
68
|
cyclopts.Parameter(
|
|
67
|
-
help="SQL query in natural language (if not provided, starts interactive mode)",
|
|
69
|
+
help="SQL query in natural language (if not provided, reads from stdin or starts interactive mode)",
|
|
68
70
|
),
|
|
69
71
|
] = None,
|
|
70
72
|
database: Annotated[
|
|
@@ -77,11 +79,28 @@ def query(
|
|
|
77
79
|
):
|
|
78
80
|
"""Run a query against the database or start interactive mode.
|
|
79
81
|
|
|
80
|
-
When called without arguments
|
|
82
|
+
When called without arguments:
|
|
83
|
+
- If stdin has data, reads query from stdin
|
|
84
|
+
- Otherwise, starts interactive mode
|
|
85
|
+
|
|
81
86
|
When called with a query string, executes that query and exits.
|
|
87
|
+
|
|
88
|
+
Examples:
|
|
89
|
+
saber # Start interactive mode
|
|
90
|
+
saber "show me all users" # Run a single query
|
|
91
|
+
echo "show me all users" | saber # Read query from stdin
|
|
82
92
|
"""
|
|
83
93
|
|
|
84
94
|
async def run_session():
|
|
95
|
+
# Check if query_text is None and stdin has data
|
|
96
|
+
actual_query = query_text
|
|
97
|
+
if query_text is None and not sys.stdin.isatty():
|
|
98
|
+
# Read from stdin
|
|
99
|
+
actual_query = sys.stdin.read().strip()
|
|
100
|
+
if not actual_query:
|
|
101
|
+
# If stdin was empty, fall back to interactive mode
|
|
102
|
+
actual_query = None
|
|
103
|
+
|
|
85
104
|
# Get database configuration or handle direct CSV file
|
|
86
105
|
if database:
|
|
87
106
|
# Check if this is a direct CSV file path
|
|
@@ -119,13 +138,13 @@ def query(
|
|
|
119
138
|
agent = AnthropicSQLAgent(db_conn, db_name)
|
|
120
139
|
|
|
121
140
|
try:
|
|
122
|
-
if
|
|
141
|
+
if actual_query:
|
|
123
142
|
# Single query mode with streaming
|
|
124
143
|
streaming_handler = StreamingQueryHandler(console)
|
|
125
144
|
console.print(
|
|
126
145
|
f"[bold blue]Connected to:[/bold blue] {db_name} {agent._get_database_type_name()}\n"
|
|
127
146
|
)
|
|
128
|
-
await streaming_handler.execute_streaming_query(
|
|
147
|
+
await streaming_handler.execute_streaming_query(actual_query, agent)
|
|
129
148
|
else:
|
|
130
149
|
# Interactive mode
|
|
131
150
|
session = InteractiveSession(console, agent)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|