Skip to main content

A lightweight data store using GitHub Issues as a backend

Project description

GitHub Issue Store

A lightweight data store using GitHub Issues as a backend. Store and update JSON objects using GitHub Issues as a persistent storage layer, with automatic update processing via GitHub Actions.

Features

  • Store JSON objects in GitHub Issues
  • Update objects through issue comments
  • Automatic update processing via GitHub Actions
  • Sequential update handling with atomic operations
  • Full audit trail of all changes
  • Idempotent processing with reaction-based tracking
  • Configurable via YAML
  • Type-safe Python interface

Installation

pip install gh-store

Or install from source:

git clone https://github.com/dmarx/gh-store.git
cd gh-store
pip install -e .

Quick Start

  1. Add the GitHub Actions workflow to your repository:
mkdir -p .github/workflows
cp gh_store/workflows/process_update.yml .github/workflows/
  1. Configure your GitHub token with repo access:
from gh_store import GitHubStore

store = GitHubStore(
    token="your-github-token",
    repo="owner/repository"
)
  1. Start using the store:
# Create an object
data = {"name": "test", "value": 42}
obj = store.create("my-object", data)

# Retrieve an object
obj = store.get("my-object")

# Update an object
store.update("my-object", {"value": 43})

How It Works

Object Storage

Each object is stored in a dedicated GitHub Issue:

  • The issue body contains the current object state as JSON
  • Each object has two labels:
    • stored-object: Base label for all stored objects
    • Custom label matching the object ID
  • Issue state indicates processing status:
    • closed: Object is stable
    • open: Updates are being processed

Update Flow

  1. Updates are submitted as JSON comments on the object's issue
  2. The issue is reopened to trigger processing
  3. GitHub Actions runs the update processor
  4. Each comment is processed in chronological order
  5. Processed comments receive a "👍" reaction
  6. The issue is closed when all updates are processed

Example update flow:

# Initial state
obj = store.get("user-123")
print(obj.data)
# {"name": "Alice", "score": 10}

# Submit an update
store.update("user-123", {"score": 15})

# After processing
obj = store.get("user-123")
print(obj.data)
# {"name": "Alice", "score": 15}

Deep Updates

The store supports deep dictionary updates:

# Initial state
{
    "user": {
        "profile": {
            "name": "Alice",
            "settings": {"theme": "dark"}
        },
        "score": 10
    }
}

# Update
store.update("user-123", {
    "user": {
        "profile": {
            "settings": {"theme": "light"}
        },
        "score": 15
    }
})

# Final state
{
    "user": {
        "profile": {
            "name": "Alice",
            "settings": {"theme": "light"}
        },
        "score": 15
    }
}

Configuration

Create a config.yml file:

store:
  base_label: "stored-object"
  processed_reaction: "+1"
  retries:
    max_attempts: 3
    backoff_factor: 2
  rate_limit:
    max_requests_per_hour: 1000
  log:
    level: "INFO"
    format: "{time} | {level} | {message}"

Pass the config file path when initializing:

store = GitHubStore(
    token="your-token",
    repo="owner/repo",
    config_path=Path("config.yml")
)

Error Handling

The store provides specific exceptions for common error cases:

from gh_store.core.exceptions import (
    ObjectNotFound,
    InvalidUpdate,
    ConcurrentUpdateError
)

try:
    obj = store.get("nonexistent")
except ObjectNotFound:
    print("Object doesn't exist")

try:
    store.update("user-123", "invalid json")
except InvalidUpdate:
    print("Invalid update format")

Command Line Interface

The package includes a CLI for use in GitHub Actions:

# Process updates for an issue
python -m gh_store process-updates \
    --issue 123 \
    --token $GITHUB_TOKEN \
    --repo "owner/repository"

Use Cases

The GitHub Issue Store is particularly useful for:

  • Lightweight data storage without additional infrastructure
  • Applications that need a full audit trail of changes
  • Collaborative data management with GitHub-based workflows
  • Prototypes and small projects
  • Data that changes infrequently but needs version history

Limitations

  • Not suitable for high-frequency updates
  • GitHub API rate limits apply
  • Maximum issue size limits apply
  • Not recommended for sensitive data
  • No transactional guarantees across multiple objects

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Add tests for new features
  4. Submit a pull request

Testing

Run the test suite:

pytest

Run with coverage:

pytest --cov=gh_store

License

MIT License - see LICENSE file for details

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

gh_store-0.1.0.tar.gz (10.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

gh_store-0.1.0-py3-none-any.whl (9.6 kB view details)

Uploaded Python 3

File details

Details for the file gh_store-0.1.0.tar.gz.

File metadata

  • Download URL: gh_store-0.1.0.tar.gz
  • Upload date:
  • Size: 10.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.0.1 CPython/3.12.8

File hashes

Hashes for gh_store-0.1.0.tar.gz
Algorithm Hash digest
SHA256 4a631bf2734012d586f6661361efecfc8b4d34d5a11db84046d101a9697ba1e2
MD5 8281b7d8d6b5fb0f337f4e1413126f60
BLAKE2b-256 4ee05fff34b98a706c3ecf0dc716b4b70b248d140af48a25ece7af9e8e5c4e0a

See more details on using hashes here.

Provenance

The following attestation bundles were made for gh_store-0.1.0.tar.gz:

Publisher: release.yml on dmarx/gh-store

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file gh_store-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: gh_store-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 9.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.0.1 CPython/3.12.8

File hashes

Hashes for gh_store-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3e0c224bfbc1a54d66e0988730934fe5d302ef38280c028e0933c3e1ca3efb91
MD5 1c1887bcc226105573f3a0aae6d7e8e2
BLAKE2b-256 65734898173bdc89bafc76279d7f5326f1fdadc14fd64514f524442a227cca17

See more details on using hashes here.

Provenance

The following attestation bundles were made for gh_store-0.1.0-py3-none-any.whl:

Publisher: release.yml on dmarx/gh-store

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page