Skip to content

[Files] Transform string into part for metadata in upload_files request#207

Open
AMoldova-NI wants to merge 3 commits into
masterfrom
users/amoldova/fix-metadata-field-in-upload-files-request
Open

[Files] Transform string into part for metadata in upload_files request#207
AMoldova-NI wants to merge 3 commits into
masterfrom
users/amoldova/fix-metadata-field-in-upload-files-request

Conversation

@AMoldova-NI
Copy link
Copy Markdown
Contributor

What does this Pull Request accomplish?

Fix upload_files method to accept metadata field with custom data.

Why should this Pull Request be merged?

This fixes a bug issued here #206

What testing has been done?

Testing done using the script provided in the issue

Co-authored-by: Copilot <copilot@github.com>
@AMoldova-NI AMoldova-NI changed the title Transform string into part [Files] Transform string into part for metadata in upload_files request May 11, 2026
@AMoldova-NI AMoldova-NI requested a review from Copilot May 11, 2026 13:09
Copy link
Copy Markdown

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

Fixes FileClient.upload_file() multipart encoding so the optional metadata argument is sent as a non-file form part (preventing the File service from rejecting it as a file), addressing the 400 Bad Request described in issue #206.

Changes:

  • Encode metadata as a multipart part tuple (None, json, "application/json") instead of passing a raw JSON string to the multipart Part.
  • Rename the intermediate variable from metadata_str to metadata_part to reflect the new payload shape.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread nisystemlink/clients/file/_file_client.py
Comment thread nisystemlink/clients/file/_file_client.py
Comment thread nisystemlink/clients/file/_file_client.py
Copy link
Copy Markdown

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 2 out of 2 changed files in this pull request and generated 3 comments.

Comment thread nisystemlink/clients/file/_file_client.py Outdated
Comment thread tests/integration/file/test_file_client.py
Comment thread tests/integration/file/test_file_client.py
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copy link
Copy Markdown

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 2 out of 2 changed files in this pull request and generated 2 comments.

Comment on lines +95 to +101
self, client: FileClient, binary_file_data: BinaryIO, random_filename_extension: str
):
file_name = random_filename_extension
metadata = {"CustomProp": "CustomValue"}

# Upload the file with metadata
file_id = client.upload_file(file=binary_file_data, metadata=metadata)
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 think this is a real problem but we can just change the fixture scope to function so it gets a new BytesIO in each test. It was previously only used by one test, so this problem would not have manifested before.

Comment on lines +100 to +115
# Upload the file with metadata
file_id = client.upload_file(file=binary_file_data, metadata=metadata)

# Verify the file was created with correct metadata
files = client.get_files(ids=[file_id])
assert files.total_count == 1
assert len(files.available_files) == 1
assert files.available_files[0].id == file_id
assert files.available_files[0].properties is not None
assert files.available_files[0].properties["Name"] == file_name
assert (
len(files.available_files[0].properties.keys()) == len(metadata) + 1
) # Name + 1 custom property

client.delete_file(id=file_id)

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 think the best approach is to change the test_file fixture to take the metadata so you can reuse it and its built-in file clean up rather than duplicating that clean up. You can still verify the delete if you want, but you can also just drop that and rely on the fixture's cleanup and only assert the get_files response has the properties you want.

Comment on lines +95 to +101
self, client: FileClient, binary_file_data: BinaryIO, random_filename_extension: str
):
file_name = random_filename_extension
metadata = {"CustomProp": "CustomValue"}

# Upload the file with metadata
file_id = client.upload_file(file=binary_file_data, metadata=metadata)
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 think this is a real problem but we can just change the fixture scope to function so it gets a new BytesIO in each test. It was previously only used by one test, so this problem would not have manifested before.

Comment on lines +100 to +115
# Upload the file with metadata
file_id = client.upload_file(file=binary_file_data, metadata=metadata)

# Verify the file was created with correct metadata
files = client.get_files(ids=[file_id])
assert files.total_count == 1
assert len(files.available_files) == 1
assert files.available_files[0].id == file_id
assert files.available_files[0].properties is not None
assert files.available_files[0].properties["Name"] == file_name
assert (
len(files.available_files[0].properties.keys()) == len(metadata) + 1
) # Name + 1 custom property

client.delete_file(id=file_id)

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 think the best approach is to change the test_file fixture to take the metadata so you can reuse it and its built-in file clean up rather than duplicating that clean up. You can still verify the delete if you want, but you can also just drop that and rely on the fixture's cleanup and only assert the get_files response has the properties you want.

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.

3 participants