Skip to content

New Feature: Implement S3 file removal method and corresponding tests for wmill python package#8216

Merged
rubenfiszel merged 11 commits intowindmill-labs:mainfrom
Roderik-WU:main
Mar 5, 2026
Merged

New Feature: Implement S3 file removal method and corresponding tests for wmill python package#8216
rubenfiszel merged 11 commits intowindmill-labs:mainfrom
Roderik-WU:main

Conversation

@Roderik-WU
Copy link
Contributor

@Roderik-WU Roderik-WU commented Mar 4, 2026

This pull request adds support for deleting files from S3 through the wmill python package. Pull request includes:

  • a new function to remove S3 files
  • a corresponding test to verify its behavior

S3 File Deletion Feature:

  • Added a new remove_s3_file method to the Windmill class in wmill/client.py, which permanently deletes a file from an S3 bucket. This method handles query parameters, error logging, and exception handling.

Testing:

  • Introduced a new integration test test_remove_s3_file in wmill_client_test.py to verify that files can be uploaded, deleted, and that deletion is confirmed by raising an exception when attempting to access the deleted file. The test is currently skipped as it requires a live Windmill instance with a configured storage backend.

The implementation was manually validated against a live Windmill workspace (Azure Blob Storage backend) by running an equivalent inline script that exercises the same code path — upload, read-back, DELETE via job_helpers/delete_s3_file, and confirmed 404 on subsequent load. The full local dev environment was not built.

Script used for testing

import os
import httpx
import wmill
from wmill import S3Object

def main():
    client = wmill.Windmill()
    test_key = "_wmill_test_remove_s3_file.txt"
    test_content = b"remove_s3_file test content"

    # 1. Upload a test file using the existing API
    s3obj = client.write_s3_file(
        S3Object(s3=test_key),
        test_content,
        s3_resource_path=None,
    )
    print(f"Uploaded: {s3obj}")

    # 2. Confirm it exists
    content = client.load_s3_file(s3obj, s3_resource_path=None)
    assert content == test_content, f"Read-back mismatch: {content!r}"
    print("Read back OK")

    # 3. Delete — inline implementation of remove_s3_file
    query_params = {"file_key": s3obj["s3"]}
    if s3obj.get("storage"):
        query_params["storage"] = s3obj["storage"]

    resp = client.client.delete(
        f"/w/{client.workspace}/job_helpers/delete_s3_file",
        params=query_params,
    )
    resp.raise_for_status()
    print(f"DELETE response: {resp.status_code}")

    # 4. Confirm deletion — load should now fail
    try:
        client.load_s3_file(s3obj, s3_resource_path=None)
        raise AssertionError("Expected error after deletion but load succeeded")
    except AssertionError:
        raise
    except Exception as e:
        print(f"Load after delete raised (expected): {type(e).__name__}: {e}")

    return "remove_s3_file logic works correctly"

Add method to permanently delete a file from S3 bucket.
Added a test case to verify removal of a file from S3.
Added a function to permanently delete a file from the S3 bucket.
@rubenfiszel
Copy link
Contributor

rename s3_file -> s3_object for consistency

Copy link
Contributor

@rubenfiszel rubenfiszel left a comment

Choose a reason for hiding this comment

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

thanks for PR. rename s3_file -> s3_object for consistency

@Roderik-WU
Copy link
Contributor Author

Done. (Based the original function name on the "write_s3_file" function but I agree "remove_s3_object" makes more sense)

@Roderik-WU Roderik-WU requested a review from rubenfiszel March 4, 2026 17:03
@rubenfiszel
Copy link
Contributor

sorry to be nitpicky but probably we want delete rather remove ?

@Roderik-WU
Copy link
Contributor Author

Roderik-WU commented Mar 5, 2026

sorry to be nitpicky but probably we want delete rather remove ?

Haha no worries. Totally understand you wanna get stuff like this right.
I made the requested change. (And if you do spot something you still don't like please just let me know!)

@rubenfiszel rubenfiszel merged commit 90f4c64 into windmill-labs:main Mar 5, 2026
1 check passed
@github-actions github-actions bot locked and limited conversation to collaborators Mar 5, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants