# <py-config> Use the `` tag to set and configure general metadata along with declaring dependencies for your PyScript application. The configuration has to be set in either [TOML](https://toml.io/)(default) or [JSON](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/JSON) format. If you are unfamiliar with TOML, consider [reading about it](https://learnxinyminutes.com/docs/toml/) or if you are unfamiliar with JSON, consider reading [freecodecamp's JSON for beginners](https://www.freecodecamp.org/news/what-is-json-a-json-file-example/) guide for more information. The `` element should be placed within the `` element. ## Attributes | attribute | type | default | description | |-----------|--------|---------|----------------------------------------------------------------------------------------------------------| | **type** | string | "toml" | Syntax type of the ``. Value can be `json` or `toml`. Default: "toml" if type is unspecified. | | **src** | url | | Source url to an external configuration file. | ## Examples ### Defining an inline config - `` using TOML (default) ```{note} Reminder: when using TOML, any Arrays of Tables defined with double-brackets (like `[[interpreters]]` and `[[fetch]]` must come after individual keys (like `plugins = ...` and `packages=...`) ``` ```html [splashscreen] autoclose = true [[interpreters]] src = "https://cdn.jsdelivr.net/pyodide/v0.21.2/full/pyodide.js" name = "pyodide-0.21.2" lang = "python" ``` - `` using JSON via `type` attribute ```html { "splashscreen": { "autoclose": true }, "interpreters": [{ "src": "https://cdn.jsdelivr.net/pyodide/v0.21.2/full/pyodide.js", "name": "pyodide-0.21.2", "lang": "python" }] } ``` ### Defining a file based config - Use of the `src` attribute ```html ``` where `custom.toml` contains ```toml [splashscreen] autoclose = true [[interpreters]] src = "https://cdn.jsdelivr.net/pyodide/v0.21.2/full/pyodide.js" name = "pyodide-0.21.2" lang = "python" ``` - JSON using the `type` and `src` attribute ```html ``` where `custom.json` contains ```json { "splashscreen": { "autoclose": true, }, "interpreters": [{ "src": "https://cdn.jsdelivr.net/pyodide/v0.21.2/full/pyodide.js", "name": "pyodide-0.21.2", "lang": "python" }] } ``` ### Mixing inline and file based configs One can also use both i.e pass the config from `src` attribute as well as specify it as `inline`. So the following snippet is also valid: ```html [[fetch]] files = ["./utils.py"] ``` This can also be done via JSON using the `type` attribute. ```html { "fetch": [{ "files": ["./utils.py"] }] } ``` Note: While the `` tag supports both TOML and JSON, one cannot mix the type of config passed from 2 different sources i.e. the case when inline config is in TOML format while config from src is in JSON format is NOT allowed. Similarly for the opposite case. --- This is helpful in cases where a number of applications share a common configuration (which can be supplied via `src`), but their specific keys need to be customised and overridden. The keys supplied through `inline` override the values present in config supplied via `src`. ## Dependencies and Packages One can also declare dependencies so as to get access to many 3rd party OSS packages that are supported by PyScript. You can also link to `.whl` files directly on disk like in our [toga example](https://github.com/pyscript/pyscript/blob/main/examples/toga/freedom.html). Package dependencies in the `` can be declared by using the direct link to the package URL (whl or any other format supported by the chosen interpreter) or by just providing the package name [and version]. If only the name [and version] are provided, packages will be installed directly from what's provided by your interpreter or from PyPI. NOTICE that only pure python packages from PyPI will work and packages with C dependencies will not. These need to be built specifically for WASM (please, consult the Pyodide project for more information about what's supported and on how to build packages with C dependencies) ```html packages = ["./static/wheels/travertino-0.1.3-py3-none-any.whl"] ``` OR in JSON like ```html { "packages": ["./static/wheels/travertino-0.1.3-py3-none-any.whl"] } ``` If your `.whl` is not a pure Python wheel, then open a PR or issue with [pyodide](https://github.com/pyodide/pyodide) to get it added [here](https://github.com/pyodide/pyodide/tree/main/packages). If there's enough popular demand, the pyodide team will likely work on supporting your package. Regardless, things will likely move faster if you make the PR and consult with the team to get unblocked. For example, NumPy and Matplotlib are available. Notice here we're using `display(fig, target="plot")`, which takes the graph and displays it in the element with the id `plot`. ```html

Let's plot random numbers

{ "packages": ["numpy", "matplotlib"] } import matplotlib.pyplot as plt import numpy as np x = np.random.randn(1000) y = np.random.randn(1000) fig, ax = plt.subplots() ax.scatter(x, y) display(fig, target="plot") ``` ## Local modules In addition to packages, you can declare local Python modules that will be imported in the `` tag. For example, we can place the random number generation steps in a function in the file `data.py`. ```python # data.py import numpy as np def make_x_and_y(n): x = np.random.randn(n) y = np.random.randn(n) return x, y ``` In the HTML tag ``, paths to local modules are provided in the `files` key within the `fetch` section. Refer to the [fetch](#fetch) section for more details. ```html

Let's plot random numbers

packages = ["numpy", "matplotlib"] [[fetch]] files = ["./data.py"] import matplotlib.pyplot as plt from data import make_x_and_y x, y = make_x_and_y(n=1000) fig, ax = plt.subplots() ax.scatter(x, y) display(fig, target="plot") ``` ## Supported configuration values The following optional values are supported by ``: | Value | Type | Description | | ------ | ---- | ----------- | | `name` | string | Name of the user application. This field can be any string and is to be used by the application author for their own customization purposes. | | `description` | string | Description of the user application. This field can be any string and is to be used by the application author for their own customization purposes. | | `version` | string | Version of the user application. This field can be any string and is to be used by the application author for their own customization purposes. It is not related to the PyScript version. | | `schema_version` | number | The version of the config schema which determines what all keys are supported. This can be supplied by the user so PyScript knows what to expect in the config. If not supplied, the latest version for the schema is automatically used. | | `type` | string | Type of the project. The default is an "app" i.e. a user application | | `author_name` | string | Name of the author. | | `author_email` | string | Email of the author. | | `license` | string | License to be used for the user application. | | `autoclose_loader` | boolean | If false, PyScript will not close the loading splash screen when the startup operations finish. | | `packages` | List of Packages | Dependencies on 3rd party OSS packages are specified here. The default value is an empty list. | | `fetch` | List of Stuff to fetch | Local Python modules OR resources from the internet are to be specified here using a Fetch Configuration, described below. The default value is an empty list. | | `plugins` | List of Plugins | List of Plugins are to be specified here. The default value is an empty list. | | `interpreters` | List of Interpreters| List of Interpreter configurations, described below. The default value contains a single Pyodide based interpreter. **Note:** Currently, only a single interpreter is supported. | | `runtimes` {bdg-warning-line}`Deprecated` | List of Runtimes | This value is deprecated, please use `interpreters`. List of runtime configurations, described below. The default value contains a single Pyodide based interpreter. | ### Fetch A fetch configuration consists of the following: | Value | Type | Description | |--------------|-----------------|-------------------------------------------------| | `from` | string | Base URL for the resource to be fetched. | | `to_folder` | string | Name of the folder to create in the filesystem. | | `to_file` | string | Name of the target to create in the filesystem. | | `files` | List of strings | List of files to be downloaded. | The parameters `to_file` and `files` shouldn't be supplied together. #### Mechanism The `fetch` mechanism works in the following manner: - If both `files` and `to_file` parameters are supplied: Error! - `from` defaults to an empty string i.e. `""` to denote relative URLs of the serving directory - `to_folder` defaults to `.` i.e. the current working directory of the filesystem - If `files` is specified - for each `file` present in the `files` array - the `sourcePath` is calculated as `from + file` - the `destination` is calculated as `to_folder + file` - thus, the object is downloaded from `sourcePath` to `destination` - Else i.e. `files` is NOT specified - If `to_file` is specified - the object is downloaded from `from` to `to_folder + to_file` - Otherwise, calculate the `filename` at the end of `from` i.e. the part after last `/` - the object is downloaded from `from` to `to_folder + filename at the end of 'from'` Learn more about `fetch` on PyScript [here](https://jeff.glass/post/whats-new-pyscript-2022-12-1) #### Use-Cases Assumptions: The directory being served has the following tree structure: ``` content/ ├─ index.html <<< File with ├─ info.txt ├─ data/ │ ├─ sensordata.csv ├─ packages/ │ ├─ my_package/ │ │ ├─ __init__.py │ │ ├─ helloworld/ │ │ │ ├─ __init__.py │ │ │ ├─ greetings.py ``` 1. Fetching a single file ```html [[fetch]] files = ['info.txt'] ``` ```html with open('info.txt', 'r') as fp: print(fp.read()) ``` 2. Single File with Renaming ```html [[fetch]] from = 'info.txt' to_file = 'info_loaded_from_web.txt' ``` ```html with open('info_loaded_from_web.txt', 'r') as fp: print(fp.read()) ``` 3. Single File to another Directory ```html [[fetch]] files = ['info.txt'] to_folder = 'infofiles/loaded_info' ``` ```html with open('infofiles/loaded_info/info.txt', 'r') as fp: print(fp.read()) ``` 4. Single File to another Directory with Renaming ```html [[fetch]] from = 'info.txt' to_folder = 'infofiles/loaded_info' to_file = 'info_loaded_from_web.txt' ``` ```html with open('infofiles/loaded_info/info_loaded_from_web.txt', 'r') as fp: print(fp.read()) ``` 5. Single file from a folder to the current working directory ```html [[fetch]] from = 'data/' files = ['sensordata.csv'] ``` ```html with open('./sensordata.csv', 'r') as fp: print(fp.read()) ``` 6. Single file from a folder to another folder (i.e. not the current working directory) ```html [[fetch]] from = 'data/' to_folder = './local_data' files = ['sensordata.csv'] ``` ```html with open('./local_data/sensordata.csv', 'r') as fp: print(fp.read()) ``` 7. Multiple files preserving directory structure ```html [[fetch]] from = 'packages/my_package/' files = ['__init__.py', 'helloworld/greetings.py', 'helloworld/__init__.py'] to_folder = 'custom_pkg' ``` ```html from custom_pkg.helloworld.greetings import say_hi print(say_hi()) ``` 8. From an API endpoint which doesn't end in a filename ```html [[fetch]] from = 'https://catfact.ninja/fact' to_file = './cat_fact.json' ``` ```html import json with open("cat_fact.json", "r") as fp: data = json.load(fp) ``` ### Interpreter An interpreter configuration consists of the following: | Value | Type | Description | |--------|-------------------|-------------| | `src` | string (Required) | URL to the interpreter source. | | `name` | string | Name of the interpreter. This field can be any string and is to be used by the application author for their own customization purposes | | `lang` | string | Programming language supported by the interpreter. This field can be used by the application author to provide clarification. It currently has no implications on how PyScript behaves. | #### Example - The default interpreter is `pyodide`, another version of which can be specified as following ```html [[interpreters]] src = "https://cdn.jsdelivr.net/pyodide/v0.20.0/full/pyodide.js" name = "pyodide-0.20.0" lang = "python" ``` ```{note} Currently, PyScript supports a single interpreter, this may change in the future. ``` ## Supplying extra information (or metadata) Besides the above schema, a user can also supply any extra keys and values that are relevant as metadata information or perhaps are being used within the application. For example, a valid config could also be with the snippet below: ```html magic = "unicorn" ``` OR in JSON like ```html { "magic": "unicorn" } ``` If this `"magic"` key is present in config supplied via `src` and also present in config supplied via `inline`, then the value in the inline config is given priority i.e. the overriding process also works for custom keys.