Skip to main content

Atomic per-string counter with sliding TTL in Redis (async).

Project description

PyPI version License: MIT Downloads LinkedIn

hashcounter

hashcounter is a tiny async Redis helper: per-string counter with a sliding TTL.
Input string → SHA-256 → key "{prefix}:{hash}" → atomic INCR + EXPIRE in one transaction.

Installation

pip install hashcounter

Requires redis>=5.0.0 and a running Redis server.

Quick start

import asyncio
from hashcounter import bump_string_counter

async def main() -> None:
    count = await bump_string_counter(
        "world_debug_test_v234",
        redis_url="redis://localhost:6379/0",
        key_prefix="llm7:seen",
        ttl_seconds=600,  # 10 minutes
    )
    print(count)  # 1 on first call, then 2, 3, ...

if __name__ == "__main__":
    asyncio.run(main())

FastAPI (shared Redis client)

from __future__ import annotations

import redis.asyncio as redis
from fastapi import FastAPI
from hashcounter import bump_string_counter

app = FastAPI()
r = redis.from_url("redis://localhost:6379/0", decode_responses=False)

@app.on_event("shutdown")
async def _shutdown() -> None:
    await r.aclose()

@app.post("/hit")
async def hit(s: str) -> dict[str, int]:
    count = await bump_string_counter(
        s,
        redis_url="redis://localhost:6379/0",
        key_prefix="llm7:seen",
        ttl_seconds=600,
        client=r,  # reuse connection pool
    )
    return {"count": count}

Behaviour

  • Key: f"{key_prefix}:{sha256(value)}".
  • Atomicity: INCR and EXPIRE run in a single MULTI/EXEC transaction.
  • Sliding TTL: TTL resets to ttl_seconds on every call.
  • First call: creates the key with value 1.
  • Return: current counter value (int).
  • Validation: raises ValueError if ttl_seconds <= 0.

API

async def bump_string_counter(
    value: str,
    *,
    redis_url: str,
    key_prefix: str,
    ttl_seconds: int = 600,
    client: Optional[redis.Redis] = None,
) -> int:
    """Increment the counter and refresh TTL. Return the current value."""

Parameters:

  • value: arbitrary string to count.
  • redis_url: Redis connection URL (ignored if client is provided).
  • key_prefix: namespace prefix for keys.
  • ttl_seconds: key time-to-live (seconds), refreshed on each call.
  • client: existing redis.asyncio.Redis instance (recommended in services).

Use cases

  • Prompt/request deduplication and anti-spam windows.
  • Per-key rate limiting by arbitrary features (prompt hash, user token, IP).
  • Telemetry: “seen count in the last N minutes”.

Contributing

Issues and PRs are welcome: https://github.com/chigwell/hashcounter/issues.

License

MIT © Eugene Evstafev

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

hashcounter-2025.8.241445.tar.gz (4.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

hashcounter-2025.8.241445-py3-none-any.whl (4.8 kB view details)

Uploaded Python 3

File details

Details for the file hashcounter-2025.8.241445.tar.gz.

File metadata

  • Download URL: hashcounter-2025.8.241445.tar.gz
  • Upload date:
  • Size: 4.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.11

File hashes

Hashes for hashcounter-2025.8.241445.tar.gz
Algorithm Hash digest
SHA256 de6ffed20bfcf706b04830500ed3c39e47b5b82579dc4ad674ce84f4def18c38
MD5 f75b21c057b9821372d488f60c4dbedf
BLAKE2b-256 f0e7f89bf27dc8e8366038abd6def2ddad15487d89e1776d139f5dd68c8f65f1

See more details on using hashes here.

File details

Details for the file hashcounter-2025.8.241445-py3-none-any.whl.

File metadata

File hashes

Hashes for hashcounter-2025.8.241445-py3-none-any.whl
Algorithm Hash digest
SHA256 d54136dabd124eaab7eb15b22241fcbf0aa77169a62781cf9bde3db8cbdd654b
MD5 83b9f8fda88c1e59149760b4c0899e07
BLAKE2b-256 415ce03c23aa119d9f8a9b5246993d1932fbb4605bd3bdda7eb9025346cfbec3

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page