Skip to main content

keyspec

PyPI version PyPI - Downloads License: Apache-2.0

A msgspec-like database system for python inspired by aiocache.

Installation

Currently there are 2 different extensions to use those being cysqlite and sqlite backends. More backends are being planned in a future release such as lmdb.

Cysqlite implementation

pip install keyspec[cysqlite]

Sqlite implementation

pip install keyspec[sqlite]

LMDB implementation

Coming soon...

Common Usage

Using the database system and finding the implementation you want should be very easy to figure out. in this example below we use cysqlite which has slightly better performance than sqlite the sqlite version can be utilized for support with the standard python libraries if dependencies are more of a concern to your needs.

import anyio
from msgspec import Struct, msgpack

from keyspec.cysqlite import Database


class User(Struct):
    name: str
    password: str

# you can specify either a type or a msgspec decoder of your choice.
database = Database("my_database.db", User)
...
# Alternative approch if custom decoders are needed.
database = Database("my_database.db", dec=msgpack.Decoder(User))


# you can wrap a database as needed or using async with
@database()
async def insert(user_db: Database[User], username:str, password: str) -> None:
    await user_db.set("user", User(username, password))
    return await user_db.get_all()

async def async_with_insert(username:str, password: str) -> None:
    async with  Database("my_database.db", User) as user_db:
        await user_db.set("user", User(username, password))
        return await user_db.get_all()

async def async_with_insert_alternative_method(username:str, password: str) -> None:
    async with database as user_db:
        await user_db.set("user", User(username, password))
        return await user_db.get_all()

@database()
async def namespaces(user_db: Database[User]) -> User | None:
    # namespaces can also be set just like how it's done in redis.
    await user_db["namespace"].set("user", User("user", "pass"))
    return await user_db["namespace"].get("user")


@database()
async def get_all(user_db: Database[User]) -> dict[str, User]:
    return await user_db.get_all()

async def test():
    # NOTE: Client is deleted as the wrapper cane take care of
    # the first attribute for you making the database wrapper 
    # an easy to use shortcut to access your newly made database.
    await insert("user", "pass")
    await insert("user1", "password")
    data = await get_all()
    # {
    #   'user': User(name='user', password='pass'),
    #   'user1': User(name='user1', password='password')
    # }
    print(data)

if __name__ == "__main__":
    anyio.run(test)

Expirable Data

Because sometimes we just want to implement a cache system and recycle the unused data later. A Good example is preventing bots from just mixing in with our users.

from msgspec import Struct
from keyspec.sqlite import Database
from datetime import timedelta

class Captcha(Struct):
    answer: str

# Time to Live and expirable systems are also accepted
captcha_db = Database("captchas.db", Captcha, default_ttl=60) # 60 seconds
captcha_db = Database("captchas.db", Captcha, default_ttl=timedelta(hours=1)) # 1 hour
# Data automatically will expire upon exiting the
# function or context manager being entered otherwise you can use auto_expire=False to set
# your own rules on how data should be expired
captcha_db = Database(
    "captchas.db",
    Captcha, default_ttl=timedelta(hours=1), auto_expire=True
)

Why I wrote it.

  • Msgspec doesn't work as an sqlalchemy table on it's own and therefore there can't be any real competitor with SQLModel and why write a class object twice, it's unnessesary. the reason for this is that sqlalchemy can't make use of __slots__. This was an alternative approch in the longrun that at least gives msgspec some form of database functionality.

  • Keyspec is smaller than sqlalchemy and is made in a redis-like format. Know however there is a disadvantage as only single key lookups can be done, so choose your keys wisely, the best choice by far is the name or id of the object you wish to serlize and deserlize out of your database.

  • Keyspec gives the user a lot of creativity right out of the box.

  • Windows doesn't have a saveable cache system with redis as far as I am aware so I gave it cysqlite and anyio to at least make up for that. As someone who hates OS-Gating, giving a proper database system for windows/linux and Apple devices was a priority for me.

  • I was requested by the aio-libs team that if there was another cache extension library, it would have to be put somewhere else. So I ended up just making my own cache-like database with a better system to utilize. It has extensions if you want to build your own database.

  • Anyio is a better choice as you automatically can support both trio and asyncio and any server implementation under the sun, however aiohttp may require a bit of setup as you need to serlize the data to the format the client may be requesting for and aiohttp doesn't support trio unless you use the trio eventloop library.

  • You can automatically pair litestar with keyspec with the best results however fastapi may require a bit of work to get data to be streamed correctly.

  • Compared to aiocache the set function adds or updates rather than one or the other. This just gets rid of another annoyance I had all together.

  • It doesn't take much practice at all to get used to using the library even a less skilled programmer could pick up this library with a little bit of paitience.

  • Cysqlite extension is regularly updated and maintained alongside it's companion library anyio-cysqlite which is written by me, the same author of this library.

Metadata

Release files for keyspec 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for keyspec 1.0.0
File Size Uploaded Provenance Actions
keyspec-1.0.0.tar.gz 18.7 kB With provenance Details for keyspec-1.0.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for keyspec 1.0.0
File Interpreter ABI Platform Actions
keyspec-1.0.0-py3-none-any.whl Python 3 none any Details for keyspec-1.0.0-py3-none-any.whl

Total release size: 37.4 kB

Release files / keyspec-1.0.0.tar.gz

Download URL keyspec-1.0.0.tar.gz
Size 18.7 kB
Tags Source
SHA-256 checksum
How to use checksums
10ed27b16715415f436f65dd034e44e7140bd38a88880e3b1fdd74f3daeda836
BLAKE2b-256 checksum
How to use checksums
df1675388ada3678976f79c23f93ab4ceb9a39a70c1e252f964901e268ea05ba
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 12, 2026.

Transparency log

Release files / keyspec-1.0.0-py3-none-any.whl

Download URL keyspec-1.0.0-py3-none-any.whl
Size 18.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a77cd2e5277dd64f7d8389784921d104ad15c5c05ee200bcb234b61e43f75e4e
BLAKE2b-256 checksum
How to use checksums
9171b85f813d1631dacddc4f132aa6b264946d9c69cf5cdda22a9a4603dfe9c7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 12, 2026.

Transparency log

Security for keyspec 1.0.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.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for keyspec-1.0.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 12, 2026.

Transparency log

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.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page