Skip to content

Commit 6927155

Browse files
committed
feat(io_storages): tag S3 user-agent for attribution
Signed-off-by: Gonzalo Peña-Castellanos <goanpeca@gmail.com>
1 parent ab271a2 commit 6927155

2 files changed

Lines changed: 45 additions & 2 deletions

File tree

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
"""Tests for the S3 client user agent.
2+
3+
Verifies get_client_and_resource attaches a label-studio user agent to both the
4+
client and resource while preserving signature_version and a custom endpoint_url
5+
(the path used for AWS S3 and S3-compatible storage such as Backblaze B2).
6+
"""
7+
8+
import unittest
9+
10+
from io_storages.s3.utils import _get_user_agent_extra, get_client_and_resource
11+
12+
13+
class TestS3ClientUserAgent(unittest.TestCase):
14+
def test_user_agent_extra_format(self):
15+
ua = _get_user_agent_extra()
16+
assert ua.startswith('label-studio/')
17+
18+
def test_client_and_resource_carry_user_agent(self):
19+
client, resource = get_client_and_resource()
20+
expected = _get_user_agent_extra()
21+
assert expected in (client.meta.config.user_agent_extra or '')
22+
assert expected in (resource.meta.client.meta.config.user_agent_extra or '')
23+
24+
def test_signature_version_preserved(self):
25+
client, _ = get_client_and_resource()
26+
assert client.meta.config.signature_version == 's3v4'
27+
28+
def test_custom_endpoint_preserved(self):
29+
endpoint = 'https://s3.us-west-004.backblazeb2.com'
30+
client, resource = get_client_and_resource(s3_endpoint=endpoint)
31+
assert client.meta.endpoint_url == endpoint
32+
assert resource.meta.client.meta.endpoint_url == endpoint
33+
assert _get_user_agent_extra() in (client.meta.config.user_agent_extra or '')

label_studio/io_storages/s3/utils.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import base64
44
import fnmatch
5+
import importlib.metadata
56
import logging
67
import mimetypes
78
import re
@@ -16,6 +17,14 @@
1617
logger = logging.getLogger(__name__)
1718

1819

20+
def _get_user_agent_extra():
21+
try:
22+
version = importlib.metadata.version('label-studio')
23+
except importlib.metadata.PackageNotFoundError:
24+
version = 'dev'
25+
return f'label-studio/{version}'
26+
27+
1928
def get_client_and_resource(
2029
aws_access_key_id=None, aws_secret_access_key=None, aws_session_token=None, region_name=None, s3_endpoint=None
2130
):
@@ -37,8 +46,9 @@ def get_client_and_resource(
3746
s3_endpoint = s3_endpoint or get_env('S3_ENDPOINT')
3847
if s3_endpoint:
3948
settings['endpoint_url'] = s3_endpoint
40-
client = session.client('s3', config=boto3.session.Config(signature_version='s3v4'), **settings)
41-
resource = session.resource('s3', config=boto3.session.Config(signature_version='s3v4'), **settings)
49+
config = boto3.session.Config(signature_version='s3v4', user_agent_extra=_get_user_agent_extra())
50+
client = session.client('s3', config=config, **settings)
51+
resource = session.resource('s3', config=config, **settings)
4252
return client, resource
4353

4454

0 commit comments

Comments
 (0)