{"id":19740347,"url":"https://github.com/distributive-network/bifrost2","last_synced_at":"2025-07-14T09:38:31.924Z","repository":{"id":246885952,"uuid":"782116682","full_name":"Distributive-Network/bifrost2","owner":"Distributive-Network","description":"The Python SDK for DCP","archived":false,"fork":false,"pushed_at":"2025-06-10T19:20:17.000Z","size":313,"stargazers_count":10,"open_issues_count":12,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-11T06:15:17.862Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","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/Distributive-Network.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,"zenodo":null}},"created_at":"2024-04-04T17:06:48.000Z","updated_at":"2025-06-10T19:20:20.000Z","dependencies_parsed_at":"2024-12-10T20:25:56.731Z","dependency_job_id":"7e58a046-c30f-4e9e-a6e3-b06f6e5ec907","html_url":"https://github.com/Distributive-Network/bifrost2","commit_stats":null,"previous_names":["distributive-network/bifrost2"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Distributive-Network/bifrost2","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Distributive-Network%2Fbifrost2","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Distributive-Network%2Fbifrost2/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Distributive-Network%2Fbifrost2/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Distributive-Network%2Fbifrost2/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Distributive-Network","download_url":"https://codeload.github.com/Distributive-Network/bifrost2/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Distributive-Network%2Fbifrost2/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264926589,"owners_count":23684367,"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":[],"created_at":"2024-11-12T01:20:40.408Z","updated_at":"2025-07-14T09:38:31.901Z","avatar_url":"https://github.com/Distributive-Network.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Bifrost2 - The Python SDK for [DCP](https://www.dcp.dev/)\n\n## Installation\n```bash\npip install dcp\n```\n\n## Example\n\nDeploying a job to DCP and getting results:\n```python\nimport dcp\ndcp.init()\n\n# define the data your workfunction will operate on\ndata = [1,2,3,4,5]\n\n# function which will execute on each datum in the dataset remotely on dcp workers\ndef work_function(input_datum):\n\timport dcp\n\tdcp.progress()\n\n\t# process the datum (in this exampe, square the value)\n\tresult = input_datum * input_datum\n\n\treturn result\n\n# define the compute workload (job)\njob = dcp.compute_for(data, work_function)\n\n# add event listeners for debug logs\njob.on('readystatechange', print)\njob.on('accepted', lambda: print(job.id))\n\n@job.on('result')\ndef on_result(event):\n\tprint(f'New result for slice {event.sliceNumber}')\n\tprint(event.result)\n\n# deploy the compute workload to the DCP network\njob.exec()\n\n# wait for the compute workload to complete and process the results\nresults = job.wait()\nprint(results) # [1.0, 4.0, 9.0, 16.0, 25.0]\n```\n## API\n\n### `dcp.init()`\n\nInitializes the `dcp` module for use.\n\nExample:\n```python\nimport dcp\ndcp.init()\n```\n\n### `dcp.compute_for(input_data: List, work_function: Union[str, Callable]) -\u003e Job`\n\nInstantiates a job handle.\n\n### `dcp.compute.Job`\n\nJob class, instances are returned by the factory functions `dcp.compute_for`, `dcp.compute.do` and from the `@dcp.distribute(...)` decorator.\n\n#### Job Methods\n**`job.exec(slicePaymentOffer=compute.marketValue: float, paymentAccountKeystore=wallet.get(): dcp.wallet.Keystore, initialSliceProfile=none: dict) -\u003e None`**\n\nDeploys the job to the DCP Network.\n`slicePaymentOffer` specifies how many DCCs will be expended per slice.\nOnce a job is deployed, workers will begin picking up slices of the job to compute.\n\n**`job.wait() -\u003e ResultHandle`**\n\nWaits for a job to complete.\nReturns a List-like ResultHandle object which can be used to access the results of the computation.\n\n**`job.on(event_name: str, callback_fn: Callable[[dict], None]) -\u003e None`**\n\nRegisters a callback function to execute each time a job event is triggered.\n\nExample: `job.on('result', print)` will print a result each time there is a result event.\n\n**`job.on(event_name: str) -\u003e FunctionDecorator`**\n\nRegisters a callback function to execute each time a job event is triggered as a decorator.\n\nExample:\n```python\n@job.on('accepted')\ndef on_accepted_callback(event):\n  print(f\"Job {job.id} has been submitted to the DCP Network for computation\")\n```\n\n#### Job Attributes\n**`job.autoClose`**\n\nWhether or not the job will remain open to accepting more slices after it has been deployed.\nSee \"Open and Closed Jobs\" in the Concepts section as well as `dcp.job.addSlices` and `dcp.job.fetchResults`.\nBy default, `job.autoClose` is `True`, meaning the job will not allow additional slices to be added.\nSo long as a job is \"open\", it can receive additional slices to be computed at any point in the future.\n\nExample:\n```python\nmy_job.autoClose = False\nmy_job.exec # deploy the job\ndcp.job.addSlices([1,2,3], my_job.id) # add three new slices to the job\n```\n\n**`job.computeGroups`**\n\nList of Dictionaries with `joinKey` and `joinSecret` keys.\nBy default, `job.computeGroups` will contain a single dictionary element which will include the credentials for the global / public DCP Compute Group; it can be overridden if deploying to the global / public DCP Compute Group is not desired.\n\nExample: `job.computeGroups = [{ 'joinKey': 'my cg', 'joinSecret': 'my epic password' }]` will deploy your job only to the imaginary \"my cg\" compute group.\n\nExample: `job.computeGroups.append({ 'joinKey': 'my cg', 'joinSecret': 'my epic password' })` will deploy your job only to both the \"public\" and \"my cg\" compute groups.\n\n**`job.fs`**\n\nAn instance of `dcp.JobFS`.\nUsed to add and manage the files that will be uploaded as part of the job. DCP Workers will download the files so they are available for use in your work function.\nCurrently only available for use in the \"pyodide\" Worktime.\n\nExample:\n```python\njob.fs.add(‘~/Downloads/will_kantor_pringle.png’) # Goes to current working directory of the VFS plus the basename of the file being added (/home/pyodide/will_kantor_pringle.png)\njob.fs.add(‘~/Downloads/severn_lortie.png’, ‘./vfs/at/dir/filename.png’) # goes to (/home/pyodide/vfs/at/dir/filename.png), creates directoies if they do not exist\njob.fs.add(‘~/Downloads/wes_garland.png’, ‘/absolute_file.png’) # goes to (/absolute_file.png)\njob.fs.chdir(‘./vfs/at/dir/’) # throws if any directories in the path do not exist\n```\n\n**`job.public`**\n\nA dictionary with three keys: \"public\", \"description\", and \"link\" which each map to strings.\nThese attributes are displayed by some DCP Workers while operating on slices of the corresponding Job.\n\nExample: `job.public.name = \"Will's Awesome DCP Job\"`\n\n**`job.worktime`**\n\nA string specifying the Worktime which will be used to execute the Work Function inside of.\nBy default, `job.worktime` will be set to `\"pyodide\"`, the Pyodide Worktime for executing Python Work Functions in DCP.\n\nExample: `job.worktime = 'map-basic'` will set the worktime to JavaScript, and a string of a JavaScript function can be specified as the Work Function.\n\n**`job.worktimeVersion`**\n\nA string specifying a semver Worktime version to use.\n\n**`job.customWorktime`**\n\nA boolean specifying if the worktime to use is custom or officially supported by DCP.\n\n\u003c!--\n### `dcp.compute.getJobInfo()`\n\n### `dcp.compute.status()`\n--\u003e\n\n### `dcp.job.addSlices(slice_data: List, job_id: str)`\n\nAdds slices to a job already deployed to DCP.\n\nExample: `dcp.job.addSlices(['Hello, 'World'], '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045')` will add two slices to the job referred to by that job ID.\n\n### `dcp.job.fetchResults(job_id: str, range_object: dcp.compute.RangeObject) -\u003e List`\n\nGets the results for a job over specified slice number ranges.\n\n### `dcp.JobFS`\n\nA JobFS (Job Filesystem) class for adding files to the Pyodide in-memory filesystem.\nThe filesystem is uploaded and accessible at job run time.\n\nExample: `fs = dcp.JobFs()`\n\n#### JobFs Methods\n\n**`fs.add(source: Union[str, Path, bytes], destination: Optional[str]) -\u003e None`**\n\nAdds a file to the filesystem.\n`source` can either be a path on the deployer's local file system or a bytes buffer in memory. \nThe destination's path is resolved to the current working directory of the fs, initially `/home/pyodide`.\n\n\n**`fs.chdir(destination: str) -\u003e None`**\n\nChanges the current working directory to another directory.\nThrows an exception if the directory passed as `destination` doesn't exist.\n\n### `dcp.wallet.get(label: Optional[str]) -\u003e dcp.wallet.Keystre`\n\nGets a dcp keystore.\n\n\u003c!--\n## Concepts\n\nJob\n\nWork Function\n\nSlice\n\nCompute Groups\n\nWorktime\n\nDCP Worker\n\nDCP Network\n\nDCCs and the DCP Compute Market\n\nOpen and Closed Jobs\n--\u003e\n\n## Contributing\n\n### Build\n\nInstall [Poetry](https://python-poetry.org/), then in the root of the project directory run the following:\n- `$ poetry install`\n- `$ poetry shell`\n\nVerify your installation is correct by running the test suite:\n- `$ poetry run pytest`\n\n### Tests\n\nRun tests with:\n- `$ poetry run pytest`\n\n### Publishing\n\nWe need to upload the tar since we need to run `npm install` after installation - this is not possible with the wheel distribution option.\n- `$ poetry build -f sdist`\n- `$ twine upload dist/dcp-\u003cnew-version-here\u003e.tar.gz`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdistributive-network%2Fbifrost2","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdistributive-network%2Fbifrost2","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdistributive-network%2Fbifrost2/lists"}