Add support to switch between deno and nodejs function executor
This commit is contained in:
14
app.py
14
app.py
@@ -46,7 +46,8 @@ app.register_blueprint(auth, url_prefix='/auth')
|
|||||||
|
|
||||||
# Swith to inter app routing, which results in speed up from ~400ms to ~270ms
|
# Swith to inter app routing, which results in speed up from ~400ms to ~270ms
|
||||||
# https://stackoverflow.com/questions/76886643/linking-two-not-exposed-dokku-apps
|
# https://stackoverflow.com/questions/76886643/linking-two-not-exposed-dokku-apps
|
||||||
API_URL = os.environ.get('API_URL', 'http://isolator.web:5000/execute') # 'https://isolator.peterstockings.com/execute' 'http://127.0.0.1:5000/execute'
|
NODE_API_URL = os.environ.get('NODE_API_URL', 'http://isolator.web:5000/execute')
|
||||||
|
DENO_API_URL = os.environ.get('DENO_API_URL', 'http://deno-isolator.web:5000/execute')
|
||||||
|
|
||||||
|
|
||||||
def map_isolator_response_to_flask_response(response):
|
def map_isolator_response_to_flask_response(response):
|
||||||
@@ -82,6 +83,9 @@ async def execute_code():
|
|||||||
try:
|
try:
|
||||||
# Extract code and convert request to a format acceptable by Node.js app
|
# Extract code and convert request to a format acceptable by Node.js app
|
||||||
code = request.json.get('code')
|
code = request.json.get('code')
|
||||||
|
runtime = request.json.get('runtime', 'node') # Default to node
|
||||||
|
api_url = DENO_API_URL if runtime == 'deno' else NODE_API_URL
|
||||||
|
|
||||||
request_obj = {
|
request_obj = {
|
||||||
'method': request.method,
|
'method': request.method,
|
||||||
'headers': dict(request.headers),
|
'headers': dict(request.headers),
|
||||||
@@ -92,9 +96,9 @@ async def execute_code():
|
|||||||
environment = request.json.get('environment_info')
|
environment = request.json.get('environment_info')
|
||||||
environment_json = json.loads(environment)
|
environment_json = json.loads(environment)
|
||||||
|
|
||||||
# Call the Node.js API asynchronously
|
# Call the selected isolator API asynchronously
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
async with session.post(API_URL, json={'code': code, 'request': request_obj, 'environment': environment_json, 'name': "anonymous"}) as response:
|
async with session.post(api_url, json={'code': code, 'request': request_obj, 'environment': environment_json, 'name': "anonymous"}) as response:
|
||||||
response_data = await response.json()
|
response_data = await response.json()
|
||||||
|
|
||||||
# check if playground=true is in the query string
|
# check if playground=true is in the query string
|
||||||
@@ -122,6 +126,7 @@ async def execute_http_function(user_id, function):
|
|||||||
|
|
||||||
code = http_function['script_content']
|
code = http_function['script_content']
|
||||||
environment_info = http_function['environment_info']
|
environment_info = http_function['environment_info']
|
||||||
|
runtime = http_function.get('runtime', 'node') # Default to node
|
||||||
|
|
||||||
# Ensure environment is a dictionary
|
# Ensure environment is a dictionary
|
||||||
if isinstance(environment_info, str) and environment_info:
|
if isinstance(environment_info, str) and environment_info:
|
||||||
@@ -176,8 +181,9 @@ async def execute_http_function(user_id, function):
|
|||||||
request_data['text'] = request.data.decode('utf-8')
|
request_data['text'] = request.data.decode('utf-8')
|
||||||
|
|
||||||
# Call the Node.js API asynchronously
|
# Call the Node.js API asynchronously
|
||||||
|
api_url = DENO_API_URL if runtime == 'deno' else NODE_API_URL
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
async with session.post(API_URL, json={'code': code, 'request': request_data, 'environment': environment, 'name': function_name}) as response:
|
async with session.post(api_url, json={'code': code, 'request': request_data, 'environment': environment, 'name': function_name}) as response:
|
||||||
response_data = await response.json()
|
response_data = await response.json()
|
||||||
|
|
||||||
db.update_http_function_environment_info_and_invoked_count(user_id, function_name, response_data['environment'])
|
db.update_http_function_environment_info_and_invoked_count(user_id, function_name, response_data['environment'])
|
||||||
|
|||||||
18
db.py
18
db.py
@@ -59,30 +59,30 @@ class DataBase():
|
|||||||
|
|
||||||
def get_http_functions_for_user(self, user_id):
|
def get_http_functions_for_user(self, user_id):
|
||||||
http_functions = self.execute(
|
http_functions = self.execute(
|
||||||
'SELECT id, user_id, NAME, script_content, invoked_count, environment_info, is_public, log_request, log_response, version_number FROM http_functions WHERE user_id=%s ORDER by id DESC', [user_id])
|
'SELECT id, user_id, NAME, script_content, invoked_count, environment_info, is_public, log_request, log_response, version_number, runtime FROM http_functions WHERE user_id=%s ORDER by id DESC', [user_id])
|
||||||
return http_functions
|
return http_functions
|
||||||
|
|
||||||
def get_http_function(self, user_id, name):
|
def get_http_function(self, user_id, name):
|
||||||
http_function = self.execute(
|
http_function = self.execute(
|
||||||
'SELECT id, user_id, NAME, script_content, invoked_count, environment_info, is_public, log_request, log_response, version_number, created_at FROM http_functions WHERE user_id=%s AND NAME=%s', [user_id, name], one=True)
|
'SELECT id, user_id, NAME, script_content, invoked_count, environment_info, is_public, log_request, log_response, version_number, created_at, runtime FROM http_functions WHERE user_id=%s AND NAME=%s', [user_id, name], one=True)
|
||||||
return http_function
|
return http_function
|
||||||
|
|
||||||
def get_http_function_by_id(self, user_id, http_function_id):
|
def get_http_function_by_id(self, user_id, http_function_id):
|
||||||
http_function = self.execute(
|
http_function = self.execute(
|
||||||
'SELECT id, user_id, NAME, script_content, invoked_count, environment_info, is_public, log_request, log_response, version_number, created_at FROM http_functions WHERE user_id=%s AND id=%s', [user_id, http_function_id], one=True)
|
'SELECT id, user_id, NAME, script_content, invoked_count, environment_info, is_public, log_request, log_response, version_number, created_at, runtime FROM http_functions WHERE user_id=%s AND id=%s', [user_id, http_function_id], one=True)
|
||||||
return http_function
|
return http_function
|
||||||
|
|
||||||
def create_new_http_function(self, user_id, name, script_content, environment_info, is_public, log_request, log_response):
|
def create_new_http_function(self, user_id, name, script_content, environment_info, is_public, log_request, log_response, runtime):
|
||||||
self.execute(
|
self.execute(
|
||||||
'INSERT INTO http_functions (user_id, NAME, script_content, environment_info, is_public, log_request, log_response) VALUES (%s, %s, %s, %s, %s, %s, %s)',
|
'INSERT INTO http_functions (user_id, NAME, script_content, environment_info, is_public, log_request, log_response, runtime) VALUES (%s, %s, %s, %s, %s, %s, %s, %s)',
|
||||||
[user_id, name, script_content, environment_info, is_public, log_request, log_response],
|
[user_id, name, script_content, environment_info, is_public, log_request, log_response, runtime],
|
||||||
commit=True
|
commit=True
|
||||||
)
|
)
|
||||||
|
|
||||||
def edit_http_function(self, user_id, function_id, name, script_content, environment_info, is_public, log_request, log_response):
|
def edit_http_function(self, user_id, function_id, name, script_content, environment_info, is_public, log_request, log_response, runtime):
|
||||||
updated_version = self.execute(
|
updated_version = self.execute(
|
||||||
'UPDATE http_functions SET NAME=%s, script_content=%s, environment_info=%s, is_public=%s, log_request=%s, log_response=%s WHERE user_id=%s AND id=%s RETURNING version_number',
|
'UPDATE http_functions SET NAME=%s, script_content=%s, environment_info=%s, is_public=%s, log_request=%s, log_response=%s, runtime=%s WHERE user_id=%s AND id=%s RETURNING version_number',
|
||||||
[name, script_content, environment_info, is_public, log_request, log_response, user_id, function_id],
|
[name, script_content, environment_info, is_public, log_request, log_response, runtime, user_id, function_id],
|
||||||
commit=True, one=True
|
commit=True, one=True
|
||||||
)
|
)
|
||||||
return updated_version
|
return updated_version
|
||||||
|
|||||||
@@ -105,8 +105,7 @@ http = Blueprint('http', __name__)
|
|||||||
@login_required
|
@login_required
|
||||||
def overview():
|
def overview():
|
||||||
user_id = current_user.id
|
user_id = current_user.id
|
||||||
http_functions = db.execute(
|
http_functions = db.get_http_functions_for_user(user_id)
|
||||||
'SELECT id, user_id, NAME, script_content, invoked_count, environment_info, is_public, log_request, log_response, version_number FROM http_functions WHERE user_id=%s ORDER by id DESC', [user_id])
|
|
||||||
http_functions = create_http_functions_view_model(http_functions)
|
http_functions = create_http_functions_view_model(http_functions)
|
||||||
if htmx:
|
if htmx:
|
||||||
return render_block(environment, "dashboard/http_functions/overview.html", "page", http_functions=http_functions)
|
return render_block(environment, "dashboard/http_functions/overview.html", "page", http_functions=http_functions)
|
||||||
@@ -128,12 +127,9 @@ def new():
|
|||||||
is_public = request.json.get('is_public')
|
is_public = request.json.get('is_public')
|
||||||
log_request = request.json.get('log_request')
|
log_request = request.json.get('log_request')
|
||||||
log_response = request.json.get('log_response')
|
log_response = request.json.get('log_response')
|
||||||
|
runtime = request.json.get('runtime', 'node')
|
||||||
|
|
||||||
db.execute(
|
db.create_new_http_function(user_id, name, script_content, environment_info, is_public, log_request, log_response, runtime)
|
||||||
'INSERT INTO http_functions (user_id, NAME, script_content, environment_info, is_public, log_request, log_response) VALUES (%s, %s, %s, %s, %s, %s, %s)',
|
|
||||||
[user_id, name, script_content, environment_info, is_public, log_request, log_response],
|
|
||||||
commit=True
|
|
||||||
)
|
|
||||||
|
|
||||||
return jsonify({
|
return jsonify({
|
||||||
"status": "success",
|
"status": "success",
|
||||||
@@ -155,12 +151,9 @@ def edit(function_id):
|
|||||||
is_public = request.json.get('is_public')
|
is_public = request.json.get('is_public')
|
||||||
log_request = request.json.get('log_request')
|
log_request = request.json.get('log_request')
|
||||||
log_response = request.json.get('log_response')
|
log_response = request.json.get('log_response')
|
||||||
|
runtime = request.json.get('runtime', 'node')
|
||||||
|
|
||||||
updated_version = db.execute(
|
updated_version = db.edit_http_function(user_id, function_id, name, script_content, environment_info, is_public, log_request, log_response, runtime)
|
||||||
'UPDATE http_functions SET NAME=%s, script_content=%s, environment_info=%s, is_public=%s, log_request=%s, log_response=%s WHERE user_id=%s AND id=%s RETURNING version_number',
|
|
||||||
[name, script_content, environment_info, is_public, log_request, log_response, user_id, function_id],
|
|
||||||
commit=True, one=True
|
|
||||||
)
|
|
||||||
|
|
||||||
return { "status": "success", "message": f'{name} updated' }
|
return { "status": "success", "message": f'{name} updated' }
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -184,9 +177,7 @@ def delete(function_id):
|
|||||||
@login_required
|
@login_required
|
||||||
def logs(function_id):
|
def logs(function_id):
|
||||||
user_id = current_user.id
|
user_id = current_user.id
|
||||||
http_function = db.execute(
|
http_function = db.get_http_function_by_id(user_id, function_id)
|
||||||
'SELECT id, user_id, NAME, script_content, invoked_count, environment_info, is_public, log_request, log_response, version_number, created_at FROM http_functions WHERE user_id=%s AND id=%s',
|
|
||||||
[user_id, function_id], one=True)
|
|
||||||
if not http_function:
|
if not http_function:
|
||||||
return jsonify({'error': 'Function not found'}), 404
|
return jsonify({'error': 'Function not found'}), 404
|
||||||
name = http_function['name']
|
name = http_function['name']
|
||||||
@@ -199,9 +190,7 @@ def logs(function_id):
|
|||||||
@login_required
|
@login_required
|
||||||
def client(function_id):
|
def client(function_id):
|
||||||
user_id = current_user.id
|
user_id = current_user.id
|
||||||
http_function = db.execute(
|
http_function = db.get_http_function_by_id(user_id, function_id)
|
||||||
'SELECT id, user_id, NAME, script_content, invoked_count, environment_info, is_public, log_request, log_response, version_number, created_at FROM http_functions WHERE user_id=%s AND id=%s',
|
|
||||||
[user_id, function_id], one=True)
|
|
||||||
if not http_function:
|
if not http_function:
|
||||||
return jsonify({'error': 'Function not found'}), 404
|
return jsonify({'error': 'Function not found'}), 404
|
||||||
|
|
||||||
@@ -265,6 +254,7 @@ def editor(function_id):
|
|||||||
'log_request': http_function['log_request'],
|
'log_request': http_function['log_request'],
|
||||||
'log_response': http_function['log_response'],
|
'log_response': http_function['log_response'],
|
||||||
'version_number': http_function['version_number'],
|
'version_number': http_function['version_number'],
|
||||||
|
'runtime': http_function.get('runtime', 'node'),
|
||||||
'user_id': user_id,
|
'user_id': user_id,
|
||||||
'function_id': function_id,
|
'function_id': function_id,
|
||||||
# Add new URLs for navigation
|
# Add new URLs for navigation
|
||||||
|
|||||||
@@ -152,10 +152,10 @@ timer = Blueprint('timer', __name__)
|
|||||||
@login_required
|
@login_required
|
||||||
def overview():
|
def overview():
|
||||||
timer_functions = db.execute("""
|
timer_functions = db.execute("""
|
||||||
SELECT id, name, code, environment, trigger_type,
|
SELECT id, name, code, environment, trigger_type,
|
||||||
frequency_minutes, run_date, next_run,
|
frequency_minutes, run_date, next_run,
|
||||||
last_run, enabled, invocation_count
|
last_run, enabled, invocation_count, runtime
|
||||||
FROM timer_functions
|
FROM timer_functions
|
||||||
WHERE user_id = %s
|
WHERE user_id = %s
|
||||||
ORDER BY id DESC
|
ORDER BY id DESC
|
||||||
""", [current_user.id])
|
""", [current_user.id])
|
||||||
@@ -182,6 +182,7 @@ def new():
|
|||||||
try:
|
try:
|
||||||
data = request.json
|
data = request.json
|
||||||
trigger_type = data.get('trigger_type')
|
trigger_type = data.get('trigger_type')
|
||||||
|
runtime = data.get('runtime', 'node')
|
||||||
|
|
||||||
# Validate trigger type
|
# Validate trigger type
|
||||||
if trigger_type not in ('interval', 'date'):
|
if trigger_type not in ('interval', 'date'):
|
||||||
@@ -202,9 +203,9 @@ def new():
|
|||||||
# Insert new timer function
|
# Insert new timer function
|
||||||
db.execute("""
|
db.execute("""
|
||||||
INSERT INTO timer_functions
|
INSERT INTO timer_functions
|
||||||
(name, code, environment, user_id, trigger_type,
|
(name, code, environment, user_id, trigger_type,
|
||||||
frequency_minutes, run_date, next_run, enabled)
|
frequency_minutes, run_date, next_run, enabled, runtime)
|
||||||
VALUES (%s, %s, %s::jsonb, %s, %s, %s, %s, %s, %s)
|
VALUES (%s, %s, %s::jsonb, %s, %s, %s, %s, %s, %s, %s)
|
||||||
RETURNING id
|
RETURNING id
|
||||||
""", [
|
""", [
|
||||||
data.get('name'),
|
data.get('name'),
|
||||||
@@ -215,7 +216,8 @@ def new():
|
|||||||
frequency_minutes if trigger_type == 'interval' else None,
|
frequency_minutes if trigger_type == 'interval' else None,
|
||||||
run_date if trigger_type == 'date' else None,
|
run_date if trigger_type == 'date' else None,
|
||||||
next_run,
|
next_run,
|
||||||
True
|
True,
|
||||||
|
runtime
|
||||||
],
|
],
|
||||||
commit=True)
|
commit=True)
|
||||||
|
|
||||||
@@ -236,10 +238,10 @@ def edit(function_id):
|
|||||||
if request.method == 'GET':
|
if request.method == 'GET':
|
||||||
# Fetch the timer function
|
# Fetch the timer function
|
||||||
timer_function = db.execute("""
|
timer_function = db.execute("""
|
||||||
SELECT id, name, code, environment, version_number, trigger_type,
|
SELECT id, name, code, environment, version_number, trigger_type,
|
||||||
frequency_minutes, run_date, next_run,
|
frequency_minutes, run_date, next_run,
|
||||||
last_run, enabled, invocation_count
|
last_run, enabled, invocation_count, runtime
|
||||||
FROM timer_functions
|
FROM timer_functions
|
||||||
WHERE id = %s AND user_id = %s
|
WHERE id = %s AND user_id = %s
|
||||||
""", [function_id, current_user.id], one=True)
|
""", [function_id, current_user.id], one=True)
|
||||||
|
|
||||||
@@ -254,7 +256,8 @@ def edit(function_id):
|
|||||||
|
|
||||||
args = {
|
args = {
|
||||||
'function_id': function_id,
|
'function_id': function_id,
|
||||||
'timer_function': timer_function
|
'timer_function': timer_function,
|
||||||
|
'runtime': timer_function.get('runtime', 'node')
|
||||||
}
|
}
|
||||||
|
|
||||||
if htmx:
|
if htmx:
|
||||||
@@ -265,6 +268,7 @@ def edit(function_id):
|
|||||||
try:
|
try:
|
||||||
data = request.json
|
data = request.json
|
||||||
trigger_type = data.get('trigger_type')
|
trigger_type = data.get('trigger_type')
|
||||||
|
runtime = data.get('runtime', 'node')
|
||||||
|
|
||||||
# Validate trigger type
|
# Validate trigger type
|
||||||
if trigger_type not in ('interval', 'date'):
|
if trigger_type not in ('interval', 'date'):
|
||||||
@@ -292,7 +296,8 @@ def edit(function_id):
|
|||||||
frequency_minutes = %s,
|
frequency_minutes = %s,
|
||||||
run_date = %s,
|
run_date = %s,
|
||||||
next_run = %s,
|
next_run = %s,
|
||||||
enabled = %s
|
enabled = %s,
|
||||||
|
runtime = %s
|
||||||
WHERE id = %s AND user_id = %s
|
WHERE id = %s AND user_id = %s
|
||||||
RETURNING id
|
RETURNING id
|
||||||
""", [
|
""", [
|
||||||
@@ -304,6 +309,7 @@ def edit(function_id):
|
|||||||
run_date if trigger_type == 'date' else None,
|
run_date if trigger_type == 'date' else None,
|
||||||
next_run,
|
next_run,
|
||||||
data.get('is_enabled', True), # Default to True if not provided
|
data.get('is_enabled', True), # Default to True if not provided
|
||||||
|
runtime,
|
||||||
function_id,
|
function_id,
|
||||||
current_user.id
|
current_user.id
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ const Editor = {
|
|||||||
this.isPublic = vnode.attrs.isPublic || false;
|
this.isPublic = vnode.attrs.isPublic || false;
|
||||||
this.logRequest = vnode.attrs.logRequest || false;
|
this.logRequest = vnode.attrs.logRequest || false;
|
||||||
this.logResponse = vnode.attrs.logResponse || false;
|
this.logResponse = vnode.attrs.logResponse || false;
|
||||||
|
this.runtime = vnode.attrs.runtime || "node"; // Add runtime
|
||||||
|
|
||||||
// Only controls whether the name/version is shown (left side of header),
|
// Only controls whether the name/version is shown (left side of header),
|
||||||
// but we still always show the Execute button on the right side.
|
// but we still always show the Execute button on the right side.
|
||||||
@@ -119,7 +120,11 @@ const Editor = {
|
|||||||
const resp = await fetch(this.executeUrl, {
|
const resp = await fetch(this.executeUrl, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: { "Content-Type": "application/json" },
|
||||||
body: JSON.stringify({ code, environment_info }),
|
body: JSON.stringify({
|
||||||
|
code,
|
||||||
|
environment_info,
|
||||||
|
runtime: this.runtime,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
if (!resp.ok) {
|
if (!resp.ok) {
|
||||||
throw new Error(`HTTP error! status: ${resp.status}`);
|
throw new Error(`HTTP error! status: ${resp.status}`);
|
||||||
@@ -149,6 +154,7 @@ const Editor = {
|
|||||||
is_public: this.isPublic,
|
is_public: this.isPublic,
|
||||||
log_request: this.logRequest,
|
log_request: this.logRequest,
|
||||||
log_response: this.logResponse,
|
log_response: this.logResponse,
|
||||||
|
runtime: this.runtime,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create payload based on whether this is a timer function
|
// Create payload based on whether this is a timer function
|
||||||
@@ -172,6 +178,7 @@ const Editor = {
|
|||||||
is_public: this.isPublic,
|
is_public: this.isPublic,
|
||||||
log_request: this.logRequest,
|
log_request: this.logRequest,
|
||||||
log_response: this.logResponse,
|
log_response: this.logResponse,
|
||||||
|
runtime: this.runtime,
|
||||||
};
|
};
|
||||||
|
|
||||||
const response = await m.request({
|
const response = await m.request({
|
||||||
@@ -513,6 +520,39 @@ const Editor = {
|
|||||||
m("div", { class: "flex flex-col space-y-4" }, [
|
m("div", { class: "flex flex-col space-y-4" }, [
|
||||||
// Toggles group
|
// Toggles group
|
||||||
m("div", { class: "flex flex-wrap gap-6" }, [
|
m("div", { class: "flex flex-wrap gap-6" }, [
|
||||||
|
// Runtime dropdown
|
||||||
|
m("div", { class: "flex flex-col" }, [
|
||||||
|
m(
|
||||||
|
"label",
|
||||||
|
{
|
||||||
|
for: "runtime-select",
|
||||||
|
class: "mb-2 text-sm font-medium",
|
||||||
|
},
|
||||||
|
"Runtime"
|
||||||
|
),
|
||||||
|
m(
|
||||||
|
"select",
|
||||||
|
{
|
||||||
|
id: "runtime-select",
|
||||||
|
class:
|
||||||
|
"bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500",
|
||||||
|
onchange: (e) => (this.runtime = e.target.value),
|
||||||
|
},
|
||||||
|
[
|
||||||
|
m(
|
||||||
|
"option",
|
||||||
|
{ value: "node", selected: this.runtime === "node" },
|
||||||
|
"Node.js"
|
||||||
|
),
|
||||||
|
m(
|
||||||
|
"option",
|
||||||
|
{ value: "deno", selected: this.runtime === "deno" },
|
||||||
|
"Deno"
|
||||||
|
),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
|
||||||
// Public/Private toggle
|
// Public/Private toggle
|
||||||
this.showPublicToggle &&
|
this.showPublicToggle &&
|
||||||
m(
|
m(
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ history_url=url_for('http.history', function_id=function_id)) }}
|
|||||||
logRequest: {{ log_request | tojson }},
|
logRequest: {{ log_request | tojson }},
|
||||||
logResponse: {{ log_response | tojson }},
|
logResponse: {{ log_response | tojson }},
|
||||||
versionNumber: {{ version_number }},
|
versionNumber: {{ version_number }},
|
||||||
|
runtime: '{{ runtime }}',
|
||||||
executeUrl: "{{ url_for('execute_code', playground='true') }}",
|
executeUrl: "{{ url_for('execute_code', playground='true') }}",
|
||||||
saveUrl: "{{ url_for('http.edit', function_id=id) if id else url_for('http.new') }}",
|
saveUrl: "{{ url_for('http.edit', function_id=id) if id else url_for('http.new') }}",
|
||||||
deleteUrl: "{{ url_for('http.delete', function_id=id) if id else '' }}",
|
deleteUrl: "{{ url_for('http.delete', function_id=id) if id else '' }}",
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ history_url=url_for('timer.history', function_id=function_id)) }}
|
|||||||
isEdit: true,
|
isEdit: true,
|
||||||
showHeader: true,
|
showHeader: true,
|
||||||
versionNumber: {{ timer_function.version_number }},
|
versionNumber: {{ timer_function.version_number }},
|
||||||
|
runtime: '{{ runtime }}',
|
||||||
isEnabled: {{ timer_function.enabled | tojson }},
|
isEnabled: {{ timer_function.enabled | tojson }},
|
||||||
executeUrl: "{{ url_for('execute_code', playground='true') }}",
|
executeUrl: "{{ url_for('execute_code', playground='true') }}",
|
||||||
saveUrl: "{{ url_for('timer.edit', function_id=function_id) }}",
|
saveUrl: "{{ url_for('timer.edit', function_id=function_id) }}",
|
||||||
|
|||||||
Reference in New Issue
Block a user