Skip to content

Commit ddcec25

Browse files
committed
use more quickjs.Function
1 parent 230d6dc commit ddcec25

1 file changed

Lines changed: 13 additions & 35 deletions

File tree

sdks/python/apache_beam/yaml/yaml_mapping.py

Lines changed: 13 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -183,35 +183,26 @@ def _check_mapping_arguments(
183183
_THREAD_LOCAL_JS_CACHE = threading.local()
184184

185185

186-
class _JsWrapper:
186+
class _JsFunctionWrapper:
187187
def __init__(self, source_code, entrypoint_name):
188188
self.source_code = source_code
189189
self.entrypoint_name = entrypoint_name
190190

191-
def _get_wrapper_fn(self):
191+
def _get_fn(self):
192192
cache = _THREAD_LOCAL_JS_CACHE
193193
if not hasattr(cache, 'functions'):
194194
cache.functions = {}
195195

196196
cache_key = (self.source_code, self.entrypoint_name)
197197
if cache_key not in cache.functions:
198-
ctx = quickjs.Context()
199-
ctx.eval(self.source_code)
200-
cache.functions[cache_key] = ctx.get(self.entrypoint_name)
198+
cache.functions[cache_key] = quickjs.Function(
199+
self.entrypoint_name, self.source_code)
201200

202201
return cache.functions[cache_key]
203202

204203
def __call__(self, row):
205-
wrapper_fn = self._get_wrapper_fn()
206-
row_as_dict = py_value_to_js_dict(row)
207-
try:
208-
js_result = wrapper_fn(json.dumps(row_as_dict))
209-
except Exception as exn:
210-
raise RuntimeError(
211-
f"Error evaluating javascript expression: {exn}") from exn
212-
if hasattr(js_result, 'json'):
213-
js_result = json.loads(js_result.json())
214-
return dicts_to_rows(js_result)
204+
fn = self._get_fn()
205+
return dicts_to_rows(fn(py_value_to_js_dict(row)))
215206

216207

217208
# TODO(yaml) Improve type inferencing for JS UDF's
@@ -249,43 +240,30 @@ def _expand_javascript_mapping_func(
249240
if name in expression and name.isidentifier()
250241
])
251242
source_code = f"""
252-
const udf = function(__row__) {{
243+
function udf(__row__) {{
253244
{unpacking_code}
254245
return ({expression});
255-
}};
256-
function wrapper(json_str) {{
257-
return udf(JSON.parse(json_str));
258246
}}
259247
"""
260-
entrypoint = 'wrapper'
248+
entrypoint = 'udf'
261249

262250
elif callable:
263251
match = re.search(r'(?:async\s+)?function\s+([a-zA-Z0-9_]+)', callable)
264252
if not match:
265253
raise ValueError(
266254
f"Could not find function declaration in callable: {callable}")
267255
udf_name = match.group(1)
268-
source_code = f"""
269-
{callable}
270-
function wrapper(json_str) {{
271-
return {udf_name}(JSON.parse(json_str));
272-
}}
273-
"""
274-
entrypoint = 'wrapper'
256+
source_code = callable
257+
entrypoint = udf_name
275258

276259
else:
277260
if not path.endswith('.js'):
278261
raise ValueError(f'File "{path}" is not a valid .js file.')
279262
udf_code = FileSystems.open(path).read().decode()
280-
source_code = f"""
281-
{udf_code}
282-
function wrapper(json_str) {{
283-
return {name}(JSON.parse(json_str));
284-
}}
285-
"""
286-
entrypoint = 'wrapper'
263+
source_code = udf_code
264+
entrypoint = name
287265

288-
return _JsWrapper(source_code, entrypoint)
266+
return _JsFunctionWrapper(source_code, entrypoint)
289267

290268

291269
def _expand_python_mapping_func(

0 commit comments

Comments
 (0)