{"id":18976847,"url":"https://github.com/yxonic/fret","last_synced_at":"2025-04-19T17:18:42.777Z","repository":{"id":56600263,"uuid":"160633252","full_name":"yxonic/fret","owner":"yxonic","description":"Framework for Reproducible ExperimenTs","archived":false,"fork":false,"pushed_at":"2022-04-06T13:50:35.000Z","size":225,"stargazers_count":20,"open_issues_count":0,"forks_count":3,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-29T10:43:39.904Z","etag":null,"topics":["cli","configuration-management","deep-learning","framework","machine-learning","python3","reproducible-experiments"],"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/yxonic.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-12-06T07:02:02.000Z","updated_at":"2021-11-16T07:51:46.000Z","dependencies_parsed_at":"2022-08-15T21:40:40.344Z","dependency_job_id":null,"html_url":"https://github.com/yxonic/fret","commit_stats":null,"previous_names":[],"tags_count":30,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yxonic%2Ffret","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yxonic%2Ffret/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yxonic%2Ffret/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yxonic%2Ffret/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yxonic","download_url":"https://codeload.github.com/yxonic/fret/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249098241,"owners_count":21212450,"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":["cli","configuration-management","deep-learning","framework","machine-learning","python3","reproducible-experiments"],"created_at":"2024-11-08T15:26:32.285Z","updated_at":"2025-04-19T17:18:42.744Z","avatar_url":"https://github.com/yxonic.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# fret\n\n[![Travis (.org)](https://img.shields.io/travis/com/yxonic/fret)](https://travis-ci.org/github/yxonic/fret/)\n[![Documentation Status](https://readthedocs.org/projects/fret/badge/?version=latest)](https://fret.readthedocs.io/en/latest/?badge=latest)\n[![Codecov](https://img.shields.io/codecov/c/github/yxonic/fret)](https://codecov.io/gh/yxonic/fret/)\n[![PyPI - Downloads](https://img.shields.io/pypi/dm/fret)](https://pypi.python.org/pypi/fret)\n\nFramework for Reproducible ExperimenTs. Read on for a quick guide. Full documentation [here](https://fret.readthedocs.io/en/latest/).\n\n## Installation\nFrom pip:\n```sh\npip install fret\n```\n\nFrom source: clone the repository and then run: `python setup.py install`.\n\n## Tutorial\n\n### Basic Usage\n\nCreate a file named `app.py` with content:\n```python\nimport fret\n\n@fret.command\ndef run(ws):\n    model = ws.build()\n    print(model)\n\n@fret.configurable\nclass Model:\n    def __init__(self, x=3, y=4):\n        ...\n```\n\nThen under the same directory, you can run: \n```sh\n$ fret config Model\n[ws/_default] configured \"main\" as \"Model\" with: x=3, y=4\n$ fret run\nModel(x=3, y=4)\n$ fret config Model -x 5 -y 10\n[ws/_default] configured \"main\" as \"Model\" with: x=5, y=10\n$ fret run\nModel(x=5, y=10)\n```\n\n### Using Workspace\n\nYou can specify different configuration in different workspace:\n```sh\n$ fret -w ws/model1 config Model\n[ws/model1] configured \"main\" as \"Model\" with: x=3, y=4\n$ fret -w ws/model2 config Model -x 5 -y 10\n[ws/model2] configured \"main\" as \"Model\" with: x=5, y=10\n$ fret -w ws/model1 run\nModel(x=3, y=4)\n$ fret -w ws/model2 run\nModel(x=5, y=10)\n```\n\n### Save/Load\n\n```python\nimport fret\n\n@fret.command\ndef train(ws):\n    model = ws.build()\n    model.train()\n    ws.save(model, 'trained')\n    \n@fret.command\ndef test(ws):\n    model = ws.load('ws/best/snapshot/main.trained.pt')\n    print(model.weight)\n    \n@fret.configurable(states=['weight'])\nclass Model:\n    def __init__(self):\n        self.weight = 0\n    def train(self):\n        self.weight = 23\n```\n\n```sh\n$ fret -w ws/best config Model\n[ws/_default] configured \"main\" as \"Model\"\n$ fret -w ws/best train\n$ fret test\n23\n```\n\n### An Advanced Workflow\n\nIn `app.py`:\n```python\nimport time\nimport fret\n\n@fret.configurable(states=['value'])\nclass Model:\n    def __init__(self):\n        self.value = 0\n\n@fret.command\ndef resumable(ws):\n    model = ws.build()\n    with ws.run('exp-1') as run:\n        run.register(model)\n        cnt = run.acc()\n        for e in fret.nonbreak(run.range(5)):\n            # with `nonbreak`, the program always finish this loop before exit\n            model.value += e\n            time.sleep(0.5)\n            cnt += 1\n            print('current epoch: %d, sum: %d, cnt: %d' %\n                  (e, model.value, cnt))\n```\n\nThen you can stop and restart this program anytime, with consistent results:\n```sh\n$ fret resumable\ncurrent epoch: 0, sum: 0, cnt: 1\ncurrent epoch: 1, sum: 1, cnt: 2\n^CW SIGINT received. Delaying KeyboardInterrupt.\ncurrent epoch: 2, sum: 3, cnt: 3\nTraceback (most recent call last):\n    ...\nKeyboardInterrupt\nW cancelled by user\n$ fret resumable\ncurrent epoch: 3, sum: 6, cnt: 4\ncurrent epoch: 4, sum: 10, cnt: 5\n```\n\n### Dynamic commands\n\nYou can specify commands inside configurables, and run them depending on current workspace setup:\n\n```python\nimport fret\n\n@fret.configurable\nclass App1:\n    @fret.command\n    def check(self):\n        print('running check from App1')\n\n@fret.configurable\nclass App2:\n    @fret.command\n    def check(self, msg):\n        print('running check from App2 with message: ' + msg)\n```\n\nThen run:\n\n```sh\n$ fret config App1\n[ws/_default] configured \"main\" as \"App1\"\n$ fret check\nrunning check from App1\n$ fret config App2\n[ws/_default] configured \"main\" as \"App2\"\n$ fret check -m hello\nrunning check from App2 with message: hello\n```\n\n### Submodule\n\n```python\n@fret.configurable\nclass A:\n    def __init__(self, foo):\n        ...\n\n@fret.configurable(submodules=['sub'], build_subs=False)\nclass B:\n    def __init__(self, sub, bar=3):\n        self.sub = sub(foo='bar')   # call sub to build submodule\n```\n\n```sh\n$ fret config sub A\n[ws/_default] configured \"sub\" as \"A\"\n$ fret config B\n[ws/_default] configured \"main\" as \"B\" with: sub='sub', bar=3\n$ fret run\nB(sub=A(), bar=3)\n```\n\n### Inheritance\n\n```python\n@fret.configurable\nclass A:\n    def __init__(self, foo='bar', sth=3):\n        ...\n\n@fret.configurable\nclass B(A):\n    def __init__(self, bar=3, **others):\n        super().__init__(**others)\n        ...\n```\n\n```sh\n$ fret config B -foo baz -bar 0\n[ws/_default] configured \"main\" as \"B\" with: bar=0, foo='baz', sth=3\n$ fret run\nB(bar=0, foo='baz', sth=3)\n```\n\n### Internals\n\n```python\n\u003e\u003e\u003e config = fret.Configuration({'foo': 'bar'})\n\u003e\u003e\u003e config\nfoo='bar'\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyxonic%2Ffret","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyxonic%2Ffret","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyxonic%2Ffret/lists"}