Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion customize/coldbrew_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@

# Controls whether to enable threading support.
# If you turn this off, the output size is smaller, but threading support will be gone.
ENABLE_THREADING = True
ENABLE_THREADING = False

######################################################################
### Internal Settings
Expand Down
Binary file added dist/coldbrew.data
Binary file not shown.
1 change: 1 addition & 0 deletions dist/coldbrew.js

Large diffs are not rendered by default.

Binary file added dist/coldbrew.wasm
Binary file not shown.
103 changes: 103 additions & 0 deletions dist/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<style type="text/css">
body {
width: 600px;
margin: 0 auto;
padding-top: 20px;
text-align: center;
font-family: Roboto, Avenir, Myriad Pro, Futura, "Helvetica Neue", Helvetica, Arial, sans-serif;
}

.pre-code {
padding: 5px 0;
}

.hide-true {
display: none;
}
</style>
</head>
<body>
<img src="images/coldbrew.png" alt="coldbrew" height="120">
<h1>Coldbrew: Run Python in JavaScript</h1>
<p>
Coldbrew is installed on this page through <a href="coldbrew.js"><code>coldbrew.js</code></a>.<br/><br/>Open the browser console and try running some of these examples in the console.<br/><br/>Start by loading Coldbrew with:
<div class="pre-code"></div>
<code>
Coldbrew.load().then(function() { console.log("Finished loading Coldbrew!") });
</code>
</p>
<hr />
<p>
Once loaded, you can interact with Python. For example, to print the version of Python run the following in the browser console:<br/>
<div class="pre-code"></div>
<code>
Coldbrew.run("import sys");<br/>
Coldbrew.run("print('The current Python version is:', sys.version)");
</code>
</p>
<hr />
<p>
You can also issue multiple commands in the same function call, to see this, run the following in the browser console:<br/>
<div class="pre-code"></div>
<code>
Coldbrew.run(["x = [i for i in range(10)]","print(x)"].join("\n"));
</code>
</p>
<hr />
<p>
You can run a Python file like <a href="https://github.com/plasticityai/coldbrew/blob/master/src/examples/add.py">add.py</a> with arguments and environment variables specified, to see this, run the following in the browser console:<br/>
<div class="pre-code"></div>
<code>
Coldbrew.runFile('add.py', {cwd:'/coldbrew/examples', env:{}, args:['5', '15', '-v']});
</code>
</p>
<hr />
<p class="hide-SMALL_BUT_NO_ASYNC">
You can access HTTP connections in Python and the requests will be handled by JavaScript's XHR / AJAX requests:<br/>
<div class="pre-code hide-SMALL_BUT_NO_ASYNC"></div>
<code class="hide-SMALL_BUT_NO_ASYNC">
Coldbrew.runAsync('import urllib.request; print(urllib.request.urlopen("http://localhost:8000/remote/example.txt").read())');
</code>
</p>
<hr class="hide-SMALL_BUT_NO_ASYNC"/>
<p class="hide-SMALL_BUT_NO_ASYNC">
You can export Python variables (objects, classes, functions, modules, primitives, etc.) and use them like a native JavaScript variable using Coldbrew's <a href="https://github.com/plasticityai/coldbrew#bridge-variables">bridge variables</a>, like, for example, the <a href="https://docs.python.org/3.1/library/collections.html#counter-objects">Counter</a> class:<br/>
<div class="pre-code hide-SMALL_BUT_NO_ASYNC"></div>
<code class="hide-SMALL_BUT_NO_ASYNC">
Coldbrew.run("from collections import Counter");<br/>
var Counter = Coldbrew.getVariable("Counter");<br/>
var c = new Counter(['red', 'blue', 'red', 'green', 'blue', 'blue']);<br/>
console.log(c.mostCommon(2));
</code>
</p>
<hr class="hide-SMALL_BUT_NO_ASYNC"/>
<p class="hide-SMALL_BUT_NO_ASYNC">
You can run Python code asynchronously, which won't lock up the browser for long-running code. <br/><br/>See the difference between running this:<br/>
<div class="pre-code hide-SMALL_BUT_NO_ASYNC"></div>
<code class="hide-SMALL_BUT_NO_ASYNC">
for(var i=0; i<5; i++) { setTimeout(function() { console.log("Every 1 second for 5 seconds from JavaScript.") }, (i+1)*1000); }<br/>
Coldbrew.<b>runAsync</b>('from time import sleep\nfor i in range(5):\n\tsleep(1)\n\tprint("Every 1 second for 5 seconds from Python.")');
</code>
<p class="hide-SMALL_BUT_NO_ASYNC">And this:</p>
<div class="pre-code hide-SMALL_BUT_NO_ASYNC"></div>
<code class="hide-SMALL_BUT_NO_ASYNC">
for(var i=0; i<5; i++) { setTimeout(function() { console.log("Every 1 second for 5 seconds from JavaScript.") }, (i+1)*1000); }<br/>
Coldbrew.<b>run</b>('from time import sleep\nfor i in range(5):\n\tsleep(1)\n\tprint("Every 1 second for 5 seconds from Python.")');
</code>
</p>
<hr class="hide-SMALL_BUT_NO_ASYNC"/>
<p>
See more documentation on <a href="https://github.com/plasticityai/coldbrew">GitHub</a> <br />for more information on interacting with the virtual filesystem, installing modules, interacting with the environment, running Python asynchronously, communicating bi-directionally between the two languages, building a custom Coldbrew Python environment, and more.
</p>

<script src='coldbrew.js'></script>
<script>
console.warn("Coldbrew is loading...");
Coldbrew.load({threadWorkers: 4});
</script>
</body>
</html>
2 changes: 1 addition & 1 deletion src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ FAST_AND_SMALL_BUT_NO_ASYNC=$(shell python -c "import sys; sys.path.append('../c

ASYNC_DEBUG ?= 0
ALWAYS_ASYNC_FUNCS='export_runAsync\nexport__runFileAsync\n_Coldbrew__sleep\n_coldbrew_yield_to_javascript\n_Coldbrew__run'
ASYNC_FUNCS='PyCFunction_Call\nPyObject_Call\nPyEval_EvalCode\nPyEval_EvalCodeEx\nPyEval_EvalFrame\nPyEval_EvalFrameEx\nPyImport_ExecCodeModule\nPyImport_ExecCodeModuleEx\nPyImport_ExecCodeModuleObject\nPyImport_ExecCodeModuleWithPathnames\nPyImport_ImportFrozenModule\nPyImport_ImportFrozenModuleObject\nPyRun_AnyFile\nPyRun_AnyFileEx\nPyRun_AnyFileExFlags\nPyRun_AnyFileFlags\nPyRun_File\nPyRun_FileEx\nPyRun_FileExFlags\nPyRun_FileFlags\nPyRun_InteractiveLoop\nPyRun_InteractiveLoopFlags\nPyRun_InteractiveOne\nPyRun_InteractiveOneFlags\nPyRun_InteractiveOneObject\nPyRun_SimpleFile\nPyRun_SimpleFileEx\nPyRun_SimpleFileExFlags\nPyRun_SimpleString\nPyRun_SimpleStringFlags\nPyRun_String\nPyRun_StringFlags\nPy_FrozenMain\nPy_Initialize\nPy_InitializeEx\nPy_Main\nPy_NewInterpreter\n_PyEval_EvalCodeWithName\n_PyGen_Finalize\n_PyGen_Send\n_Py_InitializeEx_Private\n_imp_init_frozen\nbuiltin___build_class__\nbuiltin_eval\nbuiltin_exec\ncoro_wrapper_close\ncoro_wrapper_iternext\ncoro_wrapper_send\ncoro_wrapper_throw\nfast_function\nframe_clear\nfunction_call\ngen_close\ngen_close_iter\ngen_iternext\ngen_send_ex\ngen_throw\nimport_init\nzipimporter_load_module\nPyFile_GetLine\nbuiltin_input\n_PyEval_EvalFrameDefault\nPyImport_ImportModuleLevelObject\n_PyObject_CallMethodIdObjArgs\nobject_vacall\n_PyFunction_Vectorcall\nfunction_code_fastcall\ncall_function\nPyVectorcall_Call\nmethod_vectorcall\ncfunction_call_varargs\n_PyObject_MakeTpCall\n_PyObject_FastCallDict\n_PyObject_Call_Prepend\nslot_tp_init\ntype_call\ncfunction_vectorcall_FASTCALL_KEYWORDS\nslot_tp_getattr_hook\nPyObject_CallFunctionObjArgs\nslot_tp_finalize\nsubtype_dealloc\nframe_dealloc\n_PyObject_GenericGetAttrWithDict\nproperty_descr_get\n_PyObject_FastCall_Prepend\nslot_mp_subscript\nPyObject_GetItem\ntupledealloc\n_PyObject_GetMethod\ncfunction_vectorcall_FASTCALL\ncfunction_vectorcall_O\nbuiltin_repr\nPyObject_Repr\nslot_tp_repr\nPyObject_SetAttr\nslot_tp_setattro\nbuiltin_next\nPyObject_SetItem\nslot_mp_ass_subscript\nPyObject_DelItem\nlist___init__\nlist_extend\nPyObject_LengthHint\nslot_sq_length\ndict_ass_sub\n_PyDict_DelItem_KnownHash\nslot_tp_call\nbuiltin_dir\nslot_sq_contains\nPyDict_SetItem\ninsertdict'
ASYNC_FUNCS='call_trampoline\ntrace_trampoline\n_PyEval_SetTrace\ncall_trace\ncall_trace_protected\nPyCFunction_Call\nPyObject_Call\nPyEval_EvalCode\nPyEval_EvalCodeEx\nPyEval_EvalFrame\nPyEval_EvalFrameEx\nPyImport_ExecCodeModule\nPyImport_ExecCodeModuleEx\nPyImport_ExecCodeModuleObject\nPyImport_ExecCodeModuleWithPathnames\nPyImport_ImportFrozenModule\nPyImport_ImportFrozenModuleObject\nPyRun_AnyFile\nPyRun_AnyFileEx\nPyRun_AnyFileExFlags\nPyRun_AnyFileFlags\nPyRun_File\nPyRun_FileEx\nPyRun_FileExFlags\nPyRun_FileFlags\nPyRun_InteractiveLoop\nPyRun_InteractiveLoopFlags\nPyRun_InteractiveOne\nPyRun_InteractiveOneFlags\nPyRun_InteractiveOneObject\nPyRun_SimpleFile\nPyRun_SimpleFileEx\nPyRun_SimpleFileExFlags\nPyRun_SimpleString\nPyRun_SimpleStringFlags\nPyRun_String\nPyRun_StringFlags\nPy_FrozenMain\nPy_Initialize\nPy_InitializeEx\nPy_Main\nPy_NewInterpreter\n_PyEval_EvalCodeWithName\n_PyGen_Finalize\n_PyGen_Send\n_Py_InitializeEx_Private\n_imp_init_frozen\nbuiltin___build_class__\nbuiltin_eval\nbuiltin_exec\ncoro_wrapper_close\ncoro_wrapper_iternext\ncoro_wrapper_send\ncoro_wrapper_throw\nfast_function\nframe_clear\nfunction_call\ngen_close\ngen_close_iter\ngen_iternext\ngen_send_ex\ngen_throw\nimport_init\nzipimporter_load_module\nPyFile_GetLine\nbuiltin_input\n_PyEval_EvalFrameDefault\nPyImport_ImportModuleLevelObject\n_PyObject_CallMethodIdObjArgs\nobject_vacall\n_PyFunction_Vectorcall\nfunction_code_fastcall\ncall_function\nPyVectorcall_Call\nmethod_vectorcall\ncfunction_call_varargs\n_PyObject_MakeTpCall\n_PyObject_FastCallDict\n_PyObject_Call_Prepend\nslot_tp_init\ntype_call\ncfunction_vectorcall_FASTCALL_KEYWORDS\nslot_tp_getattr_hook\nPyObject_CallFunctionObjArgs\nslot_tp_finalize\nsubtype_dealloc\nframe_dealloc\n_PyObject_GenericGetAttrWithDict\nproperty_descr_get\n_PyObject_FastCall_Prepend\nslot_mp_subscript\nPyObject_GetItem\ntupledealloc\n_PyObject_GetMethod\ncfunction_vectorcall_FASTCALL\ncfunction_vectorcall_O\nbuiltin_repr\nPyObject_Repr\nslot_tp_repr\nPyObject_SetAttr\nslot_tp_setattro\nbuiltin_next\nPyObject_SetItem\nslot_mp_ass_subscript\nPyObject_DelItem\nlist___init__\nlist_extend\nPyObject_LengthHint\nslot_sq_length\ndict_ass_sub\n_PyDict_DelItem_KnownHash\nslot_tp_call\nbuiltin_dir\nslot_sq_contains\nPyDict_SetItem\ninsertdict'
ASYNC_WHITELIST=$(shell (echo -n '["'; (echo $(ALWAYS_ASYNC_FUNCS); echo $(ASYNC_FUNCS)) | cat | sed -e ':a;N;$$!ba;s/\n/",\n"/g'; echo -n '"]') | sed -e ':a;N;$$!ba;s/\n"]/"]/g')

DEBUG_MODE=$(shell python -c "import sys; sys.path.append('../customize/'); from coldbrew_settings import *; print(str((DEBUG_MODE or bool(int('$(ASYNC_DEBUG)')))).lower())")
Expand Down