Skip to content

[ENH] V1 -> V2 Migration - Flows (module)#1609

Open
Omswastik-11 wants to merge 326 commits into
openml:mainfrom
Omswastik-11:flow-migration-stacked
Open

[ENH] V1 -> V2 Migration - Flows (module)#1609
Omswastik-11 wants to merge 326 commits into
openml:mainfrom
Omswastik-11:flow-migration-stacked

Conversation

@Omswastik-11
Copy link
Copy Markdown
Contributor

@Omswastik-11 Omswastik-11 commented Jan 8, 2026

Fixes #1601

added a Create method in FlowAPI for publishing flow but not refactored with old publish . (Needs discussion on this)
Added tests using fake_methods so that we can test without local V2 server . I have tested the FlowsV2 methods (get and exists ) and delete and list were not implemented in V2 server so I skipped them .

@Omswastik-11 Omswastik-11 changed the title [ENH] V1 -> V2 Migration [ENH] V1 -> V2 Migration - Flows (module) Jan 8, 2026
@Omswastik-11 Omswastik-11 marked this pull request as ready for review January 8, 2026 15:09
@geetu040 geetu040 mentioned this pull request Jan 9, 2026
18 tasks
@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Jan 12, 2026

Codecov Report

❌ Patch coverage is 85.08772% with 17 lines in your changes missing coverage. Please review.
✅ Project coverage is 81.33%. Comparing base (c631b28) to head (d83fb14).

Files with missing lines Patch % Lines
openml/_api/resources/flow.py 83.69% 15 Missing ⚠️
openml/flows/flow.py 86.66% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1609      +/-   ##
==========================================
- Coverage   81.42%   81.33%   -0.09%     
==========================================
  Files          63       63              
  Lines        5195     5240      +45     
==========================================
+ Hits         4230     4262      +32     
- Misses        965      978      +13     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown
Collaborator

@geetu040 geetu040 left a comment

Choose a reason for hiding this comment

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

Nicely done overall.

Comment thread openml/_api/resources/base.py Outdated
Comment thread openml/_api/resources/base/resources.py Outdated
Comment thread openml/_api/resources/flows.py Outdated
Comment thread openml/_api/resources/flow.py Outdated
Comment thread openml/flows/functions.py Outdated
Comment thread openml/flows/functions.py Outdated
Comment thread openml/flows/functions.py Outdated
Comment thread tests/test_flows/test_flow_functions.py
Comment thread tests/test_flows/test_flow_migration.py Outdated
Comment thread openml/_api/resources/flows.py Outdated
@Omswastik-11 Omswastik-11 force-pushed the flow-migration-stacked branch from 614411f to 36184e5 Compare January 14, 2026 14:56
@Omswastik-11 Omswastik-11 requested a review from geetu040 January 14, 2026 15:10
@Omswastik-11
Copy link
Copy Markdown
Contributor Author

Hi @geetu040 !! Can you review the pre-commit failure It was due to merge conflicts more specifically for tasks . Should I change it on my branch ?

@geetu040
Copy link
Copy Markdown
Collaborator

Hi @geetu040 !! Can you review the pre-commit failure It was due to merge conflicts more specifically for tasks . Should I change it on my branch ?

can you try again, sync your branch with mine? It should be fixed now.

@Omswastik-11
Copy link
Copy Markdown
Contributor Author

I think that due to conflicts it did not synced properly . I have to revert it manually

Copy link
Copy Markdown
Collaborator

@geetu040 geetu040 left a comment

Choose a reason for hiding this comment

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

Nice overall, few changes needed. I'll look at the tests later when the implementation is final.

Comment thread openml/_api/resources/flows.py Outdated
Comment thread openml/flows/functions.py Outdated
Comment thread openml/flows/functions.py Outdated
@Omswastik-11 Omswastik-11 requested a review from geetu040 January 21, 2026 18:25
@Omswastik-11 Omswastik-11 marked this pull request as draft January 27, 2026 07:30
@Omswastik-11 Omswastik-11 marked this pull request as ready for review January 27, 2026 15:13
geetu040 and others added 5 commits January 29, 2026 22:05
Signed-off-by: Omswastik-11 <omswastikpanda11@gmail.com>
Signed-off-by: Omswastik-11 <omswastikpanda11@gmail.com>
Copy link
Copy Markdown
Collaborator

@geetu040 geetu040 left a comment

Choose a reason for hiding this comment

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

sdk code look good so far, please take a look at #1575 (comment) and make changes accordingly where needed.
all tests (existing and new) should pass to make sure we are retaining the original functionality of the sdk

Comment thread openml/flows/functions.py Outdated
Comment thread openml/flows/functions.py Outdated
Copilot AI review requested due to automatic review settings May 11, 2026 13:17
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Comment thread tests/test_api/test_flow.py
Comment thread tests/test_api/test_flow.py
Comment thread tests/test_api/test_flow.py Outdated
Comment thread tests/test_api/test_flow.py Outdated
Comment thread openml/_api/resources/flow.py Outdated
Omswastik-11 and others added 2 commits May 11, 2026 19:47
Co-authored-by: Armaghan Shakir <raoarmaghanshakir040@gmail.com>
Copilot AI review requested due to automatic review settings May 11, 2026 14:18
Co-authored-by: Armaghan Shakir <raoarmaghanshakir040@gmail.com>
@Omswastik-11 Omswastik-11 requested a review from geetu040 May 11, 2026 14:30
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copy link
Copy Markdown
Collaborator

@geetu040 geetu040 left a comment

Choose a reason for hiding this comment

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

Nice work @Omswastik-11.

@PGijsbers please review/merge.

Copy link
Copy Markdown
Collaborator

@PGijsbers PGijsbers left a comment

Choose a reason for hiding this comment

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

Thanks! Minor comment with a question to take into consideration going forward.

Comment on lines +226 to +292
@staticmethod
def _convert_v2_to_v1_format(v2_json: dict[str, Any]) -> dict[str, Any]:
"""Convert v2 JSON response to v1 XML-dict format for OpenMLFlow._from_dict().

Parameters
----------
v2_json : dict
The v2 JSON response from the server.

Returns
-------
dict
A dictionary matching the v1 XML structure expected by OpenMLFlow._from_dict().
"""
# Map v2 JSON fields to v1 XML structure with oml: namespace
flow_dict = {
"oml:flow": {
"@xmlns:oml": "http://openml.org/openml",
"oml:id": str(v2_json.get("id", "0")),
"oml:uploader": str(v2_json.get("uploader", "")),
"oml:name": v2_json.get("name", ""),
"oml:version": str(v2_json.get("version", "")),
"oml:external_version": v2_json.get("external_version", ""),
"oml:description": v2_json.get("description", ""),
"oml:upload_date": (
v2_json.get("upload_date", "").replace("T", " ")
if v2_json.get("upload_date")
else ""
),
"oml:language": v2_json.get("language", ""),
"oml:dependencies": v2_json.get("dependencies", ""),
}
}

# Add optional fields
if "class_name" in v2_json:
flow_dict["oml:flow"]["oml:class_name"] = v2_json["class_name"]
if "custom_name" in v2_json:
flow_dict["oml:flow"]["oml:custom_name"] = v2_json["custom_name"]

# Convert parameters from v2 array to v1 format
if v2_json.get("parameter"):
flow_dict["oml:flow"]["oml:parameter"] = [
{
"oml:name": param.get("name", ""),
"oml:data_type": param.get("data_type", ""),
"oml:default_value": str(param.get("default_value", "")),
"oml:description": param.get("description", ""),
}
for param in v2_json["parameter"]
]

# Convert subflows from v2 to v1 components format
if v2_json.get("subflows"):
flow_dict["oml:flow"]["oml:component"] = [
{
"oml:identifier": subflow.get("identifier", ""),
"oml:flow": FlowV2API._convert_v2_to_v1_format(subflow["flow"])["oml:flow"],
}
for subflow in v2_json["subflows"]
]

# Convert tags from v2 array to v1 format
if v2_json.get("tag"):
flow_dict["oml:flow"]["oml:tag"] = v2_json["tag"]

return flow_dict
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I might be missing something, but it seems to me like just having a separate parser would have been more useful. Or even allowing the parser to be called with or without a required oml: prefix. Largely because after sunset of v1, we wouldn't want to keep this code around anymore, so we would have to do extra work.
Considering it works now and this is easily addressed as a separate PR at a later date, I'm not going to request a change here. If there were considerations or attempts that prevented you from doing it that way, I would be interested to hear about them so they can be taken into account when this is worked on in the future.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I don't think anything prevented from doing it that way. Btw in a long-term plan, are you suggesting to update the schema definition of flow dict?
Also I don't think I exactly get your idea of separate parser. Are you thinking of a general json to xml parser that could work across several other cases in code?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Sorry, I just meant that we currently interface with the XML endpoints of the REST API, which include additional qualifiers (e.g,. the oml: prefix). However, the JSON endpoint (both in v1 and v2) don't have this.
So it might have made more sense to directly parse the JSON instead of first coercing it back into the v1 style XML response.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

agreed, and going forward this should be the way.

Comment thread tests/test_api/test_flow.py
@geetu040
Copy link
Copy Markdown
Collaborator

Link doesn't work for me, but it seems like _validate_flow is part of this PR.

It was this thread if you missed: 1609/changes#r3283724084

Copilot AI review requested due to automatic review settings June 2, 2026 01:58
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.

Comment thread openml/_api/resources/flow.py Outdated
Comment on lines +137 to +144
mock_request.assert_called_once_with(
method="POST",
url=openml.config.server + "flow",
params={},
data={"api_key": test_apikey_v1},
headers=openml.config._HEADERS,
files=files,
)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Not changing — consistent with the whole test suite's convention

Comment on lines +79 to +92
@abstractmethod
def get(self, flow_id: int, *, reset_cache: bool = False) -> OpenMLFlow: ...

@abstractmethod
def list(
self,
limit: int | None = None,
offset: int | None = None,
tag: str | None = None,
uploader: str | None = None,
) -> pd.DataFrame: ...

@abstractmethod
def exists(self, name: str, external_version: str) -> int | bool: ...
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Already handled — from future import annotations + TYPE_CHECKING guards are in place

Comment on lines +312 to +319
response = requests.Response()
response.status_code = 200
response._content = (
'<oml:upload_flow xmlns:oml="http://openml.org/openml">\n'
" <oml:id>1</oml:id>\n"
"</oml:upload_flow>"
).encode()
mock_request.return_value = response
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

create_request_response() itself uses _content internally, so switching to the helper wouldn't change anything

Copilot AI review requested due to automatic review settings June 3, 2026 14:32
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review is ineligible. To be eligible to request a review, you need a paid Copilot license, or your organization must enable Copilot code review.

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.

[ENH] V1 → V2 API Migration - flows

8 participants