{"id":31577535,"url":"https://github.com/dixslyf/nbparts","last_synced_at":"2025-10-05T18:58:03.295Z","repository":{"id":314924202,"uuid":"1027189462","full_name":"dixslyf/nbparts","owner":"dixslyf","description":"Unpack a Jupyter notebook into its sources, outputs and metadata.","archived":false,"fork":false,"pushed_at":"2025-09-15T16:37:18.000Z","size":4397,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-09-15T18:06:28.877Z","etag":null,"topics":["data","haskell","jupyter","jupyter-notebook","nix","nix-flake"],"latest_commit_sha":null,"homepage":"","language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dixslyf.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-07-27T14:00:53.000Z","updated_at":"2025-09-15T16:37:21.000Z","dependencies_parsed_at":"2025-09-15T18:06:48.396Z","dependency_job_id":"6b2d0c25-e4d4-4ba7-aa38-a1611d7c2816","html_url":"https://github.com/dixslyf/nbparts","commit_stats":null,"previous_names":["dixslyf/nbparts"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/dixslyf/nbparts","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dixslyf%2Fnbparts","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dixslyf%2Fnbparts/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dixslyf%2Fnbparts/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dixslyf%2Fnbparts/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dixslyf","download_url":"https://codeload.github.com/dixslyf/nbparts/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dixslyf%2Fnbparts/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278503207,"owners_count":25997718,"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-05T02:00:06.059Z","response_time":54,"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":["data","haskell","jupyter","jupyter-notebook","nix","nix-flake"],"created_at":"2025-10-05T18:58:02.324Z","updated_at":"2025-10-05T18:58:03.289Z","avatar_url":"https://github.com/dixslyf.png","language":"Haskell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# `nbparts`\n\n[![Build](https://github.com/dixslyf/nbparts/actions/workflows/build.yaml/badge.svg?branch=master\u0026event=push)](https://github.com/dixslyf/nbparts/actions/workflows/build.yaml)\n[![Build (Nix)](https://github.com/dixslyf/nbparts/actions/workflows/build-nix.yaml/badge.svg?branch=master\u0026event=push)](https://github.com/dixslyf/nbparts/actions/workflows/build-nix.yaml)\n[![Hackage Version](https://img.shields.io/hackage/v/nbparts?label=Hackage)](https://hackage.haskell.org/package/nbparts)\n\n`nbparts` is a tool for splitting Jupyter notebooks into its \"parts\":\n\n- sources (code and Markdown content),\n\n- outputs, and\n\n- metadata.\n\nThese parts can be re-assembled back into an equivalent Jupyter notebook.\nThe goal is to make it easier to store and diff Jupyter notebooks in text-based version control systems like Git.\n\n## Features\n\n- **Unpack**: Split a Jupyter notebook into its sources, outputs and metadata.\n\n- **Pack**: Reconstruct the original Jupyter notebook from unpacked parts.\n\n- **Formats**:\n    - Sources can be exported as _YAML_, _JSON_ or _Markdown_.\n\n    - Outputs and metadata can be exported as _YAML_ or _JSON_.\n\n- **Binary outputs and attachments** (e.g. PNG images, Markdown attachments) are extracted as files alongside the parts.\n\n- **Roundtrip safety**: `unpack` followed by `pack` yields a notebook semantically equivalent to the original.\n  Markdown and code formatting is preserved.\n\n    The only known caveat at this point in time is that,\n    when re-encoding binary attachments and outputs into base64,\n    `nbparts` always performs line wrapping after 76 characters;\n    however, not all Jupyter notebook platforms perform line wrapping\n    on the base64 strings, so although the content reconstructed by `nbparts`\n    is the same, the formatting may slightly differ.\n\n## Motivation\n\nJupyter notebooks are widely used for data exploration and analysis,\nbut because they are large JSON documents,\nstoring them in version control systems like Git is painful:\n\n- Attachments, execution outputs and metadata add significant noise to diffs\n  and overshadow meaningful changes.\n\n- Even after removing metadata and binary outputs from a notebook,\n  the diffs for small edits to code or Markdown content are a little difficult to read\n  due to syntactic JSON elements.\n\n- Collaborating on notebooks is hard when every commit contains unrelated noise.\n\nTools like Jupytext (awesome tool!) help by representing notebook sources as plaintext.\n`nbparts` complements this idea by splitting a notebook not only into its sources,\nbut also into its outputs and metadata, as separate parts.\nThis gives us more flexibility:\n\n- If you only care about the source code and Markdown,\n  you can ignore the outputs and metadata.\n\n- If outputs or metadata matter for reproducibility,\n  you can commit them alongside the sources.\n  Since attachments and binary outputs are extracted,\n  you may even use tools like Git LFS for versioning them.\n\n## Installation\n\n### Cabal\n\n`nbparts` can be installed with Cabal.\n\nYou may first want to update Cabal's package database:\n\n```\ncabal update\n```\n\nThen, run:\n\n```\ncabal install nbparts\n```\n\n### Pre-Built Binaries\n\nStatic binaries for x86_64 Linux are available from the [releases](https://github.com/dixslyf/nbparts/releases).\n\nUnfortunately, no binary releases are available for macOS and Windows at this point in time (contributions welcome!).\nPlease refer to [Compiling from Source](#compiling-from-source).\n\n## Basic Usage\n\nUnpack a notebook with all parts exported to YAML:\n\n```sh\n# This will create a `notebook.ipynb.nbparts` directory.\nnbparts unpack notebook.ipynb\n```\n\nPack the parts back into a notebook:\n\n```\nnbparts pack notebook.ipynb.nbparts -o notebook-repacked.ipynb\n```\n\nUnpack a notebook, with sources exported to Markdown:\n\n```\nnbparts unpack notebook.ipynb --sources-format markdown\n```\n\nFor more options, see:\n\n```\nnbparts --help\n```\n\n## Compiling From Source\n\n### Cabal\n\n`nbparts` uses Cabal for building and packaging.\n\nTo build and install `nbparts`, ensure you have Cabal and GHC installed.\n\nUpdate Cabal's package database:\n\n```\ncabal update\n```\n\nNow, clone the repository and `cd` into it. Then, run:\n\n```\ncabal install\n```\n\n### Nix\n\n`nbparts` provides a Nix flake for building x86_64 Linux binaries.\n\nTo build:\n\n```\nnix build github:dixslyf/nbparts#nbparts\n```\n\nTo run:\n\n```\nnix run github:dixslyf/nbparts#nbparts\n```\n\nStatic binaries can be built using Nix and are exposed as the `nbparts-static` flake output:\n\n```\nnix build github:dixslyf/nbparts#nbparts-static\n```\n\n```\nnix run github:dixslyf/nbparts#nbparts-static\n```\n\n## Running Tests\n\n`nbparts` uses Hspec and Hedgehog for testing.\n\nTo run `nbparts`'s tests,\nclone the repository and `cd` into it.\nThen, run:\n\n```\ncabal test\n```\n\n### Nix\n\nTests can also be run with Nix:\n\n```\nnix run github:dixslyf/nbparts#nbparts:test:test-nbparts\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdixslyf%2Fnbparts","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdixslyf%2Fnbparts","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdixslyf%2Fnbparts/lists"}