Skip to content

Commit 6d4a874

Browse files
committed
Add Products, Teams, and Advanced Analytics support
- Add Products management endpoints (Seller/Admin only) - list_products, create_product, update_product, delete_product - get_product_analytics for product statistics - Add Teams collaboration endpoints (Pro+ tier) - Full team CRUD operations - Member invitation and management - App sharing with teams - Team-based access control - Enhance Analytics endpoints - get_dashboard_insights for basic analytics (all tiers) - get_advanced_analytics for Pro+ tier analytics - Enhanced usage statistics and license analytics - Fix API endpoint paths to ensure /v1 prefix is correctly used - Update base URL handling to automatically include /v1 - Add comprehensive examples: - basic_analytics.py - Basic analytics for all tiers - advanced_analytics.py - Advanced analytics (Pro+ tiers) - products_example.py - Product management examples - teams_example.py - Team collaboration examples - licenses_comprehensive.py - Complete license management - Update README.md with all new features and usage examples
1 parent dbb0ac0 commit 6d4a874

7 files changed

Lines changed: 1329 additions & 9 deletions

File tree

README.md

Lines changed: 116 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ Official Python SDK for LicenseChain - Secure license management for Python appl
1313
- **📜 License Management** - Create, validate, update, and revoke licenses
1414
- **🛡️ Hardware ID Validation** - Prevent license sharing and unauthorized access
1515
- **🔔 Webhook Support** - Real-time license events and notifications
16-
- **📊 Analytics Integration** - Track license usage and performance metrics
16+
- **📊 Analytics Integration** - Basic and advanced analytics with comprehensive metrics
17+
- **📦 Product Management** - Create and manage products for license sales (Seller/Admin)
18+
- **👥 Team Collaboration** - Team management and shared app/license access (Pro+)
1719
- **⚡ High Performance** - Optimized for production workloads
1820
- **🔄 Async Operations** - Non-blocking HTTP requests and data processing
1921
- **🛠️ Easy Integration** - Simple API with comprehensive documentation
@@ -286,11 +288,120 @@ await client.stop_webhook_listener()
286288
##### Analytics
287289

288290
```python
289-
# Track event
290-
await client.track_event(event_name, properties)
291+
# Get basic dashboard insights (all tiers)
292+
insights = await client.get_dashboard_insights()
291293

292-
# Get analytics data
293-
analytics = await client.get_analytics(time_range)
294+
# Get advanced analytics (Pro+ tier)
295+
advanced = await client.get_advanced_analytics(
296+
start_date="2024-01-01",
297+
end_date="2024-12-31",
298+
metric="revenue"
299+
)
300+
301+
# Get general analytics
302+
analytics = await client.get_analytics(
303+
app_id="app_123",
304+
start_date="2024-01-01",
305+
end_date="2024-12-31"
306+
)
307+
308+
# Get usage statistics
309+
usage = await client.get_usage_stats(period="30d")
310+
311+
# Get license-specific analytics
312+
license_analytics = await client.get_license_analytics("license_id")
313+
```
314+
315+
##### Product Management (Seller/Admin only)
316+
317+
```python
318+
# List products
319+
products = await client.list_products(
320+
limit=50,
321+
offset=0,
322+
active=True,
323+
search="Premium"
324+
)
325+
326+
# Create a product
327+
product = await client.create_product(
328+
name="Premium License",
329+
price=99.99,
330+
description="Premium license with all features",
331+
currency="USD",
332+
active=True
333+
)
334+
335+
# Update a product
336+
updated = await client.update_product(
337+
product_id="product_123",
338+
price=149.99,
339+
description="Updated description"
340+
)
341+
342+
# Get product analytics
343+
analytics = await client.get_product_analytics(product_id="product_123")
344+
345+
# Delete a product (if no licenses)
346+
await client.delete_product("product_123")
347+
```
348+
349+
##### Team Management (Pro+ tier)
350+
351+
```python
352+
# List teams
353+
teams = await client.list_teams()
354+
355+
# Create a team
356+
team = await client.create_team(
357+
name="Development Team",
358+
description="Team for development"
359+
)
360+
361+
# Get team details
362+
team_details = await client.get_team("team_123")
363+
364+
# Invite team member
365+
await client.invite_team_member(
366+
team_id="team_123",
367+
email="member@example.com",
368+
role="member" # owner, admin, or member
369+
)
370+
371+
# List team members
372+
members = await client.list_team_members("team_123")
373+
374+
# Update team member role
375+
await client.update_team_member(
376+
team_id="team_123",
377+
member_id="member_123",
378+
role="admin"
379+
)
380+
381+
# Remove team member
382+
await client.remove_team_member("team_123", "member_123")
383+
384+
# Share app with team
385+
await client.share_app_with_team("team_123", "app_123")
386+
387+
# List team apps
388+
team_apps = await client.list_team_apps("team_123")
389+
390+
# Remove app from team
391+
await client.remove_app_from_team("team_123", "app_123")
392+
393+
# Accept team invitation
394+
await client.accept_team_invitation("team_123")
395+
396+
# Update team
397+
await client.update_team(
398+
team_id="team_123",
399+
name="Updated Team Name",
400+
description="New description"
401+
)
402+
403+
# Delete team (owner only)
404+
await client.delete_team("team_123")
294405
```
295406

296407
## 🔧 Configuration

examples/advanced_analytics.py

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
#!/usr/bin/env python3
2+
"""
3+
LicenseChain Python SDK - Advanced Analytics Example
4+
5+
This example demonstrates how to use advanced analytics features
6+
available to Pro, Business, and Enterprise tier users.
7+
"""
8+
9+
import asyncio
10+
import os
11+
import sys
12+
from datetime import datetime, timedelta
13+
14+
# Add the parent directory to the path so we can import the SDK
15+
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
16+
17+
from licensechain.client import LicenseChainClient
18+
19+
20+
async def main():
21+
"""Main example function."""
22+
print("📊 LicenseChain Python SDK - Advanced Analytics Example\n")
23+
24+
# Initialize the client
25+
api_key = os.getenv('LICENSECHAIN_API_KEY', 'your-api-key-here')
26+
client = LicenseChainClient(
27+
api_key=api_key,
28+
base_url='https://api.licensechain.app',
29+
timeout=30,
30+
retry_attempts=3,
31+
)
32+
33+
try:
34+
# 1. Get Advanced Dashboard Insights
35+
print("📈 Getting Advanced Dashboard Insights...")
36+
insights = await client.get_dashboard_insights()
37+
38+
if insights.get('success'):
39+
# Check if advanced analytics are available
40+
analytics_type = insights.get('analyticsType', 'basic')
41+
print(f" Analytics Type: {analytics_type}")
42+
43+
if analytics_type == 'advanced':
44+
detailed = insights.get('detailed', {})
45+
print("\n✅ Advanced Analytics Available:")
46+
47+
# License Analytics
48+
if 'licenses' in detailed:
49+
licenses_data = detailed['licenses']
50+
print(f"\n 📜 License Analytics:")
51+
print(f" Total: {licenses_data.get('total', 0)}")
52+
print(f" This Month: {licenses_data.get('thisMonth', 0)}")
53+
print(f" Last Month: {licenses_data.get('lastMonth', 0)}")
54+
print(f" Last 7 Days: {licenses_data.get('last7Days', 0)}")
55+
56+
# By Status
57+
if 'byStatus' in licenses_data:
58+
print(f" By Status:")
59+
for status in licenses_data['byStatus']:
60+
print(f" - {status.get('status', 'N/A')}: {status.get('count', 0)}")
61+
62+
# App Analytics
63+
if 'apps' in detailed:
64+
apps_data = detailed['apps']
65+
print(f"\n 📱 App Analytics:")
66+
print(f" Total: {apps_data.get('total', 0)}")
67+
print(f" This Month: {apps_data.get('thisMonth', 0)}")
68+
print(f" Last Month: {apps_data.get('lastMonth', 0)}")
69+
70+
# API Usage Analytics
71+
if 'api' in detailed:
72+
api_data = detailed['api']
73+
print(f"\n 🔌 API Usage Analytics:")
74+
print(f" Total: {api_data.get('total', 0)}")
75+
print(f" This Month: {api_data.get('thisMonth', 0)}")
76+
print(f" Last Month: {api_data.get('lastMonth', 0)}")
77+
print(f" Last 7 Days: {api_data.get('last7Days', 0)}")
78+
print(f" Avg Response Time: {api_data.get('avgResponseTime', 0):.2f}ms")
79+
80+
# By Endpoint
81+
if 'byEndpoint' in api_data:
82+
print(f" By Endpoint:")
83+
for endpoint in api_data['byEndpoint'][:5]: # Show top 5
84+
print(f" - {endpoint.get('endpoint', 'N/A')}: {endpoint.get('count', 0)}")
85+
86+
# By Status Code
87+
if 'byStatus' in api_data:
88+
print(f" By Status Code:")
89+
for status in api_data['byStatus']:
90+
print(f" - {status.get('statusCode', 'N/A')}: {status.get('count', 0)}")
91+
92+
# Webhook Analytics
93+
if 'webhooks' in detailed:
94+
webhooks_data = detailed['webhooks']
95+
print(f"\n 🔗 Webhook Analytics:")
96+
print(f" Total: {webhooks_data.get('total', 0)}")
97+
print(f" This Month: {webhooks_data.get('thisMonth', 0)}")
98+
99+
# By Status
100+
if 'byStatus' in webhooks_data:
101+
print(f" By Status:")
102+
for status in webhooks_data['byStatus']:
103+
print(f" - {status.get('status', 'N/A')}: {status.get('count', 0)}")
104+
105+
# Daily Data Trends
106+
if 'dailyData' in detailed:
107+
daily_data = detailed['dailyData']
108+
print(f"\n 📅 Daily Data Trends (Last 30 days):")
109+
for day in daily_data[-7:]: # Show last 7 days
110+
date = day.get('date', 'N/A')
111+
licenses = day.get('licenses', 0)
112+
revenue = day.get('revenue', 0)
113+
print(f" {date}: {licenses} licenses, ${revenue:.2f} revenue")
114+
else:
115+
print("\n⚠️ Advanced analytics require Pro, Business, or Enterprise tier")
116+
print(" Upgrade your plan to access advanced analytics features")
117+
118+
# 2. Get Advanced Analytics with Date Range
119+
print("\n📊 Getting Advanced Analytics with Date Range...")
120+
end_date = datetime.now()
121+
start_date = end_date - timedelta(days=30)
122+
123+
advanced_analytics = await client.get_advanced_analytics(
124+
start_date=start_date.isoformat(),
125+
end_date=end_date.isoformat(),
126+
)
127+
128+
if advanced_analytics:
129+
print("✅ Advanced Analytics Retrieved:")
130+
print(f" Data: {advanced_analytics}")
131+
132+
# 3. Get Analytics for Specific Metrics
133+
print("\n📈 Getting Analytics for Specific Metrics...")
134+
metrics = ['revenue', 'licenses', 'users', 'api_calls']
135+
136+
for metric in metrics:
137+
try:
138+
metric_data = await client.get_advanced_analytics(metric=metric)
139+
print(f" ✅ {metric}: {metric_data}")
140+
except Exception as e:
141+
print(f" ⚠️ {metric}: {type(e).__name__} - {e}")
142+
143+
print("\n✅ Advanced analytics example completed successfully!")
144+
145+
except Exception as e:
146+
print(f"❌ Error: {type(e).__name__} - {e}")
147+
if os.getenv('DEBUG'):
148+
import traceback
149+
traceback.print_exc()
150+
151+
finally:
152+
# Cleanup
153+
await client.close()
154+
print("\n🔌 Client closed")
155+
156+
157+
if __name__ == '__main__':
158+
asyncio.run(main())

examples/basic_analytics.py

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
#!/usr/bin/env python3
2+
"""
3+
LicenseChain Python SDK - Basic Analytics Example
4+
5+
This example demonstrates how to use basic analytics features
6+
available to all LicenseChain users.
7+
"""
8+
9+
import asyncio
10+
import os
11+
import sys
12+
from datetime import datetime, timedelta
13+
14+
# Add the parent directory to the path so we can import the SDK
15+
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
16+
17+
from licensechain.client import LicenseChainClient
18+
19+
20+
async def main():
21+
"""Main example function."""
22+
print("📊 LicenseChain Python SDK - Basic Analytics Example\n")
23+
24+
# Initialize the client
25+
api_key = os.getenv('LICENSECHAIN_API_KEY', 'your-api-key-here')
26+
client = LicenseChainClient(
27+
api_key=api_key,
28+
base_url='https://api.licensechain.app',
29+
timeout=30,
30+
retry_attempts=3,
31+
)
32+
33+
try:
34+
# 1. Get Dashboard Insights (Basic Analytics)
35+
print("📈 Getting Dashboard Insights...")
36+
insights = await client.get_dashboard_insights()
37+
38+
if insights.get('success'):
39+
metrics = insights.get('metrics', {})
40+
print("\n✅ Dashboard Metrics:")
41+
print(f" Total Licenses: {metrics.get('totalLicenses', 0)}")
42+
print(f" Licenses Change: {metrics.get('totalLicensesChangePct', 0):.1f}%")
43+
print(f" Active Users: {metrics.get('activeUsers', 0)}")
44+
print(f" Users Change: {metrics.get('activeUsersChangePct', 0):.1f}%")
45+
print(f" Revenue: ${metrics.get('revenue', 0):.2f}")
46+
print(f" Revenue Change: {metrics.get('revenueChangePct', 0):.1f}%")
47+
print(f" API Calls: {metrics.get('apiCalls', 0)}")
48+
print(f" API Calls Change: {metrics.get('apiCallsChangePct', 0):.1f}%")
49+
50+
# Recent Activity
51+
activity = insights.get('recentActivity', [])
52+
if activity:
53+
print(f"\n📋 Recent Activity ({len(activity)} items):")
54+
for item in activity[:5]: # Show first 5
55+
print(f" - {item.get('message', 'N/A')} ({item.get('timestamp', 'N/A')})")
56+
else:
57+
print(f"❌ Failed to get insights: {insights.get('error', 'Unknown error')}")
58+
59+
# 2. Get General Analytics
60+
print("\n📊 Getting General Analytics...")
61+
analytics = await client.get_analytics()
62+
63+
if analytics:
64+
print("✅ Analytics Data Retrieved:")
65+
print(f" Data: {analytics}")
66+
67+
# 3. Get Usage Statistics
68+
print("\n📈 Getting Usage Statistics...")
69+
usage_stats = await client.get_usage_stats(period="30d")
70+
71+
if usage_stats:
72+
print("✅ Usage Statistics:")
73+
print(f" Data: {usage_stats}")
74+
75+
# 4. Get License Analytics
76+
print("\n🔑 Getting License Analytics...")
77+
# First, get a list of licenses
78+
licenses = await client.list_licenses(limit=5)
79+
80+
if licenses and licenses.get('licenses'):
81+
license_id = licenses['licenses'][0].get('id')
82+
if license_id:
83+
license_analytics = await client.get_license_analytics(license_id)
84+
print(f"✅ License Analytics for {license_id}:")
85+
print(f" Data: {license_analytics}")
86+
87+
print("\n✅ Basic analytics example completed successfully!")
88+
89+
except Exception as e:
90+
print(f"❌ Error: {type(e).__name__} - {e}")
91+
if os.getenv('DEBUG'):
92+
import traceback
93+
traceback.print_exc()
94+
95+
finally:
96+
# Cleanup
97+
await client.close()
98+
print("\n🔌 Client closed")
99+
100+
101+
if __name__ == '__main__':
102+
asyncio.run(main())

0 commit comments

Comments
 (0)