You're welcome! And I'm happy to share our current process for pulling view counts in a similar fashion, if you try to go that route.
from arcgis import GIS
import pandas as pd
from datetime import datetime
gis = GIS('portal-url', 'user', 'pass')
content_list = gis.content.search('NOT owner:esri_apps', max_items=-1)
out_dict = {}
for item in content_list:
out_dict[content_list.index(item)] = [item.title, item.type, item.numViews, datetime.now(), item.owner, item.id]
df = pd.DataFrame.from_dict(out_dict, orient='index')
df.rename(columns={0:'title', 1:'type', 2:'views', 3:'date', 4:'owner', 5:'id'}, inplace=True)
# Wasn't sure how to filter by two owners in the query, this gets rid of the straggler ESRI items
df = df.loc[df['owner'] != 'esri']
# Adjusting timestamps for server / local machine offset (UTC vs UTC -6)
df.loc[:, 'date'] = df['date'] + pd.Timedelta('6 hours')
# Get standalone table of view counts
usage_table = gis.content.get('itemID').tables[0]
# Get the count per layer from most recent run
last_count = usage_table.query(
group_by_fields_for_statistics='id',
out_statistics= [
{
"statisticType":"max",
"onStatisticField": "views",
"outStatisticFieldName": "max_views"
}
],
as_df = True)
# Merge the latest count into dataframe
df = df.merge(last_count, on=['id'], how='left')
# New column to show change
df = df.assign(daily = df.views - df.max_views)
adds = usage_table.edit_features(adds=df.fillna(0).astype({'daily':'int'}).spatial.to_featureset())
print(adds)
The resulting table can be visualized in a dashboard pretty well. Or instead of a hosted table, you could have the script append to a CSV, SQL table, etc using the same basic process, and then you could use other software like Excel or Tableau to get a nice Pivot Table.
Or just keep working in Python! Pandas with MatPlotLib could be all you need for some really slick analysis of view counts.
Schedule that script to run at whatever interval you need to identify meaningful spikes in usage. And of course, if you're only interested in certain layers, you could supply a static list of items instead of an open-ended query as I have.
This table can get pretty big pretty fast, depending on the interval and number of layers, so you may want an additional script that drops any rows outside of a certain time range, like "past 30 days" or something.
- Josh Carlson
Kendall County GIS