vibe-widget 0.1.0__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.
@@ -0,0 +1,17 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(tree:*)",
5
+ "Bash(python3:*)",
6
+ "Bash(pip install:*)",
7
+ "Bash(npm run build:*)",
8
+ "Bash(npm install:*)",
9
+ "Bash(chmod:*)",
10
+ "Bash(./scripts/build-react-widget.sh:*)",
11
+ "Bash(python:*)",
12
+ "Bash(pkill:*)"
13
+ ],
14
+ "deny": [],
15
+ "ask": []
16
+ }
17
+ }
@@ -0,0 +1,70 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+ build/
8
+ develop-eggs/
9
+ dist/
10
+ downloads/
11
+ eggs/
12
+ .eggs/
13
+ lib/
14
+ lib64/
15
+ parts/
16
+ sdist/
17
+ var/
18
+ wheels/
19
+ *.egg-info/
20
+ .installed.cfg
21
+ *.egg
22
+ MANIFEST
23
+
24
+ # Virtual environments
25
+ venv/
26
+ env/
27
+ ENV/
28
+ .venv
29
+
30
+ # IDEs
31
+ .vscode/
32
+ .idea/
33
+ *.swp
34
+ *.swo
35
+ *~
36
+ .DS_Store
37
+
38
+ # Testing
39
+ .pytest_cache/
40
+ .coverage
41
+ htmlcov/
42
+ .tox/
43
+ .mypy_cache/
44
+ .ruff_cache/
45
+
46
+ # Distribution
47
+ pip-wheel-metadata/
48
+
49
+ # Jupyter
50
+ .ipynb_checkpoints
51
+ *.ipynb
52
+
53
+ # Environment variables
54
+ .env
55
+ .env.local
56
+
57
+ # Generated widgets
58
+ *.html
59
+ output/
60
+
61
+ .meridian/
62
+
63
+ # Vibe widget cache
64
+ .vibe_cache/
65
+
66
+
67
+
68
+ /venv311/
69
+ **/widgets/**
70
+ /testdata/
@@ -0,0 +1,3 @@
1
+ include README.md
2
+ include LICENSE
3
+ recursive-include src/vibe_widget/widgets *.js
@@ -0,0 +1,135 @@
1
+ Metadata-Version: 2.4
2
+ Name: vibe_widget
3
+ Version: 0.1.0
4
+ Summary: Create interactive visualizations using natural language and LLMs
5
+ Project-URL: Homepage, https://github.com/yourusername/vibe-widget
6
+ Project-URL: Documentation, https://github.com/yourusername/vibe-widget#readme
7
+ Project-URL: Repository, https://github.com/yourusername/vibe-widget
8
+ Project-URL: Issues, https://github.com/yourusername/vibe-widget/issues
9
+ Author-email: Your Name <your.email@example.com>
10
+ License: MIT
11
+ Keywords: interactive,jupyter,llm,visualization,widgets
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Intended Audience :: Science/Research
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Topic :: Scientific/Engineering :: Visualization
22
+ Requires-Python: >=3.9
23
+ Requires-Dist: anthropic>=0.40.0
24
+ Requires-Dist: anywidget>=0.9.0
25
+ Requires-Dist: pandas>=2.0.0
26
+ Requires-Dist: python-dotenv>=1.0.0
27
+ Provides-Extra: dev
28
+ Requires-Dist: ipython>=8.12.0; extra == 'dev'
29
+ Requires-Dist: mypy>=1.8.0; extra == 'dev'
30
+ Requires-Dist: pytest-cov>=4.1.0; extra == 'dev'
31
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
32
+ Requires-Dist: ruff>=0.6.0; extra == 'dev'
33
+ Description-Content-Type: text/markdown
34
+
35
+ # Vibe Widget
36
+
37
+ Create interactive visualizations using natural language and LLMs.
38
+
39
+ ## Installation
40
+
41
+ ```bash
42
+ pip install vibe-widget
43
+ ```
44
+
45
+ Or with `uv`:
46
+
47
+ ```bash
48
+ uv pip install vibe-widget
49
+ ```
50
+
51
+ ## Quick Start
52
+
53
+ ```python
54
+ import pandas as pd
55
+ import vibe_widget as vw
56
+
57
+ df = pd.DataFrame({
58
+ 'height': [150, 160, 170, 180, 190],
59
+ 'weight': [50, 60, 70, 80, 90]
60
+ })
61
+
62
+ vw.create("an interactive scatterplot of height and weight", df)
63
+ ```
64
+
65
+ This will:
66
+ 1. Analyze your data structure
67
+ 2. Generate a React component via Claude API
68
+ 3. Return an HTML file with the interactive visualization
69
+
70
+ ## API Key Setup
71
+
72
+ Set your Anthropic API key:
73
+
74
+ ```bash
75
+ export ANTHROPIC_API_KEY='your-api-key-here'
76
+ ```
77
+
78
+ Or pass it directly:
79
+
80
+ ```python
81
+ vw.create(
82
+ "a bar chart of sales by region",
83
+ df,
84
+ api_key="your-api-key-here"
85
+ )
86
+ ```
87
+
88
+ ## Saving to File
89
+
90
+ ```python
91
+ vw.create(
92
+ "an interactive line chart showing trends over time",
93
+ df,
94
+ output_path="output/visualization.html"
95
+ )
96
+ ```
97
+
98
+ ## Development
99
+
100
+ Install with dev dependencies:
101
+
102
+ ```bash
103
+ pip install -e ".[dev]"
104
+ ```
105
+
106
+ Run tests:
107
+
108
+ ```bash
109
+ pytest
110
+ ```
111
+
112
+ Lint and format:
113
+
114
+ ```bash
115
+ ruff check .
116
+ ruff format .
117
+ ```
118
+
119
+ Type checking:
120
+
121
+ ```bash
122
+ mypy src/
123
+ ```
124
+
125
+ ## Features
126
+
127
+ - 🚀 Modern Python packaging (pyproject.toml, src layout)
128
+ - 🤖 LLM-powered visualization generation
129
+ - ⚛️ React-based interactive widgets
130
+ - 📊 Pandas DataFrame integration
131
+ - 🔧 Extensible LLM provider system
132
+
133
+ ## License
134
+
135
+ MIT
@@ -0,0 +1,101 @@
1
+ # Vibe Widget
2
+
3
+ Create interactive visualizations using natural language and LLMs.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install vibe-widget
9
+ ```
10
+
11
+ Or with `uv`:
12
+
13
+ ```bash
14
+ uv pip install vibe-widget
15
+ ```
16
+
17
+ ## Quick Start
18
+
19
+ ```python
20
+ import pandas as pd
21
+ import vibe_widget as vw
22
+
23
+ df = pd.DataFrame({
24
+ 'height': [150, 160, 170, 180, 190],
25
+ 'weight': [50, 60, 70, 80, 90]
26
+ })
27
+
28
+ vw.create("an interactive scatterplot of height and weight", df)
29
+ ```
30
+
31
+ This will:
32
+ 1. Analyze your data structure
33
+ 2. Generate a React component via Claude API
34
+ 3. Return an HTML file with the interactive visualization
35
+
36
+ ## API Key Setup
37
+
38
+ Set your Anthropic API key:
39
+
40
+ ```bash
41
+ export ANTHROPIC_API_KEY='your-api-key-here'
42
+ ```
43
+
44
+ Or pass it directly:
45
+
46
+ ```python
47
+ vw.create(
48
+ "a bar chart of sales by region",
49
+ df,
50
+ api_key="your-api-key-here"
51
+ )
52
+ ```
53
+
54
+ ## Saving to File
55
+
56
+ ```python
57
+ vw.create(
58
+ "an interactive line chart showing trends over time",
59
+ df,
60
+ output_path="output/visualization.html"
61
+ )
62
+ ```
63
+
64
+ ## Development
65
+
66
+ Install with dev dependencies:
67
+
68
+ ```bash
69
+ pip install -e ".[dev]"
70
+ ```
71
+
72
+ Run tests:
73
+
74
+ ```bash
75
+ pytest
76
+ ```
77
+
78
+ Lint and format:
79
+
80
+ ```bash
81
+ ruff check .
82
+ ruff format .
83
+ ```
84
+
85
+ Type checking:
86
+
87
+ ```bash
88
+ mypy src/
89
+ ```
90
+
91
+ ## Features
92
+
93
+ - 🚀 Modern Python packaging (pyproject.toml, src layout)
94
+ - 🤖 LLM-powered visualization generation
95
+ - ⚛️ React-based interactive widgets
96
+ - 📊 Pandas DataFrame integration
97
+ - 🔧 Extensible LLM provider system
98
+
99
+ ## License
100
+
101
+ MIT
@@ -0,0 +1,93 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "vibe_widget"
7
+ version = "0.1.0"
8
+ description = "Create interactive visualizations using natural language and LLMs"
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = { text = "MIT" }
12
+ authors = [
13
+ { name = "Your Name", email = "your.email@example.com" }
14
+ ]
15
+ keywords = ["visualization", "widgets", "llm", "interactive", "jupyter"]
16
+ classifiers = [
17
+ "Development Status :: 3 - Alpha",
18
+ "Intended Audience :: Developers",
19
+ "Intended Audience :: Science/Research",
20
+ "License :: OSI Approved :: MIT License",
21
+ "Programming Language :: Python :: 3",
22
+ "Programming Language :: Python :: 3.9",
23
+ "Programming Language :: Python :: 3.10",
24
+ "Programming Language :: Python :: 3.11",
25
+ "Programming Language :: Python :: 3.12",
26
+ "Topic :: Scientific/Engineering :: Visualization",
27
+ ]
28
+
29
+ dependencies = [
30
+ "anywidget>=0.9.0",
31
+ "anthropic>=0.40.0",
32
+ "pandas>=2.0.0",
33
+ "python-dotenv>=1.0.0",
34
+ ]
35
+
36
+ [project.optional-dependencies]
37
+ dev = [
38
+ "pytest>=8.0.0",
39
+ "pytest-cov>=4.1.0",
40
+ "mypy>=1.8.0",
41
+ "ruff>=0.6.0",
42
+ "ipython>=8.12.0",
43
+ ]
44
+
45
+ [project.urls]
46
+ Homepage = "https://github.com/yourusername/vibe-widget"
47
+ Documentation = "https://github.com/yourusername/vibe-widget#readme"
48
+ Repository = "https://github.com/yourusername/vibe-widget"
49
+ Issues = "https://github.com/yourusername/vibe-widget/issues"
50
+
51
+ [tool.hatch.build.targets.wheel]
52
+ packages = ["src/vibe_widget"]
53
+
54
+ [tool.ruff]
55
+ line-length = 100
56
+ target-version = "py39"
57
+
58
+ [tool.ruff.lint]
59
+ select = [
60
+ "E", # pycodestyle errors
61
+ "W", # pycodestyle warnings
62
+ "F", # pyflakes
63
+ "I", # isort
64
+ "B", # flake8-bugbear
65
+ "C4", # flake8-comprehensions
66
+ "UP", # pyupgrade
67
+ ]
68
+ ignore = [
69
+ "E501", # line too long (handled by formatter)
70
+ "B008", # do not perform function calls in argument defaults
71
+ ]
72
+
73
+ [tool.ruff.format]
74
+ quote-style = "double"
75
+ indent-style = "space"
76
+
77
+ [tool.mypy]
78
+ python_version = "3.9"
79
+ warn_return_any = true
80
+ warn_unused_configs = true
81
+ disallow_untyped_defs = true
82
+ ignore_missing_imports = true
83
+
84
+ [tool.pytest.ini_options]
85
+ testpaths = ["tests"]
86
+ python_files = ["test_*.py"]
87
+ python_classes = ["Test*"]
88
+ python_functions = ["test_*"]
89
+ addopts = [
90
+ "--strict-markers",
91
+ "--strict-config",
92
+ "--cov=vibe_widget",
93
+ ]
@@ -0,0 +1,4 @@
1
+ from vibe_widget.core import VibeWidget, create
2
+
3
+ __version__ = "0.1.0"
4
+ __all__ = ["VibeWidget", "create"]
@@ -0,0 +1,137 @@
1
+ import re
2
+ import time
3
+ from typing import Dict, List, Tuple
4
+
5
+
6
+ class CodeStreamParser:
7
+ """Parse streaming JavaScript code to detect landmarks and generate micro-updates."""
8
+
9
+ BUBBLE_COOLDOWN = 0.5 # 500ms between bubbles of same type
10
+
11
+ PATTERNS = {
12
+ "import": (
13
+ r'import\s+.*?\s+from\s+["\'](?:https?://)?(?:esm\.sh/)?([^"\'@]+)(?:@([^"\']+))?',
14
+ "📦 Importing {package}..."
15
+ ),
16
+ "function_render": (
17
+ r'function\s+render\s*\(',
18
+ "⚙️ Building render function..."
19
+ ),
20
+ "const_data": (
21
+ r'const\s+data\s*=\s*model\.get\(',
22
+ "📊 Loading data..."
23
+ ),
24
+ "svg_create": (
25
+ r'\.append\(["\']svg["\']\)',
26
+ "🎨 Creating SVG canvas..."
27
+ ),
28
+ "element_create": (
29
+ r'\.append\(["\'](?:div|canvas|g|circle|rect|path)["\']\)',
30
+ "🎨 Adding visualization elements..."
31
+ ),
32
+ "scale": (
33
+ r'd3\.scale(?:Linear|Band|Time|Point)',
34
+ "📏 Setting up scales..."
35
+ ),
36
+ "axis": (
37
+ r'd3\.axis(?:Bottom|Left|Top|Right)',
38
+ "📐 Creating axes..."
39
+ ),
40
+ "data_binding": (
41
+ r'model\.on\(["\']change:',
42
+ "🔄 Setting up reactivity..."
43
+ ),
44
+ "selection": (
45
+ r'\.selectAll\(["\'][^"\']+["\']\)',
46
+ "🎯 Binding data to elements..."
47
+ ),
48
+ "transition": (
49
+ r'\.transition\(\)',
50
+ "✨ Adding animations..."
51
+ ),
52
+ "event_listener": (
53
+ r'\.on\(["\'](?:click|mouseover|mouseout)',
54
+ "👆 Adding interactivity..."
55
+ ),
56
+ }
57
+
58
+ def __init__(self):
59
+ self.buffer = ""
60
+ self.detected = set()
61
+ self.actions = []
62
+ self.last_bubble_time = {}
63
+ self.has_new_updates = False
64
+
65
+ def parse_chunk(self, chunk: str) -> List[Dict[str, str]]:
66
+ """Parse a code chunk and return detected micro-updates."""
67
+ self.buffer += chunk
68
+ updates = []
69
+ self.has_new_updates = False
70
+ current_time = time.time()
71
+
72
+ for pattern_name, (regex, message_template) in self.PATTERNS.items():
73
+ if pattern_name in self.detected:
74
+ continue
75
+
76
+ match = re.search(regex, self.buffer)
77
+ if match:
78
+ # Check cooldown - only emit bubble if enough time has passed
79
+ if pattern_name in self.last_bubble_time:
80
+ if current_time - self.last_bubble_time[pattern_name] < self.BUBBLE_COOLDOWN:
81
+ continue # Skip this update, too soon
82
+
83
+ self.detected.add(pattern_name)
84
+ self.last_bubble_time[pattern_name] = current_time
85
+ self.has_new_updates = True
86
+
87
+ # Extract package name for imports
88
+ if pattern_name == "import" and match.groups():
89
+ package = match.group(1)
90
+ version = match.group(2) if len(match.groups()) > 1 else None
91
+ message = message_template.format(
92
+ package=f"{package}@{version}" if version else package
93
+ )
94
+ else:
95
+ message = message_template
96
+
97
+ updates.append({
98
+ "type": "micro_bubble",
99
+ "message": message,
100
+ "pattern": pattern_name,
101
+ })
102
+
103
+ # Also create action tile for imports
104
+ if pattern_name == "import":
105
+ self.actions.append({
106
+ "type": "action_tile",
107
+ "title": "Loaded dependency",
108
+ "message": message,
109
+ "icon": "📦"
110
+ })
111
+
112
+ return updates
113
+
114
+ def has_new_pattern(self) -> bool:
115
+ """Check if new patterns were detected in last parse."""
116
+ return self.has_new_updates
117
+
118
+ def get_actions(self) -> List[Dict[str, str]]:
119
+ """Get all detected actions for the timeline."""
120
+ return self.actions
121
+
122
+ def get_progress(self) -> float:
123
+ """Get code generation progress based on detected patterns (0.0 to 1.0)."""
124
+ total_patterns = len(self.PATTERNS)
125
+ detected_count = len(self.detected)
126
+ return min(1.0, detected_count / total_patterns)
127
+
128
+ def get_completion_summary(self) -> Dict[str, any]:
129
+ """Get summary of detected code features."""
130
+ return {
131
+ "total_patterns": len(self.detected),
132
+ "has_imports": "import" in self.detected,
133
+ "has_reactivity": "data_binding" in self.detected,
134
+ "has_animation": "transition" in self.detected,
135
+ "has_interaction": "event_listener" in self.detected,
136
+ "detected_patterns": list(self.detected),
137
+ }