diff --git a/CHANGELOG.md b/CHANGELOG.md index bb2d2df3d9..0538679d07 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -60,6 +60,7 @@ ### Fixes +- **`partition_via_api()` now sends the `content_type` it accepts.** The parameter has been part of the signature since the helper was introduced and is documented as "a string defining the file content in MIME type", but it was never read: the `shared.Files` object was built from `content` and `file_name` only, so the caller's MIME type never reached the API and the server fell back to sniffing the file name. `shared.Files` has a `content_type` field, which is now populated when the caller supplies one; omitting it leaves the field unset so the existing inference is unchanged. - **`GLOBAL_WORKING_PROCESS_DIR` no longer crashes on Windows.** Use `os.getpid()` when the POSIX-only `os.getpgid()` is unavailable. - **Preserve HTML table header semantics.** The v1 HTML parser now retains ``, ``, diff --git a/test_unstructured/partition/test_api.py b/test_unstructured/partition/test_api.py index 1206c259f0..262691e0f9 100644 --- a/test_unstructured/partition/test_api.py +++ b/test_unstructured/partition/test_api.py @@ -52,6 +52,50 @@ def test_partition_via_api_with_filename_correctly_calls_sdk( assert elements[0].metadata.filetype == "message/rfc822" +def test_partition_via_api_sends_an_explicit_content_type_for_a_filename( + request: FixtureRequest, +): + """`content_type` is a documented parameter and `shared.Files` has the field for it.""" + partition_mock_ = method_mock( + request, General, "partition", return_value=FakeResponse(status_code=200) + ) + + partition_via_api( + filename=example_doc_path("eml/fake-email.eml"), content_type="message/rfc822" + ) + + sent = partition_mock_.call_args_list[0].kwargs["request"] + assert sent.partition_parameters.files.content_type == "message/rfc822" + + +def test_partition_via_api_sends_an_explicit_content_type_for_a_file(request: FixtureRequest): + partition_mock_ = method_mock( + request, General, "partition", return_value=FakeResponse(status_code=200) + ) + + with open(example_doc_path("eml/fake-email.eml"), "rb") as f: + partition_via_api( + file=f.read(), + metadata_filename=example_doc_path("eml/fake-email.eml"), + content_type="message/rfc822", + ) + + sent = partition_mock_.call_args_list[0].kwargs["request"] + assert sent.partition_parameters.files.content_type == "message/rfc822" + + +def test_partition_via_api_leaves_content_type_unset_when_not_given(request: FixtureRequest): + """Omitting it must keep the SDK inferring the type from the file name, as before.""" + partition_mock_ = method_mock( + request, General, "partition", return_value=FakeResponse(status_code=200) + ) + + partition_via_api(filename=example_doc_path("eml/fake-email.eml")) + + sent = partition_mock_.call_args_list[0].kwargs["request"] + assert sent.partition_parameters.files.content_type is None + + def test_partition_via_api_with_file_correctly_calls_sdk( request: FixtureRequest, expected_call_: list[Any] ): diff --git a/unstructured/partition/api.py b/unstructured/partition/api.py index 2583c74bf6..2809b3cffb 100644 --- a/unstructured/partition/api.py +++ b/unstructured/partition/api.py @@ -98,11 +98,16 @@ def partition_via_api( base_url = api_url[:-19] if "/general/v0/general" in api_url else api_url sdk = UnstructuredClient(api_key_auth=api_key, server_url=base_url) + # -- `shared.Files` carries a `content_type` field; leave it unset when the caller did not + # -- specify one so the SDK keeps inferring the MIME type from the file name as before. + content_type_kwargs = {"content_type": content_type} if content_type is not None else {} + if filename is not None: with open(filename, "rb") as f: files = shared.Files( content=f.read(), file_name=filename, + **content_type_kwargs, ) elif file is not None: @@ -111,7 +116,7 @@ def partition_via_api( "If file is specified in partition_via_api, " "metadata_filename must be specified as well.", ) - files = shared.Files(content=file, file_name=metadata_filename) + files = shared.Files(content=file, file_name=metadata_filename, **content_type_kwargs) req = operations.PartitionRequest( partition_parameters=shared.PartitionParameters(files=files, **request_kwargs)