Skip to content

Commit b490ef5

Browse files
Revise README for clarity and structure (#83)
* Revise README for clarity and structure Updated README to improve clarity and organization, and fixed formatting issues. * Drop archived PHP port
1 parent 17ce309 commit b490ef5

File tree

1 file changed

+51
-54
lines changed

1 file changed

+51
-54
lines changed

README.md

Lines changed: 51 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,42 @@
11
![bitmapist](https://raw.githubusercontent.com/Doist/bitmapist/master/static/bitmapist.png "bitmapist")
22

3-
43
[![Build Status](https://travis-ci.org/Doist/bitmapist.svg?branch=master)](https://travis-ci.org/Doist/bitmapist)
54

6-
**NEW!** Try out our new standalone [bitmapist-server](https://github.com/Doist/bitmapist-server), which improves memory efficiency 443 times and makes your setup much cheaper to run (and more scaleable). It's fully compatiable with bitmapist that runs on Redis.
5+
# Bitmapist: a powerful analytics library for Redis
76

8-
# bitmapist: a powerful analytics library for Redis
7+
Bitmapist makes it possible to implement real-time, highly scalable analytics. The library is very easy to use, enabling you to create reports easily.
98

10-
This Python library makes it possible to implement real-time, highly scalable analytics that can answer following questions:
9+
Leveraging Redis bitmaps, you can store events for millions of users using a very little amount of memory (megabytes).
1110

12-
* Has user 123 been online today? This week? This month?
13-
* Has user 123 performed action "X"?
14-
* How many users have been active this month? This hour?
15-
* How many unique users have performed action "X" this week?
16-
* How many % of users that were active last week are still active?
17-
* How many % of users that were active last month are still active this month?
18-
* What users performed action "X"?
11+
> [!TIP]
12+
> Instead of Redis as a backing store, consider using [bitmapist-server](https://github.com/Doist/bitmapist-server).
13+
>
14+
> It is our custom data store that exposes a (partial) Redis-compatible API, fully compatible with Bitmapist. It is 443x more memory efficient for this particular use case, improving scalability and cost-effectiveness.
1915
20-
This library is very easy to use and enables you to create your own reports easily.
16+
## Use cases
2117

22-
Using Redis bitmaps you can store events for millions of users in a very little amount of memory (megabytes).
23-
You should be careful about using huge ids as this could require larger amounts of memory. Ids should be in range [0, 2^32).
18+
Bitmapist can answer questions like:
2419

25-
Additionally bitmapist can generate cohort graphs that can do following:
26-
* Cohort over user retention
27-
* How many % of users that were active last [days, weeks, months] are still active?
28-
* How many % of users that performed action X also performed action Y (and this over time)
29-
* And a lot of other things!
20+
- Has user 123 been online today? This week? This month?
21+
- Has user 123 performed action "X"?
22+
- How many users have been active this month? This hour?
23+
- How many unique users have performed action "X" this week?
24+
- How many % of users that were active last week are still active?
25+
- How many % of users that were active last month are still active this month?
26+
- What users performed action "X"?
3027

31-
If you want to read more about bitmaps please read following:
28+
Additionally, it can generate cohort graphs that can do following:
3229

33-
* http://blog.getspool.com/2011/11/29/fast-easy-realtime-metrics-using-redis-bitmaps/
34-
* http://redis.io/commands/setbit
35-
* http://en.wikipedia.org/wiki/Bit_array
36-
* http://www.slideshare.net/crashlytics/crashlytics-on-redis-analytics
30+
- Cohort over user retention
31+
- How many % of users that were active last [days, weeks, months] are still active?
32+
- How many % of users that performed action X also performed action Y (and this over time)
33+
- And a lot of other things!
3734

35+
### Caveat: Avoid large IDs
3836

37+
You should be careful about using large IDs as this will require larger amounts of memory. IDs should be in range `[0, 2^32)`.
3938

40-
# Installation
39+
## Installation
4140

4241
Can be installed very easily via:
4342

@@ -47,13 +46,7 @@ Or, if you use `uv`:
4746

4847
$ uv add bitmapist
4948

50-
51-
# Ports
52-
53-
* PHP port: https://github.com/jeremyFreeAgent/Bitter
54-
55-
56-
# Examples
49+
## Usage and examples
5750

5851
Setting things up:
5952

@@ -82,7 +75,6 @@ assert 123 in MonthEvents('song:played', now.year, now.month)
8275
assert MonthEvents('active', now.year, now.month).has_events_marked() == True
8376
```
8477

85-
8678
How many users have been active this week?:
8779

8880
```python
@@ -96,7 +88,6 @@ for uid in WeekEvents('active'):
9688
print(uid)
9789
```
9890

99-
10091
If you're interested in "current events", you can omit extra `now.whatever`
10192
arguments. Events will be populated with current time automatically.
10293

@@ -150,7 +141,6 @@ if ev.period_end() < now:
150141

151142
```
152143

153-
154144
As something new tracking hourly is disabled (to save memory!) To enable it as default do::
155145

156146
```python
@@ -164,7 +154,6 @@ Additionally you can supply an extra argument to `mark_event` to bypass the defa
164154
mark_event('active', 123, track_hourly=False)
165155
```
166156

167-
168157
### Unique events
169158

170159
Sometimes the date of the event makes little or no sense, for example,
@@ -213,7 +202,6 @@ for uid in premium & active_today:
213202
To get the best of two worlds you can mark unique event and regular
214203
bitmapist events at the same time.
215204

216-
217205
```python
218206
def premium_up(uid):
219207
# called when user promoted to premium
@@ -222,7 +210,6 @@ def premium_up(uid):
222210

223211
```
224212

225-
226213
### Perform bit operations
227214

228215
How many users that have been active last month are still active this month?
@@ -240,12 +227,12 @@ assert 123 in active_2_months
240227

241228
Alternatively, you can use standard Python syntax for bitwise operations.
242229

243-
244230
```python
245231
last_month_event = MonthEvents('active', last_month.year, last_month.month)
246232
this_month_event = MonthEvents('active', now.year, now.month)
247233
active_two_months = last_month_event & this_month_event
248234
```
235+
249236
Operators `&`, `|`, `^` and `~` supported.
250237

251238
Work with nested bit operations (imagine what you can do with this ;-))!
@@ -265,21 +252,23 @@ assert 123 in active_2_months
265252
active_2_months.delete()
266253
```
267254

268-
269255
### Deleting
270256

271257
If you want to permanently remove marked events for any time period you can use the `delete()` method:
258+
272259
```python
273260
last_month_event = MonthEvents('active', last_month.year, last_month.month)
274261
last_month_event.delete()
275262
```
276263

277264
If you want to remove all bitmapist events use:
265+
278266
```python
279267
bitmapist.delete_all_events()
280268
```
281269

282270
When using Bit Operations (ie `BitOpAnd`) you can (and probably should) delete the results unless you want them cached. There are different ways to go about this:
271+
283272
```python
284273
active_2_months = BitOpAnd(
285274
MonthEvents('active', last_month.year, last_month.month),
@@ -295,12 +284,12 @@ bitmapist.delete_runtime_bitop_keys()
295284
bitmapist.delete_temporary_bitop_keys()
296285
```
297286

298-
299-
# bitmapist cohort
287+
## Cohorts
300288

301289
With bitmapist cohort you can get a form and a table rendering of the data you keep in bitmapist. If this sounds confusing [please look at Mixpanel](https://mixpanel.com/retention/).
302290

303291
Here's a simple example of how to generate a form and a rendering of the data you have inside bitmapist:
292+
304293
```python
305294
from bitmapist import cohort
306295

@@ -328,14 +317,22 @@ This will render something similar to this:
328317

329318
![bitmapist cohort screenshot](https://raw.githubusercontent.com/Doist/bitmapist/master/static/cohort_screenshot.png "bitmapist cohort screenshot")
330319

320+
## References
321+
322+
If you want to read more about bitmaps please read following:
323+
324+
- http://blog.getspool.com/2011/11/29/fast-easy-realtime-metrics-using-redis-bitmaps/
325+
- http://redis.io/commands/setbit
326+
- http://en.wikipedia.org/wiki/Bit_array
327+
- http://www.slideshare.net/crashlytics/crashlytics-on-redis-analytics
331328

332329
## Contributing
333330

334331
Please see our guide [here](./CONTRIBUTING.md)
335332

336333
## Local Development
337334

338-
We use `uv` for dependency management & packaging. Please see [here for setup instructions](https://docs.astral.sh/uv/getting-started/).
335+
We use `uv` for dependency management & packaging. Please see [here for setup instructions](https://docs.astral.sh/uv/getting-started/).
339336

340337
Once you have `uv` installed, you can run the following to install the dependencies in a virtual environment:
341338

@@ -349,8 +346,8 @@ To run our tests will need to ensure a local redis server is installed.
349346

350347
You can use these environment variables to tell the tests about Redis:
351348

352-
* `BITMAPIST_REDIS_SERVER_PATH`: Path to the Redis server executable (defaults to the first one in the path or `/usr/bin/redis-server`)
353-
* `BITMAPIST_REDIS_PORT`: Port number for the Redis server (defaults to 6399)
349+
- `BITMAPIST_REDIS_SERVER_PATH`: Path to the Redis server executable (defaults to the first one in the path or `/usr/bin/redis-server`)
350+
- `BITMAPIST_REDIS_PORT`: Port number for the Redis server (defaults to 6399)
354351

355352
We use `pytest` to run unit tests, which you can run with:
356353

@@ -365,18 +362,18 @@ uv run pytest
365362
## Releasing new versions
366363

367364
1. Bump version in `pyproject.toml` (or use `uv version`)
368-
```sh
369-
uv version --bump minor
370-
```
365+
```sh
366+
uv version --bump minor
367+
```
371368
1. Update the CHANGELOG
372369
1. Commit the changes with a commit message "Version X.X.X"
373-
```sh
374-
git commit -m "Version $(uv version --short)"
375-
```
370+
```sh
371+
git commit -m "Version $(uv version --short)"
372+
```
376373
1. Tag the current commit with `vX.X.X`
377-
```sh
378-
git tag -a -m "Release $(uv version --short)" "v$(uv version --short)"
379-
```
374+
```sh
375+
git tag -a -m "Release $(uv version --short)" "v$(uv version --short)"
376+
```
380377
1. Create a new release on GitHub named `vX.X.X`
381378
1. GitHub Actions will publish the new version to PyPI for you
382379

0 commit comments

Comments
 (0)