umccr / libica

:snake: Python SDK for Illumina Connected Analytics (ICA) :dragon:
MIT License
6 stars 4 forks source link

Link Data to Bundle fails with invalid accept header #139

Open alexiswl opened 3 months ago

alexiswl commented 3 months ago

Try

# Initialise the API client
with ApiClient(get_icav2_configuration()) as api_client:
    # Create an instance of the API class
    api_instance = BundleDataApi(api_client)

try:
    # Link a data to a bundle.
    api_instance.link_data_to_bundle(bundle_id, data_id)
    return True
except ApiException as e:
    logger.error("Exception when calling BundleDataApi->link_data_to_bundle: %s\n" % e)
    raise ApiException

Fails with

{
  "id": "bf7b9495-d318-4bfd-b89d-ac392d8ca201",
  "type": "about:blank",
  "title": "ICA_API_004",
  "status": 400,
  "detail": "Invalid Accept Header",
  "instance": "http://ica.illumina.com/ica/rest/api/bundles/383b6f56-8108-4b7d-9e77-16e7d92e52bb/data/fil.be91f7c9444d4c81bf5d08dbe59e6b4a",
  "parameters": {},
  "timestamp": "2024-06-26T09:53:07Z",
  "method": "POST"
}

Solution was to add the accept header in

with ApiClient(get_icav2_configuration()) as api_client:
    # Create an instance of the API class
    api_client.set_default_header(
        header_name="Accept",
        header_value="application/vnd.illumina.v3+json"
    )
    api_instance = BundleDataApi(api_client)
victorskl commented 3 months ago

I will look into milestone 2.5.0, starting next week... ETA

alexiswl commented 3 months ago

This was a common issue with ':' based endpoints, i.e bundles/{bundle_id}:release, but this endpoint is projects/{project_id}/bundles/{bundle_id}.

victorskl commented 2 months ago

I had looked at this issue. I don't think we can do much about the situation here from SDK/Client side.

Server enforce versioning check at endpoint through HTTP header which is ambiguous and contradict the endpoint use case condition.

I can only feedback that ICAv2 backend adoption of "API versioning through media type / content type header" technique is a bit bleeding edge. This technique still have few standing caveats and ambiguity for endpoint versioning.

See OAI feature request at https://github.com/OAI/OpenAPI-Specification/issues/2142

victorskl commented 2 months ago

Solution was to add the accept header in

On the second thought over the weekend, we can add this Accept header at SDK level. This would mean every client call is set to application/vnd.illumina.v3+json by default at SDK.

One has to overwrite v4 (or any later version) if wanting to switch application/vnd.illumina.v4+json and, so on.

When server-side started to deprecate application/vnd.illumina.v3+json acceptance (assume no upfront knowledge about this), all client calls from SDK would/could be rejected. At that point, (then working well / valid) SDK release become literally broken & invalid. We will be forced to update the SDK & API client. Situation which I wish to protect.

Let me explore whether I can put some facade, in front...

victorskl commented 2 months ago

I have discussed this with Alexis. At the mo, we will keep this on hold and low prior as Alexis can work around with header switches. Non ideal, ACK.

We shall revisit with milestone 3.0; whereas we may able to sort out neatly by rooting to newer / more modern generator version.

averyschiff commented 2 months ago

Hello! I'm also encountering this error with link_pipeline_to_project from ProjectPipelineApi.

from libica.openapi.v2.api.project_pipeline_api import ProjectPipelineApi
client_v3 = get_icav2_client(version=3)
project_pipeline_api = ProjectPipelineApi(api_client=client_v3)
project_pipeline_api.link_pipeline_to_project(project_id=project_id, pipeline_id=pipeline_id)

fails with

HTTP response body: {
    "id": "cdd1e0a0-94ff-4e3c-9ff0-a54391c2f671",
    "type": "about:blank",
    "title": "ICA_API_004",
    "status": 400,
    "detail": "Invalid Accept Header",
    "instance": "http://ica.illumina.com/ica/rest/api/projects/<project-id>/pipelines/<pipeline-id>",
    "parameters": {},
    "timestamp": "2024-08-21T02:33:40Z",
    "method": "POST"
}

for a variety of different target pipelines. Are there any updates for this bug? Or a projected release date for the patch?

cc @Ben-Habermeyer

alexiswl commented 2 months ago

Hi @averyschiff,

You might want to try the solution above

with ApiClient(get_icav2_configuration()) as api_client:
    # Create an instance of the API class
    api_client.set_default_header(
        header_name="Accept",
        header_value="application/vnd.illumina.v3+json"
    )
    api_instance = BundleDataApi(api_client) 

So in your case it's a matter of running the following methods on client_v3 prior to calling ProjectPipelineApi

client_v3.set_default_header(
    header_name="Accept",
    header_value="application/vnd.illumina.v3+json"
)

You may wish to look at our other projects wrapica and icav2-cli-plugins if you'd rather not need to interact with the API and use just higher-level-functions instead

victorskl commented 2 months ago

We can make the SDK set default to application/vnd.illumina.v3+json if this get painful in application code.

victorskl commented 2 months ago

I have added examples/issue_139.py script with comments to explain the situation and work around.

averyschiff commented 1 month ago

The work-around is working great, thank you very much!