database-tycoon 0.1.0__py3-none-any.whl

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.
Files changed (67) hide show
  1. database_tycoon-0.1.0.dist-info/METADATA +222 -0
  2. database_tycoon-0.1.0.dist-info/RECORD +67 -0
  3. database_tycoon-0.1.0.dist-info/WHEEL +4 -0
  4. database_tycoon-0.1.0.dist-info/entry_points.txt +2 -0
  5. database_tycoon-0.1.0.dist-info/licenses/LICENSE +21 -0
  6. tycoon/__init__.py +3 -0
  7. tycoon/__main__.py +5 -0
  8. tycoon/cli.py +89 -0
  9. tycoon/commands/__init__.py +0 -0
  10. tycoon/commands/ask.py +319 -0
  11. tycoon/commands/data.py +25 -0
  12. tycoon/commands/db.py +163 -0
  13. tycoon/commands/doctor.py +137 -0
  14. tycoon/commands/explore.py +190 -0
  15. tycoon/commands/init.py +333 -0
  16. tycoon/commands/run.py +36 -0
  17. tycoon/commands/run_all.py +107 -0
  18. tycoon/commands/sources.py +503 -0
  19. tycoon/commands/start.py +134 -0
  20. tycoon/commands/status.py +125 -0
  21. tycoon/commands/stop.py +128 -0
  22. tycoon/commands/transform.py +170 -0
  23. tycoon/config.py +106 -0
  24. tycoon/constants.py +19 -0
  25. tycoon/dbt.py +24 -0
  26. tycoon/ingestion/__init__.py +0 -0
  27. tycoon/ingestion/catalog.py +199 -0
  28. tycoon/ingestion/ducklake_config.py +68 -0
  29. tycoon/ingestion/mta_bus_speeds_pipeline.py +107 -0
  30. tycoon/ingestion/mta_pipeline.py +102 -0
  31. tycoon/ingestion/nyc_dot_pipeline.py +102 -0
  32. tycoon/ingestion/runner.py +245 -0
  33. tycoon/ingestion/source_installer.py +72 -0
  34. tycoon/ingestion/source_manager.py +267 -0
  35. tycoon/ingestion/sources/__init__.py +1 -0
  36. tycoon/nao.py +115 -0
  37. tycoon/orchestration/__init__.py +1 -0
  38. tycoon/orchestration/assets/__init__.py +1 -0
  39. tycoon/orchestration/assets/ingestion.py +67 -0
  40. tycoon/orchestration/assets/rill.py +31 -0
  41. tycoon/orchestration/assets/transforms.py +21 -0
  42. tycoon/orchestration/definitions.py +64 -0
  43. tycoon/orchestration/resources.py +26 -0
  44. tycoon/project.py +156 -0
  45. tycoon/scaffolding/__init__.py +0 -0
  46. tycoon/scaffolding/dbt_generator.py +227 -0
  47. tycoon/scaffolding/rill_generator.py +358 -0
  48. tycoon/scaffolding/templates.py +310 -0
  49. tycoon/server/__init__.py +0 -0
  50. tycoon/server/app.py +42 -0
  51. tycoon/server/routes.py +140 -0
  52. tycoon/server/spa.py +321 -0
  53. tycoon/server/subprocess_manager.py +82 -0
  54. tycoon/server/websocket.py +57 -0
  55. tycoon/services/__init__.py +0 -0
  56. tycoon/services/definitions.py +103 -0
  57. tycoon/services/manager.py +139 -0
  58. tycoon/templates/csv-import/README +46 -0
  59. tycoon/templates/csv-import/tycoon.yml +18 -0
  60. tycoon/templates/github-analytics/tycoon.yml +24 -0
  61. tycoon/templates/nyc-transit/README +9 -0
  62. tycoon/templates/nyc-transit/tycoon.yml +41 -0
  63. tycoon/templates/weather-station/tycoon.yml +20 -0
  64. tycoon/utils/__init__.py +0 -0
  65. tycoon/utils/console.py +58 -0
  66. tycoon/utils/duckdb_utils.py +53 -0
  67. tycoon/utils/process.py +34 -0
@@ -0,0 +1,222 @@
1
+ Metadata-Version: 2.4
2
+ Name: database-tycoon
3
+ Version: 0.1.0
4
+ Summary: Database Tycoon — local-first analytics CLI that adapts to your existing data stack
5
+ Project-URL: Homepage, https://github.com/Database-Tycoon/tycoon-cli
6
+ Project-URL: Repository, https://github.com/Database-Tycoon/tycoon-cli
7
+ Project-URL: Issues, https://github.com/Database-Tycoon/tycoon-cli/issues
8
+ Author: Database Tycoon Team
9
+ License: MIT
10
+ License-File: LICENSE
11
+ Keywords: analytics,cli,data,dbt,dlt,duckdb
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Topic :: Database
18
+ Requires-Python: >=3.12
19
+ Requires-Dist: dbt-core==1.11.8
20
+ Requires-Dist: dbt-duckdb==1.10.1
21
+ Requires-Dist: dlt[duckdb]==1.24.0
22
+ Requires-Dist: duckdb==1.5.1
23
+ Requires-Dist: httpx==0.28.1
24
+ Requires-Dist: pydantic==2.12.5
25
+ Requires-Dist: pyyaml==6.0.3
26
+ Requires-Dist: rich==14.3.3
27
+ Requires-Dist: typer==0.24.1
28
+ Provides-Extra: ask
29
+ Requires-Dist: ibis-framework[duckdb]==12.0.0; extra == 'ask'
30
+ Requires-Dist: nao-core==0.0.59; extra == 'ask'
31
+ Provides-Extra: dagster
32
+ Requires-Dist: dagster-dbt==0.28.20; extra == 'dagster'
33
+ Requires-Dist: dagster-dlt==0.28.20; extra == 'dagster'
34
+ Requires-Dist: dagster-webserver==1.12.20; extra == 'dagster'
35
+ Requires-Dist: dagster==1.12.20; extra == 'dagster'
36
+ Provides-Extra: server
37
+ Requires-Dist: fastapi==0.135.3; extra == 'server'
38
+ Requires-Dist: uvicorn[standard]==0.44.0; extra == 'server'
39
+ Requires-Dist: websockets==16.0; extra == 'server'
40
+ Description-Content-Type: text/markdown
41
+
42
+ # tycoon
43
+
44
+ A pip-installable CLI that wires dlt → DuckDB → dbt → Rill into a working local analytics stack. No Docker, no cloud account required.
45
+
46
+ **Adaptable**: bring your own ingestion (Airbyte, Fivetran), warehouse (Snowflake, BigQuery, MotherDuck), dbt project, BI tool, or orchestrator — `tycoon init` asks before it assumes.
47
+
48
+ ---
49
+
50
+ ## Install
51
+
52
+ Requires Python >= 3.12.
53
+
54
+ ```bash
55
+ pip install database-tycoon
56
+ # or
57
+ uv add database-tycoon
58
+ ```
59
+
60
+ Optional extras:
61
+
62
+ ```bash
63
+ pip install "database-tycoon[dagster]" # Dagster orchestration
64
+ pip install "database-tycoon[ask]" # AI natural language queries (Ollama supported)
65
+ ```
66
+
67
+ ---
68
+
69
+ ## Quickstart
70
+
71
+ The fastest path to a working dashboard uses the PokéAPI — no credentials, no signup.
72
+
73
+ ```bash
74
+ # 1. Create a project
75
+ mkdir my-project && cd my-project
76
+ tycoon init --template csv-import
77
+
78
+ # 2. Add the PokéAPI as a source (press Enter twice for defaults)
79
+ tycoon data sources add rest_api
80
+
81
+ # 3. Ingest into DuckDB
82
+ tycoon data sources run pokeapi
83
+
84
+ # 4. Scaffold dbt models and generate Rill dashboards
85
+ tycoon data analyze pokeapi --rill
86
+
87
+ # 5. Open Rill
88
+ tycoon start --only rill
89
+ ```
90
+
91
+ Rill opens at `http://localhost:9009` with `pokemon`, `berry`, and `type` tables ready to explore.
92
+
93
+ Already have a pipeline? `tycoon init` will ask about your ingestion tool, warehouse, dbt project, BI tool, and orchestrator — and configure itself around what you already have.
94
+
95
+ ---
96
+
97
+ ## CLI Reference
98
+
99
+ | Command | Description |
100
+ |---|---|
101
+ | `tycoon init` | Scaffold a new project |
102
+ | `tycoon data sources catalog` | Browse available source integrations |
103
+ | `tycoon data sources add <type>` | Register a new data source |
104
+ | `tycoon data sources list` | List sources configured in this project |
105
+ | `tycoon data sources list show <name>` | Show detailed config for a source |
106
+ | `tycoon data sources run <name>` | Run ingestion for a named source |
107
+ | `tycoon data sources run-all` | Run ingestion for all sources |
108
+ | `tycoon data transform run` | Run dbt transformations |
109
+ | `tycoon data analyze <source>` | Scaffold dbt staging models; add `--rill` to also generate dashboards |
110
+ | `tycoon data db query <sql>` | Run a SQL query against the warehouse |
111
+ | `tycoon data run-all` | Ingest all sources then run dbt build |
112
+ | `tycoon data status` | Show freshness and row counts for each source |
113
+ | `tycoon start` | Start Rill, Dagster, Nao, and the web UI |
114
+ | `tycoon stop` | Stop all services |
115
+ | `tycoon ask chat` | Query your data in natural language (Nao) |
116
+ | `tycoon run <tool>` | Passthrough to dbt, dlt, rill, dagster |
117
+
118
+ ---
119
+
120
+ ## tycoon.yml Reference
121
+
122
+ ```yaml
123
+ name: my-project
124
+ version: 0.1.0
125
+
126
+ database:
127
+ raw: data/raw.duckdb # dlt output (or md: URI for MotherDuck)
128
+ warehouse: data/warehouse.duckdb # dbt output — read by Rill and Nao
129
+
130
+ dbt_project_dir: dbt_project # path to dbt project (yours or tycoon-scaffolded)
131
+ rill_dir: rill # path to Rill dashboard definitions
132
+
133
+ stack: # generated by tycoon init — edit as needed
134
+ ingestion: dlt # dlt | airbyte | fivetran | meltano | none
135
+ ingestion_managed: true # false = tycoon won't run `data sources run`
136
+ warehouse: duckdb # duckdb | motherduck | snowflake | bigquery | other
137
+ transformation_managed: true # false = tycoon won't scaffold or overwrite dbt
138
+ bi: rill # rill | metabase | looker | tableau | other | none
139
+ bi_managed: true # false = tycoon won't start Rill
140
+ orchestrator: dagster # dagster | airflow | prefect | other | none
141
+ orchestrator_managed: true # false = tycoon won't start Dagster
142
+
143
+ sources:
144
+ my-github:
145
+ type: github # matches a catalog source name
146
+ schema: raw_github # schema name in the raw DuckDB file
147
+ config:
148
+ access_token: ${GITHUB_TOKEN} # env vars are interpolated
149
+ owner: my-org
150
+ repo: my-repo
151
+
152
+ ask: # optional — requires tycoon[ask]
153
+ llm:
154
+ provider: ollama # fully local, no API key required
155
+ port: 5005
156
+ ```
157
+
158
+ Each source produces its own raw DuckDB file: `data/raw_<source>.duckdb`. All sources write into `data/warehouse.duckdb` after transformation.
159
+
160
+ ---
161
+
162
+ ## Catalog Sources
163
+
164
+ These sources are available via `tycoon data sources add <name>`. They are downloaded on demand via `dlt init` and not bundled in the package.
165
+
166
+ | Source | Category | Key Tables |
167
+ |---|---|---|
168
+ | `github` | Developer | commits, issues, pull_requests, repositories |
169
+ | `slack` | Communication | channels, messages, users |
170
+ | `stripe` | Finance | customers, invoices, products, subscriptions |
171
+ | `hubspot` | CRM | companies, contacts, deals, tickets |
172
+ | `notion` | Knowledge | databases, pages, users |
173
+
174
+ ---
175
+
176
+ ## Data Directory
177
+
178
+ Raw DuckDB files follow the naming convention `raw_<source>.duckdb` (written by ingestion) while `warehouse.duckdb` is the single transformed database read by Rill and Nao. See `data/README.md` for details.
179
+
180
+ ---
181
+
182
+ ## Rill Dashboards
183
+
184
+ Rill is a local-first BI tool. Dashboard definitions are YAML files in the `rill/` directory.
185
+ Launch Rill via `tycoon start` or `tycoon start --only rill`.
186
+
187
+ Auto-generate dashboards for a source after ingestion:
188
+
189
+ ```bash
190
+ tycoon data analyze my-source --rill
191
+ ```
192
+
193
+ This exports each raw table to Parquet, then generates Rill source, metrics view, and explore
194
+ files — one dashboard per table. The `--rill` flag is opt-in; dashboard generation is skipped
195
+ by default since it requires a Rill project directory (`rill/`) to already exist.
196
+
197
+ **Architecture**: sources read from Parquet via Rill's `local_file` connector into its
198
+ built-in in-memory OLAP. Dashboards are immediately usable without a dbt run.
199
+
200
+ ---
201
+
202
+ ## Optional Extras
203
+
204
+ ### Dagster orchestration (`tycoon[dagster]`)
205
+
206
+ Installs Dagster, dagster-dbt, and dagster-dlt. Provides a full asset graph covering ingestion and transformation. Run the Dagster UI with:
207
+
208
+ ```bash
209
+ dagster dev
210
+ ```
211
+
212
+ The workspace is defined in `workspace.yaml` at the project root.
213
+
214
+ ### AI queries (`tycoon[ask]`)
215
+
216
+ Installs Nao and Ibis for natural language querying of the warehouse. Requires a running LLM — Ollama (local) is supported out of the box with no API key.
217
+
218
+ ```bash
219
+ tycoon ask init
220
+ tycoon ask sync
221
+ tycoon ask chat
222
+ ```
@@ -0,0 +1,67 @@
1
+ tycoon/__init__.py,sha256=ImDNYku37x5ujYY6mb7SEOmfdmbSn9ZtIRlihPw1xxY,102
2
+ tycoon/__main__.py,sha256=yMmh1cCz2ClH8Trwestkn8OgbQOa8Fe_NgFGeOfXc8k,69
3
+ tycoon/cli.py,sha256=O2JdFR76pdt1QltdWAGQXIr_-5nNme8KLWdGqdFc1ls,2497
4
+ tycoon/config.py,sha256=9z1BRFtcxpwwX3K0ODSpmpNQ7pu1GcM-Z9EkKebQnRw,2886
5
+ tycoon/constants.py,sha256=AODZ-rshuX65i5CkmNybIzeM8TQ397YjU3STVmaoCyo,440
6
+ tycoon/dbt.py,sha256=JtrIFCENzzu5SUNfdoX_LDXN8EUfUPYRlVX_Mi7ACSA,689
7
+ tycoon/nao.py,sha256=KDq_YOAKbCXP7bW7IPLVZRKO2OhkFEZjFChY7iAJ-uo,3717
8
+ tycoon/project.py,sha256=tJtgJI-Yt8V6nBVGDZT4kKO-TOhuLsc8kMGkb5NYG9s,5474
9
+ tycoon/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
+ tycoon/commands/ask.py,sha256=vSP2yy7_5MMvyuYikhHy0jElH-jsAoI1NorZmBRElvQ,9637
11
+ tycoon/commands/data.py,sha256=GsfxqQr3Hy0SwlWCya-PVn-a3BMVszOZq-PfCQCR2dc,789
12
+ tycoon/commands/db.py,sha256=AIixLnqlYZjsw-uAs5NhPWP-l5L_c-Oeo2zo52dddTY,5192
13
+ tycoon/commands/doctor.py,sha256=mAwuzAd-qiv8-tXVCPYM9k1g40dMKkdUH8RcFEB3qa0,5057
14
+ tycoon/commands/explore.py,sha256=lg-UISHtJnweyCijVe0EnRkgeMbZqFHBwFsdCqt8DH0,6515
15
+ tycoon/commands/init.py,sha256=p9VgjYUBY_l5NhiGeJ98bSIDvWCmuM8MISGzTVla7ME,12793
16
+ tycoon/commands/run.py,sha256=WvtDFfghkp80IuKmc7YgpJJB-UP45XRwLHPyeWK-8uQ,909
17
+ tycoon/commands/run_all.py,sha256=NYUCKeaNfEosOwLHnXutqCfHjF4pUn_md-vThIlVN8M,3711
18
+ tycoon/commands/sources.py,sha256=csRlJ9cA_xmyZ-SsKyjc_RPHQKHhw3CtKS8ytoSjnXo,16962
19
+ tycoon/commands/start.py,sha256=VOkCwRDQN3ZUvD8LI-aLBj_hjT5zqluth6Bz9hZ4FuU,4188
20
+ tycoon/commands/status.py,sha256=RdlQLZGZf1NWzNmiHPzdDJB5L0eKj1r4hG8bPrC49v8,4003
21
+ tycoon/commands/stop.py,sha256=Ewgemz0CktKhJ_hKbbPoLQkcSA3L2PassR9cmgPS5b4,3474
22
+ tycoon/commands/transform.py,sha256=Jj3Cl3TJKEi-VGTeBG_M6rCiuAPQkzSg2Atgby1bcy4,5437
23
+ tycoon/ingestion/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
+ tycoon/ingestion/catalog.py,sha256=98i9t2y8XYtDpAgvTckBd20YzgK79KzkBg2WUmMsTdU,7094
25
+ tycoon/ingestion/ducklake_config.py,sha256=B17VjUMKzeQIyBc_QPvyPvsU6mjnNjc2hVwSgMmmEzo,2266
26
+ tycoon/ingestion/mta_bus_speeds_pipeline.py,sha256=MnOUEweC9zsDHRF8aeZgtOQEKxtT5DykuMTIC01O5Vg,3021
27
+ tycoon/ingestion/mta_pipeline.py,sha256=abuZUxWsA_jaq4Wg7XBQi-lJw3otxjHPu5BbilFYtfE,3331
28
+ tycoon/ingestion/nyc_dot_pipeline.py,sha256=8thZhKQAV8iWey-mkU0ohlBeDbmCtCwJXni7vt9z0v0,3237
29
+ tycoon/ingestion/runner.py,sha256=gHD3rYR6M3_hyKFUdbNBqjNgZFH-Af6d68NEKj6_EeI,8599
30
+ tycoon/ingestion/source_installer.py,sha256=hAI5z68mr8f1Uu29OwNdcT4XIqwy1mEoZ0l8CBpBywI,2137
31
+ tycoon/ingestion/source_manager.py,sha256=h2TgoltfdOzQpR-R4A2aZI6QxZOGGEwuJfbNW9Bwag8,8991
32
+ tycoon/ingestion/sources/__init__.py,sha256=w1Nz20sFyDPHN8ZGXBx8PW-rRHcWz7RMock0TwIco9Q,58
33
+ tycoon/orchestration/__init__.py,sha256=jxZUgJFa4PKYUOObgbYWlNDdtAuAxxrywW2zbN6DHDE,50
34
+ tycoon/orchestration/definitions.py,sha256=RiCj-rrlGV4gm1DsXEwBvJLBGI6bhMZfw3V97ki9xx0,1831
35
+ tycoon/orchestration/resources.py,sha256=NrGb3G55UdXAuNyRY0m9D8LJNGpZxK7xnp7W3TSJlEk,700
36
+ tycoon/orchestration/assets/__init__.py,sha256=DQrCCN6LW0Nxbo068JLzV1KWqX9qz43650may8fh8PM,44
37
+ tycoon/orchestration/assets/ingestion.py,sha256=XK1qgO-gypNkCm9A8DCNySlFdgQGzuOJV9fQDDf7Kx8,2036
38
+ tycoon/orchestration/assets/rill.py,sha256=rtcnhSH5DzGJFR8lS_LdoMZlAlCKH3k4xVKqmDPmX7c,906
39
+ tycoon/orchestration/assets/transforms.py,sha256=K_klTtUyzibA7-8yKWWLrmQp6P0OkaELKSLV_7IIhMg,577
40
+ tycoon/scaffolding/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
41
+ tycoon/scaffolding/dbt_generator.py,sha256=J_0IZioWfBH1k2Wt94Bkv2x1_WHR4mqHraI3YJWBd7o,6369
42
+ tycoon/scaffolding/rill_generator.py,sha256=0V79Bxsq9TLvvYOwmlYcPeMzgjdjL2TkIUGx6758mZQ,11028
43
+ tycoon/scaffolding/templates.py,sha256=mj_Fh-_s_hSYMjQOzJxQBoIOauSyeCCDJKB-7CXenhY,10010
44
+ tycoon/server/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
45
+ tycoon/server/app.py,sha256=OSNxqfdPJftYa5iZeAURTI4jOD56pNlNRiFqS4jIfG0,1337
46
+ tycoon/server/routes.py,sha256=P5YN__SsvwxseniX699efRQWixyHaJjqZ53irTYLo3A,4177
47
+ tycoon/server/spa.py,sha256=bAcL4Fbu3glCGvzuywMmL1NvjP_QBG9EJcSnFQNUEXU,9478
48
+ tycoon/server/subprocess_manager.py,sha256=LuuTe9zcPB_OIomyBL-4kGVcR-_wqNpFrsNagGrAIcI,2437
49
+ tycoon/server/websocket.py,sha256=tYkOuDKJ2lFI4aq3uXbyjiwn1wY-wKTDhzANk2ABPxY,1729
50
+ tycoon/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
51
+ tycoon/services/definitions.py,sha256=m63dlq4sY0s353RBoDJ_QABRQ97mZgj0gQKUVLDih6s,3025
52
+ tycoon/services/manager.py,sha256=NV6S7bQCDq47tjuM6fYH3ek6DrHl1LdBpPb9KZSv7b0,4944
53
+ tycoon/templates/csv-import/README,sha256=1p3iLV4UGF-OOLqCxsVzsvrHPU2wi1dLa6IsGFyzgkw,1174
54
+ tycoon/templates/csv-import/tycoon.yml,sha256=x2gF95ha1uan8WsdjZ5G5bZQ5S6GsmaGUgvF70jqd74,356
55
+ tycoon/templates/github-analytics/tycoon.yml,sha256=AUvSHOnvSQqKrNB8xJB8-vJIUVwpl0ygXHwu5coxX9w,591
56
+ tycoon/templates/nyc-transit/README,sha256=QxDEVburEOkn4vtON3BvKUVfnZPVFTMIjL9Yrpakua0,405
57
+ tycoon/templates/nyc-transit/tycoon.yml,sha256=gRrTpv6M_EFvopRW3bekgcmWDQ8y3Su51Tg2IZ9kKQw,1052
58
+ tycoon/templates/weather-station/tycoon.yml,sha256=6ERh6doxxyiR9as65skjMRwl4sKe5ZSdR5wlGNVySVE,481
59
+ tycoon/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
60
+ tycoon/utils/console.py,sha256=5JhuO5X9oAfvRUIMoVyxd1jEDyajL8QetrP34-THsuM,1722
61
+ tycoon/utils/duckdb_utils.py,sha256=RB6ka1ORk11soo05jGHSCIiVlZALRFLC0NKhL0D2w74,1566
62
+ tycoon/utils/process.py,sha256=Xa2IPugd4jmeoEEREczpE_WoCJGYp7eTcwjsxTMVARk,996
63
+ database_tycoon-0.1.0.dist-info/METADATA,sha256=tzS_28TYeR_qR9ow1GTuhkQi3ik5shxFMIZAtCGpfIc,7895
64
+ database_tycoon-0.1.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
65
+ database_tycoon-0.1.0.dist-info/entry_points.txt,sha256=iFuXxzrq4hM3YUaXQt8mR5R-yUKQRuMAEDcWY2uVfzU,42
66
+ database_tycoon-0.1.0.dist-info/licenses/LICENSE,sha256=z3CJiQFLI-klCa7KVfEplGwnivEbRBpG7kF6TIiTNno,1077
67
+ database_tycoon-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.29.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ tycoon = tycoon.cli:app
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Database Tycoon Team
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.
tycoon/__init__.py ADDED
@@ -0,0 +1,3 @@
1
+ """Database Tycoon — local-first analytics CLI for exploring any dataset."""
2
+
3
+ __version__ = "0.1.0"
tycoon/__main__.py ADDED
@@ -0,0 +1,5 @@
1
+ """Support `python -m tycoon`."""
2
+
3
+ from tycoon.cli import app
4
+
5
+ app()
tycoon/cli.py ADDED
@@ -0,0 +1,89 @@
1
+ """Top-level Typer app — entry point for the `tycoon` CLI."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import typer
6
+ from typer.core import TyperGroup
7
+
8
+ import tycoon
9
+
10
+ _COMMAND_ORDER = ["init", "ask", "data", "start", "stop", "run", "doctor"]
11
+
12
+ _SECTIONS = {
13
+ "init": "Project",
14
+ "ask": "AI Analytics",
15
+ "data": "Data Pipeline",
16
+ "start": "Services",
17
+ "stop": "Services",
18
+ "run": "Tools",
19
+ "doctor": "Utilities",
20
+ }
21
+
22
+
23
+ class _OrderedGroup(TyperGroup):
24
+ def list_commands(self, ctx: object) -> list[str]:
25
+ commands = super().list_commands(ctx)
26
+ return sorted(commands, key=lambda c: _COMMAND_ORDER.index(c) if c in _COMMAND_ORDER else 99)
27
+
28
+ def format_commands(self, ctx: object, formatter: object) -> None:
29
+ seen: dict[str, list[tuple[str, str]]] = {}
30
+ for name in self.list_commands(ctx):
31
+ cmd = self.commands.get(name)
32
+ if cmd is None or getattr(cmd, "hidden", False):
33
+ continue
34
+ section = _SECTIONS.get(name, "Commands")
35
+ seen.setdefault(section, []).append(
36
+ (name, cmd.get_short_help_str(limit=formatter.width))
37
+ )
38
+ for section, rows in seen.items():
39
+ with formatter.section(section):
40
+ formatter.write_dl(rows)
41
+
42
+
43
+ app = typer.Typer(
44
+ name="tycoon",
45
+ help="Database Tycoon — local-first analytics CLI for exploring any dataset.",
46
+ no_args_is_help=True,
47
+ pretty_exceptions_enable=False,
48
+ rich_markup_mode=None,
49
+ cls=_OrderedGroup,
50
+ )
51
+
52
+
53
+ def _version_callback(value: bool) -> None:
54
+ if value:
55
+ typer.echo(f"tycoon {tycoon.__version__}")
56
+ raise typer.Exit()
57
+
58
+
59
+ @app.callback()
60
+ def _root(
61
+ version: bool = typer.Option(
62
+ False,
63
+ "--version",
64
+ "-V",
65
+ help="Print version and exit.",
66
+ callback=_version_callback,
67
+ is_eager=True,
68
+ ),
69
+ ) -> None:
70
+ pass
71
+
72
+
73
+ from tycoon.commands import ask, data
74
+ from tycoon.commands.doctor import doctor_cmd
75
+ from tycoon.commands.init import init_cmd
76
+ from tycoon.commands.run import run_cmd
77
+ from tycoon.commands.start import start_cmd
78
+ from tycoon.commands.stop import stop_cmd
79
+
80
+ app.command(name="init")(init_cmd)
81
+ app.add_typer(ask.app, name="ask")
82
+ app.add_typer(data.app, name="data")
83
+ app.command(name="start")(start_cmd)
84
+ app.command(name="stop")(stop_cmd)
85
+ app.command(
86
+ name="run",
87
+ context_settings={"allow_extra_args": True, "ignore_unknown_options": True},
88
+ )(run_cmd)
89
+ app.command(name="doctor")(doctor_cmd)
File without changes