Skip to content

Python SDK beta proposal#4715

Open
huangjeff5 wants to merge 12 commits intomainfrom
jh-python-design
Open

Python SDK beta proposal#4715
huangjeff5 wants to merge 12 commits intomainfrom
jh-python-design

Conversation

@huangjeff5
Copy link
Contributor

No description provided.

@github-actions github-actions bot added docs Improvements or additions to documentation python Python labels Feb 17, 2026
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @huangjeff5, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a comprehensive proposal for the Genkit Python SDK's public API surface, aiming to enhance its Pythonic nature, consistency, and developer experience for the beta release. It addresses existing friction points by clearly segmenting the API for app developers and plugin authors, standardizing conventions, and streamlining configuration and streaming mechanisms. The changes are designed to improve usability, type safety, and maintainability across the SDK.

Highlights

  • Formalized Public API Entry Points: The Python SDK's public API is now clearly defined with three distinct entry points: genkit for app developers (core framework), genkit.types for app developers (data types), and genkit.plugin for plugin authors (contract types and metadata builders). This separation clarifies audience-specific imports and improves discoverability.
  • Adopted Pythonic API Conventions: The SDK now enforces keyword-only arguments for public methods, uses keyword arguments over options dictionaries, and aims for a single, obvious way to configure behaviors. This enhances code readability, type checking, and IDE autocomplete.
  • Streamlined Output Configuration: The generate() method's output configuration has been simplified to use flat keyword arguments like output_schema, output_format, and output_constrained, removing redundant OutputConfig, OutputConfigDict, and Output[T] types from the app developer's surface. This provides a clearer and more Pythonic approach to typed responses.
  • Proposed Dual Sync/Async Clients: A proposal is made to introduce both Genkit (sync) and AsyncGenkit (async) clients, aligning with industry standards from other major Python LLM SDKs. This addresses friction points for developers in various execution environments like Flask, Jupyter notebooks, and CLI scripts.
  • Refined Streaming API: The streaming API for generate_stream() and prompt.stream() is updated to return a directly iterable object with a .response property for the final assembled response, standardizing the streaming pattern across the SDK and removing the tuple return.
  • Cleaned Up Method Signatures: Method signatures for generate(), prompt.__call__(), generate_stream(), retrieve(), and embed() have been refined to enforce keyword-only arguments, remove unnecessary parameters (e.g., on_chunk), and consolidate options, improving clarity and maintainability.
  • Veneer Naming Aliasing: Internal 'Wrapper' suffixes for veneer types (e.g., GenerateResponseWrapper) are now aliased to cleaner names (e.g., GenerateResponse) at the public surface, preventing implementation details from leaking into the public API.
  • RetrieverResponse Iterability: RetrieverResponse now implements Python's sequence protocol (__iter__, __len__, __getitem__), allowing direct iteration over documents and behaving more like a collection-like object.
  • Internal Module Underscoring: Internal modules like genkit.core, genkit.blocks, and genkit.ai are proposed to be renamed with an underscore prefix (e.g., genkit._core) to clearly signal their private nature and lack of stability guarantees, preventing accidental external dependencies.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • py/docs/python_beta_api_proposal.md
    • Added a new document outlining the proposed public API surface for the Genkit Python SDK, detailing entry points, type architecture, and symbol lists for app developers and plugin authors.
  • py/docs/python_beta_sdk_audit.md
    • Added a new document summarizing resolved API issues and decisions based on an audit of the Python SDK, covering topics like keyword-only arguments, decorator shorthands, Part constructor, RetrieverResponse iterability, response.media property, veneer naming, type consolidation, and public API cleanup.
  • py/docs/python_beta_sdk_design.md
    • Added a new document detailing the API design review for the Genkit Python SDK, establishing guiding principles, discussing open questions related to output configuration, streaming API, sync/async support, and method signatures.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a comprehensive and well-thought-out proposal for a new Python SDK API design. The changes, presented in several detailed markdown documents, aim to create a more Pythonic, consistent, and user-friendly interface. The proposals for keyword-only arguments, distinct entry points for different user personas, a simplified streaming API, and dual sync/async clients are excellent improvements. My review focuses on ensuring the documentation is consistent and accurate, and I've identified a few minor areas for clarification and correction within the proposal documents.

Comment on lines 76 to 86
class MessageWrapper: # wraps Message, doesn't extend it
def __init__(self, message: Message): ...
@property
def text(self) -> str: ...
@property
def tool_requests(self) -> list[ToolRequestPart]: ...
```

Key distinction:
- `GenerateResponseWrapper` **extends** `GenerateResponse` (inheritance). Aliasing it as `GenerateResponse` publicly is safe — construction is compatible.
- `MessageWrapper` **wraps** `Message` (composition). Its constructor takes a `Message` instance, not raw fields. Aliasing it as `Message` would break `Message(role="user", content=[...])`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The description of MessageWrapper appears to be inconsistent. The document states that it uses composition and "doesn't extend" Message. However, the provided source code in py/packages/genkit/src/genkit/blocks/model.py shows class MessageWrapper(Message):, which is inheritance. This is a key detail for developers, as it affects type hinting and usage. Please update the documentation to accurately reflect that MessageWrapper extends Message.

huangjeff5 and others added 5 commits February 17, 2026 11:24
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

This is the one genuinely open question in the public API surface. It's covered in depth as a design decision in [PYTHON_API_REVIEW.md, section 5](./PYTHON_API_REVIEW.md).

Summary: `Output[T]` carries generic type information for typed responses (`ai.generate(output=Output(MyModel))` → `GenerateResponse[MyModel]`). The alternative is inline kwargs (`output_schema=MyModel`), which loses the generic typing. A tech lead challenged the naming — "Input of what? Output of what?" — arguing the names are too generic.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

already decided; doing inline kwargs, we can still parametrize types

def __init__(self, schema: type[T], format: str = "json", ...): ...
```

`Input[T]` and `Output[T]` exist so that `generate()` and `prompt()` can carry generic type information — `ai.generate(output=Output(MyModel))` returns `GenerateResponse[MyModel]` with typed `.output`.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove Layer 3 stuff, noisy

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs Improvements or additions to documentation python Python

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

1 participant

Comments