Skip to content
This repository was archived by the owner on Mar 23, 2026. It is now read-only.

Remove Boto resource fixtures#8674

Merged
viren-nadkarni merged 13 commits into
masterfrom
remove-boto-resource
Jul 26, 2023
Merged

Remove Boto resource fixtures#8674
viren-nadkarni merged 13 commits into
masterfrom
remove-boto-resource

Conversation

@viren-nadkarni
Copy link
Copy Markdown
Member

@viren-nadkarni viren-nadkarni commented Jul 11, 2023

This PR removes all use of Boto resources and replaces it with equivalent functionality offered by our new internal client (which uses the Boto client underneath).

There are no plans to support Boto resources as part of our new internal AWS client library. Furthermore, the Boto team does not actively develop Boto resources.

The aws_client_factory fixture supersedes this
@viren-nadkarni viren-nadkarni self-assigned this Jul 11, 2023
The equivalent functionality offered by the client is now used
@viren-nadkarni viren-nadkarni added the semver: patch Non-breaking changes which can be included in patch releases label Jul 11, 2023
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jul 11, 2023

LocalStack Community integration with Pro

       2 files         2 suites   1h 23m 12s ⏱️
2 223 tests 1 887 ✔️ 336 💤 0
2 224 runs  1 887 ✔️ 337 💤 0

Results for commit 5701d33.

♻️ This comment has been updated with latest results.

Comment on lines +225 to +245
@pytest.fixture
def s3_empty_bucket(aws_client):
"""
Returns a factory that given a bucket name, deletes all objects and deletes all object versions
"""
# Boto resource would make this a straightforward task, but our internal client does not support Boto resource
# FIXME: this won't work when bucket has more than 1000 objects
def factory(bucket_name: str):
response = aws_client.s3.list_objects_v2(Bucket=bucket_name)
objects = [{"Key": obj["Key"]} for obj in response["Contents"]]
aws_client.s3.delete_objects(Bucket=bucket_name, Delete={"Objects": objects})

response = aws_client.s3.list_object_versions(Bucket=bucket_name)
object_versions = [
{"Key": obj["Key"], "VersionId": obj["VersionId"]}
for obj in response.get("Versions", [])
]
if object_versions:
aws_client.s3.delete_objects(Bucket=bucket_name, Delete={"Objects": object_versions})

yield factory
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This new fixture replaces the functionality offered by the Boto S3 Resource

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'd probably prefer this to be a normal utility over a fixture but should be ok to leave as-is for now 👍

"`connect_to_resource_external` is obsolete. Use `localstack.aws.connect`",
DeprecationWarning,
)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

With this PR, these utilities are no longer used in the codebase but I've added these warnings so that they're properly highlighted in the IDE.

Btw, Python 3.12 will have a decorator to do exactly this https://peps.python.org/pep-0702/

item_ids = ("test", "test2", "test 3")
for item_id in item_ids:
dynamodb_table.put_item(Item={"id": item_id})
aws_client.dynamodb.put_item(TableName=table_name, Item={"id": {"S": item_id}})
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The client needs the items to be typed. The Boto resource had an intrinsic type conversion so it wasn't necessary earlier

objects = s3_resource.Bucket(s3_bucket).objects.all()
keys = []
for obj in objects:
keys.append(obj.key)
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The keys var wasn't used, hence removed

def test_create_key(self, kms_client_for_region, kms_create_key, snapshot, aws_client):
region = "us-east-1"
kms_client = kms_client_for_region(region)
account_id = aws_client.sts.get_caller_identity()["Account"]
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This call is replaced by the account_id fixture

@viren-nadkarni viren-nadkarni force-pushed the remove-boto-resource branch 4 times, most recently from 2d12c2e to 3e2d72a Compare July 13, 2023 14:26
@coveralls
Copy link
Copy Markdown

Coverage Status

coverage: 82.214% (+0.01%) from 82.204% when pulling 5701d33 on remove-boto-resource into 751c1ec on master.

@viren-nadkarni viren-nadkarni removed this from the 2.2 milestone Jul 17, 2023
@viren-nadkarni viren-nadkarni modified the milestones: 3.0, 2.2, 2.3 Jul 17, 2023
@viren-nadkarni viren-nadkarni marked this pull request as ready for review July 18, 2023 05:03
@viren-nadkarni viren-nadkarni requested review from calvernaz and removed request for baermat, bentsku, dfangl, joe4dev, macnev2013, pinzon, simonrw, steffyP and thrau July 18, 2023 05:04
Copy link
Copy Markdown
Member

@dominikschubert dominikschubert left a comment

Choose a reason for hiding this comment

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

Small nits, otherwise LGTM

Thanks so much for tackling this. 😅
The resource abstraction definitely didn't bring enough value to warrant maintaining its support besides the normal clients.
Love that we now finally have a unified abstraction and are quite close to remove the rest of the aws_stack clients soon 🚀

Comment on lines +225 to +245
@pytest.fixture
def s3_empty_bucket(aws_client):
"""
Returns a factory that given a bucket name, deletes all objects and deletes all object versions
"""
# Boto resource would make this a straightforward task, but our internal client does not support Boto resource
# FIXME: this won't work when bucket has more than 1000 objects
def factory(bucket_name: str):
response = aws_client.s3.list_objects_v2(Bucket=bucket_name)
objects = [{"Key": obj["Key"]} for obj in response["Contents"]]
aws_client.s3.delete_objects(Bucket=bucket_name, Delete={"Objects": objects})

response = aws_client.s3.list_object_versions(Bucket=bucket_name)
object_versions = [
{"Key": obj["Key"], "VersionId": obj["VersionId"]}
for obj in response.get("Versions", [])
]
if object_versions:
aws_client.s3.delete_objects(Bucket=bucket_name, Delete={"Objects": object_versions})

yield factory
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'd probably prefer this to be a normal utility over a fixture but should be ok to leave as-is for now 👍

Comment on lines -80 to +88
"x-amzn-trace-id": "Root=1-640e7ae9-63faf1aa71313dd3638b68fd"
"x-amzn-trace-id": "Root=1-64afea44-3087b2f50c440c1958c4d62e"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is actually an invalid snapshot (before and now) since it won't validate against AWS. The unique value here would need to be replaced via a transformer to make it valid.

Since this hasn't been introduced in this PR, feel free to leave as-is though.


# clean up
table.delete()
aws_client.dynamodb.delete_table(TableName=table_name)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nit: might be good while going through here anyway to do this in a safe manner (e.g. using the cleanups fixture instead)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I have a TODO note to convert the constants on top of this file into fixture which will take care of this :) I'll address these in follow up PRs

https://github.com/localstack/localstack/pull/8674/files/5701d33c5344d96114f3bdc6372c299ba8a7d1cd#diff-674a25994f44ac7d1dd2bdaff60e30cb9eb9c4b895c36d56b5c33b0a9bcfe7e7R27

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

See #8747

@viren-nadkarni viren-nadkarni merged commit 33a6200 into master Jul 26, 2023
@viren-nadkarni viren-nadkarni deleted the remove-boto-resource branch July 26, 2023 06:30
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

semver: patch Non-breaking changes which can be included in patch releases

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants