Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
29c0eec
feat: update models to vrs 2.1.0-snapshot.2026-02.2 (#615)
korikuzma Feb 24, 2026
e1d7962
ci: remove get_branch job for pypi release (#616) (#617)
korikuzma Feb 24, 2026
5f0a810
fix: change VRS_VERSION to 2.1.0-snapshot.2026-02.2 (#634)
korikuzma May 6, 2026
27d0ec4
fix: _from_vrs handle kwargs without error
jsstevenson May 23, 2026
a50b9fb
fix: _from_vrs handle kwargs without error (#635)
jsstevenson May 24, 2026
b86e16b
Merge branch 'vrs/2.1.0-snapshot.2026-02' into tlr-vrs-interface
jsstevenson May 26, 2026
a9a4897
fix: handle key error in translate_to (#639)
korikuzma Jun 8, 2026
372e293
fix: handle key error in translate_to (#639)
korikuzma Jun 8, 2026
d001404
Merge prior branch patches (#636)
jsstevenson Jun 9, 2026
79c212d
fix: JSON Schema number type should also include int (#645)
korikuzma Aug 12, 2026
053fa2e
fix: JSON Schema number type should also include int (#644)
korikuzma Aug 12, 2026
f4c7758
feat: add CORE_VERSION (gks-core) (#647)
korikuzma Aug 14, 2026
859e77a
feat: add CORE_VERSION (gks-core) (#648)
korikuzma Aug 14, 2026
f945295
feat: expose json schema metadata to core and vrs models (#650)
korikuzma Aug 19, 2026
87ffb9d
feat: update models to gkm-core 1.2.0 and vrs 2.1.0 (#652)
korikuzma Sep 1, 2026
0476ec6
feat: update models vrs 2.1.1-ballot.2026-09.1 (#658)
korikuzma Sep 29, 2026
d4baa18
fix: remove misleading ABC markers (#661)
korikuzma Sep 30, 2026
ca12a4f
feat: update vrs version to 2.1.1 (#662)
korikuzma Oct 1, 2026
21709c5
fix: detect intronic RNA (r.) variants in is_intronic (#642)
knQzx Oct 2, 2026
9c41840
Merge main (21709c5) into vrs/2.1
theferrit32 Oct 2, 2026
7ce16de
Sync from main (#664)
theferrit32 Oct 2, 2026
7bccbf8
Merge remote-tracking branch 'origin/v3' into vrs/2.1
korikuzma Oct 19, 2026
9bcf024
test: remove generated files
korikuzma Oct 19, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[submodule "submodules/vrs"]
path = submodules/vrs
url = https://github.com/ga4gh/vrs.git
branch = 2.0
branch = 2.1
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

## Features

- Pydantic implementation of GKS core models and VRS models
- Pydantic implementation of GKM-Core models and VRS models
- Algorithm for generating consistent, globally unique identifiers for variation without a central authority
- Algorithm for performing fully justified allele normalization
- Translating from and to other variant formats
Expand Down
39 changes: 31 additions & 8 deletions src/ga4gh/core/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Python support used across GA4GH projects"""

from importlib.metadata import PackageNotFoundError, version
from importlib.metadata import PackageNotFoundError
from importlib.metadata import version as package_version

import ga4gh.core.models as core_models
from ga4gh.core.digests import sha512t24u
Expand All @@ -19,14 +20,43 @@
is_ga4gh_identifier,
use_ga4gh_compute_identifier_when,
)
from ga4gh.core.metadata import (
GKMMaturityMixin,
GKMMetadataMixin,
GKMSchemaMixin,
GKSMaturityMixin,
GKSMetadataMixin,
GKSSchemaMixin,
Maturity,
)
from ga4gh.core.models import GKMCoreMetadataMixin, GKSCoreMetadataMixin
from ga4gh.core.pydantic import is_curie_type, is_pydantic_instance, pydantic_copy
from ga4gh.core.version import CORE_VERSION

try:
__version__ = package_version(__name__)
except PackageNotFoundError: # pragma: nocover
__version__ = "unknown"
finally:
del package_version, PackageNotFoundError


__all__ = [
"CORE_VERSION",
"CURIE_NAMESPACE",
"CURIE_SEP",
"GA4GH_DIGEST_REGEXP",
"GA4GH_IR_REGEXP",
"GA4GH_PREFIX_SEP",
"GKMCoreMetadataMixin",
"GKMMaturityMixin",
"GKMMetadataMixin",
"GKMSchemaMixin",
"GKSCoreMetadataMixin",
"GKSMaturityMixin",
"GKSMetadataMixin",
"GKSSchemaMixin",
"Maturity",
"PrevVrsVersion",
"VrsObjectIdentifierIs",
"core_models",
Expand All @@ -42,10 +72,3 @@
"sha512t24u",
"use_ga4gh_compute_identifier_when",
]

try:
__version__ = version(__name__)
except PackageNotFoundError: # pragma: nocover
__version__ = "unknown"
finally:
del version, PackageNotFoundError
134 changes: 134 additions & 0 deletions src/ga4gh/core/metadata.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
"""Provide shared metadata types for GA4GH GKM models."""

from enum import Enum
from typing import Any, ClassVar, Literal

import pydantic
from pydantic.json_schema import GenerateJsonSchema, JsonSchemaMode
from typing_extensions import deprecated

# union_format was introduced in pydantic 2.12
# (https://pydantic.dev/docs/validation/latest/get-started/changelog/#v2120-2025-10-07)
PYDANTIC_HAS_UNION_FORMAT = tuple(
int(p) for p in pydantic.__version__.split(".")[:2]
) >= (2, 12)


class Maturity(str, Enum):
"""Maturity levels for GA4GH product features."""

DRAFT = "draft"
TRIAL_USE = "trial use"
NORMATIVE = "normative"
DEPRECATED = "deprecated"


class GKMMaturityMixin:
"""Provide maturity metadata for a GA4GH GKM model."""

_maturity: ClassVar[Maturity]

@classmethod
def maturity(cls) -> Maturity:
"""Return the GKM maturity level for the model."""
return cls._maturity


class GKMSchemaMixin:
"""Provide a canonical JSON Schema identifier for a GA4GH GKM model."""

_schema_base_uri: ClassVar[str] = "https://w3id.org/ga4gh/schema"
_product_name: ClassVar[str]
_product_version: ClassVar[str]

@classmethod
def schema_id(cls) -> str:
"""Return the canonical JSON Schema identifier for the model."""
return f"{cls._schema_base_uri}/{cls._product_name}/{cls._product_version}/json/{cls.__name__}"


class GKMMetadataMixin(GKMMaturityMixin, GKMSchemaMixin):
"""Provide maturity and schema metadata for a GKM model."""

_abstract: ClassVar[bool] = False

@classmethod
def apply_schema_metadata(cls, schema: dict[str, Any]) -> dict[str, Any]:
"""Add GKM metadata to a generated JSON Schema.

:param schema: Generated JSON Schema to annotate.
:returns: The annotated JSON Schema.
"""
schema["$id"] = cls.schema_id()
schema["maturity"] = cls.maturity().value

if cls.__dict__.get("_abstract", False):
schema["abstract"] = True

# GA4GH identifier metadata is optional and applies only when declared.
ga4gh_class = getattr(cls, "ga4gh", None)
if not ga4gh_class:
return schema

ga4gh_metadata = {}

if prefix := getattr(ga4gh_class, "prefix", None):
ga4gh_metadata["prefix"] = prefix

if inherent := getattr(ga4gh_class, "inherent", None):
ga4gh_metadata["inherent"] = list(inherent)

if ga4gh_metadata:
schema["ga4gh"] = ga4gh_metadata

return schema

@classmethod
def model_json_schema(
cls,
by_alias: bool = True,
ref_template: str = "#/$defs/{model}",
schema_generator: type[GenerateJsonSchema] = GenerateJsonSchema,
mode: JsonSchemaMode = "validation",
*,
union_format: Literal["any_of", "primitive_type_array"] = "any_of",
) -> dict[str, Any]:
"""Generate JSON Schema with GKM metadata.

Default values follow Pydantic defaults.

:param by_alias: Whether to use field aliases.
:param ref_template: Template for schema references.
:param schema_generator: Pydantic schema generator class.
:param mode: Pydantic schema generation mode.
:param union_format: How to represent unions in the generated schema.
:returns: JSON Schema annotated with GKM metadata.
"""
schema_kwargs: dict[str, Any] = {
"by_alias": by_alias,
"ref_template": ref_template,
"schema_generator": schema_generator,
"mode": mode,
}

if PYDANTIC_HAS_UNION_FORMAT:
schema_kwargs["union_format"] = union_format

schema = super().model_json_schema(**schema_kwargs) # pyright: ignore[reportAttributeAccessIssue]

return cls.apply_schema_metadata(schema)


@deprecated("GKSMaturityMixin is deprecated; use GKMMaturityMixin instead.")
class GKSMaturityMixin(GKMMaturityMixin):
"""Deprecated alias for :class:`GKMMaturityMixin`."""


@deprecated("GKSSchemaMixin is deprecated; use GKMSchemaMixin instead.")
class GKSSchemaMixin(GKMSchemaMixin):
"""Deprecated alias for :class:`GKMSchemaMixin`."""


@deprecated("GKSMetadataMixin is deprecated; use GKMMetadataMixin instead.")
class GKSMetadataMixin(GKMMetadataMixin):
"""Deprecated alias for :class:`GKMMetadataMixin`."""
Loading
Loading