Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

Add KV Store Support

Đang mở
#49 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Đánh giá

Độ khó
5/5
Thời gian dự kiến
Hơn một tuần
Mức phù hợp với người mới
35/100
Loại issue
Tính năng
Độ rõ ràng
Khá rõ ràng
Mức độ hoạt động
Đình trệ
Công nghệ
python
Lĩnh vực
backend, databases

Hướng nghiên cứu

Bắt đầu với stubs/wit_world/imports/kv_store.py và so sánh giao diện WIT với Python API được yêu cầu. Sau đó, kiểm tra cấu hình kiểm thử Viceroy bằng test.toml và @on_viceroy để tìm dữ liệu KV inline hoặc dựa trên tệp. Hoàn thành có nghĩa là đã triển khai CRUD, các entry dạng streaming, các tùy chọn, quyền truy cập giống dict, chức năng liệt kê và các kiểm thử tương ứng.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

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

Ngôn ngữ chính
Python
Star
5
Fork
1
Chỉ số merge pull request
Không có pull request nào được merge trong 30 ngày

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của fastly/compute-sdk-python

Tất cả issue của fastly/compute-sdk-python

Issue tương tự

Thêm issue về Python

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.