AGENTS: Python Client Context for Agentic Tools
June 29, 2026 · View on GitHub
This file provides AI agents and developers with the minimum but sufficient context to work productively with the Valkey GLIDE Python client. It covers build commands, testing, contribution requirements, and essential guardrails specific to the Python implementation.
Repository Overview
This is the Python client binding for Valkey GLIDE, providing both async and sync client implementations. The Python wrapper consists of three components: async client (PyO3/Maturin), sync client (CFFI/setuptools), and shared logic.
Primary Languages: Python, Rust (PyO3 and CFFI bindings) Build System: Custom dev.py CLI with Maturin (async) and setuptools (sync) Architecture: Hybrid Python/Rust with PyO3 (async) and CFFI (sync) bindings
Key Components:
glide-async/- Async client using PyO3 bindings and Unix Domain Socket communicationglide-sync/- Sync client using CFFI bindings and direct FFI communicationglide-shared/- Shared Python logic used by both clientstests/- Shared test suite for both clientsdev.py- CLI utility for build, test, and development tasks
Architecture Quick Facts
Core Implementation: Python wrappers around glide-core Rust library Client Types: GlideClient/GlideClusterClient (async), GlideClient/GlideClusterClient (sync) API Styles: Async with asyncio/trio support, Sync with blocking calls Communication: UDS (async), Direct FFI (sync)
Supported Platforms:
- Linux: Ubuntu 20+, Amazon Linux 2/2023 (x86_64, aarch64)
- macOS: 13.7+ (x86_64), 14.7+ (aarch64)
- Note: Alpine Linux/MUSL not supported
Python Versions: 3.9, 3.10, 3.11, 3.12, 3.13 Async Frameworks: asyncio, trio, uvloop
Packages: valkey-glide (async), valkey-glide-sync (sync)
Build and Test Rules (Agents)
Preferred (dev.py CLI)
# Build commands
python3 dev.py build --client async --mode release # Build async client (optimized)
python3 dev.py build --client sync --mode release # Build sync client (optimized)
python3 dev.py build --client async --mode debug # Build async client (debug)
python3 dev.py build --client sync --mode debug # Build sync client (debug)
# Build wheels for local testing
python3 dev.py build --client async --wheel # Build async wheel
python3 dev.py build --client sync --wheel # Build sync wheel
# Testing
python3 dev.py test # Run all tests
python3 dev.py test --args -k <test_name> # Run specific test
python3 dev.py test --args --async-backend=trio # Test with trio backend
python3 dev.py test --args --async-backend=asyncio # Test with asyncio backend
# Linting and Formatting
python3 dev.py lint # Auto-fix formatting (isort, black)
python3 dev.py lint --check # Check formatting only
# Protobuf generation
python3 dev.py protobuf # Regenerate protobuf files
# Cleaning build artifacts
python3 dev.py clean # Remove all client build artifacts
python3 dev.py clean --client async # Remove async client artifacts only
python3 dev.py clean --client sync # Remove sync client artifacts only
# Help
python3 dev.py --help # Show all available commands
Raw Equivalents
# Manual async client build (from glide-async/)
source ../.env/bin/activate
maturin develop --release
# Manual sync client build (from glide-sync/)
source ../.env/bin/activate
pip install -e ../glide-shared
python setup.py build_ext --inplace
# Manual test execution (from python/)
source .env/bin/activate
pytest -v
# Manual linting
source .env/bin/activate
isort . && black . && flake8 . && mypy .
# Manual protobuf generation
protoc --python_out=glide-shared/glide_shared/protobuf --pyi_out=glide-shared/glide_shared/protobuf ../glide-core/src/protobuf/*.proto
Test Execution Options
# Run with existing endpoints
python3 dev.py test --args --cluster-endpoints=localhost:7000 --standalone-endpoints=localhost:6379
# Run with TLS
python3 dev.py test --args --tls --cluster-endpoints=localhost:7000 --standalone-endpoints=localhost:6379
# Run with specific async backend
python3 dev.py test --args --async-backend=trio --async-backend=asyncio
# Run specific test pattern
python3 dev.py test --args -k "test_set_and_get"
Contribution Requirements
Developer Certificate of Origin (DCO) Signoff REQUIRED
All commits must include a Signed-off-by line:
# Add signoff to new commits
git commit -s -m "feat(python): add new command implementation"
# Configure automatic signoff
git config --global format.signOff true
# Add signoff to existing commit
git commit --amend --signoff --no-edit
# Add signoff to multiple commits
git rebase -i HEAD~n --signoff
Conventional Commits
Use conventional commit format:
<type>(<scope>): <description>
[optional body]
Example: feat(python): implement async cluster scan with routing options
Code Quality Requirements
Python Linters (via dev.py):
python3 dev.py lint # Must pass before commit (auto-fixes)
python3 dev.py lint --check # Check-only mode
Individual Tools:
isort- Import sortingblack- Code formattingflake8- Style and error checkingmypy- Type checking
Rust Components:
# From python/ directory
rustup component add clippy rustfmt
cargo clippy --all-features --all-targets -- -D warnings
cargo fmt --manifest-path ./Cargo.toml --all
Guardrails & Policies
Generated Outputs (Never Commit)
.env/- Python virtual environmentglide-async/target/- Rust build artifacts (async)glide-sync/target/- Rust build artifacts (sync)glide-shared/glide_shared/protobuf/- Generated protobuf filesbuild/- Build artifactsdist/- Distribution artifacts*.egg-info/- Package metadata__pycache__/- Python bytecode.pytest_cache/- Pytest cache.mypy_cache/- MyPy cachedocs/_build/- Sphinx documentation build
Python-Specific Rules
- Python 3.9+ Required: Minimum runtime version
- Virtual Environment: Always use
.env/for development - Dual Client Support: Maintain compatibility between async and sync clients
- Shared Logic: Keep common code in
glide-shared/package - Implement async with anyio: Write all async code against the
anyioAPI, notasyncio— this applies to client/shared implementation, not just tests. The async client must run unmodified on asyncio, trio, and uvloop. Useanyio.sleep,anyio.fail_after/anyio.move_on_after,anyiosync primitives and streams (anyio.Event,anyio.Lock,anyio.create_memory_object_stream), andanyio.create_task_group(). Avoid asyncio-only APIs (asyncio.get_running_loop,asyncio.Queue,asyncio.gather,loop.run_in_executor); useanyio.to_thread/anyio.from_threadfor thread interop. - anyio in tests: Never use
asyncio.sleep,asyncio.wait_for, orasyncio.Queuedirectly in test code. Useanyio.sleep,anyio.fail_after, and thewait_for()helper fromtests/utils/utils.pyinstead. Tests run under both asyncio and trio via pytest-anyio. - Prefer polling over sleeps: Use
await wait_for(condition, message, timeout)instead of fixedawait anyio.sleep(N)delays. The condition should be an async callable returning bool. The timeout should be a reasonable small seconds. - Protobuf Updates: Run
python3 dev.py protobufafter proto changes - Documentation Style: Follow Google Style Python Docstrings format
Package Structure Rules
- Async Client:
import glide(PyPI:valkey-glide) - Sync Client:
import glide_sync(PyPI:valkey-glide-sync) - Shared Logic:
import glide_shared(local install only) - Independent Packaging: Each client has separate pyproject.toml and release cycle
Project Structure (Essential)
python/
├── glide-async/ # Async client (PyO3 + Maturin)
│ ├── Cargo.toml # Rust dependencies
│ ├── pyproject.toml # Python package config
│ ├── python/glide/ # Python async client code
│ └── src/ # Rust PyO3 bindings
├── glide-sync/ # Sync client (CFFI + setuptools)
│ ├── pyproject.toml # Python package config
│ ├── glide_sync/ # Python sync client code
│ └── setup.py # Build configuration
├── glide-shared/ # Shared logic for both clients
│ ├── pyproject.toml # Shared package config
│ └── glide_shared/ # Shared Python code
├── tests/ # Shared test suite
├── dev.py # CLI utility for development
├── dev_requirements.txt # Development dependencies
└── docs/ # Sphinx documentation (legacy)
Quality Gates (Agent Checklist)
- Build passes:
python3 dev.py build --client async --mode releasesucceeds - Build passes:
python3 dev.py build --client sync --mode releasesucceeds - All tests pass:
python3 dev.py testsucceeds - Linting passes:
python3 dev.py lintsucceeds - Type checking passes:
mypyruns clean - Both async backends work:
--async-backend=trio --async-backend=asyncio - No generated outputs committed (check
.gitignore) - DCO signoff present:
git log --format="%B" -n 1 | grep "Signed-off-by" - Conventional commit format used
- Documentation follows Google Style format
- Shared logic properly isolated in
glide-shared/
Quick Facts for Reasoners
Packages: valkey-glide (async), valkey-glide-sync (sync) on PyPI
API Styles: Async (asyncio/trio), Sync (blocking)
Client Types: GlideClient (standalone), GlideClusterClient (cluster) for both async/sync
Key Features: Dual client architecture, shared logic, multi-async framework support, OpenTelemetry observability
Testing: pytest with async backend selection, shared test suite
Platforms: Linux (Ubuntu, AL2/AL2023), macOS (Intel/Apple Silicon)
Dependencies: Python 3.9+, Rust toolchain, protobuf compiler
If You Need More
- Getting Started: README.md
- Development Setup: DEVELOPER.md
- Examples: ../examples/python/
- API Documentation: Valkey GLIDE Python docs
- Documentation: GLIDE Documentation
- Test Suites: tests/ directory
- Async Client: glide-async/ directory
- Sync Client: glide-sync/ directory
- Shared Logic: glide-shared/ directory
- CLI Utility: dev.py script