Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

Add KV Store Support

Abierto
#49 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
5/5
Tiempo estimado
Más de una semana
Aptitud para principiantes
35/100
Tipo de issue
Nueva funcionalidad
Claridad
Bastante claro
Estado de actividad
Estancado
Stack tecnológico
python

Línea de trabajo

Comienza con stubs/wit_world/imports/kv_store.py y compara la interfaz WIT con la API de Python solicitada. Después, inspecciona la configuración de pruebas de Viceroy usando test.toml y @on_viceroy para comprobar datos KV en línea o basados en archivos. Se considerará terminado cuando estén implementados CRUD, las entradas en streaming, las opciones, el acceso similar a un dict, el listado y las pruebas correspondientes.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

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

Lenguaje dominante
Python
Estrellas
5
Forks
1
Métricas de merge de PR
Sin PR fusionados en 30 d

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de fastly/compute-sdk-python

Todos los issues de fastly/compute-sdk-python

Issues similares

Más issues de Python

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.