kiarina-lib-google-cloud-storage 1.6.2__tar.gz → 1.6.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- kiarina_lib_google_cloud_storage-1.6.3/.env.sample +1 -0
- {kiarina_lib_google_cloud_storage-1.6.2 → kiarina_lib_google_cloud_storage-1.6.3}/.gitignore +1 -0
- {kiarina_lib_google_cloud_storage-1.6.2 → kiarina_lib_google_cloud_storage-1.6.3}/CHANGELOG.md +12 -1
- {kiarina_lib_google_cloud_storage-1.6.2 → kiarina_lib_google_cloud_storage-1.6.3}/PKG-INFO +26 -25
- {kiarina_lib_google_cloud_storage-1.6.2 → kiarina_lib_google_cloud_storage-1.6.3}/README.md +24 -23
- {kiarina_lib_google_cloud_storage-1.6.2 → kiarina_lib_google_cloud_storage-1.6.3}/pyproject.toml +2 -2
- {kiarina_lib_google_cloud_storage-1.6.2 → kiarina_lib_google_cloud_storage-1.6.3}/src/kiarina/lib/google/cloud_storage/_get_blob.py +16 -4
- {kiarina_lib_google_cloud_storage-1.6.2 → kiarina_lib_google_cloud_storage-1.6.3}/src/kiarina/lib/google/cloud_storage/_get_bucket.py +1 -5
- {kiarina_lib_google_cloud_storage-1.6.2 → kiarina_lib_google_cloud_storage-1.6.3}/src/kiarina/lib/google/cloud_storage/settings.py +3 -3
- kiarina_lib_google_cloud_storage-1.6.3/test_settings.sample.yaml +15 -0
- kiarina_lib_google_cloud_storage-1.6.3/tests/conftest.py +33 -0
- kiarina_lib_google_cloud_storage-1.6.3/tests/test_get_blob.py +82 -0
- kiarina_lib_google_cloud_storage-1.6.3/tests/test_get_bucket.py +18 -0
- kiarina_lib_google_cloud_storage-1.6.3/tests/test_get_storage_client.py +20 -0
- kiarina_lib_google_cloud_storage-1.6.2/tests/conftest.py +0 -0
- kiarina_lib_google_cloud_storage-1.6.2/tests/test_get_blob.py +0 -224
- kiarina_lib_google_cloud_storage-1.6.2/tests/test_get_bucket.py +0 -91
- kiarina_lib_google_cloud_storage-1.6.2/tests/test_get_storage_client.py +0 -57
- {kiarina_lib_google_cloud_storage-1.6.2 → kiarina_lib_google_cloud_storage-1.6.3}/.vscode/settings.json +0 -0
- {kiarina_lib_google_cloud_storage-1.6.2 → kiarina_lib_google_cloud_storage-1.6.3}/src/kiarina/lib/google/cloud_storage/__init__.py +0 -0
- {kiarina_lib_google_cloud_storage-1.6.2 → kiarina_lib_google_cloud_storage-1.6.3}/src/kiarina/lib/google/cloud_storage/_get_storage_client.py +0 -0
- {kiarina_lib_google_cloud_storage-1.6.2 → kiarina_lib_google_cloud_storage-1.6.3}/src/kiarina/lib/google/cloud_storage/py.typed +0 -0
- {kiarina_lib_google_cloud_storage-1.6.2 → kiarina_lib_google_cloud_storage-1.6.3}/tests/__init__.py +0 -0
@@ -0,0 +1 @@
|
|
1
|
+
KIARINA_LIB_GOOGLE_CLOUD_STORAGE_TEST_SETTINGS_FILE=packages/kiarina-lib-google-cloud-storage/test_settings.yaml
|
{kiarina_lib_google_cloud_storage-1.6.2 → kiarina_lib_google_cloud_storage-1.6.3}/CHANGELOG.md
RENAMED
@@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
7
7
|
|
8
8
|
## [Unreleased]
|
9
9
|
|
10
|
+
## [1.6.3] - 2025-10-13
|
11
|
+
|
12
|
+
### Changed
|
13
|
+
- Converted tests from mock-based to real integration tests with multi-tenancy patterns
|
14
|
+
- Simplified test settings loading using `load_user_configs` from pydantic-settings-manager
|
15
|
+
- Updated `pydantic-settings-manager` dependency from `>=2.1.0` to `>=2.3.0`
|
16
|
+
- Refactored to use `settings_manager.get_settings` instead of deprecated `get_settings_by_key`
|
17
|
+
|
18
|
+
### Added
|
19
|
+
- Added `.env.sample` and `test_settings.sample.yaml` for easier test setup
|
20
|
+
|
10
21
|
## [1.6.2] - 2025-10-10
|
11
22
|
|
12
23
|
### Changed
|
@@ -14,7 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
14
25
|
- `blob_name_pattern` supports both fixed names and template patterns with placeholders
|
15
26
|
- `get_blob()` now accepts `placeholders` parameter for pattern formatting
|
16
27
|
- `blob_name` parameter in `get_blob()` now always represents the full blob path
|
17
|
-
- Pattern examples: `"data.json"` (fixed), `"files/{basename}"` (single placeholder), `"
|
28
|
+
- Pattern examples: `"data.json"` (fixed), `"files/{basename}"` (single placeholder), `"my-service/{tenant_id}/users/{user_id}/files/{basename}"` (multiple placeholders)
|
18
29
|
- Priority: explicit `blob_name` → `blob_name_pattern` with `placeholders` → `blob_name_pattern` without placeholders
|
19
30
|
- Enhanced error messages for missing placeholders
|
20
31
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: kiarina-lib-google-cloud-storage
|
3
|
-
Version: 1.6.
|
3
|
+
Version: 1.6.3
|
4
4
|
Summary: Google Cloud Storage client library for kiarina namespace
|
5
5
|
Project-URL: Homepage, https://github.com/kiarina/kiarina-python
|
6
6
|
Project-URL: Repository, https://github.com/kiarina/kiarina-python
|
@@ -22,7 +22,7 @@ Classifier: Typing :: Typed
|
|
22
22
|
Requires-Python: >=3.12
|
23
23
|
Requires-Dist: google-cloud-storage>=2.19.0
|
24
24
|
Requires-Dist: kiarina-lib-google-auth>=1.4.0
|
25
|
-
Requires-Dist: pydantic-settings-manager>=2.
|
25
|
+
Requires-Dist: pydantic-settings-manager>=2.3.0
|
26
26
|
Requires-Dist: pydantic-settings>=2.10.1
|
27
27
|
Description-Content-Type: text/markdown
|
28
28
|
|
@@ -115,18 +115,18 @@ New requirement: Add agent-level isolation for multi-tenancy.
|
|
115
115
|
|
116
116
|
**Updated Security Rules:**
|
117
117
|
```javascript
|
118
|
-
match /
|
119
|
-
allow read, write: if request.auth.uid == user_id
|
120
|
-
&& request.auth.token.
|
118
|
+
match /my-service/{tenant_id}/users/{user_id}/files/{basename} {
|
119
|
+
allow read, write: if request.auth.uid == user_id
|
120
|
+
&& request.auth.token.tenant_id == tenant_id;
|
121
121
|
}
|
122
122
|
```
|
123
123
|
|
124
124
|
**Problem**: You must now update **every place** in your application code that constructs these paths:
|
125
125
|
```python
|
126
126
|
# Must change all of these
|
127
|
-
blob_name = f"
|
128
|
-
blob_name = f"
|
129
|
-
blob_name = f"
|
127
|
+
blob_name = f"my-service/{tenant_id}/users/{user_id}/files/{file_name}" # Changed!
|
128
|
+
blob_name = f"my-service/{tenant_id}/users/{user_id}/thumbnails/{file_name}" # Changed!
|
129
|
+
blob_name = f"my-service/{tenant_id}/users/{user_id}/exports/{file_name}" # Changed!
|
130
130
|
# ... and many more
|
131
131
|
```
|
132
132
|
|
@@ -138,14 +138,14 @@ blob_name = f"web/{user_id}/{agent_id}/exports/{file_name}" # Changed!
|
|
138
138
|
google_cloud_storage:
|
139
139
|
default:
|
140
140
|
bucket_name: "my-app-data"
|
141
|
-
blob_name_pattern: "
|
141
|
+
blob_name_pattern: "my-service/{tenant_id}/users/{user_id}/files/{basename}"
|
142
142
|
```
|
143
143
|
|
144
144
|
**GCS Security Rules (Infrastructure Concern):**
|
145
145
|
```javascript
|
146
|
-
match /
|
147
|
-
allow read, write: if request.auth.uid == user_id
|
148
|
-
&& request.auth.token.
|
146
|
+
match /my-service/{tenant_id}/users/{user_id}/files/{basename} {
|
147
|
+
allow read, write: if request.auth.uid == user_id
|
148
|
+
&& request.auth.token.tenant_id == tenant_id;
|
149
149
|
}
|
150
150
|
```
|
151
151
|
|
@@ -368,14 +368,14 @@ def save_document(tenant_id: str, doc_id: str, content: bytes):
|
|
368
368
|
def list_documents(tenant_id: str) -> list[str]:
|
369
369
|
"""List documents for any tenant"""
|
370
370
|
from kiarina.lib.google.cloud_storage import get_bucket
|
371
|
-
|
371
|
+
|
372
372
|
config_key = f"tenant_{tenant_id}"
|
373
373
|
bucket = get_bucket(config_key=config_key, auth_config_key=config_key)
|
374
|
-
|
374
|
+
|
375
375
|
# Get prefix from settings
|
376
|
-
settings = settings_manager.
|
376
|
+
settings = settings_manager.get_settings(config_key)
|
377
377
|
prefix = f"{settings.blob_name_prefix}/documents/" if settings.blob_name_prefix else "documents/"
|
378
|
-
|
378
|
+
|
379
379
|
blobs = bucket.list_blobs(prefix=prefix)
|
380
380
|
return [blob.name for blob in blobs]
|
381
381
|
```
|
@@ -409,10 +409,10 @@ def mock_storage_config():
|
|
409
409
|
def test_save_user_profile(mock_storage_config):
|
410
410
|
"""Test user profile saving"""
|
411
411
|
from myapp.services import save_user_profile
|
412
|
-
|
412
|
+
|
413
413
|
# Application code uses test configuration automatically
|
414
414
|
save_user_profile("user123", {"name": "Alice"})
|
415
|
-
|
415
|
+
|
416
416
|
# Verify using the same configuration
|
417
417
|
from kiarina.lib.google.cloud_storage import get_blob
|
418
418
|
blob = get_blob(blob_name="users/user123/profile.json")
|
@@ -428,20 +428,20 @@ from kiarina.lib.google.cloud_storage import settings_manager
|
|
428
428
|
|
429
429
|
def debug_storage_config(config_key: str | None = None):
|
430
430
|
"""Show actual storage paths for debugging"""
|
431
|
-
settings = settings_manager.
|
432
|
-
|
431
|
+
settings = settings_manager.get_settings(config_key)
|
432
|
+
|
433
433
|
print(f"Configuration: {config_key or 'default'}")
|
434
434
|
print(f" Bucket: {settings.bucket_name}")
|
435
435
|
print(f" Prefix: {settings.blob_name_prefix or '(none)'}")
|
436
436
|
print(f" Auth: {settings.google_auth_config_key}")
|
437
|
-
|
437
|
+
|
438
438
|
# Example paths
|
439
439
|
example_blob = "users/123/profile.json"
|
440
440
|
if settings.blob_name_prefix:
|
441
441
|
full_path = f"{settings.blob_name_prefix}/{example_blob}"
|
442
442
|
else:
|
443
443
|
full_path = example_blob
|
444
|
-
|
444
|
+
|
445
445
|
print(f" Example: gs://{settings.bucket_name}/{full_path}")
|
446
446
|
|
447
447
|
# Usage
|
@@ -665,13 +665,14 @@ blob = get_blob()
|
|
665
665
|
# Actual: gs://bucket/data/fixed.json
|
666
666
|
|
667
667
|
# Complex pattern
|
668
|
-
# If blob_name_pattern="
|
668
|
+
# If blob_name_pattern="my-service/{tenant_id}/users/{user_id}/files/{basename}"
|
669
669
|
blob = get_blob(placeholders={
|
670
|
+
"tenant_id": "tenant123",
|
670
671
|
"user_id": "user123",
|
671
672
|
"agent_id": "agent456",
|
672
673
|
"basename": "document.pdf"
|
673
674
|
})
|
674
|
-
# Actual: gs://bucket/
|
675
|
+
# Actual: gs://bucket/my-service/tenant123/users/user123/files/document.pdf
|
675
676
|
|
676
677
|
# With custom configurations
|
677
678
|
blob = get_blob(
|
@@ -700,7 +701,7 @@ settings_manager: SettingsManager[GoogleCloudStorageSettings]
|
|
700
701
|
- `active_key`: Get/set active configuration key
|
701
702
|
|
702
703
|
**Methods:**
|
703
|
-
- `
|
704
|
+
- `get_settings(key: str)`: Get settings by specific key
|
704
705
|
- `clear()`: Clear cached settings
|
705
706
|
|
706
707
|
## Common Operations
|
@@ -87,18 +87,18 @@ New requirement: Add agent-level isolation for multi-tenancy.
|
|
87
87
|
|
88
88
|
**Updated Security Rules:**
|
89
89
|
```javascript
|
90
|
-
match /
|
91
|
-
allow read, write: if request.auth.uid == user_id
|
92
|
-
&& request.auth.token.
|
90
|
+
match /my-service/{tenant_id}/users/{user_id}/files/{basename} {
|
91
|
+
allow read, write: if request.auth.uid == user_id
|
92
|
+
&& request.auth.token.tenant_id == tenant_id;
|
93
93
|
}
|
94
94
|
```
|
95
95
|
|
96
96
|
**Problem**: You must now update **every place** in your application code that constructs these paths:
|
97
97
|
```python
|
98
98
|
# Must change all of these
|
99
|
-
blob_name = f"
|
100
|
-
blob_name = f"
|
101
|
-
blob_name = f"
|
99
|
+
blob_name = f"my-service/{tenant_id}/users/{user_id}/files/{file_name}" # Changed!
|
100
|
+
blob_name = f"my-service/{tenant_id}/users/{user_id}/thumbnails/{file_name}" # Changed!
|
101
|
+
blob_name = f"my-service/{tenant_id}/users/{user_id}/exports/{file_name}" # Changed!
|
102
102
|
# ... and many more
|
103
103
|
```
|
104
104
|
|
@@ -110,14 +110,14 @@ blob_name = f"web/{user_id}/{agent_id}/exports/{file_name}" # Changed!
|
|
110
110
|
google_cloud_storage:
|
111
111
|
default:
|
112
112
|
bucket_name: "my-app-data"
|
113
|
-
blob_name_pattern: "
|
113
|
+
blob_name_pattern: "my-service/{tenant_id}/users/{user_id}/files/{basename}"
|
114
114
|
```
|
115
115
|
|
116
116
|
**GCS Security Rules (Infrastructure Concern):**
|
117
117
|
```javascript
|
118
|
-
match /
|
119
|
-
allow read, write: if request.auth.uid == user_id
|
120
|
-
&& request.auth.token.
|
118
|
+
match /my-service/{tenant_id}/users/{user_id}/files/{basename} {
|
119
|
+
allow read, write: if request.auth.uid == user_id
|
120
|
+
&& request.auth.token.tenant_id == tenant_id;
|
121
121
|
}
|
122
122
|
```
|
123
123
|
|
@@ -340,14 +340,14 @@ def save_document(tenant_id: str, doc_id: str, content: bytes):
|
|
340
340
|
def list_documents(tenant_id: str) -> list[str]:
|
341
341
|
"""List documents for any tenant"""
|
342
342
|
from kiarina.lib.google.cloud_storage import get_bucket
|
343
|
-
|
343
|
+
|
344
344
|
config_key = f"tenant_{tenant_id}"
|
345
345
|
bucket = get_bucket(config_key=config_key, auth_config_key=config_key)
|
346
|
-
|
346
|
+
|
347
347
|
# Get prefix from settings
|
348
|
-
settings = settings_manager.
|
348
|
+
settings = settings_manager.get_settings(config_key)
|
349
349
|
prefix = f"{settings.blob_name_prefix}/documents/" if settings.blob_name_prefix else "documents/"
|
350
|
-
|
350
|
+
|
351
351
|
blobs = bucket.list_blobs(prefix=prefix)
|
352
352
|
return [blob.name for blob in blobs]
|
353
353
|
```
|
@@ -381,10 +381,10 @@ def mock_storage_config():
|
|
381
381
|
def test_save_user_profile(mock_storage_config):
|
382
382
|
"""Test user profile saving"""
|
383
383
|
from myapp.services import save_user_profile
|
384
|
-
|
384
|
+
|
385
385
|
# Application code uses test configuration automatically
|
386
386
|
save_user_profile("user123", {"name": "Alice"})
|
387
|
-
|
387
|
+
|
388
388
|
# Verify using the same configuration
|
389
389
|
from kiarina.lib.google.cloud_storage import get_blob
|
390
390
|
blob = get_blob(blob_name="users/user123/profile.json")
|
@@ -400,20 +400,20 @@ from kiarina.lib.google.cloud_storage import settings_manager
|
|
400
400
|
|
401
401
|
def debug_storage_config(config_key: str | None = None):
|
402
402
|
"""Show actual storage paths for debugging"""
|
403
|
-
settings = settings_manager.
|
404
|
-
|
403
|
+
settings = settings_manager.get_settings(config_key)
|
404
|
+
|
405
405
|
print(f"Configuration: {config_key or 'default'}")
|
406
406
|
print(f" Bucket: {settings.bucket_name}")
|
407
407
|
print(f" Prefix: {settings.blob_name_prefix or '(none)'}")
|
408
408
|
print(f" Auth: {settings.google_auth_config_key}")
|
409
|
-
|
409
|
+
|
410
410
|
# Example paths
|
411
411
|
example_blob = "users/123/profile.json"
|
412
412
|
if settings.blob_name_prefix:
|
413
413
|
full_path = f"{settings.blob_name_prefix}/{example_blob}"
|
414
414
|
else:
|
415
415
|
full_path = example_blob
|
416
|
-
|
416
|
+
|
417
417
|
print(f" Example: gs://{settings.bucket_name}/{full_path}")
|
418
418
|
|
419
419
|
# Usage
|
@@ -637,13 +637,14 @@ blob = get_blob()
|
|
637
637
|
# Actual: gs://bucket/data/fixed.json
|
638
638
|
|
639
639
|
# Complex pattern
|
640
|
-
# If blob_name_pattern="
|
640
|
+
# If blob_name_pattern="my-service/{tenant_id}/users/{user_id}/files/{basename}"
|
641
641
|
blob = get_blob(placeholders={
|
642
|
+
"tenant_id": "tenant123",
|
642
643
|
"user_id": "user123",
|
643
644
|
"agent_id": "agent456",
|
644
645
|
"basename": "document.pdf"
|
645
646
|
})
|
646
|
-
# Actual: gs://bucket/
|
647
|
+
# Actual: gs://bucket/my-service/tenant123/users/user123/files/document.pdf
|
647
648
|
|
648
649
|
# With custom configurations
|
649
650
|
blob = get_blob(
|
@@ -672,7 +673,7 @@ settings_manager: SettingsManager[GoogleCloudStorageSettings]
|
|
672
673
|
- `active_key`: Get/set active configuration key
|
673
674
|
|
674
675
|
**Methods:**
|
675
|
-
- `
|
676
|
+
- `get_settings(key: str)`: Get settings by specific key
|
676
677
|
- `clear()`: Clear cached settings
|
677
678
|
|
678
679
|
## Common Operations
|
{kiarina_lib_google_cloud_storage-1.6.2 → kiarina_lib_google_cloud_storage-1.6.3}/pyproject.toml
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
[project]
|
2
2
|
name = "kiarina-lib-google-cloud-storage"
|
3
|
-
version = "1.6.
|
3
|
+
version = "1.6.3"
|
4
4
|
description = "Google Cloud Storage client library for kiarina namespace"
|
5
5
|
readme = "README.md"
|
6
6
|
license = "MIT"
|
@@ -26,7 +26,7 @@ dependencies = [
|
|
26
26
|
"google-cloud-storage>=2.19.0",
|
27
27
|
"kiarina-lib-google-auth>=1.4.0",
|
28
28
|
"pydantic-settings>=2.10.1",
|
29
|
-
"pydantic-settings-manager>=2.
|
29
|
+
"pydantic-settings-manager>=2.3.0",
|
30
30
|
]
|
31
31
|
|
32
32
|
[project.urls]
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import re
|
1
2
|
from typing import Any
|
2
3
|
|
3
4
|
from google.cloud import storage # type: ignore[import-untyped]
|
@@ -38,10 +39,10 @@ def get_blob(
|
|
38
39
|
blob = get_blob(placeholders={"user_id": "123", "basename": "profile.json"})
|
39
40
|
# With pattern "users/{user_id}/{basename}" -> "users/123/profile.json"
|
40
41
|
|
41
|
-
# Using
|
42
|
-
blob = get_blob() # Uses settings.blob_name_pattern
|
42
|
+
# Using fixed pattern from settings (no placeholders)
|
43
|
+
blob = get_blob() # Uses settings.blob_name_pattern if it has no placeholders
|
43
44
|
"""
|
44
|
-
settings = settings_manager.
|
45
|
+
settings = settings_manager.get_settings(config_key)
|
45
46
|
|
46
47
|
# Priority 1: Explicit blob_name
|
47
48
|
if blob_name is not None:
|
@@ -65,7 +66,6 @@ def get_blob(
|
|
65
66
|
|
66
67
|
# Priority 3: Default pattern from settings
|
67
68
|
elif settings.blob_name_pattern is not None:
|
68
|
-
# Pattern without placeholders (fixed name)
|
69
69
|
final_blob_name = settings.blob_name_pattern
|
70
70
|
|
71
71
|
else:
|
@@ -74,5 +74,17 @@ def get_blob(
|
|
74
74
|
"and blob_name_pattern is not set in settings"
|
75
75
|
)
|
76
76
|
|
77
|
+
# Safety check: Ensure no unresolved placeholders remain
|
78
|
+
if _has_placeholders(final_blob_name):
|
79
|
+
raise ValueError(
|
80
|
+
f"Unresolved placeholders found in blob name: {final_blob_name}. "
|
81
|
+
f"Please provide placeholders argument to resolve them."
|
82
|
+
)
|
83
|
+
|
77
84
|
bucket = get_bucket(config_key, auth_config_key=auth_config_key, **kwargs)
|
78
85
|
return bucket.blob(final_blob_name)
|
86
|
+
|
87
|
+
|
88
|
+
def _has_placeholders(pattern: str) -> bool:
|
89
|
+
"""Check if a pattern contains placeholders like {key}."""
|
90
|
+
return bool(re.search(r"\{[^}]+\}", pattern))
|
@@ -12,10 +12,6 @@ def get_bucket(
|
|
12
12
|
auth_config_key: str | None = None,
|
13
13
|
**kwargs: Any,
|
14
14
|
) -> storage.Bucket:
|
15
|
-
settings = settings_manager.
|
16
|
-
|
17
|
-
if settings.bucket_name is None:
|
18
|
-
raise ValueError("bucket_name is not set in the settings")
|
19
|
-
|
15
|
+
settings = settings_manager.get_settings(config_key)
|
20
16
|
client = get_storage_client(auth_config_key, **kwargs)
|
21
17
|
return client.bucket(settings.bucket_name)
|
@@ -3,16 +3,16 @@ from pydantic_settings_manager import SettingsManager
|
|
3
3
|
|
4
4
|
|
5
5
|
class GoogleCloudStorageSettings(BaseSettings):
|
6
|
-
bucket_name: str
|
6
|
+
bucket_name: str
|
7
7
|
|
8
8
|
blob_name_pattern: str | None = None
|
9
9
|
"""
|
10
10
|
Blob name pattern with placeholders.
|
11
|
-
|
11
|
+
|
12
12
|
Examples:
|
13
13
|
- "data.json" (fixed name)
|
14
14
|
- "files/{basename}" (single placeholder)
|
15
|
-
- "
|
15
|
+
- "my-service/{tenant_id}/users/{user_id}/files/{basename}" (multiple placeholders)
|
16
16
|
"""
|
17
17
|
|
18
18
|
|
@@ -0,0 +1,15 @@
|
|
1
|
+
kiarina.lib.google.auth:
|
2
|
+
service_account:
|
3
|
+
type: service_account
|
4
|
+
project_id: your-project-id
|
5
|
+
service_account_email: your-service-account@your-project.iam.gserviceaccount.com
|
6
|
+
service_account_file: ~/.gcp/service-account/your-project/your-service-account/key.json
|
7
|
+
kiarina.lib.google.cloud_storage:
|
8
|
+
default:
|
9
|
+
bucket_name: your-bucket-name
|
10
|
+
blob_name_pattern: "my-service/{tenant_id}/users/{user_id}/files/{basename}"
|
11
|
+
no_blob_name_pattern:
|
12
|
+
bucket_name: your-bucket-name
|
13
|
+
fixed:
|
14
|
+
bucket_name: your-bucket-name
|
15
|
+
blob_name_pattern: "my-service/kiarina-lib-google-cloud-storage/users/test_get_blob_with_fixed_pattern/files/miineko.png"
|
@@ -0,0 +1,33 @@
|
|
1
|
+
import os
|
2
|
+
from pathlib import Path
|
3
|
+
|
4
|
+
import pytest
|
5
|
+
from pydantic_settings_manager import load_user_configs
|
6
|
+
|
7
|
+
import kiarina.utils.file as kf
|
8
|
+
|
9
|
+
|
10
|
+
@pytest.fixture
|
11
|
+
def data_dir() -> Path:
|
12
|
+
return Path(__file__).parent.parent.parent.parent / "tests" / "data"
|
13
|
+
|
14
|
+
|
15
|
+
@pytest.fixture(scope="session")
|
16
|
+
def load_settings():
|
17
|
+
env_var = "KIARINA_LIB_GOOGLE_CLOUD_STORAGE_TEST_SETTINGS_FILE"
|
18
|
+
|
19
|
+
if env_var not in os.environ:
|
20
|
+
pytest.skip(f"Environment variable {env_var} not set, skipping tests.")
|
21
|
+
|
22
|
+
test_settings_file = os.environ[env_var]
|
23
|
+
test_settings_file = os.path.expanduser(test_settings_file)
|
24
|
+
|
25
|
+
if not os.path.exists(test_settings_file):
|
26
|
+
raise FileNotFoundError(f"Settings file not found: {test_settings_file}")
|
27
|
+
|
28
|
+
user_configs = kf.read_yaml_dict(test_settings_file)
|
29
|
+
|
30
|
+
if not user_configs:
|
31
|
+
raise ValueError(f"Settings file is empty or invalid: {test_settings_file}")
|
32
|
+
|
33
|
+
load_user_configs(user_configs)
|
@@ -0,0 +1,82 @@
|
|
1
|
+
import pytest
|
2
|
+
|
3
|
+
from kiarina.lib.google.cloud_storage import get_blob, settings_manager
|
4
|
+
|
5
|
+
|
6
|
+
def test_get_blob_with_blob_name(data_dir, load_settings, request):
|
7
|
+
settings = settings_manager.settings
|
8
|
+
|
9
|
+
assert settings.blob_name_pattern is not None
|
10
|
+
|
11
|
+
blob_name = settings.blob_name_pattern.format(
|
12
|
+
tenant_id="kiarina-lib-google-cloud-storage",
|
13
|
+
user_id=request.node.name,
|
14
|
+
basename="miineko.png",
|
15
|
+
)
|
16
|
+
|
17
|
+
blob = get_blob(blob_name)
|
18
|
+
|
19
|
+
if not blob.exists():
|
20
|
+
blob.upload_from_filename(data_dir / "small" / "miineko_256x256_799b.png")
|
21
|
+
|
22
|
+
|
23
|
+
def test_get_blob_with_placeholders(data_dir, load_settings, request):
|
24
|
+
blob = get_blob(
|
25
|
+
placeholders={
|
26
|
+
"tenant_id": "kiarina-lib-google-cloud-storage",
|
27
|
+
"user_id": request.node.name,
|
28
|
+
"basename": "miineko.png",
|
29
|
+
}
|
30
|
+
)
|
31
|
+
|
32
|
+
if not blob.exists():
|
33
|
+
blob.upload_from_filename(data_dir / "small" / "miineko_256x256_799b.png")
|
34
|
+
|
35
|
+
|
36
|
+
def test_get_blob_with_placeholders_but_no_pattern(data_dir, load_settings, request):
|
37
|
+
with pytest.raises(
|
38
|
+
ValueError,
|
39
|
+
match="placeholders provided but blob_name_pattern is not set in settings",
|
40
|
+
):
|
41
|
+
get_blob(
|
42
|
+
placeholders={
|
43
|
+
"user_id": request.node.name,
|
44
|
+
"basename": "miineko.png",
|
45
|
+
},
|
46
|
+
config_key="no_blob_name_pattern",
|
47
|
+
)
|
48
|
+
|
49
|
+
|
50
|
+
def test_get_blob_with_not_enough_placeholders(data_dir, load_settings, request):
|
51
|
+
with pytest.raises(
|
52
|
+
ValueError, match="Missing placeholder 'basename' in blob_name_pattern"
|
53
|
+
):
|
54
|
+
get_blob(
|
55
|
+
placeholders={
|
56
|
+
"tenant_id": "kiarina-lib-google-cloud-storage",
|
57
|
+
"user_id": request.node.name,
|
58
|
+
}
|
59
|
+
)
|
60
|
+
|
61
|
+
|
62
|
+
def test_get_blob_with_fixed_pattern(data_dir, load_settings, request):
|
63
|
+
blob = get_blob(config_key="fixed")
|
64
|
+
|
65
|
+
if not blob.exists():
|
66
|
+
blob.upload_from_filename(data_dir / "small" / "miineko_256x256_799b.png")
|
67
|
+
|
68
|
+
|
69
|
+
def test_not_enough_placeholders(data_dir, load_settings, request):
|
70
|
+
with pytest.raises(
|
71
|
+
ValueError,
|
72
|
+
match="Unresolved placeholders found in blob name",
|
73
|
+
):
|
74
|
+
get_blob()
|
75
|
+
|
76
|
+
|
77
|
+
def test_no_blob_name_provided(data_dir, load_settings, request):
|
78
|
+
with pytest.raises(
|
79
|
+
ValueError,
|
80
|
+
match="blob_name is not provided, placeholders are not provided, and blob_name_pattern is not set in settings",
|
81
|
+
):
|
82
|
+
get_blob(config_key="no_blob_name_pattern")
|
@@ -0,0 +1,18 @@
|
|
1
|
+
from kiarina.lib.google.cloud_storage import get_bucket, settings_manager
|
2
|
+
|
3
|
+
|
4
|
+
def test_get_bucket(data_dir, load_settings, request):
|
5
|
+
settings = settings_manager.settings
|
6
|
+
assert settings.blob_name_pattern is not None
|
7
|
+
|
8
|
+
blob_name = settings.blob_name_pattern.format(
|
9
|
+
tenant_id="kiarina-lib-google-cloud-storage",
|
10
|
+
user_id=request.node.name,
|
11
|
+
basename="miineko.png",
|
12
|
+
)
|
13
|
+
|
14
|
+
bucket = get_bucket()
|
15
|
+
blob = bucket.blob(blob_name)
|
16
|
+
|
17
|
+
if not blob.exists():
|
18
|
+
blob.upload_from_filename(data_dir / "small" / "miineko_256x256_799b.png")
|
@@ -0,0 +1,20 @@
|
|
1
|
+
from kiarina.lib.google.cloud_storage import settings_manager, get_storage_client
|
2
|
+
|
3
|
+
|
4
|
+
def test_get_storage_client(data_dir, load_settings, request):
|
5
|
+
settings = settings_manager.settings
|
6
|
+
assert settings.blob_name_pattern is not None
|
7
|
+
|
8
|
+
bucket_name = settings.bucket_name
|
9
|
+
blob_name = settings.blob_name_pattern.format(
|
10
|
+
tenant_id="kiarina-lib-google-cloud-storage",
|
11
|
+
user_id=request.node.name,
|
12
|
+
basename="miineko.png",
|
13
|
+
)
|
14
|
+
|
15
|
+
client = get_storage_client()
|
16
|
+
bucket = client.bucket(bucket_name)
|
17
|
+
blob = bucket.blob(blob_name)
|
18
|
+
|
19
|
+
if not blob.exists():
|
20
|
+
blob.upload_from_filename(data_dir / "small" / "miineko_256x256_799b.png")
|
File without changes
|
@@ -1,224 +0,0 @@
|
|
1
|
-
from unittest.mock import MagicMock, patch
|
2
|
-
|
3
|
-
import pytest
|
4
|
-
|
5
|
-
from kiarina.lib.google.cloud_storage import get_blob, settings_manager
|
6
|
-
|
7
|
-
|
8
|
-
def test_get_blob_with_blob_name():
|
9
|
-
"""Test get_blob with explicit blob_name parameter."""
|
10
|
-
settings_manager.user_config = {
|
11
|
-
"default": {
|
12
|
-
"bucket_name": "test-bucket",
|
13
|
-
}
|
14
|
-
}
|
15
|
-
|
16
|
-
mock_bucket = MagicMock()
|
17
|
-
mock_blob = MagicMock()
|
18
|
-
mock_blob.name = "data/file.json"
|
19
|
-
mock_bucket.blob.return_value = mock_blob
|
20
|
-
|
21
|
-
with patch(
|
22
|
-
"kiarina.lib.google.cloud_storage._get_blob.get_bucket",
|
23
|
-
return_value=mock_bucket,
|
24
|
-
):
|
25
|
-
blob = get_blob(blob_name="data/file.json")
|
26
|
-
assert blob.name == "data/file.json"
|
27
|
-
mock_bucket.blob.assert_called_once_with("data/file.json")
|
28
|
-
|
29
|
-
|
30
|
-
def test_get_blob_with_pattern_and_placeholders():
|
31
|
-
"""Test get_blob with blob_name_pattern and placeholders."""
|
32
|
-
settings_manager.user_config = {
|
33
|
-
"default": {
|
34
|
-
"bucket_name": "test-bucket",
|
35
|
-
"blob_name_pattern": "users/{user_id}/files/{basename}",
|
36
|
-
}
|
37
|
-
}
|
38
|
-
|
39
|
-
mock_bucket = MagicMock()
|
40
|
-
mock_blob = MagicMock()
|
41
|
-
mock_blob.name = "users/123/files/profile.json"
|
42
|
-
mock_bucket.blob.return_value = mock_blob
|
43
|
-
|
44
|
-
with patch(
|
45
|
-
"kiarina.lib.google.cloud_storage._get_blob.get_bucket",
|
46
|
-
return_value=mock_bucket,
|
47
|
-
):
|
48
|
-
blob = get_blob(placeholders={"user_id": "123", "basename": "profile.json"})
|
49
|
-
assert blob.name == "users/123/files/profile.json"
|
50
|
-
mock_bucket.blob.assert_called_once_with("users/123/files/profile.json")
|
51
|
-
|
52
|
-
|
53
|
-
def test_get_blob_with_fixed_pattern():
|
54
|
-
"""Test get_blob with fixed blob_name_pattern (no placeholders)."""
|
55
|
-
settings_manager.user_config = {
|
56
|
-
"default": {
|
57
|
-
"bucket_name": "test-bucket",
|
58
|
-
"blob_name_pattern": "data/fixed.json",
|
59
|
-
}
|
60
|
-
}
|
61
|
-
|
62
|
-
mock_bucket = MagicMock()
|
63
|
-
mock_blob = MagicMock()
|
64
|
-
mock_blob.name = "data/fixed.json"
|
65
|
-
mock_bucket.blob.return_value = mock_blob
|
66
|
-
|
67
|
-
with patch(
|
68
|
-
"kiarina.lib.google.cloud_storage._get_blob.get_bucket",
|
69
|
-
return_value=mock_bucket,
|
70
|
-
):
|
71
|
-
blob = get_blob()
|
72
|
-
assert blob.name == "data/fixed.json"
|
73
|
-
mock_bucket.blob.assert_called_once_with("data/fixed.json")
|
74
|
-
|
75
|
-
|
76
|
-
def test_get_blob_priority_blob_name_over_placeholders():
|
77
|
-
"""Test that blob_name takes precedence over placeholders."""
|
78
|
-
settings_manager.user_config = {
|
79
|
-
"default": {
|
80
|
-
"bucket_name": "test-bucket",
|
81
|
-
"blob_name_pattern": "users/{user_id}/files/{basename}",
|
82
|
-
}
|
83
|
-
}
|
84
|
-
|
85
|
-
mock_bucket = MagicMock()
|
86
|
-
mock_blob = MagicMock()
|
87
|
-
mock_blob.name = "direct/path.json"
|
88
|
-
mock_bucket.blob.return_value = mock_blob
|
89
|
-
|
90
|
-
with patch(
|
91
|
-
"kiarina.lib.google.cloud_storage._get_blob.get_bucket",
|
92
|
-
return_value=mock_bucket,
|
93
|
-
):
|
94
|
-
blob = get_blob(
|
95
|
-
blob_name="direct/path.json",
|
96
|
-
placeholders={"user_id": "123", "basename": "ignored.json"},
|
97
|
-
)
|
98
|
-
assert blob.name == "direct/path.json"
|
99
|
-
mock_bucket.blob.assert_called_once_with("direct/path.json")
|
100
|
-
|
101
|
-
|
102
|
-
def test_get_blob_with_missing_placeholder():
|
103
|
-
"""Test error when placeholder is missing."""
|
104
|
-
settings_manager.user_config = {
|
105
|
-
"default": {
|
106
|
-
"bucket_name": "test-bucket",
|
107
|
-
"blob_name_pattern": "users/{user_id}/files/{basename}",
|
108
|
-
}
|
109
|
-
}
|
110
|
-
|
111
|
-
with pytest.raises(
|
112
|
-
ValueError,
|
113
|
-
match=r"Missing placeholder 'basename' in blob_name_pattern: "
|
114
|
-
r"users/\{user_id\}/files/\{basename\}",
|
115
|
-
):
|
116
|
-
get_blob(placeholders={"user_id": "123"})
|
117
|
-
|
118
|
-
|
119
|
-
def test_get_blob_without_blob_name_and_pattern():
|
120
|
-
"""Test error when neither blob_name nor blob_name_pattern is provided."""
|
121
|
-
settings_manager.user_config = {
|
122
|
-
"default": {
|
123
|
-
"bucket_name": "test-bucket",
|
124
|
-
}
|
125
|
-
}
|
126
|
-
|
127
|
-
with pytest.raises(
|
128
|
-
ValueError,
|
129
|
-
match="blob_name is not provided, placeholders are not provided, "
|
130
|
-
"and blob_name_pattern is not set in settings",
|
131
|
-
):
|
132
|
-
get_blob()
|
133
|
-
|
134
|
-
|
135
|
-
def test_get_blob_with_placeholders_but_no_pattern():
|
136
|
-
"""Test error when placeholders are provided but pattern is not set."""
|
137
|
-
settings_manager.user_config = {
|
138
|
-
"default": {
|
139
|
-
"bucket_name": "test-bucket",
|
140
|
-
}
|
141
|
-
}
|
142
|
-
|
143
|
-
with pytest.raises(
|
144
|
-
ValueError,
|
145
|
-
match="placeholders provided but blob_name_pattern is not set in settings",
|
146
|
-
):
|
147
|
-
get_blob(placeholders={"user_id": "123"})
|
148
|
-
|
149
|
-
|
150
|
-
def test_get_blob_with_custom_config_key():
|
151
|
-
"""Test get_blob with custom config_key."""
|
152
|
-
settings_manager.user_config = {
|
153
|
-
"custom": {
|
154
|
-
"bucket_name": "custom-bucket",
|
155
|
-
"blob_name_pattern": "custom/path.json",
|
156
|
-
}
|
157
|
-
}
|
158
|
-
|
159
|
-
mock_bucket = MagicMock()
|
160
|
-
mock_blob = MagicMock()
|
161
|
-
mock_blob.name = "custom/path.json"
|
162
|
-
mock_bucket.blob.return_value = mock_blob
|
163
|
-
|
164
|
-
with patch(
|
165
|
-
"kiarina.lib.google.cloud_storage._get_blob.get_bucket",
|
166
|
-
return_value=mock_bucket,
|
167
|
-
) as mock_get_bucket:
|
168
|
-
blob = get_blob(config_key="custom")
|
169
|
-
assert blob.name == "custom/path.json"
|
170
|
-
mock_get_bucket.assert_called_once_with("custom", auth_config_key=None)
|
171
|
-
|
172
|
-
|
173
|
-
def test_get_blob_with_auth_config_key():
|
174
|
-
"""Test get_blob with custom auth_config_key."""
|
175
|
-
settings_manager.user_config = {
|
176
|
-
"default": {
|
177
|
-
"bucket_name": "test-bucket",
|
178
|
-
"blob_name_pattern": "data.json",
|
179
|
-
}
|
180
|
-
}
|
181
|
-
|
182
|
-
mock_bucket = MagicMock()
|
183
|
-
mock_blob = MagicMock()
|
184
|
-
mock_blob.name = "data.json"
|
185
|
-
mock_bucket.blob.return_value = mock_blob
|
186
|
-
|
187
|
-
with patch(
|
188
|
-
"kiarina.lib.google.cloud_storage._get_blob.get_bucket",
|
189
|
-
return_value=mock_bucket,
|
190
|
-
) as mock_get_bucket:
|
191
|
-
blob = get_blob(auth_config_key="custom_auth")
|
192
|
-
assert blob.name == "data.json"
|
193
|
-
mock_get_bucket.assert_called_once_with(None, auth_config_key="custom_auth")
|
194
|
-
|
195
|
-
|
196
|
-
def test_get_blob_with_complex_pattern():
|
197
|
-
"""Test get_blob with complex multi-level pattern."""
|
198
|
-
settings_manager.user_config = {
|
199
|
-
"default": {
|
200
|
-
"bucket_name": "test-bucket",
|
201
|
-
"blob_name_pattern": "web/{user_id}/{agent_id}/files/{basename}",
|
202
|
-
}
|
203
|
-
}
|
204
|
-
|
205
|
-
mock_bucket = MagicMock()
|
206
|
-
mock_blob = MagicMock()
|
207
|
-
mock_blob.name = "web/user123/agent456/files/document.pdf"
|
208
|
-
mock_bucket.blob.return_value = mock_blob
|
209
|
-
|
210
|
-
with patch(
|
211
|
-
"kiarina.lib.google.cloud_storage._get_blob.get_bucket",
|
212
|
-
return_value=mock_bucket,
|
213
|
-
):
|
214
|
-
blob = get_blob(
|
215
|
-
placeholders={
|
216
|
-
"user_id": "user123",
|
217
|
-
"agent_id": "agent456",
|
218
|
-
"basename": "document.pdf",
|
219
|
-
}
|
220
|
-
)
|
221
|
-
assert blob.name == "web/user123/agent456/files/document.pdf"
|
222
|
-
mock_bucket.blob.assert_called_once_with(
|
223
|
-
"web/user123/agent456/files/document.pdf"
|
224
|
-
)
|
@@ -1,91 +0,0 @@
|
|
1
|
-
from unittest.mock import MagicMock, patch
|
2
|
-
|
3
|
-
import pytest
|
4
|
-
|
5
|
-
from kiarina.lib.google.cloud_storage import get_bucket, settings_manager
|
6
|
-
|
7
|
-
|
8
|
-
def test_get_bucket():
|
9
|
-
# Setup settings
|
10
|
-
settings_manager.user_config = {
|
11
|
-
"default": {
|
12
|
-
"bucket_name": "test-bucket",
|
13
|
-
}
|
14
|
-
}
|
15
|
-
|
16
|
-
# Mock get_storage_client and bucket
|
17
|
-
mock_client = MagicMock()
|
18
|
-
mock_bucket = MagicMock()
|
19
|
-
mock_bucket.name = "test-bucket"
|
20
|
-
mock_client.bucket.return_value = mock_bucket
|
21
|
-
|
22
|
-
with patch(
|
23
|
-
"kiarina.lib.google.cloud_storage._get_bucket.get_storage_client",
|
24
|
-
return_value=mock_client,
|
25
|
-
) as mock_get_client:
|
26
|
-
bucket = get_bucket()
|
27
|
-
assert bucket.name == "test-bucket"
|
28
|
-
|
29
|
-
# Verify get_storage_client was called with None (default)
|
30
|
-
mock_get_client.assert_called_once_with(None)
|
31
|
-
|
32
|
-
# Verify bucket was called with correct bucket name
|
33
|
-
mock_client.bucket.assert_called_once_with("test-bucket")
|
34
|
-
|
35
|
-
|
36
|
-
def test_get_bucket_without_bucket_name():
|
37
|
-
# Setup settings without bucket_name
|
38
|
-
settings_manager.user_config = {"default": {}}
|
39
|
-
|
40
|
-
with pytest.raises(ValueError, match="bucket_name is not set in the settings"):
|
41
|
-
get_bucket()
|
42
|
-
|
43
|
-
|
44
|
-
def test_get_bucket_with_custom_config_key():
|
45
|
-
# Setup settings with custom config key
|
46
|
-
settings_manager.user_config = {
|
47
|
-
"custom": {
|
48
|
-
"bucket_name": "custom-bucket",
|
49
|
-
}
|
50
|
-
}
|
51
|
-
|
52
|
-
# Mock get_storage_client and bucket
|
53
|
-
mock_client = MagicMock()
|
54
|
-
mock_bucket = MagicMock()
|
55
|
-
mock_bucket.name = "custom-bucket"
|
56
|
-
mock_client.bucket.return_value = mock_bucket
|
57
|
-
|
58
|
-
with patch(
|
59
|
-
"kiarina.lib.google.cloud_storage._get_bucket.get_storage_client",
|
60
|
-
return_value=mock_client,
|
61
|
-
) as mock_get_client:
|
62
|
-
bucket = get_bucket(config_key="custom")
|
63
|
-
assert bucket.name == "custom-bucket"
|
64
|
-
|
65
|
-
# Verify get_storage_client was called with None (no auth_config_key specified)
|
66
|
-
mock_get_client.assert_called_once_with(None)
|
67
|
-
|
68
|
-
|
69
|
-
def test_get_bucket_with_auth_config_key():
|
70
|
-
# Setup settings
|
71
|
-
settings_manager.user_config = {
|
72
|
-
"default": {
|
73
|
-
"bucket_name": "test-bucket",
|
74
|
-
}
|
75
|
-
}
|
76
|
-
|
77
|
-
# Mock get_storage_client and bucket
|
78
|
-
mock_client = MagicMock()
|
79
|
-
mock_bucket = MagicMock()
|
80
|
-
mock_bucket.name = "test-bucket"
|
81
|
-
mock_client.bucket.return_value = mock_bucket
|
82
|
-
|
83
|
-
with patch(
|
84
|
-
"kiarina.lib.google.cloud_storage._get_bucket.get_storage_client",
|
85
|
-
return_value=mock_client,
|
86
|
-
) as mock_get_client:
|
87
|
-
bucket = get_bucket(auth_config_key="custom_auth")
|
88
|
-
assert bucket.name == "test-bucket"
|
89
|
-
|
90
|
-
# Verify get_storage_client was called with custom auth config key
|
91
|
-
mock_get_client.assert_called_once_with("custom_auth")
|
@@ -1,57 +0,0 @@
|
|
1
|
-
from unittest.mock import MagicMock, patch
|
2
|
-
|
3
|
-
from kiarina.lib.google.cloud_storage import get_storage_client
|
4
|
-
|
5
|
-
|
6
|
-
def test_get_storage_client():
|
7
|
-
# Mock get_credentials and storage.Client
|
8
|
-
mock_credentials = MagicMock()
|
9
|
-
mock_credentials.project_id = "test-project"
|
10
|
-
mock_client = MagicMock()
|
11
|
-
mock_client.project = "test-project"
|
12
|
-
|
13
|
-
with (
|
14
|
-
patch(
|
15
|
-
"kiarina.lib.google.cloud_storage._get_storage_client.get_credentials",
|
16
|
-
return_value=mock_credentials,
|
17
|
-
) as mock_get_credentials,
|
18
|
-
patch(
|
19
|
-
"kiarina.lib.google.cloud_storage._get_storage_client.storage.Client",
|
20
|
-
return_value=mock_client,
|
21
|
-
) as mock_client_class,
|
22
|
-
):
|
23
|
-
client = get_storage_client()
|
24
|
-
assert client.project == "test-project"
|
25
|
-
|
26
|
-
# Verify get_credentials was called with None (default)
|
27
|
-
mock_get_credentials.assert_called_once_with(None)
|
28
|
-
|
29
|
-
# Verify Client was called with correct credentials
|
30
|
-
mock_client_class.assert_called_once_with(credentials=mock_credentials)
|
31
|
-
|
32
|
-
|
33
|
-
def test_get_storage_client_with_auth_config_key():
|
34
|
-
# Mock get_credentials and storage.Client
|
35
|
-
mock_credentials = MagicMock()
|
36
|
-
mock_credentials.project_id = "custom-project"
|
37
|
-
mock_client = MagicMock()
|
38
|
-
mock_client.project = "custom-project"
|
39
|
-
|
40
|
-
with (
|
41
|
-
patch(
|
42
|
-
"kiarina.lib.google.cloud_storage._get_storage_client.get_credentials",
|
43
|
-
return_value=mock_credentials,
|
44
|
-
) as mock_get_credentials,
|
45
|
-
patch(
|
46
|
-
"kiarina.lib.google.cloud_storage._get_storage_client.storage.Client",
|
47
|
-
return_value=mock_client,
|
48
|
-
) as mock_client_class,
|
49
|
-
):
|
50
|
-
client = get_storage_client(auth_config_key="custom_auth")
|
51
|
-
assert client.project == "custom-project"
|
52
|
-
|
53
|
-
# Verify get_credentials was called with custom auth config key
|
54
|
-
mock_get_credentials.assert_called_once_with("custom_auth")
|
55
|
-
|
56
|
-
# Verify Client was called with correct credentials
|
57
|
-
mock_client_class.assert_called_once_with(credentials=mock_credentials)
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{kiarina_lib_google_cloud_storage-1.6.2 → kiarina_lib_google_cloud_storage-1.6.3}/tests/__init__.py
RENAMED
File without changes
|