[ENH] V1 → V2 API Migration
Mantenedores costumam responder em até 1 dia
@geetu040 já está trabalhando nisso.
Desde 22/1/2026.
Avaliação
Esta issue ainda não foi avaliada.
Descrição
This issue tracks the migration of the openml-python SDK from the legacy OpenML API v1 (PHP-based) in openml/OpenML to the newer API v2 (Python-based) in openml/server-api, along with a structural refactor of the codebase to support both APIs during the transition.
The SDK currently relies on the v1 API, which should be progressively replaced by v2 while keeping backward compatibility and fallback where v2 endpoints are incomplete.
Goals
- Separate API interaction from SDK logic by introducing clear abstraction layers
- Modularize HTTP handling, API resources, and SDK-facing interfaces
- Allow easy switching between API v1 and v2
- Provide a transparent fallback to v1 for missing or unimplemented v2 endpoints
Proposed design (high level)
- A shared
HTTPClientresponsible for:- retries
- proxy configurations
- caching
- exception handling
- thread safety
- Abstract API "blueprints" (e.g.
DatasetsAPI,TasksAPI) defining SDK-facing methods - Version-specific implementations (
*V1,*V2) mapping those methods to concrete endpoints - A fallback proxy that routes calls to v1 if a v2 endpoint is unavailable (unless
strict=True) - A central backend/context that controls API version selection and exposes resources internally
A draft implementation sketch is included below to illustrate the architecture (not final API).
# handles HTTP requests, retries, and proxy configuration
class HTTPClient:
def __init__(self, base_url: str):
self.base_url = base_url
def get(self, path, params=None):
return requests.get(f"{self.base_url}{path}", params=params)
def post(self, path, params=None, files=None):
return requests.post(f"{self.base_url}{path}", params=params, files=files)
# abstract blueprints defining SDK-exposed API endpoints and methods
class DatasetsAPI(ABC):
@abstractmethod
def get(self, id: int) -> dict: ...
class TasksAPI(ABC):
@abstractmethod
def get(self, id: int) -> dict: ...
@abstractmethod
def list(self, id: int) -> dict: ...
# version-specific implementations built on top of the API blueprints
class DatasetsV1(DatasetsAPI):
def __init__(self, http: HTTPClient):
self._http = http
def get(self, id: int) -> dict:
r = self._http.get(f"/api/v1/json/data/{id}")
d = r.json()["data_set_description"]
return {
"id": d["data_set_description"]["id"],
"name": d["data_set_description"]["name"],
"version": d["data_set_description"]["version"],
}
class DatasetsV2(DatasetsAPI):
def __init__(self, http: HTTPClient):
self._http = http
def get(self, id: int) -> dict:
r = self._http.get(f"/datasets/{id}")
d = r.json()
return {
"id": d["id"],
"name": d["name"],
"version": d["version"],
}
class TasksV1(TasksAPI):
pass
class TasksV2(TasksAPI):
pass
# proxy that falls back to v1 when v2 endpoints are missing or unimplemented
class FallbackProxy:
def __init__(self, primary, fallback, *, strict: bool):
self._primary = primary
self._fallback = fallback
self._strict = strict
def __getattr__(self, name):
primary_attr = getattr(self._primary, name)
if not callable(primary_attr):
return primary_attr
def wrapper(*args, **kwargs):
try:
return primary_attr(*args, **kwargs)
except NotImplementedError:
if self._strict:
raise
return getattr(self._fallback, name)(*args, **kwargs)
return wrapper
# core backend holding API bindings, exposed internally and to the SDK
class APIBackend:
def __init__(self, *, datasets, tasks):
self.datasets = datasets
self.tasks = tasks
def build_backend(version: str, strict: bool) -> APIBackend:
v1_http = HTTPClient("https://www.openml.org")
v2_http = HTTPClient("http://127.0.0.1:8001")
v1 = APIBackend(
datasets=DatasetsV1(v1_http),
tasks=TasksV1(v1_http),
)
if version == "v1":
return v1
v2 = APIBackend(
datasets=DatasetsV2(v2_http),
tasks=TasksV2(v2_http),
)
if strict:
return v2
return APIBackend(
datasets=FallbackProxy(v2.datasets, v1.datasets),
tasks=FallbackProxy(v2.tasks, v1.tasks),
)
class APIContext:
def __init__(self):
self._backend = build_backend("v1", strict=False)
def set_version(self, version: str, strict: bool = False):
self._backend = build_backend(version, strict)
@property
def backend(self):
return self._backend
# SDK-facing entry points and version switching helpers
api_context = APIContext()
def set_api_version(version: str, strict=False):
api_context.set_version(version=version, strict=strict)
openml.set_api_version("v2", strict=True)
api_context.backend.data.get(31)
api_context.backend.tasks.list()
Work Items / Refactor scope
Base Scaffolding
Foundation: Establish the initial folder and file structure along with minimal base implementations for core components (HTTP client, backend, resource interfaces, versioned stubs). This provides a stable scaffold that subsequent refactor and migration work can build on.
HTTPClient features: Extend the shared HTTP client to provide consistent, reusable infrastructure concerns across all API versions and resources.
Fallback policy: Define and implement the fallback behavior that transparently redirects calls from v2 to v1 when endpoints are missing or unimplemented, with strict mode disabling fallback and surfacing errors.
- Base Scaffolding #1576
- Folder/file structure and base scaffolding
- retries
- proxy configuration
- caching
- exception handling
- v2 → v1 fallback support
Resource implementations
Implement resource classes that define SDK-facing methods and map them to concrete API endpoints. Each resource should have a clear abstract interface and version-specific implementations (*V1, *V2).
- Datasets https://github.com/openml/openml-python/pull/1608
- Tasks https://github.com/openml/openml-python/pull/1611
-
TaskTypes(not used in sdk) - EvaluationMeasures https://github.com/openml/openml-python/pull/1603
- EstimationProcedures https://github.com/openml/openml-python/pull/1604
- Evaluations https://github.com/openml/openml-python/pull/1606
- Flows https://github.com/openml/openml-python/pull/1609
- Studies https://github.com/openml/openml-python/pull/1610
- Runs https://github.com/openml/openml-python/pull/1616
- Setups https://github.com/openml/openml-python/pull/1619
-
Users(not used in sdk - though questionable, since spotted in evaluations)
- Linguagem predominante
- Python
- Estrelas
- 366
- Forks
- 308
- Merge médio
- 1d 16h
- PRs com merge (30d)
- 7
Preparar o ambiente
- Sem Dockerfile nem arquivo Docker Compose
- Tem um modelo de pull request
- Ler o guia de contribuição
Primeiros passos
- Leia a issue inteira e depois o guia de contribuição do projeto.
- Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
- Faça um fork do repositório e trabalhe em uma branch.
- Abra um pull request que referencie o número da issue.
Mais de openml/openml-python
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 82/100
openml/openml-python#1777 · 1 comentário ·
Mantenedores costumam responder em até 1 dia
-
[BUG] create_task() hardcodes task_type="None" instead of inferring type string from TaskTypeTalvez já em andamento @shellyco-code assumiu há 12 dias. Aberta
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 80/100
openml/openml-python#1766 ·
Mantenedores costumam responder em até 1 dia
-
Enhancement: Add missing **kwargs support to list_setups and list_evaluationsTalvez já em andamento @shellyco-code assumiu há 19 dias. Aberta
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 84/100
openml/openml-python#1753 · 1 comentário ·
Mantenedores costumam responder em até 1 dia
-
[ENH] list_estimation_procedures() should include the procedure IDsTalvez já em andamento @Jayant-kernel assumiu há 23 dias. Aberta
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 70/100
openml/openml-python#1750 · 3 comentários · 1 responsável ·
Mantenedores costumam responder em até 1 dia
-
[DOC] Update documentation for running tests with local servicesTalvez já em andamento @nishtha-agarwal-211 assumiu há 222 dias. AbertaDocumentation Good First Issue
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 74/100
openml/openml-python#1708 · 8 comentários ·
Mantenedores costumam responder em até 1 dia
Todas as issues de openml/openml-python
Issues semelhantes
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 78/100
-
[Bug] to_ical lexicographical/default sorting moves URL property between two X-WR- propertiesAberta
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 68/100
collective/icalendar#1968 · 1 comentário ·
Mantenedores costumam responder em até 1 dia
-
Deferred from #1869: Complete the companion pytest guardrail update noted in the PR description...Aberta
Dificuldade 1/5 Menos de uma hora Facilidade para iniciantes 95/100
Mantenedores costumam responder em até 1 dia
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 88/100
NousResearch/hermes-agent#140958 ·
Mantenedores costumam responder em até 1 dia
-
Bug triage/confirmed
Dificuldade 2/5 Meio dia Facilidade para iniciantes 85/100
agentscope-ai/agentscope#3355 ·
Mantenedores costumam responder em até 2 dias