jac-scale 0.1.1__py3-none-any.whl → 0.1.3__py3-none-any.whl

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.
@@ -0,0 +1,274 @@
1
+ """Tests for the storage abstraction."""
2
+
3
+ import io
4
+ import os
5
+ import shutil
6
+ import tempfile
7
+ from collections.abc import Generator
8
+ from pathlib import Path
9
+
10
+ import pytest
11
+
12
+ try:
13
+ from jaclang.runtimelib.storage import LocalStorage # type: ignore[attr-defined]
14
+ except ImportError as e:
15
+ pytest.skip(f"Jac modules not compiled: {e}", allow_module_level=True)
16
+
17
+
18
+ @pytest.fixture
19
+ def temp_storage_dir() -> Generator[str, None, None]:
20
+ """Create a temporary directory for storage tests."""
21
+ temp_dir = tempfile.mkdtemp()
22
+ yield temp_dir
23
+ if os.path.exists(temp_dir):
24
+ shutil.rmtree(temp_dir)
25
+
26
+
27
+ @pytest.fixture
28
+ def local_storage(temp_storage_dir: str) -> Generator[LocalStorage, None, None]:
29
+ """Create a LocalStorage instance with temp directory."""
30
+ storage = LocalStorage(base_path=temp_storage_dir)
31
+ yield storage
32
+
33
+
34
+ class TestLocalStorage:
35
+ """Tests for LocalStorage implementation."""
36
+
37
+ def test_upload_from_file_path(
38
+ self, local_storage: LocalStorage, temp_storage_dir: str
39
+ ) -> None:
40
+ """Test uploading a file from a file path."""
41
+ source_file = Path(temp_storage_dir) / "source.txt"
42
+ source_file.write_text("Hello, World!")
43
+
44
+ result = local_storage.upload(str(source_file), "uploaded/file.txt")
45
+
46
+ assert local_storage.exists("uploaded/file.txt")
47
+ assert Path(result).exists()
48
+
49
+ def test_upload_from_file_object(self, local_storage: LocalStorage) -> None:
50
+ """Test uploading from a file-like object."""
51
+ file_obj = io.BytesIO(b"Binary content here")
52
+
53
+ local_storage.upload(file_obj, "binary/data.bin")
54
+
55
+ assert local_storage.exists("binary/data.bin")
56
+ content = local_storage.download("binary/data.bin")
57
+ assert content == b"Binary content here"
58
+
59
+ def test_download_returns_bytes(self, local_storage: LocalStorage) -> None:
60
+ """Test download returns bytes when no destination specified."""
61
+ file_obj = io.BytesIO(b"Test content")
62
+ local_storage.upload(file_obj, "test.txt")
63
+
64
+ content = local_storage.download("test.txt")
65
+
66
+ assert content == b"Test content"
67
+
68
+ def test_download_to_file_path(
69
+ self, local_storage: LocalStorage, temp_storage_dir: str
70
+ ) -> None:
71
+ """Test download to a file path."""
72
+ file_obj = io.BytesIO(b"Download me")
73
+ local_storage.upload(file_obj, "source.txt")
74
+ dest_path = Path(temp_storage_dir) / "downloaded.txt"
75
+
76
+ local_storage.download("source.txt", str(dest_path))
77
+
78
+ assert dest_path.exists()
79
+ assert dest_path.read_bytes() == b"Download me"
80
+
81
+ def test_download_to_file_object(self, local_storage: LocalStorage) -> None:
82
+ """Test download to a file-like object."""
83
+ file_obj = io.BytesIO(b"Stream me")
84
+ local_storage.upload(file_obj, "stream.txt")
85
+ output = io.BytesIO()
86
+
87
+ local_storage.download("stream.txt", output)
88
+
89
+ output.seek(0)
90
+ assert output.read() == b"Stream me"
91
+
92
+ def test_download_nonexistent_file_raises(
93
+ self, local_storage: LocalStorage
94
+ ) -> None:
95
+ """Test that downloading a non-existent file raises FileNotFoundError."""
96
+ with pytest.raises(FileNotFoundError):
97
+ local_storage.download("nonexistent.txt")
98
+
99
+ def test_delete_existing_file(self, local_storage: LocalStorage) -> None:
100
+ """Test deleting an existing file."""
101
+ file_obj = io.BytesIO(b"Delete me")
102
+ local_storage.upload(file_obj, "to_delete.txt")
103
+ assert local_storage.exists("to_delete.txt")
104
+
105
+ result = local_storage.delete("to_delete.txt")
106
+
107
+ assert result is True
108
+ assert not local_storage.exists("to_delete.txt")
109
+
110
+ def test_delete_nonexistent_file(self, local_storage: LocalStorage) -> None:
111
+ """Test deleting a non-existent file returns False."""
112
+ result = local_storage.delete("nonexistent.txt")
113
+
114
+ assert result is False
115
+
116
+ def test_exists_returns_true_for_existing(
117
+ self, local_storage: LocalStorage
118
+ ) -> None:
119
+ """Test exists returns True for existing file."""
120
+ file_obj = io.BytesIO(b"I exist")
121
+ local_storage.upload(file_obj, "exists.txt")
122
+
123
+ assert local_storage.exists("exists.txt") is True
124
+
125
+ def test_exists_returns_false_for_nonexistent(
126
+ self, local_storage: LocalStorage
127
+ ) -> None:
128
+ """Test exists returns False for non-existent file."""
129
+ assert local_storage.exists("nonexistent.txt") is False
130
+
131
+ def test_list_files_non_recursive(self, local_storage: LocalStorage) -> None:
132
+ """Test listing files non-recursively."""
133
+ local_storage.upload(io.BytesIO(b"1"), "folder/file1.txt")
134
+ local_storage.upload(io.BytesIO(b"2"), "folder/file2.txt")
135
+ local_storage.upload(io.BytesIO(b"3"), "folder/sub/file3.txt")
136
+
137
+ files = list(local_storage.list_files("folder", recursive=False))
138
+
139
+ # Should include file1, file2, and sub directory
140
+ assert len(files) == 3
141
+
142
+ def test_list_files_recursive(self, local_storage: LocalStorage) -> None:
143
+ """Test listing files recursively."""
144
+ local_storage.upload(io.BytesIO(b"1"), "folder/file1.txt")
145
+ local_storage.upload(io.BytesIO(b"2"), "folder/file2.txt")
146
+ local_storage.upload(io.BytesIO(b"3"), "folder/sub/file3.txt")
147
+
148
+ files = list(local_storage.list_files("folder", recursive=True))
149
+
150
+ # Should only include files (not directories) recursively
151
+ assert len(files) == 3
152
+ assert any("file1.txt" in f for f in files)
153
+ assert any("file2.txt" in f for f in files)
154
+ assert any("file3.txt" in f for f in files)
155
+
156
+ def test_get_metadata(self, local_storage: LocalStorage) -> None:
157
+ """Test getting file metadata."""
158
+ content = b"Metadata test content"
159
+ local_storage.upload(io.BytesIO(content), "meta.txt")
160
+
161
+ metadata = local_storage.get_metadata("meta.txt")
162
+
163
+ assert metadata["size"] == len(content)
164
+ assert "modified" in metadata
165
+ assert "created" in metadata
166
+ assert metadata["is_dir"] is False
167
+ assert metadata["name"] == "meta.txt"
168
+
169
+ def test_get_metadata_nonexistent_raises(self, local_storage: LocalStorage) -> None:
170
+ """Test that getting metadata of non-existent file raises error."""
171
+ with pytest.raises(FileNotFoundError):
172
+ local_storage.get_metadata("nonexistent.txt")
173
+
174
+ def test_copy_file(self, local_storage: LocalStorage) -> None:
175
+ """Test copying a file."""
176
+ local_storage.upload(io.BytesIO(b"Copy me"), "original.txt")
177
+
178
+ result = local_storage.copy("original.txt", "copied.txt")
179
+
180
+ assert result is True
181
+ assert local_storage.exists("original.txt")
182
+ assert local_storage.exists("copied.txt")
183
+ assert local_storage.download("copied.txt") == b"Copy me"
184
+
185
+ def test_copy_nonexistent_returns_false(self, local_storage: LocalStorage) -> None:
186
+ """Test copying non-existent file returns False."""
187
+ result = local_storage.copy("nonexistent.txt", "dest.txt")
188
+
189
+ assert result is False
190
+
191
+ def test_move_file(self, local_storage: LocalStorage) -> None:
192
+ """Test moving a file."""
193
+ local_storage.upload(io.BytesIO(b"Move me"), "to_move.txt")
194
+
195
+ result = local_storage.move("to_move.txt", "moved.txt")
196
+
197
+ assert result is True
198
+ assert not local_storage.exists("to_move.txt")
199
+ assert local_storage.exists("moved.txt")
200
+ assert local_storage.download("moved.txt") == b"Move me"
201
+
202
+ def test_move_nonexistent_returns_false(self, local_storage: LocalStorage) -> None:
203
+ """Test moving non-existent file returns False."""
204
+ result = local_storage.move("nonexistent.txt", "dest.txt")
205
+
206
+ assert result is False
207
+
208
+ def test_creates_directories_automatically(self, temp_storage_dir: str) -> None:
209
+ """Test that directories are created when create_dirs is True."""
210
+ new_path = os.path.join(temp_storage_dir, "new", "nested", "dir")
211
+ LocalStorage(base_path=new_path, create_dirs=True)
212
+
213
+ assert os.path.exists(new_path)
214
+
215
+ def test_upload_creates_parent_directories(
216
+ self, local_storage: LocalStorage
217
+ ) -> None:
218
+ """Test that upload creates parent directories as needed."""
219
+ file_obj = io.BytesIO(b"Nested content")
220
+
221
+ local_storage.upload(file_obj, "deep/nested/folder/file.txt")
222
+
223
+ assert local_storage.exists("deep/nested/folder/file.txt")
224
+
225
+
226
+ class TestStorageIntegration:
227
+ """Integration tests for storage operations."""
228
+
229
+ def test_full_file_lifecycle(self, local_storage: LocalStorage) -> None:
230
+ """Test complete file lifecycle: upload, read, copy, move, delete."""
231
+ # Upload
232
+ content = b"Lifecycle test content"
233
+ local_storage.upload(io.BytesIO(content), "lifecycle.txt")
234
+ assert local_storage.exists("lifecycle.txt")
235
+
236
+ # Read
237
+ downloaded = local_storage.download("lifecycle.txt")
238
+ assert downloaded == content
239
+
240
+ # Copy
241
+ local_storage.copy("lifecycle.txt", "lifecycle_copy.txt")
242
+ assert local_storage.exists("lifecycle_copy.txt")
243
+
244
+ # Move
245
+ local_storage.move("lifecycle_copy.txt", "lifecycle_moved.txt")
246
+ assert not local_storage.exists("lifecycle_copy.txt")
247
+ assert local_storage.exists("lifecycle_moved.txt")
248
+
249
+ # Delete
250
+ local_storage.delete("lifecycle.txt")
251
+ local_storage.delete("lifecycle_moved.txt")
252
+ assert not local_storage.exists("lifecycle.txt")
253
+ assert not local_storage.exists("lifecycle_moved.txt")
254
+
255
+ def test_upload_large_file(self, local_storage: LocalStorage) -> None:
256
+ """Test uploading a larger file (1MB)."""
257
+ large_content = b"x" * (1024 * 1024) # 1MB
258
+ file_obj = io.BytesIO(large_content)
259
+
260
+ local_storage.upload(file_obj, "large_file.bin")
261
+
262
+ metadata = local_storage.get_metadata("large_file.bin")
263
+ assert metadata["size"] == 1024 * 1024
264
+
265
+ downloaded = local_storage.download("large_file.bin")
266
+ assert downloaded == large_content
267
+
268
+ def test_special_characters_in_filename(self, local_storage: LocalStorage) -> None:
269
+ """Test handling files with special characters in name."""
270
+ content = b"Special chars"
271
+ local_storage.upload(io.BytesIO(content), "file-with_special.chars.txt")
272
+
273
+ assert local_storage.exists("file-with_special.chars.txt")
274
+ assert local_storage.download("file-with_special.chars.txt") == content
@@ -0,0 +1,49 @@
1
+ import jwt;
2
+ import from datetime { UTC, datetime, timedelta }
3
+ import from typing { Any }
4
+ import from fastapi { Request, Response }
5
+ import from jaclang.runtimelib.server { UserManager }
6
+ import from jaclang.runtimelib.transport { TransportResponse, Meta }
7
+ import from jac_scale.serve { Platforms, Operations }
8
+ import from jac_scale.utils { generate_random_password }
9
+ import from jac_scale.config_loader { get_scale_config }
10
+ import from jac_scale.sso_provider { SSOProvider, SSOUserInfo }
11
+ import from jac_scale.google_sso_provider { GoogleSSOProvider }
12
+
13
+ # Load configuration
14
+ glob _jwt_config = get_scale_config().get_jwt_config(),
15
+ _sso_config = get_scale_config().get_sso_config(),
16
+ JWT_SECRET = _jwt_config['secret'],
17
+ JWT_ALGORITHM = _jwt_config['algorithm'],
18
+ JWT_EXP_DELTA_DAYS = _jwt_config['exp_delta_days'],
19
+ SSO_HOST = _sso_config['host'];
20
+
21
+ obj JacScaleUserManager(UserManager) {
22
+ has SUPPORTED_PLATFORMS: dict = {};
23
+
24
+ def postinit -> None;
25
+ # JWT methods
26
+ def create_jwt_token(username: str) -> str;
27
+ def validate_jwt_token(token: str) -> (str | None);
28
+ def refresh_jwt_token(token: str) -> (str | None);
29
+ # SSO methods
30
+ def get_sso(platform: str, operation: str) -> (SSOProvider | None);
31
+ async def sso_initiate(
32
+ platform: str, operation: str
33
+ ) -> (Response | TransportResponse);
34
+
35
+ async def sso_callback(
36
+ request: Request, platform: str, operation: str
37
+ ) -> TransportResponse;
38
+
39
+ # SSO Account Linking methods
40
+ def link_sso_account(
41
+ user_id: str, platform: str, external_id: str, email: str
42
+ ) -> dict[str, str];
43
+
44
+ def unlink_sso_account(user_id: str, platform: str) -> dict[str, str];
45
+ def get_sso_accounts(user_id: str) -> list[dict[str, str]];
46
+ def get_user_by_sso(platform: str, external_id: str) -> (dict[str, str] | None);
47
+ # Override validate_token to use JWT
48
+ def validate_token(token: str) -> (str | None);
49
+ }
@@ -1,10 +1,10 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: jac-scale
3
- Version: 0.1.1
3
+ Version: 0.1.3
4
4
  Author-email: Jason Mars <jason@mars.ninja>
5
5
  Requires-Python: >=3.12
6
6
  Description-Content-Type: text/markdown
7
- Requires-Dist: jaclang>=0.9.10
7
+ Requires-Dist: jaclang>=0.9.12
8
8
  Requires-Dist: python-dotenv<2.0.0,>=1.2.1
9
9
  Requires-Dist: docker<8.0.0,>=7.1.0
10
10
  Requires-Dist: kubernetes<35.0.0,>=34.1.0
@@ -43,6 +43,13 @@ Requires-Dist: python-multipart<1.0.0,>=0.0.21
43
43
 
44
44
  Whether you're developing locally with `jac start` or deploying to production with `jac start --scale`, you get the same powerful features with the flexibility to choose your deployment strategy.
45
45
 
46
+ ### 4. Single Sign-On (SSO) Support
47
+
48
+ - **Google SSO**: Built-in support for Google Sign-In out of the box
49
+ - **Extensible Architecture**: Easily add other providers (GitHub, Microsoft, etc.)
50
+ - **Secure Authentication**: Integrated with JWT for secure session management
51
+ - **User Management**: Automatic account creation and linking
52
+
46
53
  ## Prerequisites
47
54
 
48
55
  - kubenetes(K8s) installed
@@ -1,29 +1,34 @@
1
1
  jac_scale/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  jac_scale/config_loader.jac,sha256=oOOOFcFfEP89Y3A-AI4cLqrEaO6g0jJqZglBsCoKM84,1222
3
- jac_scale/context.jac,sha256=Ezq5-9q2rBGhs5TTwYrVkFJ4nJN3e_Sgv0wM4eT9Qmc,479
4
- jac_scale/memory_hierarchy.jac,sha256=GFaLQNLMqHvS5anYNWD_TcsW8iAYIMk-7gNzWcoBGpU,4469
5
- jac_scale/plugin.jac,sha256=6kx1gE6hYtcOHECAUwkLVQEceQF47EMpXU7EIeQLd4o,8047
6
- jac_scale/plugin_config.jac,sha256=yaXyP1nUSDtVrTBFGwa0_NDeVHNlbEP1zGSgioe-F5k,7230
7
- jac_scale/serve.jac,sha256=9ZLK4Xfu3DbmX50QE02EaNW8L5ekfuu2Br8rkdYrwwk,4775
3
+ jac_scale/context.jac,sha256=SIqQineAlLHJV3yWtYkeTIfcnqS0Oj15n8CWVSIqwJ8,529
4
+ jac_scale/google_sso_provider.jac,sha256=UUTDgQrBHXp0eqHxiw7v_VkQyFMMza0UDM6S4T5e4OM,2473
5
+ jac_scale/memory_hierarchy.jac,sha256=GuydhwujsH71TAkxeJ6Wfutp4v6GjDj23vGMreRj4yg,4533
6
+ jac_scale/plugin.jac,sha256=E1Ou_sQ8RV35emY9-gM295Uu-Eg4w4qSEJYm3TTYsWY,9585
7
+ jac_scale/plugin_config.jac,sha256=Gxvyy8V0uP1I4XARfHaHqoz0oeZ0LbHibri3gi5Odp8,8700
8
+ jac_scale/serve.jac,sha256=IU1a6ijW19FCBx53P_d-fzgukuZzS6MDTdazkhbtuzQ,4430
9
+ jac_scale/sso_provider.jac,sha256=Kky8cxm5gR2Sbg-CFrWTILKSZrV6Ju-DCEgfG4Akxb8,2092
10
+ jac_scale/user_manager.jac,sha256=UBApt_znhVEyxtfAdJ9sp_gslkHel4GGwXCBcNen_as,1932
8
11
  jac_scale/utils.jac,sha256=zpxA08_NlDDSd1oVlbknQ_UOwHWGBbhzjmT_u6UYN04,491
9
12
  jac_scale/abstractions/database_provider.jac,sha256=NZbFmcESulYsmG-27f8GY9nxVs3JflGIEb3aDDOIPu0,1454
10
13
  jac_scale/abstractions/deployment_target.jac,sha256=5rJOd25FUXZZCNmDSUkyMljcXTAVJJDmelKw8WdPZm0,2071
11
14
  jac_scale/abstractions/image_registry.jac,sha256=UCOwwuts5e1emsdDIlHJOiyW2ePA7k7D8UJdzd2kN10,1386
12
15
  jac_scale/abstractions/logger.jac,sha256=YnXn8_jCpZ0IOBkJ7bFBMqo6WXO6BaDNVBqPq0lHbjk,652
13
- jac_scale/abstractions/config/app_config.jac,sha256=XD-VtltmHaXPFdVWw6HRqLJjSTqxS4fwQFZTnbGoYSQ,798
16
+ jac_scale/abstractions/config/app_config.jac,sha256=yxXlTOFRNBq5yFMgYm1LjEzobwxP_k2EG4zXcoHf688,912
14
17
  jac_scale/abstractions/config/base_config.jac,sha256=ePT-up-63QGu2Jifi_CpPhd7_V9cPcHkInqGKDFryC4,785
15
18
  jac_scale/abstractions/models/deployment_result.jac,sha256=3Mx8TVvL74AF8LLnhMbuCyHTTu-DXesYWMvht1HoGFs,704
16
19
  jac_scale/abstractions/models/resource_status.jac,sha256=H6I9ZF92ia56bNmHR9dLMGsaFG4BafGh4sY-YwVRPu0,1031
17
20
  jac_scale/factories/database_factory.jac,sha256=-8QfF1vDUqsdDKnldmayxvB-Z6DwQeNMOlo7HgTaouQ,1736
18
21
  jac_scale/factories/deployment_factory.jac,sha256=1pzQ2HkqpKaeoycbRxdZ05McgTLpgj5Y5hmKhFTm1AY,1673
19
22
  jac_scale/factories/registry_factory.jac,sha256=qWgwEH75EtjXGj3d9NGeg7D9Yx2S_RW9udlCFvOOCqU,1210
23
+ jac_scale/factories/storage_factory.jac,sha256=FVlx-f1BOq6H1yLWXT7OLSG-ZCENvlBPNr0OwFdo-VU,2661
20
24
  jac_scale/factories/utility_factory.jac,sha256=64gMv_N_pFeq5E7z3gXrLIqeRGS_RGIF5eLT8RxNl_I,1262
21
25
  jac_scale/impl/config_loader.impl.jac,sha256=j8YngI4mdcBKCBtly-8vN0WYXDwzdhwZ6bmmMc9Kza4,4769
22
- jac_scale/impl/context.impl.jac,sha256=LU9R3318_eXOOgLcv2x76Cl6lxmxPlILDI7E9U3QzUU,1000
26
+ jac_scale/impl/context.impl.jac,sha256=D8B7K-Y1VdbqBfGjYtGA5BDBiizlL8MmvAqxO8xMLwE,1106
23
27
  jac_scale/impl/memory_hierarchy.main.impl.jac,sha256=Jc4Cy-5cy0TtK2uQ6rdYruxa0ZfZKSYgo3jOoXv4ER4,2339
24
28
  jac_scale/impl/memory_hierarchy.mongo.impl.jac,sha256=APh7YloOj7bWGtv6DTBm7ekX13w_fectbZiFY0btwWU,6626
25
29
  jac_scale/impl/memory_hierarchy.redis.impl.jac,sha256=x27TzeBI87vz72s7esQvFz8EPk3EfhVMNKU8sP4s2hk,4900
26
- jac_scale/impl/serve.impl.jac,sha256=zs3JgM3w7e-fSZjnICUEJ8gcli--9XkE5yHF6kQiowI,66860
30
+ jac_scale/impl/serve.impl.jac,sha256=UX7GIoB27kHeyq1JxtkM4CYC1BnhGpipCu0qOGaePRM,61376
31
+ jac_scale/impl/user_manager.impl.jac,sha256=7xGoLMweQuoVW-na7XbK3bctfUHaSEnT9nB7DLgSlgw,11817
27
32
  jac_scale/jserver/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
33
  jac_scale/jserver/jfast_api.jac,sha256=Ez7EZ883TS9IIACzK8QMqTgVTtNoaOenbmwNKnekBuc,5561
29
34
  jac_scale/jserver/jserver.jac,sha256=8gWh22nX9Z5rJp3D1AxOSU8lBhoX4-kBZ0uvJPPNqX8,3356
@@ -32,26 +37,32 @@ jac_scale/jserver/impl/jserver.impl.jac,sha256=4NOzfys4WQmGt6vttTTh6By12hEJqdvOz
32
37
  jac_scale/providers/database/kubernetes_mongo.jac,sha256=nP43b-ePR8XInhhk7gzdvJvOJMZcTZanm1VALdiCqXA,4952
33
38
  jac_scale/providers/database/kubernetes_redis.jac,sha256=qF9HkNLLgiymxiCXbmETbVVDs5Wqs1m4s3O6xFR7jRA,3778
34
39
  jac_scale/providers/registry/dockerhub.jac,sha256=7KlgQJGGUeDF7zP8-KNF8HTShB4td1946OtIdS57EHI,2282
35
- jac_scale/targets/kubernetes/kubernetes_config.jac,sha256=R0h6g9-z9_K9Z4FpO2-t6Wefc-y_aLtLb3YeqPNU30Y,9513
36
- jac_scale/targets/kubernetes/kubernetes_target.jac,sha256=Dv-uq_HyhQm8czdak2_u0BK1gJ0ohjaHNU8Pgtb1BUE,29928
40
+ jac_scale/targets/kubernetes/kubernetes_config.jac,sha256=Xk3EjKTEjptlctD2C5cTYjgw9V8i8mfsO-jKAa2IZZs,9406
41
+ jac_scale/targets/kubernetes/kubernetes_target.jac,sha256=itICKs_sA4jOs7_wrFgpj5QhupjKVXRSvkaJMBL6t9g,35523
37
42
  jac_scale/targets/kubernetes/utils/kubernetes_utils.impl.jac,sha256=CPSlFlhCE3qdzPWiPVa7KbHkL_h5Gle5ySvq7UkwR4k,15756
38
43
  jac_scale/targets/kubernetes/utils/kubernetes_utils.jac,sha256=Nr257oCyduodJbxkLJeNYphFzz9NxviFfW1Tpc5dQKk,2129
39
44
  jac_scale/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
40
45
  jac_scale/tests/conftest.py,sha256=uiS352_HVmMf7V6T0BZl-Kn8svkKbj3jhNr-hEKrcPw,820
41
46
  jac_scale/tests/test_abstractions.py,sha256=gb5ueNcUcxpq0U0r_nEize9v027gRR_XiZlCEooAW6U,2612
42
- jac_scale/tests/test_deploy_k8s.py,sha256=iV7q1hK7BMulV4H_Rg9VJ3NrFFoEFE2gVWyvK7Zl6HE,9104
43
- jac_scale/tests/test_examples.py,sha256=FlmVbrCJk0Jt_NTSExctSI5sNShqS5vWa0eMyek1itQ,16898
47
+ jac_scale/tests/test_deploy_k8s.py,sha256=rX9kJohqTeaRch-KSruWYF8eUnPGtJ_p6zy0sPkBXIA,9164
48
+ jac_scale/tests/test_examples.py,sha256=2xOTf0rBiT_9w92ku7k9Pfv4A7ohLZpZdpAH0VHM86E,24044
44
49
  jac_scale/tests/test_factories.py,sha256=cf1gLrBdK9q8SlHyocZqtixyPtO2dLlrgNYeX5-_RYM,5073
45
50
  jac_scale/tests/test_file_upload.py,sha256=JooF-9rgwOqtNkWRfvfHu4W5x-gzk91bHVi13J9mnNE,16595
51
+ jac_scale/tests/test_hooks.py,sha256=TzikM6dd1uKg1G2L1MtgXYzzjY6YhrbAQXZah-TO33Y,1366
46
52
  jac_scale/tests/test_k8s_utils.py,sha256=Oqocwl4m2IFgM27Lgsi96WJeHS8hnx9WDOcxq9YkqJU,4613
47
53
  jac_scale/tests/test_memory_hierarchy.py,sha256=q_DsKyPIuQymab_sEtXojDW0GOyunRxZJsNTJDrGA7s,8324
48
- jac_scale/tests/test_serve.py,sha256=VhZdU75PDMH71DEMKWkfs2KTUW6mpK9ZzpWOglCpFEk,65119
49
- jac_scale/tests/test_sso.py,sha256=hFFvjbrgtO_5557XaEwZLjrrQsc4k4S3GPTroU2bwPA,26779
50
- jac_scale/tests/fixtures/test_api.jac,sha256=JBQUXb7l7M3cHGjcY7I9e6XhQyLQY7FKiC8z1Ei7Ve8,4109
54
+ jac_scale/tests/test_restspec.py,sha256=ynkDlu9mHl98hUL49UYwcJNXbsLhBd8yPL9TTw12xN0,6582
55
+ jac_scale/tests/test_serve.py,sha256=LsLgGGS5_52wtB0EyBEsIzX6KwIQ4m5hTVoOq3dYnWc,67299
56
+ jac_scale/tests/test_sso.py,sha256=9h2AUC9JBM74O6xfpyIcl98iXyZWcDIGdKRtlb_5uqo,28104
57
+ jac_scale/tests/test_storage.py,sha256=Y7CIbKrH3OmJQlBeV9A965-7TtxL6nuZtfkfoeqIeS4,10514
58
+ jac_scale/tests/fixtures/test_api.jac,sha256=78tw_0lFR2k7uI0nrU_e8fdJJOcOG2z0J5C47MQ42DU,4744
59
+ jac_scale/tests/fixtures/test_restspec.jac,sha256=bE8-7qyDXkNGGhv0HqQCKFpLWCDa5ciRzrJS-bkqWDo,1173
51
60
  jac_scale/tests/fixtures/todo_app.jac,sha256=beI6AiRutmXsXxuzU9nIZTE-AuoBBP-WqbRA2ux1pN4,1216
61
+ jac_scale/tests/fixtures/scale-feats/main.jac,sha256=QN8Opodha9jLWdRGCASByIogePr1XKphgKjyE9Pp73c,4205
62
+ jac_scale/tests/fixtures/scale-feats/components/Button.cl.jac,sha256=e8tvNzW_QikFJMSTcbkziKP69NF00DqQVxcjLPkAW-w,903
52
63
  jac_scale/utilities/loggers/standard_logger.jac,sha256=6XL5ETAOBwbsFCOp0VN_7TOnqcQDmbLZVzubA-JR3vA,1376
53
- jac_scale-0.1.1.dist-info/METADATA,sha256=I-nL8nlf_Bc45KaJLHgTji6ozrF9I-xNHg3drRXM-8g,20125
54
- jac_scale-0.1.1.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
55
- jac_scale-0.1.1.dist-info/entry_points.txt,sha256=n-Wm8JEtGOqy_IY_kgIOi3-uYnuVK-iWsvKiLkxlG4E,105
56
- jac_scale-0.1.1.dist-info/top_level.txt,sha256=PpgR0R8z9qoFbSser2K20r5Is4K6TxVwguoN6LfTEKU,10
57
- jac_scale-0.1.1.dist-info/RECORD,,
64
+ jac_scale-0.1.3.dist-info/METADATA,sha256=zRQUUOCa0B6p2qC4Fo-sptUZbayDW85aS51iX1SvSI4,20457
65
+ jac_scale-0.1.3.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
66
+ jac_scale-0.1.3.dist-info/entry_points.txt,sha256=n-Wm8JEtGOqy_IY_kgIOi3-uYnuVK-iWsvKiLkxlG4E,105
67
+ jac_scale-0.1.3.dist-info/top_level.txt,sha256=PpgR0R8z9qoFbSser2K20r5Is4K6TxVwguoN6LfTEKU,10
68
+ jac_scale-0.1.3.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.10.1)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5