claude-code-analytics 0.1.0__tar.gz → 0.1.1__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.
- claude_code_analytics-0.1.1/.idea/misc.xml +7 -0
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/CLAUDE.md +25 -25
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/Cargo.lock +1 -1
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/Cargo.toml +2 -2
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/PKG-INFO +37 -37
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/README.md +36 -36
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/pyproject.toml +3 -3
- {claude_code_analytics-0.1.0/python/claude_sdk → claude_code_analytics-0.1.1/python/claude_code_analytics}/__init__.py +1 -1
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/python/examples/README.md +12 -12
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/python/examples/analyze_costs.py +7 -7
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/python/examples/basic_usage.py +10 -10
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/python/examples/conversation_analysis.py +4 -4
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/python/examples/example_utils.py +6 -6
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/python/examples/export_sessions.py +5 -5
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/python/examples/tool_usage_analysis.py +6 -6
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/python/old_pyproj/__init__.py +12 -12
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/python/old_pyproj/message.py +2 -2
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/python/old_pyproj/session.py +3 -3
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/python/tests/test_edge_cases.py +4 -4
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/python/tests/test_enhanced_methods.py +15 -15
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/python/tests/test_ingtegration.py +7 -7
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/src/main.rs +1 -1
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/src/python/classes.rs +4 -4
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/src/python/functions.rs +1 -1
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/src/python/models.rs +12 -12
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/tests/debug_file.rs +1 -1
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/tests/integration_test.rs +3 -3
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/tests/parsing_test.rs +2 -2
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/tests/simple_test.rs +1 -1
- claude_code_analytics-0.1.0/.idea/misc.xml +0 -0
- claude_code_analytics-0.1.0/python/claude_sdk/_core.pyi +0 -328
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/.gitignore +0 -0
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/LICENSE +0 -0
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/docs/RUST_CLAUDE_CODE_SDK_SPECIFICATION.md +0 -0
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/python/examples/test_all_examples.py +0 -0
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/python/old_pyproj/errors.py +0 -0
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/python/old_pyproj/executor.py +0 -0
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/python/old_pyproj/models_broken.py +0 -0
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/python/old_pyproj/parser.py +0 -0
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/python/old_pyproj/utils.py +0 -0
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/python/tests/fixtures/malformed.jsonl +0 -0
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/python/tests/test_fixture_analysis.py +0 -0
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/src/conversation/mod.rs +0 -0
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/src/conversation/tree.rs +0 -0
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/src/error.rs +0 -0
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/src/lib.rs +0 -0
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/src/parser/mod.rs +0 -0
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/src/parser/session.rs +0 -0
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/src/python/exceptions.rs +0 -0
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/src/python/mod.rs +0 -0
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/src/python/utils.rs +0 -0
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/src/types/content.rs +0 -0
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/src/types/enums.rs +0 -0
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/src/types/message.rs +0 -0
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/src/types/metadata.rs +0 -0
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/src/types/mod.rs +0 -0
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/src/types/project.rs +0 -0
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/src/types/session.rs +0 -0
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/src/types/tool.rs +0 -0
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/src/utils/analysis.rs +0 -0
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/src/utils/discovery.rs +0 -0
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/src/utils/mod.rs +0 -0
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/src/utils/path.rs +0 -0
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/tests/db68d083-0471-4213-8609-356b0bf38fec.jsonl +0 -0
- {claude_code_analytics-0.1.0 → claude_code_analytics-0.1.1}/tests/fixtures/example_sample.jsonl +0 -0
@@ -0,0 +1,7 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<project version="4">
|
3
|
+
<component name="Black">
|
4
|
+
<option name="sdkName" value="Python 3.12 (rust_sdk)" />
|
5
|
+
</component>
|
6
|
+
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.12 (rust_sdk)" project-jdk-type="Python SDK" />
|
7
|
+
</project>
|
@@ -16,7 +16,7 @@ cd python
|
|
16
16
|
uv build
|
17
17
|
|
18
18
|
# Test the installation
|
19
|
-
python -c "import
|
19
|
+
python -c "import claude_code_analytics; print('✅ Import successful!')"
|
20
20
|
```
|
21
21
|
|
22
22
|
## Project Structure
|
@@ -35,7 +35,7 @@ rust_sdk/
|
|
35
35
|
│ └── ...
|
36
36
|
├── python/ # Python package
|
37
37
|
│ ├── pyproject.toml # Python build configuration
|
38
|
-
│ ├──
|
38
|
+
│ ├── claude_code_analytics/ # Python package source
|
39
39
|
│ │ └── __init__.py # Python API exports
|
40
40
|
│ └── .venv/ # Python virtual environment
|
41
41
|
├── Cargo.toml # Rust dependencies and config
|
@@ -99,7 +99,7 @@ uv build
|
|
99
99
|
uv run -m pytest tests/
|
100
100
|
|
101
101
|
# Quick import test
|
102
|
-
python -c "import
|
102
|
+
python -c "import claude_code_analytics; print('✅ Working!')"
|
103
103
|
```
|
104
104
|
|
105
105
|
### Integration Testing
|
@@ -107,8 +107,8 @@ python -c "import claude_sdk; print('✅ Working!')"
|
|
107
107
|
```bash
|
108
108
|
# Test with real session file
|
109
109
|
python -c "
|
110
|
-
import
|
111
|
-
session =
|
110
|
+
import claude_code_analytics
|
111
|
+
session = claude_code_analytics.load('path/to/session.jsonl')
|
112
112
|
print(f'Loaded session with {len(session.messages)} messages')
|
113
113
|
"
|
114
114
|
```
|
@@ -119,7 +119,7 @@ print(f'Loaded session with {len(session.messages)} messages')
|
|
119
119
|
|
120
120
|
1. **Rust changes**: Edit files in `src/`
|
121
121
|
2. **Python binding changes**: Edit files in `src/python/`
|
122
|
-
3. **Python API changes**: Edit `python/
|
122
|
+
3. **Python API changes**: Edit `python/claude_code_analytics/__init__.py`
|
123
123
|
|
124
124
|
### Rebuilding After Changes
|
125
125
|
|
@@ -130,7 +130,7 @@ cd python
|
|
130
130
|
uv build
|
131
131
|
|
132
132
|
# Test your changes
|
133
|
-
python -c "import
|
133
|
+
python -c "import claude_code_analytics; # your test code"
|
134
134
|
```
|
135
135
|
|
136
136
|
### Release Build
|
@@ -149,13 +149,13 @@ ls ../target/wheels/
|
|
149
149
|
|
150
150
|
### `Cargo.toml`
|
151
151
|
- **Package name**: `claude-code-analytics` (matches Python package)
|
152
|
-
- **Library name**: `
|
152
|
+
- **Library name**: `claude_code_analytics` (matches Python import)
|
153
153
|
- **Python feature**: Enable with `--features python`
|
154
154
|
- **Excludes**: Top-level `python/` directory from Rust build
|
155
155
|
|
156
156
|
### `python/pyproject.toml`
|
157
|
-
- **Module name**: `
|
158
|
-
- **Python packages**: `["
|
157
|
+
- **Module name**: `claude_code_analytics._core` (Rust extension)
|
158
|
+
- **Python packages**: `["claude_code_analytics"]`
|
159
159
|
- **Manifest path**: `../Cargo.toml` (points to Rust config)
|
160
160
|
|
161
161
|
## Common Issues & Solutions
|
@@ -185,25 +185,25 @@ ls ../target/wheels/
|
|
185
185
|
## Available Python API
|
186
186
|
|
187
187
|
```python
|
188
|
-
import
|
188
|
+
import claude_code_analytics
|
189
189
|
|
190
190
|
# Core functions
|
191
|
-
session =
|
192
|
-
sessions =
|
193
|
-
projects =
|
194
|
-
project =
|
191
|
+
session = claude_code_analytics.load("session.jsonl")
|
192
|
+
sessions = claude_code_analytics.find_sessions()
|
193
|
+
projects = claude_code_analytics.find_projects()
|
194
|
+
project = claude_code_analytics.load_project("project_name")
|
195
195
|
|
196
196
|
# Classes
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
197
|
+
claude_code_analytics.Session # Session data
|
198
|
+
claude_code_analytics.Message # Individual messages
|
199
|
+
claude_code_analytics.Project # Project with multiple sessions
|
200
|
+
claude_code_analytics.ToolResult # Tool execution results
|
201
201
|
|
202
202
|
# Exceptions
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
203
|
+
claude_code_analytics.ClaudeSDKError
|
204
|
+
claude_code_analytics.ParseError
|
205
|
+
claude_code_analytics.ValidationError
|
206
|
+
claude_code_analytics.SessionError
|
207
207
|
```
|
208
208
|
|
209
209
|
## Performance Notes
|
@@ -222,8 +222,8 @@ claude_sdk.SessionError
|
|
222
222
|
cargo clean
|
223
223
|
|
224
224
|
# Remove Python build artifacts
|
225
|
-
rm -rf python/
|
226
|
-
rm -rf python/
|
225
|
+
rm -rf python/claude_code_analytics/*.so
|
226
|
+
rm -rf python/claude_code_analytics/*.pyi
|
227
227
|
|
228
228
|
# Rebuild everything
|
229
229
|
uv build
|
@@ -1,13 +1,13 @@
|
|
1
1
|
[package]
|
2
2
|
name = "claude-code-analytics"
|
3
|
-
version = "0.1.
|
3
|
+
version = "0.1.1"
|
4
4
|
edition = "2021"
|
5
5
|
exclude = ["python/.venv", "python/.pytest_cache", "target/", "dist/"]
|
6
6
|
readme = "README.md"
|
7
7
|
license = "MIT"
|
8
8
|
|
9
9
|
[lib]
|
10
|
-
name = "
|
10
|
+
name = "claude_code_analytics"
|
11
11
|
crate-type = ["cdylib", "rlib"]
|
12
12
|
|
13
13
|
[features]
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: claude-code-analytics
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.1
|
4
4
|
Classifier: Development Status :: 4 - Beta
|
5
5
|
Classifier: Intended Audience :: Developers
|
6
6
|
Classifier: License :: OSI Approved :: MIT License
|
@@ -73,10 +73,10 @@ uv build
|
|
73
73
|
## Quick Start
|
74
74
|
|
75
75
|
```python
|
76
|
-
import
|
76
|
+
import claude_code_analytics
|
77
77
|
|
78
78
|
# Load a session from a JSONL file
|
79
|
-
session =
|
79
|
+
session = claude_code_analytics.load("~/.claude/projects/myproject/session_20240101_120000.jsonl")
|
80
80
|
|
81
81
|
# Basic session info
|
82
82
|
print(f"Session ID: {session.session_id}")
|
@@ -89,7 +89,7 @@ for message in session:
|
|
89
89
|
print(f"{message.role}: {message.text[:100]}...")
|
90
90
|
|
91
91
|
# Find all your sessions
|
92
|
-
sessions =
|
92
|
+
sessions = claude_code_analytics.find_sessions()
|
93
93
|
for session_path in sessions:
|
94
94
|
print(f"Found session: {session_path}")
|
95
95
|
```
|
@@ -139,7 +139,7 @@ The SDK automatically reconstructs the conversation structure, handling:
|
|
139
139
|
Load a Claude Code session from a JSONL file.
|
140
140
|
|
141
141
|
```python
|
142
|
-
session =
|
142
|
+
session = claude_code_analytics.load("path/to/session.jsonl")
|
143
143
|
```
|
144
144
|
|
145
145
|
**Parameters:**
|
@@ -158,13 +158,13 @@ Discover Claude Code session files.
|
|
158
158
|
|
159
159
|
```python
|
160
160
|
# Find all sessions
|
161
|
-
all_sessions =
|
161
|
+
all_sessions = claude_code_analytics.find_sessions()
|
162
162
|
|
163
163
|
# Find sessions in a specific project
|
164
|
-
project_sessions =
|
164
|
+
project_sessions = claude_code_analytics.find_sessions(project="myproject")
|
165
165
|
|
166
166
|
# Search in a custom location
|
167
|
-
custom_sessions =
|
167
|
+
custom_sessions = claude_code_analytics.find_sessions(base_path="/custom/path")
|
168
168
|
```
|
169
169
|
|
170
170
|
**Parameters:**
|
@@ -178,7 +178,7 @@ custom_sessions = claude_sdk.find_sessions(base_path="/custom/path")
|
|
178
178
|
Find all Claude Code projects.
|
179
179
|
|
180
180
|
```python
|
181
|
-
projects =
|
181
|
+
projects = claude_code_analytics.find_projects()
|
182
182
|
for project_path in projects:
|
183
183
|
print(f"Project: {project_path.name}")
|
184
184
|
```
|
@@ -194,10 +194,10 @@ Load an entire project with all its sessions.
|
|
194
194
|
|
195
195
|
```python
|
196
196
|
# Load by project name
|
197
|
-
project =
|
197
|
+
project = claude_code_analytics.load_project("myproject")
|
198
198
|
|
199
199
|
# Load by path
|
200
|
-
project =
|
200
|
+
project = claude_code_analytics.load_project("/path/to/project")
|
201
201
|
|
202
202
|
print(f"Total sessions: {len(project.sessions)}")
|
203
203
|
print(f"Total cost: ${project.total_cost:.2f}")
|
@@ -303,9 +303,9 @@ text_blocks = message.get_text_blocks()
|
|
303
303
|
|
304
304
|
# Get all content blocks with proper typing
|
305
305
|
for block in message.get_content_blocks():
|
306
|
-
if isinstance(block,
|
306
|
+
if isinstance(block, claude_code_analytics.TextBlock):
|
307
307
|
print(f"Text: {block.text}")
|
308
|
-
elif isinstance(block,
|
308
|
+
elif isinstance(block, claude_code_analytics.ToolUseBlock):
|
309
309
|
print(f"Tool: {block.name}")
|
310
310
|
```
|
311
311
|
|
@@ -325,7 +325,7 @@ Container for multiple sessions in a project.
|
|
325
325
|
| `total_duration` | `Optional[float]` | Total time in seconds |
|
326
326
|
|
327
327
|
```python
|
328
|
-
project =
|
328
|
+
project = claude_code_analytics.load_project("myproject")
|
329
329
|
|
330
330
|
# Analyze tool usage patterns
|
331
331
|
for tool, count in project.tool_usage_count.items():
|
@@ -396,17 +396,17 @@ for root in tree.root_messages:
|
|
396
396
|
|
397
397
|
```python
|
398
398
|
# Exception hierarchy
|
399
|
-
|
400
|
-
├──
|
401
|
-
├──
|
402
|
-
└──
|
399
|
+
claude_code_analytics.ClaudeSDKError # Base exception
|
400
|
+
├── claude_code_analytics.ParseError # JSONL parsing failed
|
401
|
+
├── claude_code_analytics.ValidationError # Invalid data
|
402
|
+
└── claude_code_analytics.SessionError # Session-specific issues
|
403
403
|
|
404
404
|
# Example handling
|
405
405
|
try:
|
406
|
-
session =
|
407
|
-
except
|
406
|
+
session = claude_code_analytics.load("session.jsonl")
|
407
|
+
except claude_code_analytics.ParseError as e:
|
408
408
|
print(f"Failed to parse: {e}")
|
409
|
-
except
|
409
|
+
except claude_code_analytics.ClaudeSDKError as e:
|
410
410
|
print(f"SDK error: {e}")
|
411
411
|
```
|
412
412
|
|
@@ -415,10 +415,10 @@ except claude_sdk.ClaudeSDKError as e:
|
|
415
415
|
### Basic Session Analysis
|
416
416
|
|
417
417
|
```python
|
418
|
-
import
|
418
|
+
import claude_code_analytics
|
419
419
|
|
420
420
|
# Load session
|
421
|
-
session =
|
421
|
+
session = claude_code_analytics.load("session.jsonl")
|
422
422
|
|
423
423
|
# Print summary
|
424
424
|
print(f"Session: {session.session_id}")
|
@@ -435,10 +435,10 @@ print(f"Total tokens: {total_tokens:,}")
|
|
435
435
|
### Tool Usage Patterns
|
436
436
|
|
437
437
|
```python
|
438
|
-
import
|
438
|
+
import claude_code_analytics
|
439
439
|
from collections import defaultdict
|
440
440
|
|
441
|
-
session =
|
441
|
+
session = claude_code_analytics.load("session.jsonl")
|
442
442
|
|
443
443
|
# Count tool usage by message
|
444
444
|
tool_messages = defaultdict(list)
|
@@ -460,16 +460,16 @@ for tool, messages in sorted(tool_messages.items()):
|
|
460
460
|
### Cost Analysis Across Projects
|
461
461
|
|
462
462
|
```python
|
463
|
-
import
|
463
|
+
import claude_code_analytics
|
464
464
|
|
465
465
|
# Find all projects
|
466
|
-
projects =
|
466
|
+
projects = claude_code_analytics.find_projects()
|
467
467
|
|
468
468
|
# Analyze costs
|
469
469
|
project_costs = []
|
470
470
|
for project_path in projects:
|
471
471
|
try:
|
472
|
-
project =
|
472
|
+
project = claude_code_analytics.load_project(project_path)
|
473
473
|
project_costs.append((project.name, project.total_cost, len(project.sessions)))
|
474
474
|
except Exception as e:
|
475
475
|
print(f"Failed to load {project_path}: {e}")
|
@@ -488,9 +488,9 @@ for name, cost, session_count in project_costs:
|
|
488
488
|
### Conversation Flow Analysis
|
489
489
|
|
490
490
|
```python
|
491
|
-
import
|
491
|
+
import claude_code_analytics
|
492
492
|
|
493
|
-
session =
|
493
|
+
session = claude_code_analytics.load("session.jsonl")
|
494
494
|
tree = session.conversation_tree
|
495
495
|
|
496
496
|
# Find branching points
|
@@ -517,11 +517,11 @@ if sidechain_messages:
|
|
517
517
|
### Exporting Session Data
|
518
518
|
|
519
519
|
```python
|
520
|
-
import
|
520
|
+
import claude_code_analytics
|
521
521
|
import json
|
522
522
|
import csv
|
523
523
|
|
524
|
-
session =
|
524
|
+
session = claude_code_analytics.load("session.jsonl")
|
525
525
|
|
526
526
|
# Export to JSON
|
527
527
|
export_data = {
|
@@ -578,7 +578,7 @@ The Claude SDK is built with Rust for exceptional performance:
|
|
578
578
|
|
579
579
|
### Common Issues
|
580
580
|
|
581
|
-
#### ImportError: No module named '
|
581
|
+
#### ImportError: No module named 'claude_code_analytics'
|
582
582
|
|
583
583
|
**Solution**: Ensure you've installed the package:
|
584
584
|
```bash
|
@@ -594,7 +594,7 @@ uv build
|
|
594
594
|
import os
|
595
595
|
path = os.path.expanduser("~/.claude/projects/myproject/session.jsonl")
|
596
596
|
if os.path.exists(path):
|
597
|
-
session =
|
597
|
+
session = claude_code_analytics.load(path)
|
598
598
|
```
|
599
599
|
|
600
600
|
#### ParseError: Invalid JSONL format
|
@@ -614,8 +614,8 @@ python -m json.tool session.jsonl
|
|
614
614
|
```python
|
615
615
|
# Instead of loading all sessions at once
|
616
616
|
sessions = []
|
617
|
-
for path in
|
618
|
-
session =
|
617
|
+
for path in claude_code_analytics.find_sessions(project="large_project"):
|
618
|
+
session = claude_code_analytics.load(path)
|
619
619
|
# Process session
|
620
620
|
del session # Free memory
|
621
621
|
```
|
@@ -629,7 +629,7 @@ import logging
|
|
629
629
|
logging.basicConfig(level=logging.DEBUG)
|
630
630
|
|
631
631
|
# Now SDK operations will print debug info
|
632
|
-
session =
|
632
|
+
session = claude_code_analytics.load("session.jsonl")
|
633
633
|
```
|
634
634
|
|
635
635
|
## Development
|
@@ -50,10 +50,10 @@ uv build
|
|
50
50
|
## Quick Start
|
51
51
|
|
52
52
|
```python
|
53
|
-
import
|
53
|
+
import claude_code_analytics
|
54
54
|
|
55
55
|
# Load a session from a JSONL file
|
56
|
-
session =
|
56
|
+
session = claude_code_analytics.load("~/.claude/projects/myproject/session_20240101_120000.jsonl")
|
57
57
|
|
58
58
|
# Basic session info
|
59
59
|
print(f"Session ID: {session.session_id}")
|
@@ -66,7 +66,7 @@ for message in session:
|
|
66
66
|
print(f"{message.role}: {message.text[:100]}...")
|
67
67
|
|
68
68
|
# Find all your sessions
|
69
|
-
sessions =
|
69
|
+
sessions = claude_code_analytics.find_sessions()
|
70
70
|
for session_path in sessions:
|
71
71
|
print(f"Found session: {session_path}")
|
72
72
|
```
|
@@ -116,7 +116,7 @@ The SDK automatically reconstructs the conversation structure, handling:
|
|
116
116
|
Load a Claude Code session from a JSONL file.
|
117
117
|
|
118
118
|
```python
|
119
|
-
session =
|
119
|
+
session = claude_code_analytics.load("path/to/session.jsonl")
|
120
120
|
```
|
121
121
|
|
122
122
|
**Parameters:**
|
@@ -135,13 +135,13 @@ Discover Claude Code session files.
|
|
135
135
|
|
136
136
|
```python
|
137
137
|
# Find all sessions
|
138
|
-
all_sessions =
|
138
|
+
all_sessions = claude_code_analytics.find_sessions()
|
139
139
|
|
140
140
|
# Find sessions in a specific project
|
141
|
-
project_sessions =
|
141
|
+
project_sessions = claude_code_analytics.find_sessions(project="myproject")
|
142
142
|
|
143
143
|
# Search in a custom location
|
144
|
-
custom_sessions =
|
144
|
+
custom_sessions = claude_code_analytics.find_sessions(base_path="/custom/path")
|
145
145
|
```
|
146
146
|
|
147
147
|
**Parameters:**
|
@@ -155,7 +155,7 @@ custom_sessions = claude_sdk.find_sessions(base_path="/custom/path")
|
|
155
155
|
Find all Claude Code projects.
|
156
156
|
|
157
157
|
```python
|
158
|
-
projects =
|
158
|
+
projects = claude_code_analytics.find_projects()
|
159
159
|
for project_path in projects:
|
160
160
|
print(f"Project: {project_path.name}")
|
161
161
|
```
|
@@ -171,10 +171,10 @@ Load an entire project with all its sessions.
|
|
171
171
|
|
172
172
|
```python
|
173
173
|
# Load by project name
|
174
|
-
project =
|
174
|
+
project = claude_code_analytics.load_project("myproject")
|
175
175
|
|
176
176
|
# Load by path
|
177
|
-
project =
|
177
|
+
project = claude_code_analytics.load_project("/path/to/project")
|
178
178
|
|
179
179
|
print(f"Total sessions: {len(project.sessions)}")
|
180
180
|
print(f"Total cost: ${project.total_cost:.2f}")
|
@@ -280,9 +280,9 @@ text_blocks = message.get_text_blocks()
|
|
280
280
|
|
281
281
|
# Get all content blocks with proper typing
|
282
282
|
for block in message.get_content_blocks():
|
283
|
-
if isinstance(block,
|
283
|
+
if isinstance(block, claude_code_analytics.TextBlock):
|
284
284
|
print(f"Text: {block.text}")
|
285
|
-
elif isinstance(block,
|
285
|
+
elif isinstance(block, claude_code_analytics.ToolUseBlock):
|
286
286
|
print(f"Tool: {block.name}")
|
287
287
|
```
|
288
288
|
|
@@ -302,7 +302,7 @@ Container for multiple sessions in a project.
|
|
302
302
|
| `total_duration` | `Optional[float]` | Total time in seconds |
|
303
303
|
|
304
304
|
```python
|
305
|
-
project =
|
305
|
+
project = claude_code_analytics.load_project("myproject")
|
306
306
|
|
307
307
|
# Analyze tool usage patterns
|
308
308
|
for tool, count in project.tool_usage_count.items():
|
@@ -373,17 +373,17 @@ for root in tree.root_messages:
|
|
373
373
|
|
374
374
|
```python
|
375
375
|
# Exception hierarchy
|
376
|
-
|
377
|
-
├──
|
378
|
-
├──
|
379
|
-
└──
|
376
|
+
claude_code_analytics.ClaudeSDKError # Base exception
|
377
|
+
├── claude_code_analytics.ParseError # JSONL parsing failed
|
378
|
+
├── claude_code_analytics.ValidationError # Invalid data
|
379
|
+
└── claude_code_analytics.SessionError # Session-specific issues
|
380
380
|
|
381
381
|
# Example handling
|
382
382
|
try:
|
383
|
-
session =
|
384
|
-
except
|
383
|
+
session = claude_code_analytics.load("session.jsonl")
|
384
|
+
except claude_code_analytics.ParseError as e:
|
385
385
|
print(f"Failed to parse: {e}")
|
386
|
-
except
|
386
|
+
except claude_code_analytics.ClaudeSDKError as e:
|
387
387
|
print(f"SDK error: {e}")
|
388
388
|
```
|
389
389
|
|
@@ -392,10 +392,10 @@ except claude_sdk.ClaudeSDKError as e:
|
|
392
392
|
### Basic Session Analysis
|
393
393
|
|
394
394
|
```python
|
395
|
-
import
|
395
|
+
import claude_code_analytics
|
396
396
|
|
397
397
|
# Load session
|
398
|
-
session =
|
398
|
+
session = claude_code_analytics.load("session.jsonl")
|
399
399
|
|
400
400
|
# Print summary
|
401
401
|
print(f"Session: {session.session_id}")
|
@@ -412,10 +412,10 @@ print(f"Total tokens: {total_tokens:,}")
|
|
412
412
|
### Tool Usage Patterns
|
413
413
|
|
414
414
|
```python
|
415
|
-
import
|
415
|
+
import claude_code_analytics
|
416
416
|
from collections import defaultdict
|
417
417
|
|
418
|
-
session =
|
418
|
+
session = claude_code_analytics.load("session.jsonl")
|
419
419
|
|
420
420
|
# Count tool usage by message
|
421
421
|
tool_messages = defaultdict(list)
|
@@ -437,16 +437,16 @@ for tool, messages in sorted(tool_messages.items()):
|
|
437
437
|
### Cost Analysis Across Projects
|
438
438
|
|
439
439
|
```python
|
440
|
-
import
|
440
|
+
import claude_code_analytics
|
441
441
|
|
442
442
|
# Find all projects
|
443
|
-
projects =
|
443
|
+
projects = claude_code_analytics.find_projects()
|
444
444
|
|
445
445
|
# Analyze costs
|
446
446
|
project_costs = []
|
447
447
|
for project_path in projects:
|
448
448
|
try:
|
449
|
-
project =
|
449
|
+
project = claude_code_analytics.load_project(project_path)
|
450
450
|
project_costs.append((project.name, project.total_cost, len(project.sessions)))
|
451
451
|
except Exception as e:
|
452
452
|
print(f"Failed to load {project_path}: {e}")
|
@@ -465,9 +465,9 @@ for name, cost, session_count in project_costs:
|
|
465
465
|
### Conversation Flow Analysis
|
466
466
|
|
467
467
|
```python
|
468
|
-
import
|
468
|
+
import claude_code_analytics
|
469
469
|
|
470
|
-
session =
|
470
|
+
session = claude_code_analytics.load("session.jsonl")
|
471
471
|
tree = session.conversation_tree
|
472
472
|
|
473
473
|
# Find branching points
|
@@ -494,11 +494,11 @@ if sidechain_messages:
|
|
494
494
|
### Exporting Session Data
|
495
495
|
|
496
496
|
```python
|
497
|
-
import
|
497
|
+
import claude_code_analytics
|
498
498
|
import json
|
499
499
|
import csv
|
500
500
|
|
501
|
-
session =
|
501
|
+
session = claude_code_analytics.load("session.jsonl")
|
502
502
|
|
503
503
|
# Export to JSON
|
504
504
|
export_data = {
|
@@ -555,7 +555,7 @@ The Claude SDK is built with Rust for exceptional performance:
|
|
555
555
|
|
556
556
|
### Common Issues
|
557
557
|
|
558
|
-
#### ImportError: No module named '
|
558
|
+
#### ImportError: No module named 'claude_code_analytics'
|
559
559
|
|
560
560
|
**Solution**: Ensure you've installed the package:
|
561
561
|
```bash
|
@@ -571,7 +571,7 @@ uv build
|
|
571
571
|
import os
|
572
572
|
path = os.path.expanduser("~/.claude/projects/myproject/session.jsonl")
|
573
573
|
if os.path.exists(path):
|
574
|
-
session =
|
574
|
+
session = claude_code_analytics.load(path)
|
575
575
|
```
|
576
576
|
|
577
577
|
#### ParseError: Invalid JSONL format
|
@@ -591,8 +591,8 @@ python -m json.tool session.jsonl
|
|
591
591
|
```python
|
592
592
|
# Instead of loading all sessions at once
|
593
593
|
sessions = []
|
594
|
-
for path in
|
595
|
-
session =
|
594
|
+
for path in claude_code_analytics.find_sessions(project="large_project"):
|
595
|
+
session = claude_code_analytics.load(path)
|
596
596
|
# Process session
|
597
597
|
del session # Free memory
|
598
598
|
```
|
@@ -606,7 +606,7 @@ import logging
|
|
606
606
|
logging.basicConfig(level=logging.DEBUG)
|
607
607
|
|
608
608
|
# Now SDK operations will print debug info
|
609
|
-
session =
|
609
|
+
session = claude_code_analytics.load("session.jsonl")
|
610
610
|
```
|
611
611
|
|
612
612
|
## Development
|
@@ -1,6 +1,6 @@
|
|
1
1
|
[project]
|
2
2
|
name = "claude-code-analytics"
|
3
|
-
version = "0.1.
|
3
|
+
version = "0.1.1"
|
4
4
|
description = "Python SDK for Claude Code with Rust core"
|
5
5
|
authors = [{ name = "Darin Kishore", email = "darinkishore@protonmail.com" }]
|
6
6
|
requires-python = ">=3.11"
|
@@ -25,8 +25,8 @@ Repository = "https://github.com/darinkishore/rust_sdk.git"
|
|
25
25
|
Issues = "https://github.com/darinkishore/rust_sdk/issues"
|
26
26
|
|
27
27
|
[tool.maturin]
|
28
|
-
module-name = "
|
29
|
-
python-packages = ["
|
28
|
+
module-name = "claude_code_analytics._core"
|
29
|
+
python-packages = ["claude_code_analytics"]
|
30
30
|
features = ["python"]
|
31
31
|
manifest-path = "Cargo.toml"
|
32
32
|
binding = "pyo3"
|