Marking Events

Marking an event is the fundamental write operation in bitmapist. It records that a specific user (identified by an integer ID) performed a certain action at a particular time.

Marking a Time-Based Event

The primary function for this is mark_event().

from bitmapist import mark_event

# Mark that user with ID 123 was 'active'
mark_event('active', 123)

# Mark that user 456 'completed a task'
mark_event('task:completed', 456)

When you call mark_event, bitmapist automatically records this event across multiple time granularities: day, week, and month. This allows you to query the data across different time windows without any extra work.

Backdating Events

By default, mark_event uses datetime.now(tz=timezone.utc) as the timestamp. You can provide a specific datetime object to the now parameter to record an event in the past.

from datetime import datetime, timedelta, timezone

yesterday = datetime.now(tz=timezone.utc) - timedelta(days=1)

# Mark that user 789 logged in yesterday
mark_event('login', 789, now=yesterday)

Unmarking an Event

If you need to reverse an event, you can use unmark_event(). This is useful for correcting data or handling state changes where an event is no longer considered valid.

from bitmapist import unmark_event

# User 123 is no longer considered 'active' today
unmark_event('active', 123)

Controlling Hourly Tracking

By default, hourly tracking is disabled to save memory. You can enable it globally or on a per-call basis.

import bitmapist

# Enable hourly tracking for all subsequent mark_event calls
bitmapist.TRACK_HOURLY = True
mark_event('page:view', 1001) # This will be tracked hourly

# Or, enable it for a single call, overriding the global default
bitmapist.TRACK_HOURLY = False
mark_event('page:view', 1002, track_hourly=True) # This is also tracked hourly

Marking Unique Events (Flags)

Sometimes, you need to track user properties or flags that are not time-dependent, such as subscription status or A/B test groups. For this, bitmapist provides UniqueEvents.

mark_unique() and unmark_unique()

Use mark_unique() to set a flag for a user and unmark_unique() to clear it.

from bitmapist import mark_unique, unmark_unique

# User 777 is now a premium subscriber
mark_unique('premium_user', 777)

# User 888 is in the 'new_signup_flow' A/B test group
mark_unique('ab_test:new_flow', 888)

# User 777's subscription has lapsed
unmark_unique('premium_user', 777)

These unique events can be combined with time-based events in queries. See the Bitwise Operations guide for examples.

Combining Time-Based and Unique Marking

You can mark an event as both time-based and unique in a single call by using the track_unique parameter in mark_event.

# Mark that user 321 just became a premium user
# This creates a time-based 'premium' event (e.g., for today)
# AND a permanent 'premium' unique flag.
mark_event('premium', 321, track_unique=True)

This is a convenient way to track both when a user entered a state and their current state.