Skip to content

Commit e2a80bf

Browse files
authored
feat(native): More concise module structure (#7180)
* feat(native): More concise module structure * feat: Load only globals.py as the entry point for template functions
1 parent d345d74 commit e2a80bf

File tree

8 files changed

+214
-218
lines changed

8 files changed

+214
-218
lines changed
Lines changed: 168 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,188 @@
1-
class JinjaException(Exception):
1+
import os
2+
from typing import Union, Callable, Dict, Any
3+
4+
5+
def file_repository(path):
6+
files = []
7+
8+
for (dirpath, dirnames, filenames) in os.walk(path):
9+
for fileName in filenames:
10+
if fileName.endswith(".js") or fileName.endswith(".yml") or fileName.endswith(".yaml") or fileName.endswith(".jinja") or fileName.endswith(".py"):
11+
path = os.path.join(dirpath, fileName)
12+
13+
f = open(path, 'r')
14+
content = f.read()
15+
f.close()
16+
17+
files.append({
18+
'fileName': fileName,
19+
'content': content
20+
})
21+
22+
return files
23+
24+
class ConfigurationException(Exception):
25+
pass
26+
27+
class RequestContext:
28+
url: str
29+
method: str
30+
headers: dict[str, str]
31+
32+
33+
class Configuration:
34+
web_sockets: bool
35+
http: Dict
36+
graceful_shutdown: int
37+
process_subscriptions_interval: int
38+
web_sockets_base_path: str
39+
schema_path: str
40+
base_path: str
41+
dev_server: bool
42+
api_secret: str
43+
cache_and_queue_driver: str
44+
allow_js_duplicate_props_in_schema: bool
45+
jwt: Dict
46+
scheduled_refresh_timer: Any
47+
scheduled_refresh_timezones: list[str]
48+
scheduled_refresh_concurrency: int
49+
scheduled_refresh_batch_size: int
50+
compiler_cache_size: int
51+
update_compiler_cache_keep_alive: bool
52+
max_compiler_cache_keep_alive: int
53+
telemetry: bool
54+
sql_cache: bool
55+
live_preview: bool
56+
# SQL API
57+
pg_sql_port: int
58+
sql_super_user: str
59+
sql_user: str
60+
sql_password: str
61+
# Functions
62+
logger: Callable
63+
context_to_app_id: Union[str, Callable[[RequestContext], str]]
64+
context_to_orchestrator_id: Union[str, Callable[[RequestContext], str]]
65+
driver_factory: Callable[[RequestContext], Dict]
66+
external_driver_factory: Callable[[RequestContext], Dict]
67+
db_type: Union[str, Callable[[RequestContext], str]]
68+
check_auth: Callable
69+
check_sql_auth: Callable
70+
can_switch_sql_user: Callable
71+
extend_context: Callable
72+
scheduled_refresh_contexts: Callable
73+
context_to_api_scopes: Callable
74+
repository_factory: Callable
75+
schema_version: Union[str, Callable[[RequestContext], str]]
76+
semantic_layer_sync: Union[Dict, Callable[[], Dict]]
77+
pre_aggregations_schema: Union[Callable[[RequestContext], str]]
78+
orchestrator_options: Union[Dict, Callable[[RequestContext], Dict]]
79+
80+
def __init__(self):
81+
self.web_sockets = None
82+
self.http = None
83+
self.graceful_shutdown = None
84+
self.schema_path = None
85+
self.base_path = None
86+
self.dev_server = None
87+
self.api_secret = None
88+
self.web_sockets_base_path = None
89+
self.pg_sql_port = None
90+
self.cache_and_queue_driver = None
91+
self.allow_js_duplicate_props_in_schema = None
92+
self.process_subscriptions_interval = None
93+
self.jwt = None
94+
self.scheduled_refresh_timer = None
95+
self.scheduled_refresh_timezones = None
96+
self.scheduled_refresh_concurrency = None
97+
self.scheduled_refresh_batch_size = None
98+
self.compiler_cache_size = None
99+
self.update_compiler_cache_keep_alive = None
100+
self.max_compiler_cache_keep_alive = None
101+
self.telemetry = None
102+
self.sql_cache = None
103+
self.live_preview = None
104+
self.sql_super_user = None
105+
self.sql_user = None
106+
self.sql_password = None
107+
# Functions
108+
self.logger = None
109+
self.context_to_app_id = None
110+
self.context_to_orchestrator_id = None
111+
self.driver_factory = None
112+
self.external_driver_factory = None
113+
self.db_type = None
114+
self.check_auth = None
115+
self.check_sql_auth = None
116+
self.can_switch_sql_user = None
117+
self.query_rewrite = None
118+
self.extend_context = None
119+
self.scheduled_refresh_contexts = None
120+
self.context_to_api_scopes = None
121+
self.repository_factory = None
122+
self.schema_version = None
123+
self.semantic_layer_sync = None
124+
self.pre_aggregations_schema = None
125+
self.orchestrator_options = None
126+
127+
def __call__(self, func):
128+
if isinstance(func, str):
129+
return AttrRef(self, func)
130+
131+
if not callable(func):
132+
raise ConfigurationException("@config decorator must be used with functions, actual: '%s'" % type(func).__name__)
133+
134+
if hasattr(self, func.__name__):
135+
setattr(self, func.__name__, func)
136+
else:
137+
raise ConfigurationException("Unknown configuration property: '%s'" % func.__name__)
138+
139+
class AttrRef:
140+
config: Configuration
141+
attribute: str
142+
143+
def __init__(self, config: Configuration, attribue: str):
144+
self.config = config
145+
self.attribute = attribue
146+
147+
def __call__(self, func):
148+
if not callable(func):
149+
raise ConfigurationException("@config decorator must be used with functions, actual: '%s'" % type(func).__name__)
150+
151+
if hasattr(self.config, self.attribute):
152+
setattr(self.config, self.attribute, func)
153+
else:
154+
raise ConfigurationException("Unknown configuration property: '%s'" % func.__name__)
155+
156+
return func
157+
158+
config = Configuration()
159+
# backward compatibility
160+
settings = config
161+
162+
class TemplateException(Exception):
2163
pass
3164

4-
class JinjaContext:
165+
class TemplateContext:
5166
def function(self, func):
6167
if not callable(func):
7-
raise JinjaException("function registration must be used with functions, actual: '%s'" % type(func).__name__)
168+
raise TemplateException("function registration must be used with functions, actual: '%s'" % type(func).__name__)
8169

9170
return context_func(func)
10171

11172
def filter(self, func):
12173
if not callable(func):
13-
raise JinjaException("function registration must be used with functions, actual: '%s'" % type(func).__name__)
174+
raise TemplateException("function registration must be used with functions, actual: '%s'" % type(func).__name__)
14175

15-
raise JinjaException("filter registration is not supported")
176+
raise TemplateException("filter registration is not supported")
16177

17178
def variable(self, func):
18-
raise JinjaException("variable registration is not supported")
19-
20-
class TemplateModule:
21-
def JinjaContext():
22-
return JinjaContext()
23-
24-
template = TemplateModule
179+
raise TemplateException("variable registration is not supported")
25180

26181
def context_func(func):
27182
func.cube_context_func = True
28183
return func
29184

30185
__all__ = [
31186
'context_func',
32-
'template'
187+
'TemplateContext'
33188
]

packages/cubejs-backend-native/python/cube/src/conf/__init__.py

Lines changed: 0 additions & 160 deletions
This file was deleted.

packages/cubejs-backend-native/src/python/entry.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@ fn python_load_config(mut cx: FunctionContext) -> JsResult<JsPromise> {
2020
py_runtime_init(&mut cx, channel.clone())?;
2121

2222
let conf_res = Python::with_gil(|py| -> PyResult<CubeConfigPy> {
23-
let cube_conf_code = include_str!(concat!(
23+
let cube_code = include_str!(concat!(
2424
env!("CARGO_MANIFEST_DIR"),
25-
"/python/cube/src/conf/__init__.py"
25+
"/python/cube/src/__init__.py"
2626
));
27-
PyModule::from_code(py, cube_conf_code, "__init__.py", "cube.conf")?;
27+
PyModule::from_code(py, cube_code, "__init__.py", "cube")?;
2828

2929
let config_module = PyModule::from_code(py, &file_content_arg, &options_file_name, "")?;
3030
let settings_py = if config_module.hasattr("__execution_context_locals")? {

packages/cubejs-backend-native/test/config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from cube.conf import (
1+
from cube import (
22
config,
33
file_repository
44
)

packages/cubejs-backend-native/test/old-config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from cube.conf import (
1+
from cube import (
22
settings,
33
file_repository
44
)

packages/cubejs-backend-native/test/scoped-config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
source_code = """
2-
from cube.conf import (
2+
from cube import (
33
settings,
44
config
55
)

0 commit comments

Comments
 (0)