Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

Add KV Store Support

Aperta
#49 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
5/5
Tempo stimato
Più di una settimana
Idoneità per principianti
35/100
Tipo di issue
Funzionalità
Chiarezza
Abbastanza chiara
Stato di attività
Ferma
Stack tecnologico
python
Ambito
backend, databases

Direzione di ricerca

Inizia da stubs/wit_world/imports/kv_store.py e confronta l’interfaccia WIT con l’API Python richiesta. Poi esamina la configurazione dei test di Viceroy usando test.toml e @on_viceroy per i dati KV inline o basati su file. Il lavoro è completato quando sono implementati CRUD, le entry in streaming, le opzioni, l’accesso simile a un dict, l’elenco e i test corrispondenti.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Overview

Add support for Fastly's KV Store, providing distributed key-value storage with read and write operations at the edge.

WIT Interface

interface kv-store {
  use types.{error, open-error};
  use http-body.{body};

  resource store {
    open: static func(name: string) -> result<store, open-error>;
    lookup: func(key: string) -> result<option<entry>, kv-error>;
    insert: func(key: string, body: body, options: insert-options) -> result<_, kv-error>;
    delete: func(key: string) -> result<bool, kv-error>;
    %list: func(options: list-options) -> result<body, kv-error>;
  }

  resource entry {
    take-body: func() -> option<body>;
    metadata: func(max-len: u64) -> result<option<string>, error>;
    generation: func() -> u64;
  }

  resource extra-kv-error;
  
  variant kv-error {
    bad-request,
    precondition-failed,
    payload-too-large,
    internal-error,
    too-many-requests,
    generic-error,
    extra(extra-kv-error),
  }

  enum insert-mode {
    overwrite,
    add,
    append,
    prepend,
  }

  resource extra-insert-options;

  record insert-options {
    background-fetch: bool,
    if-generation-match: option<u64>,
    metadata: option<string>,
    time-to-live-sec: option<u32>,
    mode: insert-mode,
    extra: option<borrow<extra-insert-options>>,
  }

  enum list-mode {
    strong,
    eventual,
  }

  resource extra-list-options;

  record list-options {
    mode: list-mode,
    cursor: option<string>,
    limit: option<u32>,
    prefix: option<string>,
    extra: option<borrow<extra-list-options>>,
  }
}

WIT bindings: stubs/wit_world/imports/kv_store.py

API Design

  • Implement KVStore resource wrapper
  • Implement KVStoreEntry as a file-like object inheriting from io.IOBase or io.RawIOBase:
    • Implement read(size=-1) or readinto(b) for standard file-like interface
    • Users get read_all() for free via .read() with no size argument
    • Standard library functions work: shutil.copyfileobj(), io.BufferedReader, etc.
    • metadata property, generation property
    • text() convenience: entry.read().decode('utf-8')
    • json() convenience: json.loads(entry.read())
  • Provide dict-like interface on Store: __getitem__, __setitem__, __delitem__, __contains__
  • Support InsertOptions with modes (overwrite, add, append, prepend), TTL, metadata, and generation matching
  • List operation returns iterator over keys with optional prefix filtering

Streaming Support: Entry values can be large (up to 25MB). By implementing standard io.IOBase:

  1. Users can use familiar file-like API: entry.read(8192) for chunks, entry.read() for all
  2. Works with stdlib: shutil.copyfileobj(entry, response_body) for zero-copy proxying
  3. Can wrap in io.BufferedReader for additional buffering if needed
  4. Document that .read() with no argument loads entire value into memory

Example:

entry = store.lookup("large-file")

# Streaming approach (memory-efficient) - standard file-like API
chunk = entry.read(8192)
while chunk:
    process_chunk(chunk)
    chunk = entry.read(8192)

# Or use with stdlib utilities
import shutil
shutil.copyfileobj(entry, output_file)

# Eager loading (beware large values!)
data = entry.read()  # reads all, standard Python pattern
text = entry.read().decode('utf-8')  # or entry.text()
obj = json.loads(entry.read())  # or entry.json()

Note on Future Async Support: Using io.IOBase for sync API is compatible with later adding async support. The WIT layer provides Pollable objects and select() for async operations. If/when async is added:

  • Sync API: entry.read() - returns immediately (blocking)
  • Async API: async def read() - returns coroutine, uses await with Pollable
  • These would be separate classes/methods, not the same io.IOBase instance
  • Similar to how aiofiles provides async wrappers over sync file operations

Cross-SDK Comparison:

  • Rust: StoreHandle::open() with methods lookup(), insert(), delete(). Returns LookupResponse with take_body() (streaming), take_body_bytes() (eager), metadata(), generation(). Has list() returning iterator over ListPage. Supports async with PendingLookupHandle, etc. Strongly typed InsertMode and ListMode enums.

  • Go: Open() returns *Store with Lookup(), Insert(), Delete(). Entry embeds io.Reader for streaming, plus String() helper for eager loading (with warning about memory). Meta(), Generation() accessors. No built-in async support (blocks). No list method yet.

  • JS: new KVStore(name) with async methods get(), put(), delete(), list(). Entry has body (ReadableStream) for streaming, text(), json(), arrayBuffer() for eager loading, metadata(), metadataText(). Put options include ttl, mode, gen. List returns {list: string[], cursor: string | undefined}.

Recommended Python approach:

  • Entry should inherit from io.IOBase to be a proper file-like object
  • Implement read(size=-1) method - standard file API that Python users know
  • No need for custom bytes(), read_all() - users just call .read() with no args
  • Works with stdlib: shutil.copyfileobj(), io.BufferedReader, etc.
  • Convenience methods (text(), json()) are thin wrappers over .read()
  • Dict-like API: store[key], store[key] = value, del store[key], key in store
  • list(prefix=None, limit=None, cursor=None) returning iterator/generator
  • InsertMode enum for put operations (overwrite, add, append, prepend)

Viceroy Testing

Viceroy supports KV Store with inline or file-based test data via test.toml:

[local_server]
# Inline data
kv_stores.my_store = [
  {key = "user:123", data = "John Doe"},
  {key = "config", file = "path/to/file.txt"},
  {key = "metadata_example", data = "value", metadata = "some metadata"}
]

# Or JSON file format
kv_stores.json_store = { file = "data/store.json", format = "json" }

Full CRUD operations (lookup, insert, delete) are supported. List operations work with test data. Tests can use @on_viceroy with inline TOML configuration.

Reference

Lingua principale
Python
Stelle
5
Fork
1
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di fastly/compute-sdk-python

Tutte le issue di fastly/compute-sdk-python

Issue simili

Altre issue su Python

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.