{"id":16092264,"url":"https://github.com/alecthomas/porpoise","last_synced_at":"2025-10-07T22:03:13.659Z","repository":{"id":57454196,"uuid":"9805292","full_name":"alecthomas/porpoise","owner":"alecthomas","description":"Porpoise - A Redis-based analytics framework","archived":false,"fork":false,"pushed_at":"2024-01-01T14:46:41.000Z","size":6,"stargazers_count":5,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-28T07:51:14.574Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alecthomas.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2013-05-02T03:54:02.000Z","updated_at":"2024-05-29T12:26:24.000Z","dependencies_parsed_at":"2024-10-27T17:23:48.779Z","dependency_job_id":"577bb8b4-4a29-4abf-95f4-7dc7ae6e6cdc","html_url":"https://github.com/alecthomas/porpoise","commit_stats":{"total_commits":4,"total_committers":1,"mean_commits":4.0,"dds":0.0,"last_synced_commit":"df1a49461b84363513635fa09d2c4f37d7b37f75"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alecthomas%2Fporpoise","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alecthomas%2Fporpoise/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alecthomas%2Fporpoise/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alecthomas%2Fporpoise/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alecthomas","download_url":"https://codeload.github.com/alecthomas/porpoise/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243909991,"owners_count":20367536,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-09T16:06:25.275Z","updated_at":"2025-10-07T22:03:08.607Z","avatar_url":"https://github.com/alecthomas.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Porpoise - A Redis-based analytics framework\n\nPorpoise implements two analytics primitives: counters and events.\n\n\n## Recording\n\n### Events\n\nThe following example records that two users (ids 1 and 2) were active at the\ncurrent time, and user 1 played a song:\n\n```python\nfrom porpoise import Analytics\n\nporpoise = Analytics()\n\nporpoise.event('active', 1)\nporpoise.event('active', 2)\nporpoise.event('login', 1)\nporpoise.event('song:played', 1)\n```\n\n\n### Counters\n\nA couple of examples of incrementing counters:\n\n```python\nporpoise.count('signups', 'all')\nporpoise.count('song:played', song.id)\n```\n\n## Analysis\n\nThere are two steps to analysing Porpoise data:\n\n1. Specify time ranges to analyse.\n2. Specify which metrics to analyse.\n\n### Time ranges\n\nPorpoise exposes a set of classes that make dealing with time ranges more\nconvenient: `{minute,hour,day,week,month}range`.\n\nEach class accepts a start and end time. These times can be specified as\nnegative offsets from the current time, in the base unit (day, week, etc.):\n\n```python\nlast_24_hours = hourrange(-24)\nlast_four_days = dayrange(-4)\nlast_seven_days = weekrange(-1)\nprevious_week = weekrange(-2, -1)\n```\n\nThey can also be specified as absolute datetime start/end times:\n\n```python\nfirst_seven_days_of_2010 = dayrange(datetime(2010, 1, 1), datetime(2010, 1, 8))\n```\n\n### Analysing events\n\nQueries across multiple events can be expressed as bit-wise expressions. For\nexample, to find all users who logged in and played a song in the same hour:\n\n```python\nevents = porpoise.events\nloggedin_and_played = events('login') \u0026 events('song:played')\nfor users in loggedin_and_played(last_24_hours):\n  print users\n```\n\n\n### Analysing counters\n\nEach counter key has a number of IDs associated with it. When analysing\ncounters, the returned data is a dictionary mapping these IDs to their count.\n\nFor example, to print the top 10 songs played in each hour for the last 24 hours:\n\n```python\ncounters = porpoise.counters\n\nsongs_played = counters('song:played')\n\nfor songs in songs_played(last_24_hours):\n  top10 = sorted(songs.iteritems(), lambda s: -s[1])[:5]\n  for song, played in top10:\n    print song, played\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falecthomas%2Fporpoise","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falecthomas%2Fporpoise","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falecthomas%2Fporpoise/lists"}