|
1 | 1 | """ |
2 | | -File analytics — view activity stats, get activities by time interval, |
3 | | -and check item views/modifications over time. |
| 2 | +File analytics — view activity stats and access patterns. |
4 | 3 |
|
5 | | -Shows who accessed a file, when, and how often. Useful for adoption |
6 | | -tracking, content governance, and understanding which files are |
7 | | -most actively used in a drive. |
8 | | -
|
9 | | -Requires delegated permission ``Files.Read`` and ``Analytics.Read``. |
10 | | -
|
11 | | -https://learn.microsoft.com/en-us/graph/api/itemanalytics-get |
12 | | -https://learn.microsoft.com/en-us/graph/api/driveitem-getactivitiesbyinterval |
| 4 | +Requires delegated permissions Files.Read and Analytics.Read. |
13 | 5 | """ |
14 | 6 |
|
15 | 7 | from datetime import datetime, timedelta, timezone |
|
21 | 13 | def main(): |
22 | 14 | client = GraphClient(tenant=test_tenant).with_client_secret(test_client_id, test_client_secret) |
23 | 15 |
|
24 | | - drive = client.me.drive |
25 | | - |
26 | | - # -- Step 1: pick a file to analyse (most recent) -- |
27 | | - items = drive.root.children.top(20).get().execute_query() |
28 | | - files = [i for i in items if i.is_file] |
29 | | - |
| 16 | + drive = client.sites.get_by_path("/sites/project").drive |
| 17 | + files = [i for i in drive.root.children.top(20).get().execute_query() if i.is_file] |
30 | 18 | if not files: |
31 | | - print("No files found in OneDrive root. Creating a test file...") |
32 | | - drive.root.upload("analytics_test.txt", b"Analytics test content.").execute_query() |
33 | | - files = drive.root.children.top(20).get().execute_query() |
34 | | - files = [i for i in files if i.is_file] |
| 19 | + print("No files found.") |
| 20 | + return |
35 | 21 |
|
36 | 22 | target = files[0] |
37 | | - print(f"Analysing: {target.name} (size: {target.size or 0} bytes)\n") |
38 | | - |
39 | | - # -- Step 2: get analytics for the item -- |
40 | | - try: |
41 | | - analytics = target.analytics.get().execute_query() |
42 | | - if analytics: |
43 | | - print("Item analytics:") |
44 | | - if hasattr(analytics, "all_time") and analytics.all_time: |
45 | | - a = analytics.all_time |
46 | | - print(f" All time: {a.access_count or 0} accesses, {a.view_count or 0} views") |
47 | | - print(f" {a.share_count or 0} shares, {a.download_count or 0} downloads") |
48 | | - if hasattr(analytics, "last_seven_days") and analytics.last_seven_days: |
49 | | - l7 = analytics.last_seven_days |
50 | | - print(f" Last 7d : {l7.access_count or 0} accesses, {l7.view_count or 0} views") |
51 | | - else: |
52 | | - print(" (analytics returned no data — may need Analytics.Read permission)") |
53 | | - except Exception as e: |
54 | | - print(f" (analytics not available: {e})") |
55 | | - |
56 | | - # -- Step 3: get activity by interval (last 30 days) -- |
57 | | - now = datetime.now(timezone.utc) |
58 | | - start = now - timedelta(days=30) |
59 | | - end = now |
60 | | - |
61 | | - print("\nActivity by day for the last 30 days:") |
62 | | - try: |
63 | | - activities = target.get_activities_by_interval( |
64 | | - start_dt=start, |
65 | | - end_dt=end, |
66 | | - interval="day", |
67 | | - ).execute_query() |
68 | | - |
69 | | - print(f" {len(activities)} days with activity") |
70 | | - for act in activities: |
71 | | - dt = act.start_date_time.strftime("%Y-%m-%d") if act.start_date_time else "?" |
72 | | - access = act.access_count or 0 |
73 | | - act_view = act.view_count or 0 |
74 | | - act_down = act.download_count or 0 |
75 | | - act_share = act.share_count or 0 |
76 | | - print(f" {dt} accesses={access:>3} views={act_view:>3} downloads={act_down:>3} shares={act_share:>2}") |
77 | | - except Exception as e: |
78 | | - print(f" (activity by interval not available: {e})") |
79 | | - |
80 | | - # -- Step 4: item activity (who did what) -- |
81 | | - print("\nRecent activities on this file:") |
82 | | - try: |
83 | | - activities_v2 = target.get_activities_by_interval( |
84 | | - start_dt=start, |
85 | | - end_dt=end, |
86 | | - interval="day", |
87 | | - ).execute_query() |
88 | | - if activities_v2: |
89 | | - print(" (see activity timeline above — details available via activity insight resources)") |
90 | | - except Exception as e: |
91 | | - print(f" {e}") |
| 23 | + print(f"File: {target.name}") |
| 24 | + |
| 25 | + analytics = target.analytics.select(["allTime"]).get().execute_query() |
| 26 | + if analytics.all_time: |
| 27 | + a = analytics.all_time |
| 28 | + print(f" All time: {a.accessCount or 0} accesses, {a.viewCount or 0} views, {a.shareCount or 0} shares") |
| 29 | + if analytics.last_seven_days: |
| 30 | + l7 = analytics.last_seven_days |
| 31 | + print(f" Last 7d: {l7.accessCount or 0} accesses, {l7.viewCount or 0} views") |
| 32 | + |
| 33 | + activities = target.get_activities_by_interval( |
| 34 | + start_dt=datetime.now(timezone.utc) - timedelta(days=30), |
| 35 | + end_dt=datetime.now(timezone.utc), |
| 36 | + interval="day", |
| 37 | + ).execute_query() |
| 38 | + print(f"\nActivity ({len(activities)} days with activity):") |
| 39 | + for act in activities: |
| 40 | + print(f" {act.start_date_time.date()} accesses={act.accessCount or 0} views={act.viewCount or 0}") |
92 | 41 |
|
93 | 42 |
|
94 | 43 | if __name__ == "__main__": |
|
0 commit comments