MemSharp client for Python
A dependency-free client for MemSharp, an in-memory database for .NET that speaks RESP. Python 3.10+.
pip install ./clients/python
Start a server first: memsharp serve --port 6380.
from memsharp import MemSharpClient, WrongTypeError
with MemSharpClient(port=6380) as db:
db.set("symbol:BTC", "68350.25")
db.set("session:9f2", "kang", ex=1800)
db.zadd("book:BTC:bids", {"bid-1": 68349.75})
top = db.zrange("book:BTC:bids", 0, 9, desc=True, withscores=True)
db.xadd("trades", {"sym": "BTC", "qty": "5"}, maxlen=100_000)
db.ts_add("px", 68_350.25)
# rows come back keyed by column name
for row in db.sql("SELECT key, size FROM keys WHERE key LIKE 'order:%'"):
print(row["key"], row["size"])
# one round-trip for the whole batch
db.pipeline([["SET", f"k{i}", str(i)] for i in range(1000)])
Streams and consumer groups
Times are in seconds, as everywhere else in this client (ex=, ttl()).
with MemSharpClient(port=6380) as db:
db.xgroup_create("jobs", "workers", mkstream=True) # id defaults to "$": only new entries
# {key: [(id, fields), ...]}, or None if nothing arrived within block seconds
batch = db.xreadgroup("workers", "w1", "jobs", count=10, block=5)
for entry_id, fields in (batch or {}).get("jobs", []):
...
db.xack("jobs", "workers", entry_id)
db.xpending("jobs", "workers") # {"count", "min", "max", "consumers": {name: n}}
db.xpending_range("jobs", "workers", count=10) # [{"id", "consumer", "idle", "deliveries"}, ...]
# recover what a crashed consumer left behind
next_start, claimed, deleted = db.xautoclaim("jobs", "workers", "w2", min_idle=60)
db.xclaim("jobs", "workers", "w2", 60, "1700000000000-0", justid=True)
db.xread({"prices": "$"}, block=0) # plain tail, no group; 0 waits forever
A blocking read lifts the socket timeout for its duration, so block= longer than the client's
timeout works. Also: xgroup_destroy, xgroup_createconsumer, xgroup_delconsumer,
xgroup_setid, xinfo_groups, xinfo_consumers, xinfo_stream.
Also in 1.1
| Method | Notes |
|---|---|
strlen, getrange, setrange |
Byte offsets. A range that would split a UTF-8 character raises rather than returning half of it. |
lpos(key, el, rank=, count=, maxlen=) |
An index or None; with count, a list (count=0 is every match). |
sinterstore, sunionstore, sdiffstore |
Return the result size; an empty result deletes the destination. |
zunionstore, zinterstore(dest, keys, weights=, aggregate=) |
aggregate is sum, min or max. |
info(*sections) |
No argument still means everything. |
config_get(*patterns), config_resetstat() |
config_get returns a dict. There is no CONFIG SET. |
memory_usage(key, samples=) |
Bytes, or None for a missing key. |
Tests
They run against a live server rather than a mock, because the only thing worth testing in a protocol client is that its bytes match what the server actually sends back.
memsharp serve --port 6391 --quiet &
python clients/python/test_client.py # 126 checks
Notes
- No dependencies. RESP is simple enough that a client dragging in a dependency tree costs its users more than it saves them.
- A missing key is distinguishable from an empty one.
WRONGTYPEgets its own exception type, so you can catch it specifically.- Pipelining returns errors in place rather than raising, so one failing command does not hide the replies to the others.
- Subscribing takes over the connection. Use a second client for ordinary commands.
Full reference, including every method: docs/en/clients.md · docs/id/clients.md
By Gravicode Studios, led by Kang Fadhil. MIT licensed.
Metadata
Release files for memsharp 1.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| memsharp-1.1.0.tar.gz | 21.3 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| memsharp-1.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 35.5 kB
Release files / memsharp-1.1.0.tar.gz
| Download URL | memsharp-1.1.0.tar.gz |
|---|---|
| Size | 21.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
cdd421ea712783ab3f5583ec4ad007d048e345f5a2f969c7be231ce7401730d4
|
|
BLAKE2b-256 checksum How to use checksums |
bf8e30a424375cd5d4f89374ffc2c05aa259e42564b745dfed3f036a65367b81
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.15
|
Release files / memsharp-1.1.0-py3-none-any.whl
| Download URL | memsharp-1.1.0-py3-none-any.whl |
|---|---|
| Size | 14.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3d3a3c8c1645e29abab4fcf4f8c24411696c584288de13d0f98af1a8b2f3b27f
|
|
BLAKE2b-256 checksum How to use checksums |
bfcad0f2cc6dc65c2635e9798f4aa6eebd1c0d047858ba8c47e56bb68c9ca7a7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.15
|
Security for memsharp 1.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.