{"id":13557482,"url":"https://github.com/nteract/bookstore","last_synced_at":"2025-04-07T05:09:13.913Z","repository":{"id":48664322,"uuid":"153337860","full_name":"nteract/bookstore","owner":"nteract","description":"📚 Notebook storage and publishing workflows for the masses","archived":false,"fork":false,"pushed_at":"2021-08-26T18:26:16.000Z","size":721,"stargazers_count":201,"open_issues_count":35,"forks_count":23,"subscribers_count":19,"default_branch":"master","last_synced_at":"2024-04-14T04:55:39.425Z","etag":null,"topics":["data-science","notebook","nteract","scheduling","storage","versioned-buckets"],"latest_commit_sha":null,"homepage":"https://bookstore.readthedocs.io","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nteract.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-10-16T18:54:00.000Z","updated_at":"2024-01-20T23:22:34.000Z","dependencies_parsed_at":"2022-07-25T01:02:32.414Z","dependency_job_id":null,"html_url":"https://github.com/nteract/bookstore","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nteract%2Fbookstore","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nteract%2Fbookstore/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nteract%2Fbookstore/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nteract%2Fbookstore/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nteract","download_url":"https://codeload.github.com/nteract/bookstore/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247595334,"owners_count":20963943,"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":["data-science","notebook","nteract","scheduling","storage","versioned-buckets"],"created_at":"2024-08-01T12:04:22.766Z","updated_at":"2025-04-07T05:09:13.890Z","avatar_url":"https://github.com/nteract.png","language":"Python","funding_links":[],"categories":["Python","data-science","Jupyter-Notebook分享与格式转换"],"sub_categories":[],"readme":"# bookstore :books:\n\n[![Documentation Status](https://readthedocs.org/projects/bookstore/badge/?version=latest)](https://bookstore.readthedocs.io/en/latest/?badge=latest)\n[![Build Status](https://travis-ci.org/nteract/bookstore.svg?branch=master)](https://travis-ci.org/nteract/bookstore)\n[![CircleCI](https://circleci.com/gh/nteract/bookstore.svg?style=shield)](https://circleci.com/gh/nteract/bookstore)\n[![Codecov](https://codecov.io/gh/nteract/bookstore/branch/master/graph/badge.svg)](https://codecov.io/gh/nteract/bookstore)\n\n**bookstore** :books: provides tooling and workflow recommendations for storing :cd:, scheduling :calendar:, and publishing :book: notebooks.\n\nThe full documentation is hosted on [ReadTheDocs](https://bookstore.readthedocs.io).\n\n## How does bookstore work\n\n### Automatic Notebook Versioning\n\nEvery *save* of a notebook creates an *immutable copy* of the notebook on object storage.\n\nTo simplify implementation, we currently rely on S3 as the object store, using [versioned buckets](https://docs.aws.amazon.com/AmazonS3/latest/dev/Versioning.html).\n\n\u003c!--\n\nInclude diagram for versioning\n\n--\u003e\n\n### Storage Paths\n\nAll notebooks are archived to a single versioned S3 bucket with specific prefixes denoting the lifecycle of the notebook:\n\n- `/workspace` - where users edit\n- `/published` - public notebooks (to an organization)\n\nEach notebook path is a namespace that an external service ties into the schedule. We archive off versions, keeping the path intact (until a user changes them).\n\n| Prefix                                  | Intent                 |\n|-----------------------------------------|------------------------|\n| `/workspace/kylek/notebooks/mine.ipynb` | Notebook in “draft”    |\n| `/published/kylek/notebooks/mine.ipynb` | Current published copy |\n\nScheduled notebooks will also be referred to by the notebook key. In addition, we'll need to be able to surface version IDs as well.\n\n### Transitioning to this Storage Plan\n\nSince most people are on a regular filesystem, we'll start with writing to the\n`/workspace` prefix as Archival Storage (writing on save using a `post_save_hook`\nfor a Jupyter contents manager).\n\n### Publishing\n\nThe bookstore publishing endpoint is a `serverextension` to the classic Jupyter\nserver. This means you will need to explicitly enable the `serverextension`\nto use the endpoint.\n\nTo do so, run:\n\n    jupyter serverextension enable --py bookstore\n\nTo enable it only for the current environment, run:\n\n    jupyter serverextension enable --py bookstore --sys-prefix\n\n## Installation\n\n**bookstore** requires Python 3.6 or higher.\n\nNote: Supports installation on Jupyter servers running Python 3.6 and above.\nYour notebooks can still be run in Python 2 or Python 3.\n\n1. Clone this repo.\n2. At the repo's root, enter in the Terminal: `python3 -m pip install .` (Tip: don't forget the dot at the end of the command)\n\n## Configuration\n\n```python\n# jupyter config\n# At ~/.jupyter/jupyter_notebook_config.py for user installs on macOS\n# See https://jupyter.readthedocs.io/en/latest/projects/jupyter-directories.html for other places to plop this\n\nfrom bookstore import BookstoreContentsArchiver\n\nc.NotebookApp.contents_manager_class = BookstoreContentsArchiver\n\n# All Bookstore settings are centralized on one config object so you don't have to configure it for each class\nc.BookstoreSettings.workspace_prefix = \"/workspace/kylek/notebooks\"\nc.BookstoreSettings.published_prefix = \"/published/kylek/notebooks\"\n\nc.BookstoreSettings.s3_bucket = \"\u003cbucket-name\u003e\"\n\n# Note: if bookstore is used from an EC2 instance with the right IAM role, you don't\n# have to specify these\nc.BookstoreSettings.s3_access_key_id = \u003cAWS Access Key ID / IAM Access Key ID\u003e\nc.BookstoreSettings.s3_secret_access_key = \u003cAWS Secret Access Key / IAM Secret Access Key\u003e\n```\n\n## Developing\n\nIf you are developing on bookstore you will want to run the ci tests locally and to make releases.\n\nUse [CONTRIBUTING.md](./CONTRIBUTING.md) to learn more about contributing.\nUse [running_ci_locally.md](./running_ci_locally.md) to learn more about running ci tests locally.\nUse [running_python_tests.md](./running_python_tests.md) to learn about running tests locally.\nUse [RELEASING.md](./RELEASING.md) to learn more about releasing bookstore.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnteract%2Fbookstore","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnteract%2Fbookstore","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnteract%2Fbookstore/lists"}