cometapi-cli 0.3.5__py3-none-any.whl → 0.3.6__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.
cometapi_cli/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  """CometAPI CLI — professional terminal interface for CometAPI."""
2
2
 
3
- __version__ = "0.3.5"
3
+ __version__ = "0.3.6"
cometapi_cli/client.py CHANGED
@@ -161,7 +161,6 @@ class CometClient(openai.OpenAI):
161
161
  start_timestamp: int | None = None,
162
162
  end_timestamp: int | None = None,
163
163
  group: str | None = None,
164
- request_id: str | None = None,
165
164
  ) -> dict:
166
165
  """List the user's usage logs (requires access token)."""
167
166
  params: dict[str, Any] = {"p": page, "page_size": page_size}
@@ -177,10 +176,35 @@ class CometClient(openai.OpenAI):
177
176
  params["end_timestamp"] = end_timestamp
178
177
  if group:
179
178
  params["group"] = group
180
- if request_id:
181
- params["request_id"] = request_id
182
179
  return self._account_request("GET", "/api/log/self", params=params)
183
180
 
181
+ def lookup_log(
182
+ self,
183
+ *,
184
+ request_id: str,
185
+ log_type: int | None = None,
186
+ model_name: str | None = None,
187
+ token_name: str | None = None,
188
+ start_timestamp: int | None = None,
189
+ end_timestamp: int | None = None,
190
+ group: str | None = None,
191
+ ) -> dict:
192
+ """Look up one usage log by request ID using the indexed operator endpoint."""
193
+ params: dict[str, Any] = {"p": 1, "page_size": 1, "request_id": request_id}
194
+ if log_type is not None:
195
+ params["type"] = log_type
196
+ if model_name:
197
+ params["model_name"] = model_name
198
+ if token_name:
199
+ params["token_name"] = token_name
200
+ if start_timestamp is not None:
201
+ params["start_timestamp"] = start_timestamp
202
+ if end_timestamp is not None:
203
+ params["end_timestamp"] = end_timestamp
204
+ if group:
205
+ params["group"] = group
206
+ return self._account_request("GET", "/api/log/", params=params)
207
+
184
208
  def search_logs(self, keyword: str) -> dict:
185
209
  """Search usage logs by keyword (requires access token)."""
186
210
  return self._account_request("GET", "/api/log/self/search", params={"keyword": keyword})
@@ -4,7 +4,6 @@ from __future__ import annotations
4
4
 
5
5
  import json as _json
6
6
  import sys
7
- from datetime import datetime, time, timedelta, timezone
8
7
  from typing import Annotated
9
8
 
10
9
  import typer
@@ -32,9 +31,6 @@ LOG_TYPE_MAP = {
32
31
  }
33
32
 
34
33
  _LOG_TYPE_NAMES = {v: k for k, v in LOG_TYPE_MAP.items()}
35
- REQUEST_ID_PAGE_SIZE = 100
36
- REQUEST_ID_DEFAULT_MAX_PAGES = 10
37
- REQUEST_ID_LOCAL_TZ = timezone(timedelta(hours=8))
38
34
 
39
35
 
40
36
  def _parse_other(other_raw: str | None) -> dict:
@@ -48,21 +44,6 @@ def _parse_other(other_raw: str | None) -> dict:
48
44
  return {}
49
45
 
50
46
 
51
- def _request_id_date_window(request_id: str) -> tuple[int, int] | None:
52
- """Infer the local request day from a CometAPI request ID prefix."""
53
- prefix = request_id[:14]
54
- if len(prefix) != 14 or not prefix.isdigit():
55
- return None
56
- try:
57
- local_dt = datetime.strptime(prefix, "%Y%m%d%H%M%S").replace(tzinfo=REQUEST_ID_LOCAL_TZ)
58
- except ValueError:
59
- return None
60
-
61
- local_day_start = datetime.combine(local_dt.date(), time.min, tzinfo=REQUEST_ID_LOCAL_TZ)
62
- local_day_end = local_day_start + timedelta(days=1) - timedelta(seconds=1)
63
- return int(local_day_start.timestamp()), int(local_day_end.timestamp())
64
-
65
-
66
47
  def _exact_request_id_match(items: list, request_id: str) -> dict | None:
67
48
  for item in items:
68
49
  if isinstance(item, dict) and item.get("request_id") == request_id:
@@ -80,59 +61,18 @@ def _lookup_log_by_id(
80
61
  start_timestamp: int | None = None,
81
62
  end_timestamp: int | None = None,
82
63
  group: str | None = None,
83
- max_pages: int = REQUEST_ID_DEFAULT_MAX_PAGES,
84
- ) -> tuple[dict | None, dict]:
85
- """Look up a log entry by request ID, using server filtering before fallback scans."""
86
- meta = {
87
- "used_server_filter": False,
88
- "used_inferred_window": False,
89
- "scanned_pages": 0,
90
- "max_pages": max_pages,
91
- }
92
-
93
- # Older backends may ignore request_id, so verify the returned item matches
94
- # before trusting this direct lookup.
95
- resp = client.list_logs( # type: ignore[union-attr]
96
- page=1,
97
- page_size=REQUEST_ID_PAGE_SIZE,
64
+ ) -> dict | None:
65
+ """Look up a log entry by request ID without falling back to page scans."""
66
+ resp = client.lookup_log( # type: ignore[union-attr]
67
+ request_id=request_id,
98
68
  log_type=log_type,
99
69
  model_name=model_name,
100
70
  token_name=token_name,
101
71
  start_timestamp=start_timestamp,
102
72
  end_timestamp=end_timestamp,
103
73
  group=group,
104
- request_id=request_id,
105
74
  )
106
- meta["used_server_filter"] = True
107
- if match := _exact_request_id_match(extract_items(resp), request_id):
108
- return match, meta
109
-
110
- scan_start = start_timestamp
111
- scan_end = end_timestamp
112
- if scan_start is None and scan_end is None:
113
- inferred = _request_id_date_window(request_id)
114
- if inferred:
115
- scan_start, scan_end = inferred
116
- meta["used_inferred_window"] = True
117
-
118
- for pg in range(1, max_pages + 1):
119
- resp = client.list_logs( # type: ignore[union-attr]
120
- page=pg,
121
- page_size=REQUEST_ID_PAGE_SIZE,
122
- log_type=log_type,
123
- model_name=model_name,
124
- token_name=token_name,
125
- start_timestamp=scan_start,
126
- end_timestamp=scan_end,
127
- group=group,
128
- )
129
- meta["scanned_pages"] = pg
130
- items = extract_items(resp)
131
- if not items:
132
- break
133
- if match := _exact_request_id_match(items, request_id):
134
- return match, meta
135
- return None, meta
75
+ return _exact_request_id_match(extract_items(resp), request_id)
136
76
 
137
77
 
138
78
  def _build_log_record(log: dict) -> dict:
@@ -284,14 +224,6 @@ def logs(
284
224
  str | None,
285
225
  typer.Option("--request-id", help="Look up cost by request ID (X-Cometapi-Request-Id header)."),
286
226
  ] = None,
287
- request_id_max_pages: Annotated[
288
- int,
289
- typer.Option(
290
- "--request-id-max-pages",
291
- min=1,
292
- help="Fallback pages to scan when direct request-ID lookup is unavailable.",
293
- ),
294
- ] = REQUEST_ID_DEFAULT_MAX_PAGES,
295
227
  detail: Annotated[
296
228
  bool,
297
229
  typer.Option("--detail", help="Show extended columns (request ID, pricing ratios)."),
@@ -325,7 +257,7 @@ def logs(
325
257
  if log_type:
326
258
  type_int = LOG_TYPE_MAP.get(log_type.lower())
327
259
 
328
- log_entry, lookup_meta = _lookup_log_by_id(
260
+ log_entry = _lookup_log_by_id(
329
261
  client,
330
262
  request_id=request_id,
331
263
  log_type=type_int,
@@ -334,22 +266,15 @@ def logs(
334
266
  start_timestamp=start_ts,
335
267
  end_timestamp=end_ts,
336
268
  group=group,
337
- max_pages=request_id_max_pages,
338
269
  )
339
270
 
340
271
  if log_entry is None:
341
- if lookup_meta["used_inferred_window"]:
342
- scan_note = (
343
- f"Then scanned {lookup_meta['scanned_pages']} page(s) in the request ID's "
344
- "inferred local date window."
345
- )
346
- else:
347
- scan_note = f"Then scanned {lookup_meta['scanned_pages']} fallback page(s)."
348
272
  err_console.print(
349
273
  f"[red]No log found for request_id=[/]{request_id}\n"
350
- "[dim]Tried direct request-id lookup first. "
351
- f"{scan_note} Increase --request-id-max-pages or narrow with --start/--end "
352
- "if the backend does not support direct request-id filtering.[/]"
274
+ "[dim]Tried one indexed lookup against /api/log with request_id. "
275
+ "No fallback page scan was performed because /api/log/self does not "
276
+ "currently apply request_id filtering. Use an operations/admin access token "
277
+ "or update the backend self-log endpoint to support request_id filtering.[/]"
353
278
  )
354
279
  raise typer.Exit(code=1)
355
280
 
@@ -399,7 +324,6 @@ def logs(
399
324
  start_timestamp=start_ts,
400
325
  end_timestamp=end_ts,
401
326
  group=group,
402
- request_id=None,
403
327
  )
404
328
 
405
329
  data = extract_items(resp)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cometapi-cli
3
- Version: 0.3.5
3
+ Version: 0.3.6
4
4
  Summary: CometAPI CLI — official command-line interface for the CometAPI AI gateway
5
5
  Project-URL: Homepage, https://pypi.org/project/cometapi-cli/
6
6
  Project-URL: Documentation, https://apidoc.cometapi.com/libraries/cli/overview
@@ -156,9 +156,9 @@ cometapi logs --type consume --start 2026-06-01 --json
156
156
  cometapi logs --request-id 20260617165550885561292gJBlzjtp
157
157
  ```
158
158
 
159
- `logs --request-id` first asks the backend for that exact request ID. If the installed
160
- backend does not support direct request-ID filtering yet, the CLI falls back to scanning
161
- a bounded number of log pages. Use `--request-id-max-pages` to widen that fallback scan.
159
+ `logs --request-id` performs one indexed lookup against the operator log endpoint and
160
+ accepts only an exact `request_id` match. The CLI does not scan fallback log pages,
161
+ because the self-log endpoint does not currently apply `request_id` filtering.
162
162
 
163
163
  ## Models
164
164
 
@@ -1,7 +1,7 @@
1
- cometapi_cli/__init__.py,sha256=iWnDoeAexgv0uI8MY7FPkoyOJLyoPyoDgNeMvB6CIXw,92
1
+ cometapi_cli/__init__.py,sha256=vXkHbUQYPVVuqrSa6Fz9KuR8AU-NkIpO2liuMYMO0Ow,92
2
2
  cometapi_cli/app.py,sha256=d2IZJabWmdZtPtFNOB4YiuSJ1GYvO0hgIOkjm4gQjxA,2948
3
3
  cometapi_cli/catalog.py,sha256=Pc0XGoskMEKIzfbU2H_0Yi8zecLzKl1ss8fd2mV7778,4929
4
- cometapi_cli/client.py,sha256=QBtQ1cvmwvwjpIYpzupC3BMNqxREhMoRnzgCZOeJnEE,9998
4
+ cometapi_cli/client.py,sha256=zg0QEjDOxvZkkZ0XHXoiQ_A_yooDU1kokbIL61p_NmQ,10903
5
5
  cometapi_cli/config.py,sha256=oJXQidKCOsKNYPnE8OfLLoOfsv0MSZEDICB6VShJRSA,3307
6
6
  cometapi_cli/console.py,sha256=HFSU1gL9SDmwjBvgVgDraoaU50oTwCRpsAwYXYlVP9o,163
7
7
  cometapi_cli/constants.py,sha256=UPfU36fnRTl4JdcyjySQ0UEVign3i_UTNH9mQ-Gb4ls,1826
@@ -16,7 +16,7 @@ cometapi_cli/commands/chat.py,sha256=xQgsjFQ33kVRfSnU5t3fbahjZE8nmVSa_w8qUTPeacE
16
16
  cometapi_cli/commands/chat_repl.py,sha256=b9lkYnbbaOb0AlSpRcq3wWHmnhtTXvaqeJiUImsMEBY,8176
17
17
  cometapi_cli/commands/config_cmd.py,sha256=OqR0TuAq6gQXw8nJIt5AAv_Fk4zdfbg-KhNLuUsrEsU,8619
18
18
  cometapi_cli/commands/doctor.py,sha256=s9XzRIkF9FIMAWSc7b3c6v3g8Px9kb0k6WDucOrdXY8,5360
19
- cometapi_cli/commands/logs.py,sha256=__6Ft5TpBwVtRPTkFbmCjnriGfb1CBNGgGH_CWFmOeY,16082
19
+ cometapi_cli/commands/logs.py,sha256=VxUND6YIbzN4K2u0FHnFh6nmbyD4Hs2OmSuamJmpmGw,13318
20
20
  cometapi_cli/commands/model.py,sha256=YyMRt6enCAZfxW_dVcNvdNgYSl-J4iOqPlSsv14nfJs,2654
21
21
  cometapi_cli/commands/models.py,sha256=1TQC8LJ6JASErkLG5XtaZyRrq4vr4sVWH7eo426FeNs,8824
22
22
  cometapi_cli/commands/repl.py,sha256=b5z1jmEXOsCrb6fwEUyv-IKot929NIPQQAbA1uas1D4,4283
@@ -24,8 +24,8 @@ cometapi_cli/commands/run.py,sha256=JQQ1DFSyJoD4pByLmhMht1-XhDDZpV94F0hshXL7hKY,
24
24
  cometapi_cli/commands/stats.py,sha256=bEVywsom7bm8AGKGWlgAWTFjOp4NTJxDk6YEEvECM6U,1411
25
25
  cometapi_cli/commands/tasks.py,sha256=NBKOKrDow52sVjoM0ezwS9IhVRltlqYLmpamoEUbAWA,4718
26
26
  cometapi_cli/commands/tokens.py,sha256=U0AI8T690NJxAKFBwrWrsr3izXIiB_PZ9avmwpdgM9A,3042
27
- cometapi_cli-0.3.5.dist-info/METADATA,sha256=QNozKU1kN57hrfCXF-fizdkmWE2IkqxkScqxIsoFWzU,10646
28
- cometapi_cli-0.3.5.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
29
- cometapi_cli-0.3.5.dist-info/entry_points.txt,sha256=xoiE2ZVNNWXTq0JRBtzC8hJ2JkdKuaBNz_fEd8OJpLs,50
30
- cometapi_cli-0.3.5.dist-info/licenses/LICENSE,sha256=-rBwHQzkmLbty07abmGvQvsRrvDeEQUkPDhNJfTcjdE,1065
31
- cometapi_cli-0.3.5.dist-info/RECORD,,
27
+ cometapi_cli-0.3.6.dist-info/METADATA,sha256=ykOW7C9QdwBX2anfx1S6q2vm4oQuI-rkZrwVDWAo0t0,10630
28
+ cometapi_cli-0.3.6.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
29
+ cometapi_cli-0.3.6.dist-info/entry_points.txt,sha256=xoiE2ZVNNWXTq0JRBtzC8hJ2JkdKuaBNz_fEd8OJpLs,50
30
+ cometapi_cli-0.3.6.dist-info/licenses/LICENSE,sha256=-rBwHQzkmLbty07abmGvQvsRrvDeEQUkPDhNJfTcjdE,1065
31
+ cometapi_cli-0.3.6.dist-info/RECORD,,