Git Product home page Git Product logo

deathbeds / jupyterlab-starters Goto Github PK

View Code? Open in Web Editor NEW
36.0 2.0 8.0 2.3 MB

Starter notebooks and directories in JupyterLab

Home Page: https://jupyterstarters.readthedocs.io

License: BSD 3-Clause "New" or "Revised" License

TypeScript 34.99% CSS 6.00% Shell 0.19% Python 47.13% RobotFramework 10.28% JavaScript 1.41%
rjsf jupyterlab-extension jsonschema jupyter-server-extension cookiecutter

jupyterlab-starters's Introduction

jupyterlab-starters

Parameterized file and directory starters for JupyterLab.

releases deps ci demo docs
pypi-badge
npm-badge
license-badge
python-badge
jupyterlab-badge
ci-badge binder-badge docs-badge
roadmap-badge
changelog-badge

screenshot

What's a starter?

A starter is a...

  • single file
  • directory
  • python function
  • cookiecutter
  • notebook

... that creates a...

  • single file
  • directory of files (or more directories)

... that shows up where you want it in JupyterLab at the click of a button

Installing

pip install jupyter-starters jupyterlab=3
# or
mamba install -c conda-forge jupyter-starters jupyterlab=3
# or
conda install -c conda-forge jupyter-starters jupyterlab=3

Configuring

Like the Jupyter Server, JupyterHub and other Jupyter interactive computing tools, jupyter-starters can be configured via Python or JSON files in well-known locations. You can find out where to put them on your system with:

jupyter --paths

They will be merged from bottom to top, and the directory where you launch jupyter lab wins, making it easy to check in to version control.

The very simplest starter, copy, will copy a file or folder to the location it is launched from in the JupyterLab Launcher.


> an example `jupyter_server_config.json`

~~~json
{
  "StarterManager": {
    "extra_starters": {
      "whitepaper-single": {
        "type": "copy",
        "label": "Whitepaper Notebook",
        "description": "A reusable notebook for proposing research",
        "src": "examples/whitepaper-single.ipynb"
      }
    }
  }
}
~~~

Alternatives

Don't like what you see here? Try these other approaches:

jupyterlab-starters's People

Contributors

bollwyvl avatar nrbgt avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

jupyterlab-starters's Issues

Pre-populate starter body in URL params

Elevator Pitch

In addition to ?starter=, accept a (partial) starter body.

Motivation

Pre-seeding a starter's body by URL would make linking into starters more interesting, where a single starter might include a few common fields, might have a "type", which would trigger some conditional properties.

It might also be relevant for providing a URL from an external site to inject into a notebook which would otherwise need to be manually typed.

Design Ideas

  • JSON-encoded would be powerful, but are hard to type by hand... but easy enough to generate with access to a url encoder
- [create a food](?starter=make-food)
- [create a fruit](?starter=make-food&starter-body={"type":"fruit"})  # <- needs escaping
- [create a vegetable](?starter=make-food&starter-body={"type":"vegetable"})   # <- needs escaping
  • PHP-style params are more verbose, and would require some parsing, but can usually get the point across even for relatively complicated structures.
- [create a food](?starter=make-food)
- [create a fruit](?starter=make-food&starter-body[type]=fruit)
- [create a vegetable](?starter=make-food&starter-body[type]=vegetable)

Allow custom label for Start button

For a continuing starter, clicking Start button again and again sounds confusing. On the other hand, changing button labels in fly is also confusing...

So, maybe not changes yet, but some discussion.

Improve building Starters in the Advanced Settings Editor

Elevator Pitch

Improve the editability of a settings-backed starter.

Motivation

While settings could theoretically be built in the rjsf-based Advanced Settings Editor, this is not a very rewarding experience at present, there are many unlabeled and undescribed fields.

Design Ideas

  • Update the schema to provide better UI feedback
  • Add a accept test of building an new starter

Incompatibility with newer cookiecutter versions

Description

The cookiecutter starter fails to import, probably due to some bad upstream metadata:

Reproduce

  • Install jupyter-starters (latest) and cookiecutter (latest)
  • Start jupyter lab
  • See some errors
terminal output
 Traceback (most recent call last):
      File "~/.venv/lib/python3.9/site-packages/traitlets/traitlets.py", line 537, in get
        value = obj._trait_values[self.name]
    KeyError: '_starters'
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "~/.venv/lib/python3.9/site-packages/notebook/notebookapp.py", line 2030, in init_server_extensions
        func(self)
      File "~/.venv/lib/python3.9/site-packages/jupyter_starters/serverextension.py", line 11, in load_jupyter_server_extension
        nbapp.log.info(f"""<U+1F4A1> starters: {", ".join(manager.starter_names)}""")
      File "~/.venv/lib/python3.9/site-packages/jupyter_starters/manager.py", line 131, in starter_names
        return sorted(dict(self.starters).keys())
      File "~/.venv/lib/python3.9/site-packages/jupyter_starters/manager.py", line 113, in starters
        for name, starter in dict(self._starters).items():
      File "~/.venv/lib/python3.9/site-packages/traitlets/traitlets.py", line 577, in __get__
        return self.get(obj, cls)
      File "~/.venv/lib/python3.9/site-packages/traitlets/traitlets.py", line 540, in get
        default = obj.trait_defaults(self.name)
      File "~/.venv/lib/python3.9/site-packages/traitlets/traitlets.py", line 1580, in trait_defaults
        return self._get_trait_default_generator(names[0])(self)
      File "~/.venv/lib/python3.9/site-packages/traitlets/traitlets.py", line 977, in __call__
        return self.func(*args, **kwargs)
      File "~/.venv/lib/python3.9/site-packages/jupyter_starters/manager.py", line 101, in _default_starters
        starters.update(cookiecutter_starters(self))
      File "~/.venv/lib/python3.9/site-packages/jupyter_starters/py_starters/cookiecutter.py", line 95, in cookiecutter_starters
        *cookiecutter_pantry(),
      File "~/.venv/lib/python3.9/site-packages/jupyter_starters/py_starters/cookiecutter.py", line 119, in cookiecutter_pantry
        str(metadata("cookiecutter")).split("Pantry")[1].split("\n## ")[0].strip()
      File "~/.venv/lib/python3.9/email/message.py", line 135, in __str__
        return self.as_string()
      File "~/.venv/lib/python3.9/email/message.py", line 158, in as_string
        g.flatten(self, unixfrom=unixfrom)
      File "~/.venv/lib/python3.9/email/generator.py", line 116, in flatten
        self._write(msg)
      File "~/.venv/lib/python3.9/email/generator.py", line 199, in _write
        self._write_headers(msg)
      File "~/.venv/lib/python3.9/email/generator.py", line 226, in _write_headers
        self.write(self.policy.fold(h, v))
      File "~/.venv/lib/python3.9/email/_policybase.py", line 326, in fold
        return self._fold(name, value, sanitize=True)
      File "~/.venv/lib/python3.9/email/_policybase.py", line 369, in _fold
        parts.append(h.encode(linesep=self.linesep, maxlinelen=maxlinelen))
      File "~/.venv/lib/python3.9/email/header.py", line 389, in encode
        raise HeaderParseError("header value appears to contain "
  • don't see API responses, or any UI (cookiecutter or otherwise)

Expected behavior

  • See (empty) cookiecutter list
  • See other starters

Context

  • trying to write a new starter, don't even want cookiecutter

[jupyterlab-rjsf] Setting formData in SchemaForm has no effect

Description

Setting formData has no effect, e.g.:

const schema = {
	  type: ["string"],
	};
const formData = "a";
const form = new SchemaForm(schema, {formData: formData});
layout.addWidget(form);

results in a empty input field. Same goes for any forms I tried.

Expected behavior

SchemaForm renders with data from formData.

Context

  • Operating System and version: WSL2 Ubuntu 20.04
  • Browser and version: Edge
  • JupyterLab version: 3.0.14
  • jupyter-starters version: N/A
  • @deathbeds/jupyterlab-rjsf: 1.0.2

Possible fixes

The issue seems to be with FormModel constructor.

SchemaForm.render() unpacks the variables from model:

const { schema, props, formData } = this.model;

However, model constructor never sets formData and it ends up being undefined.

Then, finalProps mixes props and formData (among other things)

const finalProps = {
// props from model
...props,
// assure a default prefix
idPrefix: this._idPrefix,
schema,
formData,
// overload classname
className,
validate: (formData: T, errors: rjsf.AjvError[]) => {
return errors;
},
// overload onChange
onChange: (evt: rjsf.IChangeEvent<T>, err?: rjsf.ErrorSchema) => {
this.onChange(evt, err);
if (props.onChange) {
props.onChange(evt, err);
}
},
};

Since props.formData (which comes from model) is undefined, formData ends up being undefined and not rendered.

Use doit and GitHub actions

What are you trying to do?

Improve time to implement new features and test fixes.

How is it done today, and what are the limits of current practice?

We currently use:

  • anaconda-project
    • brittle environment locking (if used)
    • non-intuitive how to replace some parts
    • mental model required of what to do next
    • challenges with cross-platform dependencies
  • Azure Pipelines
    • extra complexity vs. in-house on GitHub

What is new in your approach and why do you think it will be successful?

Using approaches from wxyz, gt-coar-lab and robotframework-jupyterlibrary, we should be able to achieve equivalent/better development and testing, fairly rapidly.

Who cares? If you are successful, what difference will it make?

Developers, and users of new features.

What are the risks?

N/A

How much will it cost?

Wear and tear on Ctrl, V and C.

How long will it take?

Couple hours.

What are the mid-term and final “exams” to check for success?

  • Working locally
  • Working binder
  • Working on GitHub Actions

Release 2.0.0a0

Checklist

  • start a release issue with a checklist (maybe like this one)
  • merge all outstanding PRs
  • ensure the versions have been bumped (check with doit test:integrity)
  • ensure the CHANGELOG is up-to-date
    • move the new release to the top of the stack
  • validate on binder
  • validate on ReadTheDocs
  • wait for a successful build of master
  • download the dist archive and unpack somewhere (maybe a fresh dist)
  • create a new release through the GitHub UI
    • paste in the relevant CHANGELOG entries
    • upload the artifacts
  • actually upload to npm.com, pypi.org
    cd dist
    twine upload jupyter_starters*
    npm login
    npm publish deathbeds-jupyterlab-rjsf-$VERSION.tgz
    npm publish deathbeds-jupyterlab-starters-$VERSION.tgz
    npm logout
  • postmortem
    • handle conda-forge feedstock tasks
    • validate on binder via simplest-possible gists
    • activate the version on ReadTheDocs
    • bump to next development version
    • update release procedures

Add visual indication that starter is running

Elevator Pitch

When you click the START button for the first time (especially on a notebook), it just sits there and then abruptly everything changes. It should have a text/icon/color/animation change to indicate that it works.

Motivation

c/f #28 (comment)

Throbber or something to indicate that the notebook is starting after the first "Start" would be nice.

Also, I have not idea what will happen if you click it again.

Design Ideas

Animation is cute, but maybe just going to ... Starting would be enough for now. Dropping opacity/setting disabled is probably also good.

How to build a wizard with helpful feedback, but no questions

A simple "guiding starter notebook" would need no questions, but just helpful texts and prompt for pressing "Start" to continue to the next step (and the notebook code would validate that the copied notebook template has been properly filled and add the next step for the form).

Yet, I am unable to figure out, how to define text without input fields with JSON schema.

What would you suggest?

Expand templates in destination, commands

Elevator Pitch

Currently, only the dest field has Jinja templates enabled, and can only see the body of text. Expanding what is available for templating, and what is templated, would allow JSON-only definitions to have more expressive power

Motivation

Over on robotlab, we want to do a simple copy of a folder, and then open a particular, known notebook.

Design Ideas

StarterManager:
  extra_starters:
    robotkernel-examples:
      src: {{ sys_prefix }}/var/www/robotkernel-examples
      commands:
        - id: filebrowser:open-path
          args:
            path: {{ dest }}/00 JupyterLab Interface.ipynb

The simplest approach may be to dump to JSON, apply Jinja, and then reload

Add a jupyter starters CLI

Elevator Pitch

Provide a way to list the currently-configured starters.

Motivation

When packaging a starter, it would be handy to be able to be able to do a simple grep test to ensure the starter is configured.

Design Ideas

  • make a JupyterApp
  • add a StarterListApp subcommand (might want more in the future)
  • add the appropriate entry_point for the console command
  • offer both a "pretty" YAML-style one and a --json one

Cell Starters

Elevator Pitch

Add a new kind of starter that interactively creates new cells.

Motivation

Sometimes a full notebook is too large of a thing to start, or after running a starter, there might be sensible places to continue.

Design Ideas

  • as a user
    • see a command palette item/menu/button in the cell toolbar
      • when activated
        • show a sidebar with a list of starters
        • select a cell starter
        • see a form
        • interactively fill out the form
          • store intermediate values in the cell metadata
        • run cell
  • as a starter author
    • create a new cell_starter by config, etc.
    • might create a python module, etc.

Add keyring to dev environment

Description

twine upload presently failing... looks like it just needs keyring>=15.1. Investigate upstream.

Reproduce

twine upload dist/*

Traceback (most recent call last):
  File "~/projects/deathbeds/jupyterlab-starters/envs/default/bin/twine", line 10, in <module>
    sys.exit(main())
  File "~/projects/deathbeds/jupyterlab-starters/envs/default/lib/python3.7/site-packages/twine/__main__.py", line 25, in main
    return dispatch(sys.argv[1:])
  File "~/projects/deathbeds/jupyterlab-starters/envs/default/lib/python3.7/site-packages/twine/cli.py", line 72, in dispatch
    main = registered_commands[args.command].load()
  File "~/projects/deathbeds/jupyterlab-starters/envs/default/lib/python3.7/site-packages/pkg_resources/__init__.py", line 2442, in load
    self.require(*args, **kwargs)
  File "~/projects/deathbeds/jupyterlab-starters/envs/default/lib/python3.7/site-packages/pkg_resources/__init__.py", line 2465, in require
    items = working_set.resolve(reqs, env, installer, extras=self.extras)
  File "~/projects/deathbeds/jupyterlab-starters/envs/default/lib/python3.7/site-packages/pkg_resources/__init__.py", line 786, in resolve
    raise DistributionNotFound(req, requirers)
pkg_resources.DistributionNotFound: The 'keyring>=15.1' distribution was not found and is required by the application

Expected behavior

Uploads to twine

Notebook-as-starter

Elevator Pitch

Add notebooks as starters with a notebook launcher type. Copied into a temporary directory, the contents of the directory (minus the starter itself) would be pushed to the contents manager. Configuring and launching a notebook as a starter could be supported in Lab.

Motivation

Notebooks are well-suited to this kind of task, and would act as their own documentation, both of the launcher.

Design Ideas

I/O could be managed through updating the notebook metadata (as any kernel language should be able to work with JSON on disk). Adding a schema-constrained starter authoring tool directly to the lab interface is straightforward, as rjsf is already close at hand, and it can discover commands directly from the registry.

Add category and rank properties for placement in launcher

Elevator Pitch

Wouldn't it be great if you can make new categories for each starter that you have defined? This would mean that each category gets its own header in the launcher and you can structure the starters that you have better.

In addition, would be nice to sort those starters based on rank instead of the current default alphabetical sorting.

Motivation

To better structure the starters in the launcher.

Design Ideas

Already created a PR for this from my fork.

Split out JSON Schema Form

Elevator Pitch

Distribute the react-jsonschema-form component as a separate package.

Motivation

The rjsf integration was originally extracted from @deathbeds/wxyz, but has since been exercised much more robustly on this repo, with a number of useful additions. It should get pulled out, and made into one or more proper libraries which can be reused in other JupyterLab extensions, with a goal of someday getting into JupyterLab core.

Design Ideas

More lerna, more fun! It will probably take a few releases for it to work properly, due to some known limitations of the development process that have since been solved in Lab 2.0.

Continue-with-copy

Elevator Pitch

Right now, continuing doesn't copy files, and done does. If continuing could create (some) files, a process could gradually build up a directory, while gradually revealing the schema. At each step, additional commands could be run, e.g. open a terminal, open a log viewer, open an inspector, etc.

Motivation

In robotlab, we'd like users to (optionally) advance one by one through the content 10+ notebooks.

Design Ideas

Add an independent copy property to the response which allows files to be posted.

Add hyperlink type for starter

What are you trying to do?

I would like to add a new starter type: "hyperlink". This starter is quite simple: you give a link (e.g. https://google.com) and when you click the starter it will go to the link.

Options could be to open the link in a new browser tab or to open the link in an HTML viewer window inside Jupyter Lab.

How is it done today, and what are the limits of current practice?

This is not part of the current jupyterlab-starters as far as I know.

What is new in your approach and why do you think it will be successful?

Not sure about the approach actually, any pointers are welcome! Else I will just get started with what I know.

Who cares? If you are successful, what difference will it make?

You can then add hyperlinks as starters as well. I think it could be nice to refer to, for example, documentation pages, YouTube videos, etc.

What are the risks?

I'm not aware of any.

How much will it cost?

Low cost as far as I can see.

How long will it take?

2 days?

What are the mid-term and final “exams” to check for success?

Mid-term: add starter with hyperlink that directs to external webpage, either as new browser tab or as new tab in Jupyter Lab UI.

Final remarks

  • Any pointers in the right direction to achieve this?
  • Can this be part of the upcoming release 2.0.0 ? If so, when should it be finished?

Add no-click starter-starter for binder, etc.

Elevator Pitch

Add a way to open a starter immediately on Lab launch without any user interaction.

Motivation

Sometimes, one click is still too much to introduce something in lab, compounded by starters appearing "below the fold" in smaller windows due to JupyterLab Launcher style choices.

Design Ideas

Add a router, such that a binder URL can be created like ?urlpath=lab/starter/<starter>/<path> and immediately open the sidebar.

Add JupyterLite demo to documentation

What I am trying to do...

Try out jupyterlab starters faster than binder

How I would like to learn how to do it...

  • Go to the documentation site
  • open the demo site
  • maybe see some tour info

How the project might keep the docs accurate...

  • include development build of key packages in the build chain

Notebook Meta schema is occasionally replaced with empty object

Description

Notebook metadata editor sometimes replaces schema value with {}

Reproduce

  1. Open examples/Starter Notebook.ipynb
  2. Click on in the notebook toolbar
  3. Scroll down to Schema
  4. See value is {}

Expected behavior

Value should be a required field called name.

Context

  • Operating System and version: Ubuntu Linux 19.10
  • Browser and version: Chromium 79
  • JupyterLab version: 1.2.4
  • jupyter-starters version: 0.2.0a0
  • @deathbeds/jupyterlab-starters version: 0.2.0a0

Autofocus on input and Ctrl + Enter to press Starter button on starter form

Using a starter from keyboard would be nicer if the first input field would have focus after launching a starter and, once the input is completed, some familiar keybinding would invoke the "Start"-button. Not sure if just Enter (like in HTML forms) or Ctrl+Enter (like in Windows dialogs) would be better.

Add more project templating/generator engines

Elevator Pitch

While #18 includes some TLC for cookiecutter, there are more project templating tools. We should support more of them.

Motivation

Cookiecutter is great, though discoverability is a bit minimal. Other generators exist, with yeoman boasting a very large collection of discoverable endpoints.

Design Ideas

Yeoman documents their integration approach, but it may require some serious plumbing to get it to work. Perhaps a jlpm-style single-file package, potentially with a private (or at least Not Lab) node_modules for generators.

(Prospective) User- and developer-focused docs

What I am trying to do...

  • As a prospective user, how might I understand what this is without starting it up?
  • As a developer, how might I use this to add guided to my interactive demos, e.g. binder?
  • As a user, how might I discover more of the interesting things I can do?

How I would like to learn how to do it...

  • As a prospective user, I'd like a screencast on the homepage that better shows what the project does
  • As a user, I would
  • As a developer, I would like a step-by-step tutorial (with screenshots and code snippets) of how to configure and release a starter

How the project might keep the docs accurate...

Use robotkernel notebooks for the docs to continuously test the viability of the information?

Release 1.1.0

  • start a release issue with a checklist (maybe like this one)
  • merge all outstanding PRs
  • ensure the versions have been bumped (check with doit integrity)
  • ensure the CHANGELOG is up-to-date
    • move the new release to the top of the stack
  • validate on binder
  • validate on ReadTheDocs
  • wait for a successful build of master
  • download the dist archive and unpack somewhere (maybe a fresh dist)
  • create a new release through the GitHub UI
    • paste in the relevant CHANGELOG entries
    • upload the artifacts
  • actually upload to npm.com, pypi.org
    cd dist
    twine upload jupyter_starters*
    npm login
    npm publish deathbeds-jupyterlab-starters-$VERSION.tgz
    npm publish deathbeds-jupyterlab-rjsf-$VERSION.tgz
    npm logout
  • postmortem
    • handle conda-forge feedstock tasks: conda-forge/jupyter-starters-feedstock#1
    • validate on binder via simplest-possible gists
    • activate the version on ReadTheDocs
    • bump to next development version
    • update release procedures

Fix rjsf 5 styles for controls

Description

Some of the new rjsf 5 styles are off, e.g. checkboxes.

image

Reproduce

  • visit current binder
  • open multistage notebook

Expected behavior

checkboxes should look "nice"

Context

  • binder
  • vs master

KeyError: 'schema'

Launching starter without "schema" key in its metadata results in parsing error dialog on JupyterLab (and KeyError: 'schema' on server console).

Not sure if schemaless notebooks is a real use case for notebook starter, but nevertheless i was able to create a one.

Release v1.0.2

  • investigate cookiecutter
  • docs pass
  • release
  • upload
  • post-mortem
    • gist binder smoke test
    • conda-forge
    • go back to setup-miniconda@v2

Improve markdown rendering

Elevator Pitch

Improve the robustness of markdown label rendering.

Motivation

The current markdown rendering on labels is fairly brittle, and especially falls down when rapidly changed (i.e. wxyz.json_schema_form).

Design Ideas

Subclass everything that uses the title and/or description fields, and add/extend componentDidUpdate with the markdown method. This may well require a full theme, but that's probably okay.

Schema level title and description twice on the generated starter form

When, e.g. on jupyterlab-starters binder, I update "Multi-Stage Starter Notebook"'s schema to include title and description:

    "schema": {
     "title": "Schema title",
     "description": "Schema description",
     "properties": {
      "name": {
       "description": "What is your name?",
       "title": "Name",
       "type": "string"
      }
     },

The form opened from the launcher will show title and description twice:

Schema title

Schema description

Schema title

Schema description

Name*

What is your name?

    is a required property

Release 0.6.0a0

  • archive artifacts in CI #47
  • tag, add built artifacts
  • upload to pypi, npm, etc.

Adopt rjsf 5

Elevator Pitch

rjsf 5 is in beta. Skip the 4.x line entirely and support 5.x as part of the breaking changes represented in #87.

Motivation

5 improves the long-term supportability of downstreams, as it decouples validation from a hard dependency on a specific version of ajv (even if practically it doesn't have any other implementations yet). It also makes certain customizations easier, such as templates which might make #52 easier.

Design Ideas

  • see migration guide.
  • time permitting, we could already start kicking the tires with the beta releases
    • hanging tight for an rc might be a better use of time
  • perhaps work this into a more thorough pr to jupyterlab, which still has a lot of razor-sharp edges for downstreams to use effectively

Update to JupyterLab 4

Elevator Pitch

@deathbeds/jupyterlab-starters and @deathbeds/jupyterlab-rjsf are very helpful libraries, since Jlab 4 is around the corner, I want to know if you have a time frame for alphas/betas version which are compatible with JLab 4

Motivation

We are using @deathbeds/jupyterlab-rjsf in our extension https://github.com/QuantStack/jupytercad, which is a JLab 4-only extension. It still works but causes a lot of trouble in resolving the dependencies.

Design Ideas

N/A

Allow package-relative src

Elevator Pitch

Expand the src spec to allow for starters relative to a python package.

Motivation

Distributing a simple starter with a package needs to be really easy. Including jupyter_notebook_config.d JSON is not super easy. It should be possible to specify a package as the root of a config location.

Design Ideas

  • introduce a new key, e.g. py_src which gets imported, has the __file__ interpreted, and prepended to the source
    • e.g. py_src: module_name
  • offer a jinja function which can be used in the src,
    • e.g. src: '{{ py_src("module_name') }}/path/to/file.json'
  • introduce a custom syntax in src
    • e.g. src: 'module_name:path/to/file.json'

Add markdown

Elevator Pitch

All schema descriptions, etc. are currently plain text. Allowing markdown would make things a little more interesting.

Motivation

#10 suggests there is the potential for significantly more involved starters. Markdown would make it much more fun.

Design Ideas

Add a markdown property to the response. Re-use existing markdown renderer.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.