{"id":19066014,"url":"https://github.com/metapages/metaframe-py","last_synced_at":"2026-04-29T14:33:55.925Z","repository":{"id":206708197,"uuid":"716738282","full_name":"metapages/metaframe-py","owner":"metapages","description":"Python metaframe via pyiodide","archived":false,"fork":false,"pushed_at":"2023-11-11T20:47:41.000Z","size":1290,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-02T14:25:22.632Z","etag":null,"topics":["metaframe","pyodide","python"],"latest_commit_sha":null,"homepage":"https://py.mtfm.io","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/metapages.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-11-09T19:10:41.000Z","updated_at":"2024-02-06T15:39:36.000Z","dependencies_parsed_at":null,"dependency_job_id":"7547aa74-68d6-4c79-a9d0-e869fce36e12","html_url":"https://github.com/metapages/metaframe-py","commit_stats":null,"previous_names":["metapages/metaframe-py"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metapages%2Fmetaframe-py","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metapages%2Fmetaframe-py/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metapages%2Fmetaframe-py/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metapages%2Fmetaframe-py/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/metapages","download_url":"https://codeload.github.com/metapages/metaframe-py/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240118421,"owners_count":19750491,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["metaframe","pyodide","python"],"created_at":"2024-11-09T00:54:00.148Z","updated_at":"2026-04-29T14:33:50.889Z","avatar_url":"https://github.com/metapages.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Python [metaframe](https://docs.metapage.io/docs) (via pyiodide)\n\n```mermaid\ngraph LR\n    classDef mpColor fill:#87d0ff,stroke:#87d0ff,stroke-width:2px;\n    subgraph metapage\n    direction LR\n        left1(upstream metaframe) --\u003e|inputs| M(python code):::mpColor\n        M --\u003e |outputs| right1(downstream metaframe)\n    end\n\n```\n\nExamples:\n - [create matplotlib plots](https://app.metapages.org/#?definition=JTdCJTIybWV0YSUyMiUzQSU3QiUyMmxheW91dHMlMjIlM0ElN0IlMjJyZWFjdC1ncmlkLWxheW91dCUyMiUzQSU3QiUyMmRvY3MlMjIlM0ElMjJodHRwcyUzQSUyRiUyRnd3dy5ucG1qcy5jb20lMkZwYWNrYWdlJTJGcmVhY3QtZ3JpZC1sYXlvdXQlMjIlMkMlMjJsYXlvdXQlMjIlM0ElNUIlN0IlMjJoJTIyJTNBMyUyQyUyMmklMjIlM0ElMjJpbWFnZTElMjIlMkMlMjJtb3ZlZCUyMiUzQWZhbHNlJTJDJTIyc3RhdGljJTIyJTNBZmFsc2UlMkMlMjJ3JTIyJTNBMTIlMkMlMjJ4JTIyJTNBMCUyQyUyMnklMjIlM0EyJTdEJTJDJTdCJTIyaCUyMiUzQTUlMkMlMjJpJTIyJTNBJTIyaW1hZ2UyJTIyJTJDJTIybW92ZWQlMjIlM0FmYWxzZSUyQyUyMnN0YXRpYyUyMiUzQWZhbHNlJTJDJTIydyUyMiUzQTEyJTJDJTIyeCUyMiUzQTAlMkMlMjJ5JTIyJTNBNSU3RCUyQyU3QiUyMmglMjIlM0EyJTJDJTIyaSUyMiUzQSUyMnB5aW9kaWRlLWRldiUyMiUyQyUyMm1vdmVkJTIyJTNBZmFsc2UlMkMlMjJzdGF0aWMlMjIlM0FmYWxzZSUyQyUyMnclMjIlM0ExMiUyQyUyMnglMjIlM0EwJTJDJTIyeSUyMiUzQTAlN0QlNUQlMkMlMjJwcm9wcyUyMiUzQSU3QiUyMmNvbHMlMjIlM0ExMiUyQyUyMmNvbnRhaW5lclBhZGRpbmclMjIlM0ElNUI1JTJDNSU1RCUyQyUyMm1hcmdpbiUyMiUzQSU1QjEwJTJDMjAlNUQlMkMlMjJyb3dIZWlnaHQlMjIlM0ExMDAlN0QlN0QlN0QlMkMlMjJuYW1lJTIyJTNBJTIyQSUyMG5ldyUyMGtpbmQlMjBvZiUyMHB1Ymxpc2hpbmclMjAtJTIwc2VsZi1jb250YWluZWQlMjBVUkxTJTIyJTdEJTJDJTIybWV0YWZyYW1lcyUyMiUzQSU3QiUyMmltYWdlMSUyMiUzQSU3QiUyMmlucHV0cyUyMiUzQSU1QiU3QiUyMm1ldGFmcmFtZSUyMiUzQSUyMnB5aW9kaWRlLWRldiUyMiUyQyUyMnNvdXJjZSUyMiUzQSUyMmltYWdlMSUyMiUyQyUyMnRhcmdldCUyMiUzQSUyMmltYWdlMSUyMiU3RCU1RCUyQyUyMnVybCUyMiUzQSUyMmh0dHBzJTNBJTJGJTJGanMubXRmbS5pbyUyRiUyMyUzRmVkaXQlM0QxJTI2anMlM0RZMjl1YzNRbE1qQnliMjkwSlRJd0pUTkVKVEl3Wkc5amRXMWxiblF1WjJWMFJXeGxiV1Z1ZEVKNVNXUW9KVEl5Y205dmRDVXlNaWtsTUVFbE1FRjJZWElsTWpCdmJrbHVjSFYwY3lVeU1DVXpSQ1V5TUdsdWNIVjBjeVV5TUNVelJDVXpSU1V5TUNVM1FpVXdRU1V5TUNVeU1DVXlNQ1V5TUdOdmJuTjBKVEl3YXlVeU1DVXpSQ1V5TUU5aWFtVmpkQzVyWlhsektHbHVjSFYwY3lrbE5VSXdKVFZFSlROQ0pUQkJKVEl3SlRJd0pUSXdKVEl3YVdZbE1qQW9JU2hySlRJd0pUSTJKVEkySlRJd2FXNXdkWFJ6SlRWQ2F5VTFSQ2twSlRJd0pUZENKVEJCSlRJd0pUSXdKVEl3SlRJd0pUSXdKVEl3SlRJd0pUSXdjbVYwZFhKdUpUTkNKVEJCSlRJd0pUSXdKVEl3SlRJd0pUZEVKVEJCSlRJd0pUSXdKVEl3SlRJd1kyOXVjM1FsTWpCMkpUSXdKVE5FSlRJd2FXNXdkWFJ6SlRWQ2F5VTFSQ1V3UVNVeU1DVXlNQ1V5TUNVeU1IWmhjaVV5TUdsdFlXZGxKVEl3SlRORUpUSXdaRzlqZFcxbGJuUXVZM0psWVhSbFJXeGxiV1Z1ZENnbmFXMW5KeWtsTTBJbE1FRWxNRGxwYldGblpTNXpjbU1sTWpBbE0wUWxNakIwZVhCbGIyWW9kaWtsTWpBbE0wUWxNMFFsTTBRbE1qQWxNakp6ZEhKcGJtY2xNaklsTWpBbE1qWWxNallsTWpCMkxuTjBZWEowYzFkcGRHZ29KVEl5WkdGMFlTVXpRV2x0WVdkbEpUSXlLU1V5TUNVelJpVXlNSFlsTWpBbE0wRWxNakJWVWt3dVkzSmxZWFJsVDJKcVpXTjBWVkpNS0hZcEpUTkNKVEJCSlRJd0pUSXdKVEl3SlRJd2QyaHBiR1VsTWpBb2NtOXZkQzVtYVhKemRFTm9hV3hrS1NVeU1DVTNRaVV3UVNVeU1DVXlNQ1V5TUNVeU1DVXlNQ1V5TUNVeU1DVXlNSEp2YjNRdWNtVnRiM1psUTJocGJHUW9jbTl2ZEM1c1lYTjBRMmhwYkdRcEpUTkNKVEJCSlRJd0pUSXdKVEl3SlRJd0pUZEVKVEJCSlRJd0pUSXdKVEl3SlRJd2NtOXZkQzVoY0hCbGJtUkRhR2xzWkNocGJXRm5aU2tsTTBJbE1FRWxOMFFsTUVFbE1FRnZia2x1Y0hWMGN5aHRaWFJoWm5KaGJXVXVaMlYwU1c1d2RYUnpLQ2twSlRCQkpUQkJZMjl1YzNRbE1qQmthWE53YjNObEpUSXdKVE5FSlRJd2JXVjBZV1p5WVcxbExtOXVTVzV3ZFhSektHOXVTVzV3ZFhSektTVXdRWGRwYm1SdmR5NXpZM0pwY0hSVmJteHZZV1FsTWpBbE0wUWxNakFvS1NVeU1DVXpSQ1V6UlNVeU1DVTNRaVV3UVNVd09XUnBjM0J2YzJVb0tTVXdRU1UzUkElM0QlM0QlMjZtb2R1bGVzJTNESlRWQ0pUVkUlMjIlN0QlMkMlMjJpbWFnZTIlMjIlM0ElN0IlMjJpbnB1dHMlMjIlM0ElNUIlN0IlMjJtZXRhZnJhbWUlMjIlM0ElMjJweWlvZGlkZS1kZXYlMjIlMkMlMjJzb3VyY2UlMjIlM0ElMjJpbWFnZTIlMjIlMkMlMjJ0YXJnZXQlMjIlM0ElMjJpbWFnZTIlMjIlN0QlNUQlMkMlMjJ1cmwlMjIlM0ElMjJodHRwcyUzQSUyRiUyRmpzLm10Zm0uaW8lMkYlMjMlM0ZlZGl0JTNEMSUyNmpzJTNEWTI5dWMzUWxNakJ5YjI5MEpUSXdKVE5FSlRJd1pHOWpkVzFsYm5RdVoyVjBSV3hsYldWdWRFSjVTV1FvSlRJeWNtOXZkQ1V5TWlrbE1FRWxNRUYyWVhJbE1qQnZia2x1Y0hWMGN5VXlNQ1V6UkNVeU1HbHVjSFYwY3lVeU1DVXpSQ1V6UlNVeU1DVTNRaVV3UVNVeU1DVXlNQ1V5TUNVeU1HTnZibk4wSlRJd2F5VXlNQ1V6UkNVeU1FOWlhbVZqZEM1clpYbHpLR2x1Y0hWMGN5a2xOVUl3SlRWRUpUTkNKVEJCSlRJd0pUSXdKVEl3SlRJd2FXWWxNakFvSVNockpUSXdKVEkySlRJMkpUSXdhVzV3ZFhSekpUVkNheVUxUkNrcEpUSXdKVGRDSlRCQkpUSXdKVEl3SlRJd0pUSXdKVEl3SlRJd0pUSXdKVEl3Y21WMGRYSnVKVE5DSlRCQkpUSXdKVEl3SlRJd0pUSXdKVGRFSlRCQkpUSXdKVEl3SlRJd0pUSXdZMjl1YzNRbE1qQjJKVEl3SlRORUpUSXdhVzV3ZFhSekpUVkNheVUxUkNVd1FTVXlNQ1V5TUNVeU1DVXlNSFpoY2lVeU1HbHRZV2RsSlRJd0pUTkVKVEl3Wkc5amRXMWxiblF1WTNKbFlYUmxSV3hsYldWdWRDZ25hVzFuSnlrbE0wSWxNRUVsTURscGJXRm5aUzV6Y21NbE1qQWxNMFFsTWpCMGVYQmxiMllvZGlrbE1qQWxNMFFsTTBRbE0wUWxNakFsTWpKemRISnBibWNsTWpJbE1qQWxNallsTWpZbE1qQjJMbk4wWVhKMGMxZHBkR2dvSlRJeVpHRjBZU1V6UVdsdFlXZGxKVEl5S1NVeU1DVXpSaVV5TUhZbE1qQWxNMEVsTWpCVlVrd3VZM0psWVhSbFQySnFaV04wVlZKTUtIWXBKVE5DSlRCQkpUSXdKVEl3SlRJd0pUSXdkMmhwYkdVbE1qQW9jbTl2ZEM1bWFYSnpkRU5vYVd4a0tTVXlNQ1UzUWlVd1FTVXlNQ1V5TUNVeU1DVXlNQ1V5TUNVeU1DVXlNQ1V5TUhKdmIzUXVjbVZ0YjNabFEyaHBiR1FvY205dmRDNXNZWE4wUTJocGJHUXBKVE5DSlRCQkpUSXdKVEl3SlRJd0pUSXdKVGRFSlRCQkpUSXdKVEl3SlRJd0pUSXdjbTl2ZEM1aGNIQmxibVJEYUdsc1pDaHBiV0ZuWlNrbE0wSWxNRUVsTjBRbE1FRWxNRUZ2YmtsdWNIVjBjeWh0WlhSaFpuSmhiV1V1WjJWMFNXNXdkWFJ6S0NrcEpUQkJKVEJCWTI5dWMzUWxNakJrYVhOd2IzTmxKVEl3SlRORUpUSXdiV1YwWVdaeVlXMWxMbTl1U1c1d2RYUnpLRzl1U1c1d2RYUnpLU1V3UVhkcGJtUnZkeTV6WTNKcGNIUlZibXh2WVdRbE1qQWxNMFFsTWpBb0tTVXlNQ1V6UkNVelJTVXlNQ1UzUWlVd1FTVXdPV1JwYzNCdmMyVW9LU1V3UVNVM1JBJTNEJTNEJTI2bW9kdWxlcyUzREpUVkNKVFZFJTIyJTdEJTJDJTIycHlpb2RpZGUtZGV2JTIyJTNBJTdCJTIyaW5wdXRzJTIyJTNBJTVCJTdCJTIybWV0YWZyYW1lJTIyJTNBJTIyaW5wdXQlMjIlMkMlMjJzb3VyY2UlMjIlM0ElMjJ0ZXh0JTIyJTJDJTIydGFyZ2V0JTIyJTNBJTIydGV4dCUyMiU3RCUyQyU3QiUyMm1ldGFmcmFtZSUyMiUzQSUyMmdlbmVyYXRlLWlucHV0cyUyMiUyQyUyMnNvdXJjZSUyMiUzQSUyMiolMjIlMkMlMjJ0YXJnZXQlMjIlM0ElMjIqJTIyJTdEJTVEJTJDJTIydXJsJTIyJTNBJTIyaHR0cHMlM0ElMkYlMkZweS5tdGZtLmlvJTJGJTIzJTNGZWRpdCUzRDElMjZvcHRpb25zJTNESlRkQ0pUSXljaVV5TWlVelFYUnlkV1VsTjBRJTNEJTI2cHklM0RhVzF3YjNKMEpUSXdjSGx2Wkdsa1pTVXdRV2x0Y0c5eWRDVXlNRzFwWTNKdmNHbHdKVEJCWm5KdmJTVXlNR3B6SlRJd2FXMXdiM0owSlRJd2JXVjBZV1p5WVcxbEpUSkRKVEl3Ykc5bkpUQkJKVEJCWVhkaGFYUWxNakJ0YVdOeWIzQnBjQzVwYm5OMFlXeHNLQ1V5TW0xaGRIQnNiM1JzYVdJbE1qSXBKVEJCWVhkaGFYUWxNakJ0YVdOeWIzQnBjQzVwYm5OMFlXeHNLQ1V5TW01MWJYQjVKVEl5S1NVd1FTVXdRV2x0Y0c5eWRDVXlNRzFoZEhCc2IzUnNhV0l1Y0hsd2JHOTBKVEl3WVhNbE1qQndiSFFsTUVGcGJYQnZjblFsTWpCcGJ5VXlReVV5TUdKaGMyVTJOQ1V3UVdsdGNHOXlkQ1V5TUc1MWJYQjVKVEl3WVhNbE1qQnVjQ1V3UVNVd1FXeHZaeWdsTWpKUWVYUm9iMjRsTWpCemRHRnlkR1ZrSlRKREpUSXdZMjl0Y0hWMGFXNW5KVEl3Y0d4dmRITXVMaTRsTWpJcEpUQkJKVEJCYm5BdWNtRnVaRzl0TG5ObFpXUW9NVGsyT0RBNE1ERXBKVEl3SlRJd0pUSXpKVEl3YzJWbFpDVXlNSFJvWlNVeU1ISmhibVJ2YlNVeU1HNTFiV0psY2lVeU1HZGxibVZ5WVhSdmNpNGxNRUZrWVhSaEpUSXdKVE5FSlRJd0pUZENKMkVuSlROQkpUSXdibkF1WVhKaGJtZGxLRFV3S1NVeVF5VXdRU1V5TUNVeU1DVXlNQ1V5TUNVeU1DVXlNQ1V5TUNVeU1DZGpKeVV6UVNVeU1HNXdMbkpoYm1SdmJTNXlZVzVrYVc1MEtEQWxNa01sTWpBMU1DVXlReVV5TURVd0tTVXlReVV3UVNVeU1DVXlNQ1V5TUNVeU1DVXlNQ1V5TUNVeU1DVXlNQ2RrSnlVelFTVXlNRzV3TG5KaGJtUnZiUzV5WVc1a2JpZzFNQ2tsTjBRbE1FRmtZWFJoSlRWQ0oySW5KVFZFSlRJd0pUTkVKVEl3WkdGMFlTVTFRaWRoSnlVMVJDVXlNQ1V5UWlVeU1ERXdKVEl3S2lVeU1HNXdMbkpoYm1SdmJTNXlZVzVrYmlnMU1Da2xNRUZrWVhSaEpUVkNKMlFuSlRWRUpUSXdKVE5FSlRJd2JuQXVZV0p6S0dSaGRHRWxOVUluWkNjbE5VUXBKVEl3S2lVeU1ERXdNQ1V3UVNVd1FXWnBaeVV5UXlVeU1HRjRKVEl3SlRORUpUSXdjR3gwTG5OMVluQnNiM1J6S0dacFozTnBlbVVsTTBRb05TVXlReVV5TURJdU55a2xNa01sTWpCc1lYbHZkWFFsTTBRblkyOXVjM1J5WVdsdVpXUW5LU1V3UVdGNExuTmpZWFIwWlhJb0oyRW5KVEpESlRJd0oySW5KVEpESlRJd1l5VXpSQ2RqSnlVeVF5VXlNSE1sTTBRblpDY2xNa01sTWpCa1lYUmhKVE5FWkdGMFlTa2xNRUZoZUM1elpYUmZlR3hoWW1Wc0tDZGxiblJ5ZVNVeU1HRW5LU1V3UVdGNExuTmxkRjk1YkdGaVpXd29KMlZ1ZEhKNUpUSXdZaWNwSlRCQkpUQkJZblZtSlRJd0pUTkVKVEl3YVc4dVFubDBaWE5KVHlncEpUQkJabWxuTG5OaGRtVm1hV2NvWW5WbUpUSkRKVEl3Wm05eWJXRjBKVE5FSjNCdVp5Y3BKVEJCWW5WbUxuTmxaV3NvTUNrbE1FRnBiV2RmYzNSeUpUSXdKVE5FSlRJd0oyUmhkR0VsTTBGcGJXRm5aU1V5Um5CdVp5VXpRbUpoYzJVMk5DVXlReWNsTWpBbE1rSWxNakJpWVhObE5qUXVZalkwWlc1amIyUmxLR0oxWmk1eVpXRmtLQ2twTG1SbFkyOWtaU2duVlZSR0xUZ25LU1V3UVd4dlp5Z2xNakpUWlc1MEpUSXdhVzFoWjJVeElTVXlNaWtsTUVGdFpYUmhabkpoYldVdWMyVjBUM1YwY0hWMEtDVXlNbWx0WVdkbE1TVXlNaVV5UXlVeU1HbHRaMTl6ZEhJcEpUQkJKVEJCSlRCQlptbG5KVEpESlRJd1lYZ2xNakFsTTBRbE1qQndiSFF1YzNWaWNHeHZkSE1vS1NVd1FXRjRMbkJzYjNRb0pUVkNNU1V5UXpNbE1rTXlKVFZFS1NVd1FXSjFaaVV5TUNVelJDVXlNR2x2TGtKNWRHVnpTVThvS1NVd1FXWnBaeTV6WVhabFptbG5LR0oxWmlVeVF5VXlNR1p2Y20xaGRDVXpSQ2R3Ym1jbktTVXdRV0oxWmk1elpXVnJLREFwSlRCQmFXMW5YM04wY2lVeU1DVXpSQ1V5TUNka1lYUmhKVE5CYVcxaFoyVWxNa1p3Ym1jbE0wSmlZWE5sTmpRbE1rTW5KVEl3SlRKQ0pUSXdZbUZ6WlRZMExtSTJOR1Z1WTI5a1pTaGlkV1l1Y21WaFpDZ3BLUzVrWldOdlpHVW9KMVZVUmkwNEp5a2xNRUZzYjJjb0pUSXlVMlZ1ZENVeU1HbHRZV2RsTWlFbE1qSXBKVEJCYldWMFlXWnlZVzFsTG5ObGRFOTFkSEIxZENnbE1qSnBiV0ZuWlRJbE1qSWxNa01sTWpCcGJXZGZjM1J5S1ElM0QlM0QlMjIlN0QlN0QlMkMlMjJwbHVnaW5zJTIyJTNBJTVCJTIyaHR0cHMlM0ElMkYlMkZtZXJtYWlkLm10Zm0uaW8lMkYlMjMlM0ZobSUzRGRpc2FibGVkJTIyJTJDJTIyaHR0cHMlM0ElMkYlMkZlZGl0b3IubXRmbS5pbyUyRiUyMyUzRmhtJTNEZGlzYWJsZWQlMjZvcHRpb25zJTNESlRkQ0pUSXliVzlrWlNVeU1pVXpRU1V5TW1wemIyNGxNaklsTWtNbE1qSnpZWFpsYkc5aFpHbHVhR0Z6YUNVeU1pVXpRWFJ5ZFdVbE1rTWxNakowYUdWdFpTVXlNaVV6UVNVeU1uWnpMV1JoY21zbE1qSWxOMFElM0QlMjIlNUQlMkMlMjJ2ZXJzaW9uJTIyJTNBJTIyMC4zJTIyJTdE)\n - [inputs/outputs](https://app.metapage.io/dion/py.mtfm.io-test/view) \n\n\n - Run python code entire in the browser, and connect to other metaframes\n - Edit python code directly in the frame\n - All code and configuration is stored in the URL\n   - shareable and durable\n\n## Configuration + Inputs/Outputs\n\nThere are two (metaframe) modes (set in ⚙️ Options):\n\n1. `✅ Re-run python code on new inputs`: Anytime new metaframe inputs arrive, restart the script. Any files in `/outputs` are copied and send as metaframe outputs. If the file suffix is recognized (e.g. `.js`, `.json`, `.py`) then it will be sent as a string (or directly as JSON if ending in `.json`), otherwise it will be send as an ArrayBuffer.\n   - Inputs **are** copied as files\n2. `❌ Re-run python code on new inputs`: Run the script once, the script is responsible for listening to inputs by calling the metaframe object (see examples below).\n   - Inputs are **not** copied as files \n  \nThe use case of copying inputs and outputs as files but **not* re-running seems counterintuitive to me, let me know if you have this use case: https://github.com/metapages/metaframe-py/issues\n\n## Useful code snippets\n\n### Get the (current) metaframe inputs\n\n```python\nfrom js import metaframe\n\ninputs = metaframe.getInputs().as_object_map()\n\nfor key in inputs:\n    print(key)\n    print(inputs[key])\n    # Do something with the value\n```\n\n### Listen to new metaframe inputs\n\n```python\nfrom pyodide.ffi import create_proxy\nfrom js import metaframe\n\ndef onInputs(*args):\n    print('got inputs in python:')\n    inputs = args[0].as_object_map()\n    for key in inputs:\n      print(key)\n\nonInputsProxy = create_proxy(onInputs) \ndisposer = metaframe.onInputs(onInputsProxy)\n# Call the disposer via the scriptUnload described next below\n\n```\n\n### Unload/cleanup/dispose\n\nWhen iterating/editing, the python script is repeatedly run in the `pyiodide` object. This can cause problems if proxied `js \u003c-\u003e python` objects are not properly disposed.\n\nBefore every new python script execution, (in javascript) if a `window.scriptUnload` script exists, it is called. This is where you put your cleanup:\n\n```python\nfrom pyodide.ffi import create_proxy\nfrom js import window\n\n# Put this at the end of your script:\ndef scriptUnload(*args):\n    print('unloading from python')\n    # Call your cleanup code here\nproxy_scriptUnload = create_proxy(scriptUnload)\nwindow.scriptUnload = proxy_scriptUnload\n```\n\n### Logging to the main div\n\nSome convenience functions:\n\n```py\n\n# log is the same as logStderr \nfrom js import log, logStdout, logStderr\n\n# These functions only take a single string, no fancy formatting or multiple arguments\nlog(\"some string\")\nlogStdout(\"some string\")\nlogStderr(\"some error\")\n```\n\n## Advanced\n\n- Testing, input/outputs, capabilities, development metapage: \n  - https://app.metapage.io/dion/py.mtfm.io-test/view\n- Example metapage running python with inputs and outputs and plotting:\n  - https://app.metapage.io/dion/py.mtfm.io-example-01\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmetapages%2Fmetaframe-py","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmetapages%2Fmetaframe-py","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmetapages%2Fmetaframe-py/lists"}