Skip to content

Commit 59655a8

Browse files
wtbates99claude
andcommitted
feat: migrate docs to MyST/Markdown and update dev dependencies
- Convert Sphinx config to use myst-parser with colon_fence, deflist, and tasklist extensions; set alabaster theme options and release version - Replace index.rst with index.md toctree for all doc sections - Add contributing.md guide covering setup, testing, and PR process - Remove legacy .rst source files (contexts, local_development, providers, querying, index) - Move dev dependencies from [tool.uv] to [dependency-groups] and add sphinx + myst-parser as dev deps Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 1bba263 commit 59655a8

10 files changed

Lines changed: 580 additions & 580 deletions

File tree

docs/conf.py

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,48 @@
11
# Configuration file for the Sphinx documentation builder.
2-
#
3-
# For the full list of built-in configuration values, see the documentation:
42
# https://www.sphinx-doc.org/en/master/usage/configuration.html
53

6-
# -- Project information -----------------------------------------------------
7-
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
4+
# -- Project information -------------------------------------------------------
85

96
project = "tabletalk"
107
copyright = "2025, william bates"
118
author = "william bates"
12-
release = "0"
9+
release = "0.2.1"
1310

14-
# -- General configuration ---------------------------------------------------
15-
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
11+
# -- General configuration -----------------------------------------------------
1612

17-
extensions: list[str] = []
13+
extensions = [
14+
"myst_parser",
15+
]
16+
17+
# MyST parser settings — enable common markdown extensions
18+
myst_enable_extensions = [
19+
"colon_fence", # ::: fenced directives
20+
"deflist", # definition lists
21+
"tasklist", # - [ ] checkboxes
22+
]
23+
24+
# Auto-generate anchors for headings up to level 3 (enables #anchor-name links)
25+
myst_heading_anchors = 3
26+
27+
# Use index.md as the root document
28+
root_doc = "index"
29+
30+
source_suffix = {
31+
".md": "markdown",
32+
}
1833

1934
templates_path = ["_templates"]
2035
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
2136

22-
23-
# -- Options for HTML output -------------------------------------------------
24-
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
37+
# -- Options for HTML output ---------------------------------------------------
2538

2639
html_theme = "alabaster"
2740
html_static_path = ["_static"]
41+
42+
html_theme_options = {
43+
"description": "dbt for agents — declarative natural-language SQL agents",
44+
"github_user": "wtbates99",
45+
"github_repo": "tabletalk",
46+
"github_button": True,
47+
"fixed_sidebar": True,
48+
}

docs/contributing.md

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
# Contributing
2+
3+
tabletalk is a Python project managed with [uv](https://github.com/astral-sh/uv). Contributions are welcome — this guide covers environment setup, adding new providers, and the pull request process.
4+
5+
---
6+
7+
## Development setup
8+
9+
**Prerequisites:** Python 3.10+, [uv](https://github.com/astral-sh/uv)
10+
11+
```bash
12+
git clone https://github.com/wtbates99/tabletalk.git
13+
cd tabletalk
14+
15+
# Install the package and all dev dependencies in one step
16+
uv sync --extra all
17+
```
18+
19+
This installs tabletalk in editable mode along with all optional database drivers plus the dev tools (pytest, ruff, mypy, duckdb).
20+
21+
---
22+
23+
## Running tests
24+
25+
```bash
26+
# All tests (DuckDB and SQLite run without extra setup)
27+
uv run pytest
28+
29+
# Specific test file
30+
uv run pytest tabletalk/tests/test_providers.py -v
31+
```
32+
33+
Tests live in `tabletalk/tests/`. PostgreSQL and MySQL tests require a running local instance — configure credentials in the test config if you need them.
34+
35+
---
36+
37+
## Code style
38+
39+
```bash
40+
# Lint and auto-fix
41+
uv run ruff check --fix tabletalk/
42+
43+
# Type checking
44+
uv run mypy tabletalk/
45+
```
46+
47+
Line length is 100. The linter enforces `pyflakes`, `pycodestyle`, `isort`, and `pyupgrade` rules. Run both before pushing.
48+
49+
---
50+
51+
## Adding a database provider
52+
53+
All database providers implement the `DatabaseProvider` ABC in `tabletalk/interfaces.py`.
54+
55+
**1. Create the provider file** at `tabletalk/providers/mydb_provider.py`:
56+
57+
```python
58+
from typing import Any, Dict, List, Optional
59+
from tabletalk.interfaces import DatabaseProvider
60+
61+
62+
class MyDBProvider(DatabaseProvider):
63+
def __init__(self, config: Dict[str, Any]):
64+
# initialize connection from config dict
65+
...
66+
67+
def execute_query(self, sql_query: str) -> List[Dict[str, Any]]:
68+
"""Execute SQL and return a list of row dicts."""
69+
...
70+
71+
def get_client(self) -> Any:
72+
"""Return the raw connection/client object."""
73+
...
74+
75+
def get_database_type_map(self) -> Dict[str, str]:
76+
"""Map native type names to compact codes used in manifests.
77+
78+
Standard codes: I=integer, S=string/text, N=numeric/float,
79+
B=boolean, TS=timestamp, D=date, J=json, X=other
80+
"""
81+
return {
82+
"integer": "I",
83+
"text": "S",
84+
# ...
85+
}
86+
87+
def get_compact_tables(
88+
self, schema_name: str, table_names: Optional[List[str]] = None
89+
) -> List[Dict[str, Any]]:
90+
"""Fetch table schemas in compact format for manifest generation.
91+
92+
Returns a list of dicts:
93+
{
94+
't': 'schema.table_name',
95+
'd': 'table description or empty string',
96+
'f': [
97+
{'n': 'col_name', 't': 'I', 'pk': True},
98+
{'n': 'other_col', 't': 'S', 'fk': 'other_table.id'},
99+
]
100+
}
101+
"""
102+
...
103+
```
104+
105+
**2. Register the provider** in `tabletalk/factories.py` — add a branch to `get_db_provider()` that maps your type string to your class.
106+
107+
**3. Add the optional dependency** in `pyproject.toml` under `[project.optional-dependencies]`:
108+
109+
```toml
110+
mydb = ["mydb-driver>=1.0"]
111+
```
112+
113+
And add it to the `all` extras list.
114+
115+
**4. Add a test** in `tabletalk/tests/` following the pattern of the existing provider tests.
116+
117+
---
118+
119+
## Adding an LLM provider
120+
121+
LLM providers implement the `LLMProvider` ABC in `tabletalk/interfaces.py`.
122+
123+
**1. Create the provider file** at `tabletalk/providers/myllm_provider.py`:
124+
125+
```python
126+
from typing import Dict, Generator, List
127+
from tabletalk.interfaces import LLMProvider
128+
129+
130+
class MyLLMProvider(LLMProvider):
131+
def __init__(self, config: Dict):
132+
# initialize client from config dict
133+
...
134+
135+
def generate_response(self, prompt: str) -> str:
136+
"""Single-turn: return the full response as a string."""
137+
...
138+
139+
def generate_response_stream(self, prompt: str) -> Generator[str, None, None]:
140+
"""Single-turn: yield response tokens as they arrive."""
141+
...
142+
143+
def generate_chat_stream(
144+
self, messages: List[Dict[str, str]]
145+
) -> Generator[str, None, None]:
146+
"""Multi-turn: yield tokens given a full messages list (OpenAI format).
147+
148+
messages is a list of {'role': 'system'|'user'|'assistant', 'content': '...'}.
149+
"""
150+
...
151+
```
152+
153+
**2. Register the provider** in `tabletalk/factories.py` in `get_llm_provider()`.
154+
155+
---
156+
157+
## Project structure
158+
159+
```
160+
tabletalk/
161+
├── cli.py — Click CLI (all user-facing commands)
162+
├── app.py — Flask web server + SSE streaming endpoints
163+
├── interfaces.py — DatabaseProvider, LLMProvider, QuerySession, Parser ABCs
164+
├── factories.py — Provider instantiation from config dicts
165+
├── profiles.py — ~/.tabletalk/profiles.yml management + dbt import
166+
├── utils.py — Project scaffolding helpers
167+
├── providers/ — One file per database or LLM backend
168+
└── tests/ — pytest test suite
169+
```
170+
171+
The `QuerySession` class in `interfaces.py` is the core orchestrator — it owns SQL generation, execution, history, favorites, and explain/suggest logic. `Parser` handles `tabletalk apply` (schema introspection → manifest files).
172+
173+
---
174+
175+
## Pull requests
176+
177+
- Open an issue first for non-trivial changes
178+
- Keep PRs focused — one feature or fix per PR
179+
- Ensure `ruff` and `mypy` pass with no new errors
180+
- Add or update tests for changed behavior
181+
- Update the relevant docs page if your change affects user-visible behavior

docs/dev/contexts.rst

Lines changed: 0 additions & 45 deletions
This file was deleted.

0 commit comments

Comments
 (0)