Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

Add KV Store Support

オープン
#49 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
5/5
見積もり時間
1週間以上
初心者へのやさしさ
35/100
issue の種類
機能追加
明瞭さ
おおむね明確
活発さ
停滞
技術スタック
python
領域
backend, databases

調査の方向性

stubs/wit_world/imports/kv_store.py から始め、WIT インターフェースと要求された Python API を比較します。次に、test.toml と @on_viceroy を使って、インラインまたはファイルベースの KV データに関する Viceroy のテスト設定を調べます。CRUD、ストリーミングエントリ、オプション、dict のようなアクセス、一覧表示、および対応するテストが実装されていれば完了です。

索引モデルが issue の本文から書いたものです。

説明

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

主要言語
Python
スター
5
フォーク
1
PR マージ指標
30日以内にマージされた PR はありません

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

fastly/compute-sdk-python のほかの issue

fastly/compute-sdk-python の issue をすべて見る

似ている issue

Python の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。