chatsbom 0.2.2__py3-none-any.whl → 0.2.4__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.
@@ -244,29 +244,42 @@ def main(
244
244
  ):
245
245
  """Index SBOM data into the database."""
246
246
 
247
+ # Check ClickHouse connection and ensure database exists
248
+ from chatsbom.core.clickhouse import check_clickhouse_connection
249
+
250
+ # First check basic connectivity
251
+ check_clickhouse_connection(
252
+ host=host,
253
+ port=port,
254
+ user=user,
255
+ password=password,
256
+ database='default',
257
+ console=console,
258
+ require_database=False,
259
+ )
260
+
247
261
  # Ensure database exists
248
262
  try:
249
- # Connect to default database first
250
263
  tmp_client = clickhouse_connect.get_client(
251
264
  host=host, port=port, username=user, password=password, database='default',
252
265
  )
253
266
  tmp_client.command(f"CREATE DATABASE IF NOT EXISTS {database}")
267
+ console.print(
268
+ f'[green]Database [cyan]{database}[/cyan] is ready.[/green]',
269
+ )
254
270
  except Exception as e:
255
271
  console.print(
256
- f'[bold red]Error:[/] Failed to connect to ClickHouse at '
257
- f'[cyan]{host}:{port}[/]\n\n'
258
- f'Details: {e}\n\n'
259
- 'Please ensure:\n'
260
- ' 1. ClickHouse is running: [cyan]docker compose up -d[/]\n'
261
- ' 2. Host and port are correct\n'
262
- ' 3. User credentials are valid',
272
+ f'[bold red]Error:[/] Failed to create database [cyan]{database}[/]\n\n'
273
+ f'Details: {e}',
263
274
  )
264
275
  raise typer.Exit(1)
265
276
 
266
277
  try:
267
278
  client = get_client(host, port, user, password, database)
268
279
  except Exception as e:
269
- console.print(f"[red]Failed to connect to ClickHouse: {e}[/red]")
280
+ console.print(
281
+ f"[red]Failed to connect to database {database}: {e}[/red]",
282
+ )
270
283
  raise typer.Exit(code=1)
271
284
 
272
285
  if clean:
@@ -68,8 +68,8 @@ def main(
68
68
 
69
69
  candidate_query = f"""
70
70
  SELECT a.name, count() as cnt
71
- FROM {db_config.artifacts_table} a
72
- JOIN {db_config.repositories_table} r ON a.repository_id = r.id
71
+ FROM {db_config.artifacts_table} FINAL a
72
+ JOIN {db_config.repositories_table} FINAL r ON a.repository_id = r.id
73
73
  WHERE a.name ILIKE {{pattern:String}} {lang_filter}
74
74
  GROUP BY a.name
75
75
  ORDER BY cnt DESC
@@ -109,8 +109,8 @@ def main(
109
109
  # Count total results first
110
110
  count_query = f"""
111
111
  SELECT count()
112
- FROM {db_config.artifacts_table} a
113
- JOIN {db_config.repositories_table} r ON a.repository_id = r.id
112
+ FROM {db_config.artifacts_table} FINAL a
113
+ JOIN {db_config.repositories_table} FINAL r ON a.repository_id = r.id
114
114
  WHERE a.name = {{library:String}} {lang_filter}
115
115
  """
116
116
 
@@ -139,8 +139,8 @@ def main(
139
139
  r.stars,
140
140
  a.version,
141
141
  r.url
142
- FROM {db_config.artifacts_table} AS a
143
- JOIN {db_config.repositories_table} AS r ON a.repository_id = r.id
142
+ FROM {db_config.artifacts_table} FINAL AS a
143
+ JOIN {db_config.repositories_table} FINAL AS r ON a.repository_id = r.id
144
144
  WHERE a.name = {{library:String}} {lang_filter}
145
145
  ORDER BY r.stars DESC
146
146
  LIMIT {{limit:UInt32}}
@@ -34,11 +34,19 @@ def main(
34
34
  database=database or config.database.database,
35
35
  )
36
36
 
37
- try:
38
- repo = SBOMRepository(db_config)
39
- except Exception as e:
40
- console.print(f"[red]Failed to connect to ClickHouse: {e}[/red]")
41
- raise typer.Exit(code=1)
37
+ # Check ClickHouse connection before proceeding
38
+ from chatsbom.core.clickhouse import check_clickhouse_connection
39
+ check_clickhouse_connection(
40
+ host=db_config.host,
41
+ port=db_config.port,
42
+ user=db_config.user,
43
+ password=db_config.password,
44
+ database=db_config.database,
45
+ console=console,
46
+ require_database=True,
47
+ )
48
+
49
+ repo = SBOMRepository(db_config)
42
50
 
43
51
  # 1. Total Counts
44
52
  try:
@@ -91,7 +99,7 @@ def main(
91
99
  # 4. Dependency Types Distribution
92
100
  try:
93
101
  type_res = repo.client.query(
94
- f'SELECT type, count() as cnt FROM {db_config.artifacts_table} GROUP BY type ORDER BY cnt DESC',
102
+ f'SELECT type, count() as cnt FROM {db_config.artifacts_table} FINAL GROUP BY type ORDER BY cnt DESC',
95
103
  ).result_rows
96
104
  except Exception as e:
97
105
  console.print(
@@ -112,7 +120,7 @@ def main(
112
120
  try:
113
121
  lang_counts = {
114
122
  row[0]: row[1] for row in repo.client.query(
115
- f'SELECT language, count() FROM {db_config.repositories_table} GROUP BY language',
123
+ f'SELECT language, count() FROM {db_config.repositories_table} FINAL GROUP BY language',
116
124
  ).result_rows
117
125
  }
118
126
  except Exception as e:
@@ -143,8 +151,8 @@ def main(
143
151
  # Query count of projects in this language using this framework
144
152
  fw_count_query = f"""
145
153
  SELECT count(DISTINCT r.id)
146
- FROM {db_config.repositories_table} r
147
- JOIN {db_config.artifacts_table} a ON r.id = a.repository_id
154
+ FROM {db_config.repositories_table} FINAL r
155
+ JOIN {db_config.artifacts_table} FINAL a ON r.id = a.repository_id
148
156
  WHERE r.language = {{lang:String}} AND a.name IN {{pkgs:Array(String)}}
149
157
  """
150
158
  fw_count = repo.client.query(
@@ -194,8 +202,8 @@ def main(
194
202
  # Query top 3 repositories for this framework
195
203
  top_repos_query = f"""
196
204
  SELECT DISTINCT r.full_name, r.stars, r.url
197
- FROM {db_config.repositories_table} r
198
- JOIN {db_config.artifacts_table} a ON r.id = a.repository_id
205
+ FROM {db_config.repositories_table} FINAL r
206
+ JOIN {db_config.artifacts_table} FINAL a ON r.id = a.repository_id
199
207
  WHERE r.language = {{lang:String}} AND a.name IN {{pkgs:Array(String)}}
200
208
  ORDER BY r.stars DESC
201
209
  LIMIT 3
@@ -101,7 +101,7 @@ class SBOMRepository:
101
101
  def get_repository_count(self) -> int:
102
102
  """Get total number of repositories."""
103
103
  result = self.client.query(
104
- f'SELECT count() FROM {self.config.repositories_table}',
104
+ f'SELECT count() FROM {self.config.repositories_table} FINAL',
105
105
  )
106
106
  return result.result_rows[0][0]
107
107
 
@@ -114,7 +114,7 @@ class SBOMRepository:
114
114
  """
115
115
  query = f"""
116
116
  SELECT language, count() as cnt
117
- FROM {self.config.repositories_table}
117
+ FROM {self.config.repositories_table} FINAL
118
118
  GROUP BY language
119
119
  ORDER BY cnt DESC
120
120
  """
@@ -140,7 +140,7 @@ class SBOMRepository:
140
140
  where_clause = f"WHERE language = '{language}'" if language else ''
141
141
  query = f"""
142
142
  SELECT full_name, stars, language, description
143
- FROM {self.config.repositories_table}
143
+ FROM {self.config.repositories_table} FINAL
144
144
  {where_clause}
145
145
  ORDER BY stars DESC
146
146
  LIMIT {limit}
@@ -201,7 +201,7 @@ class SBOMRepository:
201
201
  def get_artifact_count(self) -> int:
202
202
  """Get total number of artifacts."""
203
203
  result = self.client.query(
204
- f'SELECT count() FROM {self.config.artifacts_table}',
204
+ f'SELECT count() FROM {self.config.artifacts_table} FINAL',
205
205
  )
206
206
  return result.result_rows[0][0]
207
207
 
@@ -232,8 +232,8 @@ class SBOMRepository:
232
232
  r.language,
233
233
  a.name,
234
234
  a.version
235
- FROM {self.config.artifacts_table} a
236
- JOIN {self.config.repositories_table} r ON a.repository_id = r.id
235
+ FROM {self.config.artifacts_table} FINAL a
236
+ JOIN {self.config.repositories_table} FINAL r ON a.repository_id = r.id
237
237
  WHERE a.name LIKE %(pattern)s
238
238
  {lang_filter}
239
239
  ORDER BY r.stars DESC
@@ -269,7 +269,7 @@ class SBOMRepository:
269
269
  if language:
270
270
  lang_filter = f"""
271
271
  WHERE repository_id IN (
272
- SELECT id FROM {self.config.repositories_table}
272
+ SELECT id FROM {self.config.repositories_table} FINAL
273
273
  WHERE language = '{language}'
274
274
  )
275
275
  """
@@ -278,7 +278,7 @@ class SBOMRepository:
278
278
  SELECT
279
279
  name,
280
280
  count(DISTINCT repository_id) as repo_count
281
- FROM {self.config.artifacts_table}
281
+ FROM {self.config.artifacts_table} FINAL
282
282
  {lang_filter}
283
283
  GROUP BY name
284
284
  ORDER BY repo_count DESC
@@ -311,8 +311,8 @@ class SBOMRepository:
311
311
  a.name,
312
312
  count(DISTINCT a.repository_id) as repo_count,
313
313
  sum(r.stars) as total_stars
314
- FROM {self.config.artifacts_table} a
315
- JOIN {self.config.repositories_table} r ON a.repository_id = r.id
314
+ FROM {self.config.artifacts_table} FINAL a
315
+ JOIN {self.config.repositories_table} FINAL r ON a.repository_id = r.id
316
316
  WHERE a.name IN ('{packages_str}')
317
317
  GROUP BY a.name
318
318
  ORDER BY repo_count DESC
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: chatsbom
3
- Version: 0.2.2
3
+ Version: 0.2.4
4
4
  Summary: ChatSBOM - Talk to your Supply Chain. Chat with SBOMs.
5
5
  Requires-Python: >=3.12
6
6
  Requires-Dist: claude-agent-sdk>=0.1.0
@@ -79,7 +79,7 @@ uvx chatsbom index --language go
79
79
  uvx chatsbom status
80
80
 
81
81
  # 6. Query dependencies
82
- uvx chatsbom query gin
82
+ uvx chatsbom query gin --language go
83
83
 
84
84
  # 7. Launch AI chat interface
85
85
  uvx chatsbom chat
@@ -5,20 +5,20 @@ chatsbom/commands/chat.py,sha256=ns9DFTjGJwVD_m6K2m0Flg-LQSmmhAMKjnkzPPfBYYg,109
5
5
  chatsbom/commands/collect.py,sha256=ApweQztO889o4X4lBrxlIwdYorDUSiE01M4-XMO0HUM,16536
6
6
  chatsbom/commands/convert.py,sha256=etc6s_tT4VAvjOCZs8dnHppbTYEeAHI6kHJikkUWD64,8249
7
7
  chatsbom/commands/download.py,sha256=I9TwEXO1zrh9-DwvUUMh4iZ1W5ZCXbtE4jcJiK2KqnY,10218
8
- chatsbom/commands/index.py,sha256=B5kweeKgcHJ1ICbZ7y1f4qk9EjYoaRsAwWaYsghjEEI,10391
9
- chatsbom/commands/query.py,sha256=9mVot94ZeZ-rFZRfM3bkcNQBhWAuWqDaMJ36JcKT0zQ,5661
10
- chatsbom/commands/status.py,sha256=g0kEn4H2LYrh62_HVW72EHtICa9UlNKxHAr2oVh0tjY,8274
8
+ chatsbom/commands/index.py,sha256=DlK5FtwOFoJqy9gA6mYvfuVQLL9S15KRrH7_Qw7l0Fk,10633
9
+ chatsbom/commands/query.py,sha256=NfsQKjLwV0uCDMG89FujcPC3vc-x4wtkWcC5-gkXUoE,5697
10
+ chatsbom/commands/status.py,sha256=WbDFzIP0gC8AFrByRPvtpnEI2X8phoU5Sii4-dantys,8541
11
11
  chatsbom/core/__init__.py,sha256=x8qFrlBTgFn7TkmBN11ysPCUzRWBY350c5AN4u-3dWE,17
12
12
  chatsbom/core/clickhouse.py,sha256=sw4gWiaC2BE4QJlVWDsoDULKFB6YslB0W1FM630IY94,3530
13
13
  chatsbom/core/client.py,sha256=GSnOOAxoSUKU1pLXPX4W3cM5G4Iv7fQnknW-YkcX43Q,1400
14
14
  chatsbom/core/config.py,sha256=K4vDe387iVwwMY9aTDbDLlUPVOHCKLcA5ZMK000MQgk,3992
15
- chatsbom/core/repository.py,sha256=HUvwOAR7wFzP0Pqx3zS0sJtNIZOKBmeEcoh83sSPiUc,9765
15
+ chatsbom/core/repository.py,sha256=Un788vLvVnCNqUn9EgTplQB0--_yCVjRNMCfTzwhSm4,9825
16
16
  chatsbom/core/schema.py,sha256=oZUNNjS3UerZtIMo9-KOL-2E3XwS8FT9JNQStWq4tYE,1267
17
17
  chatsbom/core/validation.py,sha256=v4boiht4hK73nuZNYpzLTkZKsNSoFPMUDIX-8sP2E9g,3927
18
18
  chatsbom/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
19
  chatsbom/models/framework.py,sha256=Whlsbnn64YwftMifMEMVvhsWADC9uupBV4QN1i1BoNQ,2833
20
20
  chatsbom/models/language.py,sha256=RgbBQZfG630uNZ7w-BtB1LZ5B5Q_nEExGrwUadfpRqE,3601
21
- chatsbom-0.2.2.dist-info/METADATA,sha256=HC4d-l40-TAlbqxEXi69UjS6laqZe2i7yrQKMY3yiSU,4100
22
- chatsbom-0.2.2.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
23
- chatsbom-0.2.2.dist-info/entry_points.txt,sha256=906Ig6u2FwWk3ftNi4mth03N1NRgP4-B2p9kpppcqWA,51
24
- chatsbom-0.2.2.dist-info/RECORD,,
21
+ chatsbom-0.2.4.dist-info/METADATA,sha256=twAfr2y7Ix3kkFEF4Q8nuwQQ-JZ77fYSpK_1OWJWi_w,4114
22
+ chatsbom-0.2.4.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
23
+ chatsbom-0.2.4.dist-info/entry_points.txt,sha256=906Ig6u2FwWk3ftNi4mth03N1NRgP4-B2p9kpppcqWA,51
24
+ chatsbom-0.2.4.dist-info/RECORD,,