Skip to content

Instantly share code, notes, and snippets.

View Graeme22's full-sized avatar
🐍
Building a better Redis client for Python πŸ‘€

Graeme Holliday Graeme22

🐍
Building a better Redis client for Python πŸ‘€
View GitHub Profile
@Graeme22
Graeme22 / idempotent.py
Last active June 27, 2025 17:59
Idempotency with coredis
from datetime import timedelta
from coredis import Redis
redis = Redis.from_url("redis://localhost:6379", decode_responses=True)
async def idempotent(key: str, ttl: timedelta | int | None = 60) -> bool:
"""
Shields code from being run multiple times.
"""
return bool(
@Graeme22
Graeme22 / typedredis.py
Created April 26, 2025 04:00
Fix redis-py's terrible types and add serialization
import pickle
from typing import Any, Set, Type, TypeVar
from redis.asyncio import Redis
from redis.typing import AbsExpiryT, ExpiryT, KeyT, ResponseT
T = TypeVar("T")
class TypedRedis(Redis):
@Graeme22
Graeme22 / pydempotent.py
Created April 23, 2025 23:34
Idempotency keys with redis-py
from datetime import timedelta
from redis import Redis
def pydempotent(redis: Redis, ttl: timedelta | int | None, key: str):
"""
Shields a block of code from repeated execution.
"""
return redis.set(f"pydempotent:{key}", 1, nx=True, ex=ttl)
redis = Redis.from_url("redis://localhost:6379")
@Graeme22
Graeme22 / example.py
Created March 18, 2025 00:56
Python async constructor (via __await__)
import asyncio
class AsyncObj:
def __init__(self, name):
self.name = name
async def __aenter__(self):
await asyncio.sleep(1)
print(f"Hello {self.name}!")
return self
@Graeme22
Graeme22 / docker-compose.yml
Created March 18, 2025 00:54
Redis Sentinel example with Docker Compose
services:
redis-master:
image: redis:latest
container_name: redis-master
hostname: redis-master
ports:
- "6379:6379"
volumes:
- ./data/master:/data
command:
#!/bin/sh
echo "you've been pwned!"
@Graeme22
Graeme22 / example.py
Last active April 8, 2025 15:53
Use SQLModel to query a table using `skip` and `limit` and also get the number of items, using a single query (FastAPI)
from typing import Generic, TypeVar
from pydantic import BaseModel, Field
from sqlmodel import Session, func
M = TypeVar("M", bound=BaseModel)
class QueryResults(BaseModel, Generic[M]):
count: int
@Graeme22
Graeme22 / init.lua
Last active October 28, 2024 21:16
Vue/Nuxt LSP support for kickstart.nvim Neovim config
-- add this line above the servers variable in nvim-lspconfig's setup function:
local vue_path = require('mason-registry').get_package('vue-language-server'):get_install_path() .. '/node_modules/@vue/language-server'
-- modify your existing LSP plugins like so:
local servers = {
ts_ls = {
init_options = {
plugins = {
{
name = '@vue/typescript-plugin',
location = vue_path,
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract DecentralizedStockWithAMM is ERC20 {
uint public reserveToken;
uint public reserveEther;