jac-scale 0.1.2__tar.gz → 0.1.5__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.
- {jac_scale-0.1.2 → jac_scale-0.1.5}/PKG-INFO +4 -4
- {jac_scale-0.1.2 → jac_scale-0.1.5}/README.md +1 -1
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/abstractions/config/app_config.jac +5 -2
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/config_loader.jac +2 -1
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/context.jac +2 -1
- jac_scale-0.1.5/jac_scale/factories/storage_factory.jac +75 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/impl/config_loader.impl.jac +28 -3
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/impl/context.impl.jac +1 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/impl/serve.impl.jac +749 -46
- jac_scale-0.1.5/jac_scale/impl/webhook.impl.jac +212 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/jserver/impl/jfast_api.impl.jac +4 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/memory_hierarchy.jac +3 -1
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/plugin.jac +38 -3
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/plugin_config.jac +28 -1
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/serve.jac +33 -4
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/targets/kubernetes/kubernetes_config.jac +9 -15
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/targets/kubernetes/kubernetes_target.jac +167 -13
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/targets/kubernetes/utils/kubernetes_utils.impl.jac +8 -7
- jac_scale-0.1.5/jac_scale/tests/fixtures/scale-feats/components/Button.cl.jac +32 -0
- jac_scale-0.1.5/jac_scale/tests/fixtures/scale-feats/main.jac +147 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/tests/fixtures/test_api.jac +89 -0
- jac_scale-0.1.5/jac_scale/tests/fixtures/test_restspec.jac +88 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/tests/test_deploy_k8s.py +2 -1
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/tests/test_examples.py +180 -5
- jac_scale-0.1.5/jac_scale/tests/test_restspec.py +289 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/tests/test_serve.py +411 -4
- jac_scale-0.1.5/jac_scale/tests/test_storage.py +274 -0
- jac_scale-0.1.5/jac_scale/webhook.jac +93 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale.egg-info/PKG-INFO +4 -4
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale.egg-info/SOURCES.txt +8 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale.egg-info/requires.txt +2 -2
- {jac_scale-0.1.2 → jac_scale-0.1.5}/pyproject.toml +3 -3
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/__init__.py +0 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/abstractions/config/base_config.jac +0 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/abstractions/database_provider.jac +0 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/abstractions/deployment_target.jac +0 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/abstractions/image_registry.jac +0 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/abstractions/logger.jac +0 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/abstractions/models/deployment_result.jac +0 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/abstractions/models/resource_status.jac +0 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/factories/database_factory.jac +0 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/factories/deployment_factory.jac +0 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/factories/registry_factory.jac +0 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/factories/utility_factory.jac +0 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/google_sso_provider.jac +0 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/impl/memory_hierarchy.main.impl.jac +0 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/impl/memory_hierarchy.mongo.impl.jac +0 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/impl/memory_hierarchy.redis.impl.jac +0 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/impl/user_manager.impl.jac +0 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/jserver/__init__.py +0 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/jserver/impl/jserver.impl.jac +0 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/jserver/jfast_api.jac +0 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/jserver/jserver.jac +0 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/providers/database/kubernetes_mongo.jac +0 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/providers/database/kubernetes_redis.jac +0 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/providers/registry/dockerhub.jac +0 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/sso_provider.jac +0 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/targets/kubernetes/utils/kubernetes_utils.jac +0 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/tests/__init__.py +0 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/tests/conftest.py +0 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/tests/fixtures/todo_app.jac +0 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/tests/test_abstractions.py +0 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/tests/test_factories.py +0 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/tests/test_file_upload.py +0 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/tests/test_hooks.py +0 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/tests/test_k8s_utils.py +0 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/tests/test_memory_hierarchy.py +0 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/tests/test_sso.py +0 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/user_manager.jac +0 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/utilities/loggers/standard_logger.jac +0 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale/utils.jac +0 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale.egg-info/dependency_links.txt +0 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale.egg-info/entry_points.txt +0 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/jac_scale.egg-info/top_level.txt +0 -0
- {jac_scale-0.1.2 → jac_scale-0.1.5}/setup.cfg +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: jac-scale
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.5
|
|
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.
|
|
7
|
+
Requires-Dist: jaclang>=0.9.14
|
|
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
|
|
@@ -12,7 +12,7 @@ Requires-Dist: pymongo<5.0.0,>=4.15.4
|
|
|
12
12
|
Requires-Dist: redis<8.0.0,>=7.1.0
|
|
13
13
|
Requires-Dist: fastapi<0.122.0,>=0.121.3
|
|
14
14
|
Requires-Dist: uvicorn<0.39.0,>=0.38.0
|
|
15
|
-
Requires-Dist: pyjwt
|
|
15
|
+
Requires-Dist: pyjwt<2.11.0,>=2.10.1
|
|
16
16
|
Requires-Dist: fastapi-sso<1.0.0,>=0.18.0
|
|
17
17
|
Requires-Dist: python-multipart<1.0.0,>=0.0.21
|
|
18
18
|
|
|
@@ -491,7 +491,7 @@ async walker FetchData {
|
|
|
491
491
|
| `MONGODB_URI` | URL of MongoDB database | - |
|
|
492
492
|
| `REDIS_URL` | URL of Redis database | - |
|
|
493
493
|
| `JWT_EXP_DELTA_DAYS` | Number of days until JWT token expires | `7` |
|
|
494
|
-
| `JWT_SECRET` | Secret key used for JWT token signing and verification | `'
|
|
494
|
+
| `JWT_SECRET` | Secret key used for JWT token signing and verification | `'supersecretkey_for_testing_only!'` |
|
|
495
495
|
| `JWT_ALGORITHM` | Algorithm used for JWT token encoding/decoding | `'HS256'` |
|
|
496
496
|
| `SSO_HOST` | SSO host URL | `'http://localhost:8000/sso'` |
|
|
497
497
|
| `SSO_GOOGLE_CLIENT_ID` | Google OAuth client ID | - |
|
|
@@ -473,7 +473,7 @@ async walker FetchData {
|
|
|
473
473
|
| `MONGODB_URI` | URL of MongoDB database | - |
|
|
474
474
|
| `REDIS_URL` | URL of Redis database | - |
|
|
475
475
|
| `JWT_EXP_DELTA_DAYS` | Number of days until JWT token expires | `7` |
|
|
476
|
-
| `JWT_SECRET` | Secret key used for JWT token signing and verification | `'
|
|
476
|
+
| `JWT_SECRET` | Secret key used for JWT token signing and verification | `'supersecretkey_for_testing_only!'` |
|
|
477
477
|
| `JWT_ALGORITHM` | Algorithm used for JWT token encoding/decoding | `'HS256'` |
|
|
478
478
|
| `SSO_HOST` | SSO host URL | `'http://localhost:8000/sso'` |
|
|
479
479
|
| `SSO_GOOGLE_CLIENT_ID` | Google OAuth client ID | - |
|
|
@@ -7,7 +7,8 @@ class AppConfig {
|
|
|
7
7
|
file_name: str = 'none',
|
|
8
8
|
build: bool = False,
|
|
9
9
|
app_name: (str | None) = None,
|
|
10
|
-
testing: bool = False
|
|
10
|
+
testing: bool = False,
|
|
11
|
+
experimental: bool = False;
|
|
11
12
|
|
|
12
13
|
def init(
|
|
13
14
|
self: AppConfig,
|
|
@@ -15,13 +16,15 @@ class AppConfig {
|
|
|
15
16
|
file_name: str = 'none',
|
|
16
17
|
build: bool = False,
|
|
17
18
|
app_name: (str | None) = None,
|
|
18
|
-
testing: bool = False
|
|
19
|
+
testing: bool = False,
|
|
20
|
+
experimental: bool = False
|
|
19
21
|
) -> None {
|
|
20
22
|
self.code_folder = code_folder;
|
|
21
23
|
self.file_name = file_name;
|
|
22
24
|
self.build = build;
|
|
23
25
|
self.app_name = app_name;
|
|
24
26
|
self.testing = testing;
|
|
27
|
+
self.experimental = experimental;
|
|
25
28
|
}
|
|
26
29
|
|
|
27
30
|
def get_code_path(self: AppConfig) -> Path {
|
|
@@ -12,7 +12,7 @@ import os;
|
|
|
12
12
|
|
|
13
13
|
"""Scale-specific configuration loader.
|
|
14
14
|
|
|
15
|
-
Provides access to jwt, sso, database, kubernetes, and
|
|
15
|
+
Provides access to jwt, sso, database, kubernetes, server and webhook configuration
|
|
16
16
|
from the [plugins.scale] section of jac.toml.
|
|
17
17
|
"""
|
|
18
18
|
class JacScaleConfig(PluginConfigBase) {
|
|
@@ -23,6 +23,7 @@ class JacScaleConfig(PluginConfigBase) {
|
|
|
23
23
|
def get_database_config(self: JacScaleConfig) -> dict[str, Any];
|
|
24
24
|
def get_kubernetes_config(self: JacScaleConfig) -> dict[str, Any];
|
|
25
25
|
def get_server_config(self: JacScaleConfig) -> dict[str, Any];
|
|
26
|
+
def get_webhook_config(self: JacScaleConfig) -> dict[str, Any];
|
|
26
27
|
}
|
|
27
28
|
|
|
28
29
|
glob _scale_config_instance: JacScaleConfig | None = None;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import from contextvars { ContextVar }
|
|
1
2
|
import from dataclasses { MISSING }
|
|
2
3
|
import from typing { Any }
|
|
3
4
|
import from uuid { UUID }
|
|
4
5
|
import from jaclang.pycore.constant { Constants as Con }
|
|
5
|
-
import from jaclang.runtimelib.context { ExecutionContext }
|
|
6
|
+
import from jaclang.runtimelib.context { ExecutionContext, CallState }
|
|
6
7
|
|
|
7
8
|
"""Jac Scale Execution Context with custom memory backend.
|
|
8
9
|
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"""Factory for creating storage instances."""
|
|
2
|
+
import from typing { Any }
|
|
3
|
+
import os;
|
|
4
|
+
import from jaclang.runtimelib.storage { Storage }
|
|
5
|
+
import from jaclang.project.config { get_config }
|
|
6
|
+
|
|
7
|
+
enum StorageType {
|
|
8
|
+
LOCAL = "local"
|
|
9
|
+
# Future: S3, GCS, AZURE - add when implemented
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
"""Factory for creating storage instances.
|
|
13
|
+
|
|
14
|
+
Configuration priority: jac.toml > environment variable > default
|
|
15
|
+
|
|
16
|
+
In jac.toml:
|
|
17
|
+
[storage]
|
|
18
|
+
type = "local" # or "s3", "gcs", "azure"
|
|
19
|
+
base_path = "/data/storage"
|
|
20
|
+
create_dirs = true
|
|
21
|
+
|
|
22
|
+
Environment variables:
|
|
23
|
+
JAC_STORAGE_TYPE: Storage type (local, s3, gcs, azure)
|
|
24
|
+
JAC_STORAGE_PATH: Base directory for local storage
|
|
25
|
+
JAC_STORAGE_CREATE_DIRS: Whether to auto-create directories
|
|
26
|
+
"""
|
|
27
|
+
class StorageFactory {
|
|
28
|
+
static def create(
|
|
29
|
+
storage_type: (StorageType | str), config: (dict[str, Any] | None) = None
|
|
30
|
+
) -> Storage {
|
|
31
|
+
# Convert string to enum if needed
|
|
32
|
+
if isinstance(storage_type, str) {
|
|
33
|
+
storage_type = StorageType(storage_type);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if storage_type == StorageType.LOCAL {
|
|
37
|
+
import from jaclang.runtimelib.storage { LocalStorage }
|
|
38
|
+
cfg = config or {};
|
|
39
|
+
return LocalStorage(
|
|
40
|
+
base_path=cfg.get("base_path", "./storage"),
|
|
41
|
+
create_dirs=cfg.get("create_dirs", True)
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
raise ValueError(f"Unsupported storage type: {storage_type}") ;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
static def get_default(
|
|
48
|
+
base_path: str = "./storage", create_dirs: bool = True
|
|
49
|
+
) -> Storage {
|
|
50
|
+
# Get config from jac.toml if available
|
|
51
|
+
jac_config = get_config();
|
|
52
|
+
|
|
53
|
+
# Config priority: jac.toml > env var > parameter
|
|
54
|
+
if jac_config and jac_config.storage {
|
|
55
|
+
storage_type = StorageType(jac_config.storage.storage_type);
|
|
56
|
+
base_path = jac_config.storage.base_path;
|
|
57
|
+
create_dirs = jac_config.storage.create_dirs;
|
|
58
|
+
} elif os.environ.get("JAC_STORAGE_TYPE") or os.environ.get("JAC_STORAGE_PATH") {
|
|
59
|
+
storage_type_str = os.environ.get(
|
|
60
|
+
"JAC_STORAGE_TYPE", StorageType.LOCAL.value
|
|
61
|
+
);
|
|
62
|
+
storage_type = StorageType(storage_type_str);
|
|
63
|
+
base_path = os.environ.get("JAC_STORAGE_PATH", base_path);
|
|
64
|
+
create_dirs_str = os.environ.get(
|
|
65
|
+
"JAC_STORAGE_CREATE_DIRS", str(create_dirs)
|
|
66
|
+
);
|
|
67
|
+
create_dirs = create_dirs_str.lower() == "true";
|
|
68
|
+
} else {
|
|
69
|
+
storage_type = StorageType.LOCAL;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
storage_config = {"base_path": base_path, "create_dirs": create_dirs};
|
|
73
|
+
return StorageFactory.create(storage_type, storage_config);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -18,7 +18,11 @@ impl JacScaleConfig.get_plugin_name(self: JacScaleConfig) -> str {
|
|
|
18
18
|
"""Get default configuration structure for scale."""
|
|
19
19
|
impl JacScaleConfig.get_default_config(self: JacScaleConfig) -> dict[str, Any] {
|
|
20
20
|
return {
|
|
21
|
-
'jwt': {
|
|
21
|
+
'jwt': {
|
|
22
|
+
'secret': 'supersecretkey_for_testing_only!',
|
|
23
|
+
'algorithm': 'HS256',
|
|
24
|
+
'exp_delta_days': 7
|
|
25
|
+
},
|
|
22
26
|
'sso': {
|
|
23
27
|
'host': 'http://localhost:8000/sso',
|
|
24
28
|
'google': {'client_id': '', 'client_secret': ''}
|
|
@@ -50,7 +54,13 @@ impl JacScaleConfig.get_default_config(self: JacScaleConfig) -> dict[str, Any] {
|
|
|
50
54
|
'liveness_period': 20,
|
|
51
55
|
'liveness_failure_threshold': 80
|
|
52
56
|
},
|
|
53
|
-
'server': {'port': 8000, 'host': '0.0.0.0'}
|
|
57
|
+
'server': {'port': 8000, 'host': '0.0.0.0'},
|
|
58
|
+
'webhook': {
|
|
59
|
+
'secret': 'webhook-secret-key',
|
|
60
|
+
'signature_header': 'X-Webhook-Signature',
|
|
61
|
+
'verify_signature': True,
|
|
62
|
+
'api_key_expiry_days': 365
|
|
63
|
+
}
|
|
54
64
|
};
|
|
55
65
|
}
|
|
56
66
|
|
|
@@ -59,7 +69,7 @@ impl JacScaleConfig.get_jwt_config(self: JacScaleConfig) -> dict[str, Any] {
|
|
|
59
69
|
config = self.load();
|
|
60
70
|
jwt_config = config.get('jwt', {});
|
|
61
71
|
return {
|
|
62
|
-
'secret': jwt_config.get('secret', '
|
|
72
|
+
'secret': jwt_config.get('secret', 'supersecretkey_for_testing_only!'),
|
|
63
73
|
'algorithm': jwt_config.get('algorithm', 'HS256'),
|
|
64
74
|
'exp_delta_days': int(jwt_config.get('exp_delta_days', 7))
|
|
65
75
|
};
|
|
@@ -115,6 +125,21 @@ impl JacScaleConfig.get_server_config(self: JacScaleConfig) -> dict[str, Any] {
|
|
|
115
125
|
};
|
|
116
126
|
}
|
|
117
127
|
|
|
128
|
+
"""Get webhook configuration from jac.toml."""
|
|
129
|
+
impl JacScaleConfig.get_webhook_config(self: JacScaleConfig) -> dict[str, Any] {
|
|
130
|
+
config = self.load();
|
|
131
|
+
webhook_config = config.get('webhook', {});
|
|
132
|
+
return {
|
|
133
|
+
'secret': os.environ.get('WEBHOOK_SECRET')
|
|
134
|
+
or webhook_config.get('secret', 'webhook-secret-key'),
|
|
135
|
+
'signature_header': webhook_config.get(
|
|
136
|
+
'signature_header', 'X-Webhook-Signature'
|
|
137
|
+
),
|
|
138
|
+
'verify_signature': webhook_config.get('verify_signature', True),
|
|
139
|
+
'api_key_expiry_days': int(webhook_config.get('api_key_expiry_days', 365))
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
|
|
118
143
|
"""Get or create the global JacScaleConfig instance."""
|
|
119
144
|
impl get_scale_config(project_dir: Path | None = None) -> JacScaleConfig {
|
|
120
145
|
global _scale_config_instance;
|
|
@@ -21,4 +21,5 @@ impl JScaleExecutionContext.init(self: JScaleExecutionContext) -> None {
|
|
|
21
21
|
# Default user_root and entry_node to system_root
|
|
22
22
|
self.user_root = self.system_root;
|
|
23
23
|
self.entry_node = self.system_root;
|
|
24
|
+
self.call_state: ContextVar[CallState] = ContextVar('call_state');
|
|
24
25
|
}
|