# Frequently Asked Questions (FAQ) ## How can I load external Python files in Pyodide? The two possible solutions are, - include these files in a Python package, build a pure Python wheel with `python setup.py bdist_wheel` and {ref}`load it with micropip `. - fetch the Python code as a string and evaluate it in Python, ```js pyodide.runPython(await fetch('https://some_url/...')) ``` In both cases, files need to be served with a web server and cannot be loaded from local file system. ## Why can't I load files from the local file system? For security reasons Javascript in the browser is not allowed to load local data files. You need to serve them with a web-browser. Recently there is a [Native File System API](https://wicg.github.io/file-system-access/) supported in Chrome but not in Firefox. [There is a discussion about implementing it for Firefox here.](https://github.com/mozilla/standards-positions/issues/154) ## How can I change the behavior of {any}`runPython ` and {any}`runPythonAsync `? The definitions of {any}`runPython ` and {any}`runPythonAsync ` are very simple: ```javascript function runPython(code){ pyodide.pyodide_py.eval_code(code, pyodide.globals); } ``` ```javascript async function runPythonAsync(code, messageCallback, errorCallback) { await pyodide.loadPackagesFromImports(code, messageCallback, errorCallback); return pyodide.runPython(code); }; ``` To make your own version of {any}`runPython `: ```pyodide pyodide.runPython(` import pyodide def my_eval_code(code, ns): extra_info = None result = pyodide.eval_code(code, ns) return ns["extra_info"], result] `) function myRunPython(code){ return pyodide.globals.get("my_eval_code")(code, pyodide.globals); } function myAsyncRunPython(code){ await pyodide.loadPackagesFromImports(code, messageCallback, errorCallback); return pyodide.myRunPython(code, pyodide.globals); } ``` Then `pyodide.myRunPython("2+7")` returns `[None, 9]` and `pyodide.myRunPython("extra_info='hello' ; 2 + 2")` returns `['hello', 4]`. If you want to change which packages {any}`pyodide.loadPackagesFromImports` loads, you can monkey patch {any}`pyodide.find_imports` which takes `code` as an argument and returns a list of packages imported. ## How can I execute code in a custom namespace? The second argument to {any}`pyodide.eval_code` is a global namespace to execute the code in. The namespace is a Python dictionary. ```javascript let my_namespace = pyodide.globals.dict(); pyodide.pyodide_py.eval_code(`x = 1 + 1`, my_namespace); pyodide.pyodide_py.eval_code(`y = x ** x`, my_namespace); my_namespace.y; // ==> 4 ``` This effectively runs the code in "module scope". Like the [Python `eval` function](https://docs.python.org/3/library/functions.html?highlight=eval#eval) you can provide a third argument to `eval_code` to specify a separate `locals` dict to run code in "function scope". ## How to detect that code is run with Pyodide? **At run time**, you can detect that a code is running with Pyodide using, ```py import sys if "pyodide" in sys.modules: # running in Pyodide ``` More generally you can detect Python built with Emscripten (which includes Pyodide) with, ```py import platform if platform.system() == 'Emscripten': # running in Pyodide or other Emscripten based build ``` This however will not work at build time (i.e. in a `setup.py`) due to the way the Pyodide build system works. It first compiles packages with the host compiler (e.g. gcc) and then re-runs the compilation commands with emsdk. So the `setup.py` is never run inside the Pyodide environement. To detect Pyodide, **at build time** use, ```python import os if "PYODIDE" in os.environ: # building for Pyodide ``` We used to use the environment variable `PYODIDE_BASE_URL` for this purpose, but this usage is deprecated. ## How do I create custom Python packages from Javascript? Put a collection of functions into a Javascript object and use {any}`pyodide.registerJsModule`: Javascript: ```javascript let my_module = { f : function(x){ return x*x + 1; }, g : function(x){ console.log(`Calling g on argument ${x}`); return x; }, submodule : { h : function(x) { return x*x - 1; }, c : 2, }, }; pyodide.registerJsModule("my_js_module", my_module); ``` You can import your package like a normal Python package: ```py import my_js_module from my_js_module.submodule import h, c assert my_js_module.f(7) == 50 assert h(9) == 80 assert c == 2 ```