Skip to content

Commit 73ef1ec

Browse files
authored
Merge pull request #2 from aptabase/fix/textual_samples
fix: add textual samples
2 parents 16af2fd + e15b73a commit 73ef1ec

File tree

7 files changed

+1166
-0
lines changed

7 files changed

+1166
-0
lines changed

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ line-ending = "auto"
7373
mypy_path = "src"
7474
explicit_package_bases = true
7575
namespace_packages = true
76+
exclude = ["samples/", "testcases/"]
7677
follow_imports = "silent"
7778
warn_redundant_casts = true
7879
warn_unused_ignores = true
Lines changed: 298 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,298 @@
1+
# Simple Counter - Textual + Aptabase
2+
3+
A minimal example demonstrating how to integrate [Aptabase](https://aptabase.com/) analytics into a [Textual](https://textual.textualize.io/) TUI application.
4+
5+
Perfect for learning the basics of adding privacy-first analytics to your terminal apps!
6+
7+
## 🎯 What It Does
8+
9+
This is a simple counter app that:
10+
- Increments a counter when you click a button
11+
- Resets the counter to zero
12+
- Tracks all interactions with Aptabase analytics
13+
- Shows notifications for user feedback
14+
15+
## 📸 Features
16+
17+
- **Clean UI**: Centered layout with large counter display
18+
- **Two Buttons**:
19+
- "Click Me!" - Increments the counter
20+
- "Reset" - Resets to zero
21+
- **Analytics Tracking**:
22+
- App start/stop events
23+
- Button clicks with counter values
24+
- Reset actions with previous count
25+
- Session duration
26+
27+
## 🚀 Quick Start
28+
29+
### Installation
30+
31+
#### Using uv (recommended)
32+
33+
```bash
34+
# Install dependencies
35+
uv pip install textual aptabase
36+
37+
# Run the app
38+
uv run main.py
39+
```
40+
41+
#### Using pip
42+
43+
```bash
44+
# Create and activate virtual environment
45+
python -m venv venv
46+
source venv/bin/activate # On Windows: venv\Scripts\activate
47+
48+
# Install dependencies
49+
pip install textual aptabase
50+
51+
# Run the app
52+
python main.py
53+
```
54+
55+
#### Using pyproject.toml
56+
57+
```bash
58+
# If you have the pyproject.toml file
59+
uv sync
60+
uv run counter
61+
```
62+
63+
## ⚙️ Configuration
64+
65+
Before running, you need to set your Aptabase app key:
66+
67+
1. Sign up at [aptabase.com](https://aptabase.com/)
68+
2. Create a new app
69+
3. Copy your app key (format: `A-EU-XXXXXXXXXX` or `A-US-XXXXXXXXXX`)
70+
4. Update the key in `simple_counter.py`:
71+
72+
```python
73+
# Replace with your actual Aptabase app key
74+
app = CounterApp(app_key="A-EU-XXXXXXXXXX")
75+
```
76+
77+
## 📊 Tracked Events
78+
79+
The app automatically tracks:
80+
81+
### 1. **app_started**
82+
Sent when the app launches.
83+
84+
```python
85+
{
86+
"event": "app_started"
87+
}
88+
```
89+
90+
### 2. **button_clicked**
91+
Sent when "Click Me!" is pressed.
92+
93+
```python
94+
{
95+
"event": "button_clicked",
96+
"action": "increment",
97+
"count": 5 # Current counter value
98+
}
99+
```
100+
101+
### 3. **counter_reset**
102+
Sent when "Reset" is pressed.
103+
104+
```python
105+
{
106+
"event": "counter_reset",
107+
"previous_count": 10 # Value before reset
108+
}
109+
```
110+
111+
### 4. **app_closed**
112+
Sent when the app exits.
113+
114+
```python
115+
{
116+
"event": "app_closed",
117+
"final_count": 7 # Final counter value
118+
}
119+
```
120+
121+
## 🎮 Usage
122+
123+
1. **Start the app**: Run `python simple_counter.py`
124+
2. **Click the button**: Press "Click Me!" to increment (or press `Enter` when focused)
125+
3. **Reset**: Click "Reset" to set counter back to zero
126+
4. **Quit**: Press `q` or `Ctrl+C`
127+
128+
## 💻 Code Structure
129+
130+
```python
131+
class CounterApp(App):
132+
def __init__(self, app_key: str):
133+
# Initialize with your Aptabase key
134+
135+
async def on_mount(self):
136+
# Start Aptabase when app starts
137+
138+
async def on_unmount(self):
139+
# Stop Aptabase and send final events
140+
141+
async def on_button_pressed(self, event):
142+
# Handle button clicks and track events
143+
```
144+
145+
### Key Components
146+
147+
**Aptabase Initialization:**
148+
```python
149+
self.aptabase = Aptabase(
150+
app_key=self.app_key,
151+
app_version="1.0.0",
152+
is_debug=True # Shows debug info
153+
)
154+
await self.aptabase.start()
155+
```
156+
157+
**Tracking Events:**
158+
```python
159+
await self.aptabase.track("button_clicked", {
160+
"action": "increment",
161+
"count": self.counter
162+
})
163+
```
164+
165+
**Cleanup:**
166+
```python
167+
await self.aptabase.stop() # Flushes pending events
168+
```
169+
170+
## 🔧 Customization Ideas
171+
172+
Here are some ways to extend this app:
173+
174+
### Add More Buttons
175+
```python
176+
yield Button("Increment by 5", id="btn-plus5")
177+
yield Button("Decrement", id="btn-decrement")
178+
```
179+
180+
### Track Time Between Clicks
181+
```python
182+
import time
183+
184+
self.last_click = time.time()
185+
186+
# In button handler
187+
time_since_last = time.time() - self.last_click
188+
await self.aptabase.track("button_clicked", {
189+
"count": self.counter,
190+
"time_since_last_click": round(time_since_last, 2)
191+
})
192+
```
193+
194+
### Add Keyboard Shortcuts
195+
```python
196+
BINDINGS = [
197+
Binding("space", "increment", "Increment"),
198+
Binding("r", "reset", "Reset"),
199+
]
200+
201+
async def action_increment(self):
202+
self.counter += 1
203+
await self.aptabase.track("keyboard_increment")
204+
```
205+
206+
### Save High Score
207+
```python
208+
self.high_score = 0
209+
210+
if self.counter > self.high_score:
211+
self.high_score = self.counter
212+
await self.aptabase.track("new_high_score", {
213+
"score": self.high_score
214+
})
215+
```
216+
217+
## 🐛 Troubleshooting
218+
219+
### "Analytics unavailable" message
220+
221+
**Cause**: Invalid app key or network issues.
222+
223+
**Solutions**:
224+
1. Check your app key format: Must be `A-EU-*` or `A-US-*`
225+
2. Verify network connectivity
226+
3. Check Aptabase dashboard status
227+
4. Look for error details in the console
228+
229+
### Import errors
230+
231+
```bash
232+
ModuleNotFoundError: No module named 'textual'
233+
```
234+
235+
**Solution**: Install dependencies
236+
```bash
237+
pip install textual aptabase
238+
```
239+
240+
### App won't start
241+
242+
**Check Python version**:
243+
```bash
244+
python --version # Must be 3.11+
245+
```
246+
247+
## 📚 Learn More
248+
249+
### Next Steps
250+
251+
Once you're comfortable with this simple example, check out:
252+
253+
1. **textual_aptabase_demo.py** - Full dashboard with tabs, forms, and real-time stats
254+
2. **advanced_patterns.py** - User identification, error tracking, performance monitoring
255+
256+
### Resources
257+
258+
- **Aptabase**: [https://aptabase.com/docs](https://aptabase.com/docs)
259+
- **Aptabase Python SDK**: [https://github.com/aptabase/aptabase-py](https://github.com/aptabase/aptabase-py)
260+
- **Textual**: [https://textual.textualize.io/](https://textual.textualize.io/)
261+
- **Textual Tutorial**: [https://textual.textualize.io/tutorial/](https://textual.textualize.io/tutorial/)
262+
263+
## 🔐 Privacy
264+
265+
Aptabase is privacy-first analytics:
266+
- ✅ No personal data collected
267+
- ✅ No IP addresses stored
268+
- ✅ No cookies or tracking
269+
- ✅ GDPR compliant
270+
- ✅ Open source
271+
272+
This example only tracks:
273+
- Counter values (anonymous)
274+
- Button click events
275+
- Session duration
276+
- App lifecycle events
277+
278+
## 📄 License
279+
280+
MIT License - feel free to use this as a starting point for your own projects!
281+
282+
## 🤝 Contributing
283+
284+
This is a simple example/demo. Feel free to:
285+
- Fork and modify
286+
- Use in your own projects
287+
- Share improvements
288+
289+
## ❓ Questions?
290+
291+
- **Aptabase Support**: [https://aptabase.com/](https://aptabase.com/)
292+
- **Textual Discord**: [https://discord.gg/Enf6Z3qhVr](https://discord.gg/Enf6Z3qhVr)
293+
294+
---
295+
296+
**Happy coding!** 🚀
297+
298+
Built with ❤️ using [Textual](https://textual.textualize.io/) and [Aptabase](https://aptabase.com/)

0 commit comments

Comments
 (0)