Skip to content

feat: add get_version_id() across gt-i18n, gt-fastapi, gt-flask#27

Merged
ErnestM1234 merged 4 commits intogeneraltranslation:mainfrom
moss-bryophyta:moss/add-version-id
Mar 19, 2026
Merged

feat: add get_version_id() across gt-i18n, gt-fastapi, gt-flask#27
ErnestM1234 merged 4 commits intogeneraltranslation:mainfrom
moss-bryophyta:moss/add-version-id

Conversation

@moss-bryophyta
Copy link
Copy Markdown
Contributor

@moss-bryophyta moss-bryophyta commented Mar 19, 2026

Mirrors the useVersionId/getVersionId hook added to the JS packages in generaltranslation/gt#1121.

Changes:

  • I18nManager: new version_id param + get_version_id() method
  • Config loader: reads _versionId from gt.config.json
  • Helper: get_version_id() convenience function
  • Re-exported from gt-i18n, gt-fastapi, gt-flask
  • initialize_gt() in both FastAPI and Flask forwards version_id from config

All 105 existing tests pass.

Greptile Summary

This PR ports the getVersionId/useVersionId feature from the JS packages to the Python SDK by threading a version_id value through the config loader, I18nManager, and a new convenience helper function that is re-exported from gt-i18n, gt-fastapi, and gt-flask.

The core implementation is correct and the approach is consistent with existing patterns in the codebase. There is one notable inconsistency worth addressing before merging:

  • version_id not exposed as a direct parameter of initialize_gt() (both FastAPI and Flask): unlike every other configuration value (project_id, cache_url, default_locale, locales, custom_mapping), version_id can only be supplied via gt.config.json — there is no keyword argument on initialize_gt() that would let users set it programmatically. This limits usability in environments that don't use the config file (e.g. tests, dynamic multi-tenant setups).
  • The I18nManager class docstring is missing an entry for the new version_id constructor parameter.

Confidence Score: 3/5

  • Safe to merge functionally, but the missing version_id parameter on initialize_gt() is an API inconsistency that should be fixed before shipping.
  • All existing tests pass and the feature works end-to-end when using gt.config.json. The score is reduced because initialize_gt() in both FastAPI and Flask lacks a version_id keyword argument, making the new feature inaccessible to users who configure the manager programmatically — a clear inconsistency with the established pattern for all other parameters.
  • packages/gt-fastapi/src/gt_fastapi/_setup.py and packages/gt-flask/src/gt_flask/_setup.py both need a version_id parameter added to initialize_gt().

Important Files Changed

Filename Overview
packages/gt-i18n/src/gt_i18n/i18n_manager/_i18n_manager.py Adds version_id param to I18nManager.__init__ and a get_version_id() accessor; implementation is correct but the class docstring is missing documentation for the new parameter.
packages/gt-fastapi/src/gt_fastapi/_setup.py Reads version_id from config file and forwards it to I18nManager, but initialize_gt() does not expose a version_id keyword argument — breaking consistency with every other parameter that supports both programmatic and file-based configuration.
packages/gt-flask/src/gt_flask/_setup.py Same issue as gt-fastapi/_setup.pyversion_id is only sourced from config, with no function-argument override available in initialize_gt().
packages/gt-i18n/src/gt_i18n/helpers/_version_id.py New convenience helper that delegates to the singleton manager; straightforward and consistent with existing locale helpers.
packages/gt-i18n/src/gt_i18n/internal/_load_gt_config.py Adds _versionIdversion_id mapping and the version_id: str field to GTConfig; clean and correct change.
packages/gt-i18n/src/gt_i18n/init.py Imports and re-exports get_version_id; correctly placed in the public API and __all__.
packages/gt-fastapi/src/gt_fastapi/init.py Adds get_version_id to the FastAPI package's public re-exports; straightforward and correct.
packages/gt-flask/src/gt_flask/init.py Adds get_version_id to the Flask package's public re-exports; straightforward and correct.

Sequence Diagram

sequenceDiagram
    participant App as Application
    participant Setup as initialize_gt()
    participant Config as load_gt_config()
    participant Manager as I18nManager
    participant Helper as get_version_id()
    participant Singleton as _singleton

    App->>Setup: initialize_gt(app, ...)
    Setup->>Config: load_gt_config(config_path)
    Config-->>Setup: GTConfig (incl. version_id from _versionId)
    Setup->>Manager: I18nManager(..., version_id=resolved_version_id)
    Manager->>Manager: self._version_id = version_id
    Setup->>Singleton: set_i18n_manager(manager)
    Setup-->>App: manager

    Note over App,Helper: Later, during request handling
    App->>Helper: get_version_id()
    Helper->>Singleton: get_i18n_manager()
    Singleton-->>Helper: manager
    Helper->>Manager: manager.get_version_id()
    Manager-->>Helper: self._version_id
    Helper-->>App: str | None
Loading

Comments Outside Diff (1)

  1. packages/gt-i18n/src/gt_i18n/i18n_manager/_i18n_manager.py, line 20-33 (link)

    P2 I18nManager docstring missing version_id

    The class-level docstring documents every constructor parameter except the newly added version_id. This omission will make it harder for library consumers to discover the parameter.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: packages/gt-i18n/src/gt_i18n/i18n_manager/_i18n_manager.py
    Line: 20-33
    
    Comment:
    **`I18nManager` docstring missing `version_id`**
    
    The class-level docstring documents every constructor parameter except the newly added `version_id`. This omission will make it harder for library consumers to discover the parameter.
    
    
    
    How can I resolve this? If you propose a fix, please make it concise.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: packages/gt-fastapi/src/gt_fastapi/_setup.py
Line: 59

Comment:
**`version_id` not passable as a direct parameter to `initialize_gt()`**

`resolved_version_id` is read only from the config file — there is no `version_id` keyword argument on `initialize_gt()`. Every other configuration value (`project_id`, `cache_url`, `default_locale`, `locales`, `custom_mapping`) follows the pattern of accepting both a function argument (which takes precedence) and a file-config fallback. Users who want to set `version_id` programmatically — e.g. in tests or in apps that don't use `gt.config.json` — have no way to do so.

The same issue exists in `packages/gt-flask/src/gt_flask/_setup.py` at line 59.

Suggested fix (FastAPI — Flask is identical):

```
def initialize_gt(
    app: Any,
    *,
    default_locale: str | None = None,
    locales: list[str] | None = None,
    custom_mapping: CustomMapping | None = None,
    project_id: str | None = None,
    cache_url: str | None = None,
    version_id: str | None = None,   # ← add
    get_locale: Callable[..., str] | None = None,
    load_translations: Callable[[str], dict[str, str]] | None = None,
    eager_loading: bool = True,
    config_path: str | None = None,
    load_config: Callable[[str | None], GTConfig] | None = None,
) -> I18nManager:
    ...
    resolved_version_id = version_id or file_config.get("version_id")
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: packages/gt-i18n/src/gt_i18n/i18n_manager/_i18n_manager.py
Line: 20-33

Comment:
**`I18nManager` docstring missing `version_id`**

The class-level docstring documents every constructor parameter except the newly added `version_id`. This omission will make it harder for library consumers to discover the parameter.

```suggestion
    """Central orchestrator for i18n operations.

    Args:
        default_locale: The source/default locale.
        locales: List of target locales the application supports.
        project_id: GT project ID (used for CDN loader).
        cache_url: CDN base URL override.
        store_adapter: Custom storage adapter. Defaults to
            :class:`ContextVarStorageAdapter`.
        load_translations: Custom translation loader. Overrides the
            remote CDN loader when provided.
        cache_expiry_time: Cache expiry in milliseconds.
        version_id: Optional version ID for the current source content.
    """
```

How can I resolve this? If you propose a fix, please make it concise.

Last reviewed commit: "feat: add get_versio..."

Greptile also left 1 inline comment on this PR.

Mirrors the useVersionId/getVersionId hook added to the JS packages
in generaltranslation/gt#1121.

- I18nManager: new version_id param + get_version_id() method
- Config loader: reads _versionId from gt.config.json
- Helper: get_version_id() convenience function
- Re-exported from gt-i18n, gt-fastapi, gt-flask
resolved_cache_url = cache_url or file_config.get("cache_url")
resolved_custom_mapping = custom_mapping or file_config.get("custom_mapping")

resolved_version_id = file_config.get("version_id")
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 version_id not passable as a direct parameter to initialize_gt()

resolved_version_id is read only from the config file — there is no version_id keyword argument on initialize_gt(). Every other configuration value (project_id, cache_url, default_locale, locales, custom_mapping) follows the pattern of accepting both a function argument (which takes precedence) and a file-config fallback. Users who want to set version_id programmatically — e.g. in tests or in apps that don't use gt.config.json — have no way to do so.

The same issue exists in packages/gt-flask/src/gt_flask/_setup.py at line 59.

Suggested fix (FastAPI — Flask is identical):

def initialize_gt(
    app: Any,
    *,
    default_locale: str | None = None,
    locales: list[str] | None = None,
    custom_mapping: CustomMapping | None = None,
    project_id: str | None = None,
    cache_url: str | None = None,
    version_id: str | None = None,   # ← add
    get_locale: Callable[..., str] | None = None,
    load_translations: Callable[[str], dict[str, str]] | None = None,
    eager_loading: bool = True,
    config_path: str | None = None,
    load_config: Callable[[str | None], GTConfig] | None = None,
) -> I18nManager:
    ...
    resolved_version_id = version_id or file_config.get("version_id")
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/gt-fastapi/src/gt_fastapi/_setup.py
Line: 59

Comment:
**`version_id` not passable as a direct parameter to `initialize_gt()`**

`resolved_version_id` is read only from the config file — there is no `version_id` keyword argument on `initialize_gt()`. Every other configuration value (`project_id`, `cache_url`, `default_locale`, `locales`, `custom_mapping`) follows the pattern of accepting both a function argument (which takes precedence) and a file-config fallback. Users who want to set `version_id` programmatically — e.g. in tests or in apps that don't use `gt.config.json` — have no way to do so.

The same issue exists in `packages/gt-flask/src/gt_flask/_setup.py` at line 59.

Suggested fix (FastAPI — Flask is identical):

```
def initialize_gt(
    app: Any,
    *,
    default_locale: str | None = None,
    locales: list[str] | None = None,
    custom_mapping: CustomMapping | None = None,
    project_id: str | None = None,
    cache_url: str | None = None,
    version_id: str | None = None,   # ← add
    get_locale: Callable[..., str] | None = None,
    load_translations: Callable[[str], dict[str, str]] | None = None,
    eager_loading: bool = True,
    config_path: str | None = None,
    load_config: Callable[[str | None], GTConfig] | None = None,
) -> I18nManager:
    ...
    resolved_version_id = version_id or file_config.get("version_id")
```

How can I resolve this? If you propose a fix, please make it concise.

…-flask

Greptile correctly identified that version_id was the only config value
not passable as a direct parameter. Now follows the same pattern as
project_id, cache_url, etc. — function argument takes precedence over
file config fallback.

Also adds changeset for the release.
@ErnestM1234 ErnestM1234 merged commit 9ec9e3f into generaltranslation:main Mar 19, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants