|
| 1 | +# mem-db-utils - GitHub Copilot Instructions |
| 2 | + |
| 3 | +**Python package for in-memory database utilities supporting Redis, Memcached, Dragonfly, and Valkey.** |
| 4 | + |
| 5 | +Always reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the info here. |
| 6 | + |
| 7 | +## Working Effectively |
| 8 | + |
| 9 | +### Bootstrap, Build, and Test Repository: |
| 10 | +- `pip install -e .` -- installs the package in development mode. NEVER CANCEL: Takes 10-60 seconds, may timeout due to network issues. Set timeout to 120+ seconds (extra margin for slow mirrors or network issues). |
| 11 | +- `pip install coverage pre-commit pytest pytest-cov pytest-dotenv ruff` -- installs development dependencies. NEVER CANCEL: Takes 30-120 seconds. Set timeout to 180+ seconds (extra margin for slow mirrors or network issues). |
| 12 | +- `python -m pytest tests/ -v` -- runs unit tests (takes ~0.4 seconds, 20 passed, 5 skipped without database) |
| 13 | +- `ruff check .` -- runs linting (takes ~0.01 seconds) |
| 14 | +- `ruff format --check .` -- checks code formatting (takes ~0.01 seconds) |
| 15 | + |
| 16 | +### Environment Configuration: |
| 17 | +- Create `.env` file with `DB_URL=redis://localhost:6379/0` for basic testing |
| 18 | +- Package requires `DB_URL` environment variable to be set at runtime |
| 19 | +- Supported database URLs: `redis://`, `memcached://`, `dragonfly://`, `valkey://` |
| 20 | +- Optional environment variables: `DB_TYPE`, `REDIS_CONNECTION_TYPE`, `REDIS_MASTER_SERVICE`, `DB_TIMEOUT` |
| 21 | + |
| 22 | +### Run Integration Tests with Real Database: |
| 23 | +- Start Redis: `docker run -d --name test-redis -p 6379:6379 redis:7-alpine` (NEVER CANCEL: Takes 30-60 seconds for first download) |
| 24 | +- Wait for startup: `sleep 5` |
| 25 | +- Run integration tests: `DB_URL=redis://localhost:6379/0 python -m pytest tests/test_integration.py -v` (takes ~0.4 seconds, 1 may fail on error handling test) |
| 26 | +- Clean up: `docker stop test-redis && docker rm test-redis` |
| 27 | + |
| 28 | +## Validation Scenarios |
| 29 | + |
| 30 | +### Always Test After Making Changes: |
| 31 | +1. **Import Test**: `DB_URL=redis://localhost:6379/0 python -c "from mem_db_utils import MemDBConnector; print('Import successful')"` |
| 32 | +2. **Basic Functionality Test** (requires Redis running): |
| 33 | + ```bash |
| 34 | + DB_URL=redis://localhost:6379/0 python -c " |
| 35 | + from mem_db_utils import MemDBConnector |
| 36 | + conn = MemDBConnector().connect(db=0) |
| 37 | + conn.ping() |
| 38 | + conn.set('test', 'value') |
| 39 | + assert conn.get('test') == 'value' |
| 40 | + conn.delete('test') |
| 41 | + print('Validation PASSED') |
| 42 | + " |
| 43 | + ``` |
| 44 | +3. **Run Full Test Suite**: `python -m pytest tests/ -v --cov=src --cov-report=term-missing` |
| 45 | +4. **Linting**: `ruff check . && ruff format --check .` |
| 46 | + |
| 47 | +### Manual Testing Requirements: |
| 48 | +- ALWAYS test basic database connection and operations after code changes |
| 49 | +- Test with different database types by changing DB_URL protocol |
| 50 | +- Verify configuration loading works with various environment variable combinations |
| 51 | +- Test error handling with invalid database URLs or unreachable servers |
| 52 | + |
| 53 | +## Common Tasks |
| 54 | + |
| 55 | +### Repository Structure: |
| 56 | +``` |
| 57 | +mem-db-utils/ |
| 58 | +├── .github/workflows/ # CI/CD pipelines |
| 59 | +├── src/mem_db_utils/ # Main package source |
| 60 | +│ ├── __init__.py # MemDBConnector class |
| 61 | +│ ├── config.py # Environment configuration |
| 62 | +│ └── py.typed # Type hints marker |
| 63 | +├── tests/ # Test files |
| 64 | +├── pyproject.toml # Project configuration |
| 65 | +└── README.md # Documentation |
| 66 | +``` |
| 67 | + |
| 68 | +### Key Files to Check After Changes: |
| 69 | +- Always verify `src/mem_db_utils/__init__.py` after changing MemDBConnector logic |
| 70 | +- Check `src/mem_db_utils/config.py` after modifying configuration handling |
| 71 | +- Update tests in `tests/` when adding new functionality |
| 72 | +- Run integration tests in `tests/test_integration.py` with real database |
| 73 | + |
| 74 | +### Development Dependencies: |
| 75 | +- **Testing**: pytest, pytest-cov, pytest-dotenv, coverage |
| 76 | +- **Linting**: ruff (replaces black, flake8, isort) |
| 77 | +- **Git hooks**: pre-commit |
| 78 | +- **Type checking**: Built into package with py.typed marker |
| 79 | + |
| 80 | +### Build and Package: |
| 81 | +- `python -m build` -- builds distribution packages. NEVER CANCEL: May fail due to network timeouts depending on the configured build backend and network environment (see `pyproject.toml` for the backend in use). Consider this command unreliable in constrained network environments. |
| 82 | +- Package metadata in `pyproject.toml` |
| 83 | +- Uses standard Python packaging; the build backend is specified in `pyproject.toml` (may require network access to a custom PyPI index depending on backend). |
| 84 | +- **Note**: Package installation works fine, but building from source may be problematic due to external dependencies |
| 85 | + |
| 86 | +## Database Types and Testing |
| 87 | + |
| 88 | +### Supported Database Types: |
| 89 | +- **Redis**: `redis://localhost:6379/0` (most common, full functionality) |
| 90 | +- **Memcached**: `memcached://localhost:11211` (basic key-value operations) |
| 91 | +- **Dragonfly**: `dragonfly://localhost:6380` (Redis-compatible) |
| 92 | +- **Valkey**: `valkey://localhost:6381` (Redis-compatible) |
| 93 | + |
| 94 | +### Database-Specific Testing: |
| 95 | +- **Redis/Dragonfly/Valkey**: Support database selection (`db` parameter), ping, set/get/delete |
| 96 | +- **Memcached**: Basic connection only, no database selection |
| 97 | +- **Redis Sentinel**: Requires `REDIS_CONNECTION_TYPE=sentinel` and `REDIS_MASTER_SERVICE` environment variables |
| 98 | + |
| 99 | +### Setting up Test Databases with Docker: |
| 100 | +- Redis: `docker run -d --name test-redis -p 6379:6379 redis:7-alpine` |
| 101 | +- Memcached: `docker run -d --name test-memcached -p 11211:11211 memcached:1.6-alpine` |
| 102 | +- Dragonfly: `docker run -d --name test-dragonfly -p 6380:6380 docker.dragonflydb.io/dragonflydb/dragonfly` |
| 103 | + |
| 104 | +## CI/CD Pipeline (.github/workflows) |
| 105 | + |
| 106 | +### Linter Pipeline (linter.yaml): |
| 107 | +- Runs on pull requests |
| 108 | +- Uses `chartboost/ruff-action@v1` for linting and format checking |
| 109 | +- ALWAYS run `ruff check .` and `ruff format --check .` before committing |
| 110 | + |
| 111 | +### Package Publishing (publish_package.yaml): |
| 112 | +- Triggers on git tags |
| 113 | +- Builds with `python -m build` |
| 114 | +- Publishes to PyPI |
| 115 | +- Creates GitHub releases with sigstore signatures |
| 116 | + |
| 117 | +## Critical Notes |
| 118 | + |
| 119 | +### Environment Variable Loading: |
| 120 | +- Package uses `pydantic-settings` with `python-dotenv` integration |
| 121 | +- Environment variables are loaded from `.env` files automatically |
| 122 | +- Configuration is validated at import time, not lazily |
| 123 | +- Missing `DB_URL` will cause import failure with ValidationError |
| 124 | + |
| 125 | +### Error Handling: |
| 126 | +- Import failures occur when `DB_URL` is missing or invalid protocol |
| 127 | +- Connection failures in integration tests are skipped (pytest.skip) |
| 128 | +- Invalid database numbers may or may not raise exceptions depending on database type |
| 129 | + |
| 130 | +### Memory and Performance: |
| 131 | +- MemDBConnector uses `__slots__` for memory efficiency |
| 132 | +- Connection objects are created per call to `connect()` |
| 133 | +- No connection pooling implemented in base connector |
| 134 | +- Timeouts configurable via `DB_TIMEOUT` environment variable (default: 30 seconds) |
| 135 | + |
| 136 | +## Troubleshooting |
| 137 | + |
| 138 | +### Common Issues: |
| 139 | +1. **Import Error**: Ensure `DB_URL` environment variable is set |
| 140 | +2. **Test Failures**: Start appropriate database container first |
| 141 | +3. **Linting Failures**: Run `ruff format .` to auto-fix formatting issues |
| 142 | +4. **Missing Dependencies**: Run `pip install -e .` to reinstall package |
| 143 | +5. **Network Timeouts**: Package uses custom PyPI index (pypi.prismatica.in) which may be unreachable. pip install and python -m build commands may timeout. |
| 144 | + |
| 145 | +### Network Dependencies: |
| 146 | +- Package depends on custom PyPI index at pypi.prismatica.in |
| 147 | +- Build commands may fail with network timeouts in restricted environments |
| 148 | +- Runtime functionality works fine once dependencies are installed |
| 149 | +- Consider using pre-installed environments or alternative package sources if network issues persist |
| 150 | + |
| 151 | +### Database Connection Issues: |
| 152 | +- Check if database container is running: `docker ps` |
| 153 | +- Test connection manually: `docker exec -it test-redis redis-cli ping` |
| 154 | +- Verify port availability: `netstat -tlnp | grep 6379` |
| 155 | +- Check firewall settings if running on remote host |
0 commit comments