{"id":22144023,"url":"https://github.com/pytask-dev/pytask-r","last_synced_at":"2025-10-03T21:15:00.436Z","repository":{"id":40558890,"uuid":"281623822","full_name":"pytask-dev/pytask-r","owner":"pytask-dev","description":"Run R scripts with pytask.","archived":false,"fork":false,"pushed_at":"2025-08-25T17:58:35.000Z","size":254,"stargazers_count":6,"open_issues_count":6,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-08-25T19:35:54.258Z","etag":null,"topics":["pytask"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pytask-dev.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","contributing":null,"funding":null,"license":"LICENSE","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,"zenodo":null}},"created_at":"2020-07-22T08:44:46.000Z","updated_at":"2025-07-26T11:16:44.000Z","dependencies_parsed_at":"2024-02-19T20:36:41.374Z","dependency_job_id":"bd700963-7df1-40d4-88ad-4c119b5f661c","html_url":"https://github.com/pytask-dev/pytask-r","commit_stats":{"total_commits":41,"total_committers":2,"mean_commits":20.5,"dds":0.3414634146341463,"last_synced_commit":"8c3fdaef4b03ae7990280704fa4d738147aadd0e"},"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"purl":"pkg:github/pytask-dev/pytask-r","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pytask-dev%2Fpytask-r","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pytask-dev%2Fpytask-r/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pytask-dev%2Fpytask-r/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pytask-dev%2Fpytask-r/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pytask-dev","download_url":"https://codeload.github.com/pytask-dev/pytask-r/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pytask-dev%2Fpytask-r/sbom","scorecard":{"id":752053,"data":{"date":"2025-08-11","repo":{"name":"github.com/pytask-dev/pytask-r","commit":"e4a37d48769b9ee7eda225054659bcaf30257629"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.6,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/16 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":1,"reason":"2 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 1","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: jobLevel 'contents' permission set to 'write': .github/workflows/publish-to-pypi.yml:60","Warn: no topLevel permission defined: .github/workflows/main.yml:1","Warn: no topLevel permission defined: .github/workflows/publish-to-pypi.yml:1"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yml:24: update your workflow using https://app.stepsecurity.io/secureworkflow/pytask-dev/pytask-r/main.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/main.yml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/pytask-dev/pytask-r/main.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yml:44: update your workflow using https://app.stepsecurity.io/secureworkflow/pytask-dev/pytask-r/main.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/main.yml:45: update your workflow using https://app.stepsecurity.io/secureworkflow/pytask-dev/pytask-r/main.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/main.yml:58: update your workflow using https://app.stepsecurity.io/secureworkflow/pytask-dev/pytask-r/main.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/main.yml:67: update your workflow using https://app.stepsecurity.io/secureworkflow/pytask-dev/pytask-r/main.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/publish-to-pypi.yml:11: update your workflow using https://app.stepsecurity.io/secureworkflow/pytask-dev/pytask-r/publish-to-pypi.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/publish-to-pypi.yml:13: update your workflow using https://app.stepsecurity.io/secureworkflow/pytask-dev/pytask-r/publish-to-pypi.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/publish-to-pypi.yml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/pytask-dev/pytask-r/publish-to-pypi.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/publish-to-pypi.yml:44: update your workflow using https://app.stepsecurity.io/secureworkflow/pytask-dev/pytask-r/publish-to-pypi.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/publish-to-pypi.yml:49: update your workflow using https://app.stepsecurity.io/secureworkflow/pytask-dev/pytask-r/publish-to-pypi.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/publish-to-pypi.yml:65: update your workflow using https://app.stepsecurity.io/secureworkflow/pytask-dev/pytask-r/publish-to-pypi.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/publish-to-pypi.yml:70: update your workflow using https://app.stepsecurity.io/secureworkflow/pytask-dev/pytask-r/publish-to-pypi.yml/main?enable=pin","Warn: pipCommand not pinned by hash: .github/workflows/publish-to-pypi.yml:18","Info:   0 out of   7 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   6 third-party GitHubAction dependencies pinned","Info:   0 out of   1 pipCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":8,"reason":"1 out of the last 1 releases have a total of 1 signed artifacts.","details":["Info: signed release artifact: pytask_r-0.4.1-py3-none-any.whl.sigstore: https://github.com/pytask-dev/pytask-r/releases/tag/v0.4.1","Warn: release artifact v0.4.1 does not have provenance: https://api.github.com/repos/pytask-dev/pytask-r/releases/152036387"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/publish-to-pypi.yml:30"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 30 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-22T20:38:55.860Z","repository_id":40558890,"created_at":"2025-08-22T20:38:55.860Z","updated_at":"2025-08-22T20:38:55.860Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278228285,"owners_count":25952074,"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","status":"online","status_checked_at":"2025-10-03T02:00:06.070Z","response_time":53,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["pytask"],"created_at":"2024-12-01T22:18:06.660Z","updated_at":"2025-10-03T21:15:00.408Z","avatar_url":"https://github.com/pytask-dev.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pytask-r\n\n[![PyPI](https://img.shields.io/pypi/v/pytask-r?color=blue)](https://pypi.org/project/pytask-r)\n[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/pytask-r)](https://pypi.org/project/pytask-r)\n[![image](https://img.shields.io/conda/vn/conda-forge/pytask-r.svg)](https://anaconda.org/conda-forge/pytask-r)\n[![image](https://img.shields.io/conda/pn/conda-forge/pytask-r.svg)](https://anaconda.org/conda-forge/pytask-r)\n[![PyPI - License](https://img.shields.io/pypi/l/pytask-r)](https://pypi.org/project/pytask-r)\n[![image](https://img.shields.io/github/actions/workflow/status/pytask-dev/pytask-r/main.yml?branch=main)](https://github.com/pytask-dev/pytask-r/actions?query=branch%3Amain)\n[![image](https://codecov.io/gh/pytask-dev/pytask-r/branch/main/graph/badge.svg)](https://codecov.io/gh/pytask-dev/pytask-r)\n[![pre-commit.ci status](https://results.pre-commit.ci/badge/github/pytask-dev/pytask-r/main.svg)](https://results.pre-commit.ci/latest/github/pytask-dev/pytask-r/main)\n[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)\n\n______________________________________________________________________\n\nRun R scripts with pytask.\n\n## Installation\n\npytask-r is available on [PyPI](https://pypi.org/project/pytask-r) and\n[Anaconda.org](https://anaconda.org/conda-forge/pytask-r). Install it with\n\n```console\n$ pip install pytask-r\n\n# or\n\n$ conda install -c conda-forge pytask-r\n```\n\nYou also need to have R installed and `Rscript` on your command line. Test it by typing\nthe following on the command line\n\n```console\nRscript --help\n```\n\nIf an error is shown instead of a help page, you can install R with `conda`.\n\n```console\nconda install -c conda-forge r-base\n```\n\nOr install install R from the official [R Project](https://www.r-project.org/).\n\n## Usage\n\nTo create a task that runs an R script, define a task function with the `@mark.r`\ndecorator. The `script` keyword provides an absolute path or a path relative to the task\nmodule.\n\n```python\nfrom pathlib import Path\nfrom pytask import mark\n\n\n@mark.r(script=Path(\"script.r\"))\ndef task_run_r_script(produces: Path = Path(\"out.rds\")):\n    pass\n```\n\nIf you are wondering why the function body is empty, know that pytask-r replaces the\nbody with a predefined internal function. See the section on implementation details for\nmore information.\n\n### Dependencies and Products\n\nDependencies and products can be added as usual. See this\n[tutorial](https://pytask-dev.readthedocs.io/en/stable/tutorials/defining_dependencies_products.html)\nfor some help.\n\n### Accessing dependencies and products in the script\n\nTo access the paths of dependencies and products in the script, pytask-r stores the\ninformation by default in a `.json` file. The path to this file is passed as a\npositional argument to the script. Inside the script, you can read the information.\n\n```r\nlibrary(jsonlite)\n\nargs \u003c- commandArgs(trailingOnly=TRUE)\n\npath_to_json \u003c- args[length(args)]\n\nconfig \u003c- read_json(path_to_json)\n\nconfig$produces  # Is the path to the output file \"../out.csv\".\n```\n\nThe `.json` file is stored in the same folder as the task in a `.pytask` directory.\n\nTo parse the JSON file, you need to install\n[jsonlite](https://github.com/jeroen/jsonlite).\n\nYou can also pass any other information to your script by using the `@task` decorator.\n\n```python\nfrom pathlib import Path\nfrom pytask import mark, task\n\n\n@task(kwargs={\"number\": 1})\n@mark.r(script=Path(\"script.r\"))\ndef task_run_r_script(produces: Path = Path(\"out.rds\")):\n    pass\n```\n\nand inside the script use\n\n```r\nconfig$number  # Is 1.\n```\n\n### Debugging\n\nIn case a task throws an error, you might want to execute the script independently from\npytask. After a failed execution, you see the command that executed the R script in the\nreport of the task. It looks roughly like this\n\n```console\nRscript \u003coptions\u003e script.r \u003cpath-to\u003e/.pytask/pytask-r/\u003cuuid4\u003e.json\n```\n\n### Command Line Arguments\n\nThe decorator can be used to pass command line arguments to `Rscript`. See the following\nexample.\n\n```python\n@mark.r(script=Path(\"script.r\"), options=\"--vanilla\")\ndef task_run_r_script(produces: Path = Path(\"out.rds\")):\n    pass\n```\n\n### Repeating tasks with different scripts or inputs\n\nYou can also repeat the execution of tasks, meaning executing multiple R scripts or\npassing different command line arguments to the same R script.\n\nThe following task executes two R scripts, `script_1.r` and `script_2.r`, which produce\ndifferent outputs.\n\n```python\nfor i in range(2):\n\n    @task\n    @mark.r(script=Path(f\"script_{i}.r\"))\n    def task_execute_r_script(produces: Path = Path(f\"out_{i}.csv\")):\n        pass\n```\n\nIf you want to pass different inputs to the same R script, pass these arguments with the\n`kwargs` keyword of the `@task` decorator.\n\n```python\nfor i in range(2):\n\n    @task(kwargs={\"i\": i})\n    @mark.r(script=Path(\"script.r\"))\n    def task_execute_r_script(produces: Path = Path(f\"output_{i}.csv\")):\n        pass\n```\n\nand inside the task access the argument `i` with\n\n```r\nlibrary(jsonlite)\n\nargs \u003c- commandArgs(trailingOnly=TRUE)\n\npath_to_json \u003c- args[length(args)]\n\nconfig \u003c- read_json(path_to_json)\n\nconfig$produces  # Is the path to the output file \"../output_{i}.csv\".\n\nconfig$i  # Is the number.\n```\n\n### Serializers\n\nYou can also serialize your data with any other tool you like. By default, pytask-r also\nsupports YAML (if PyYaml is installed).\n\nUse the `serializer` keyword arguments of the `@pytask.mark.r` decorator with\n\n```python\n@mark.r(script=Path(\"script.r\"), serializer=\"yaml\")\ndef task_example(): ...\n```\n\nAnd, in your R script use\n\n```r\nlibrary(yaml)\nargs \u003c- commandArgs(trailingOnly=TRUE)\nconfig \u003c- read_yaml(args[length(args)])\n```\n\nNote that the `YAML` package needs to be installed.\n\nIf you need a custom serializer, you can also provide any callable `serializer` which\ntransforms data into a string. Use `suffix` to set the correct file ending.\n\nHere is a replication of the JSON example.\n\n```python\nimport json\n\n\n@mark.r(script=Path(\"script.r\"), serializer=json.dumps, suffix=\".json\")\ndef task_example(): ...\n```\n\n### Configuration\n\nYou can influence the default behavior of pytask-r with configuration values.\n\n**`r_serializer`**\n\nUse this option to change the default serializer.\n\n```toml\n[tool.pytask.ini_options]\nr_serializer = \"json\"\n```\n\n**`r_suffix`**\n\nUse this option to set the default suffix of the file which contains serialized paths to\ndependencies, products and more.\n\n```toml\n[tool.pytask.ini_options]\nr_suffix = \".json\"\n```\n\n**`r_options`**\n\nUse this option to set default options for each task which are separated by whitespace.\n\n```toml\n[tool.pytask.ini_options]\nr_options = [\"--vanilla\"]\n```\n\n## Changes\n\nConsult the [release notes](CHANGES.md) to find out about what is new.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpytask-dev%2Fpytask-r","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpytask-dev%2Fpytask-r","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpytask-dev%2Fpytask-r/lists"}