-
Notifications
You must be signed in to change notification settings - Fork 65
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[proposal] Jupyter Extension Generator #7
Conversation
@bollwyvl thanks for putting this together!
|
A few more comments after looking through the list of possibly templates:
|
@ellisonbg thanks for the input! I'll try to answer some of the pieces below, and reflect on how to update the PR. PRs on PRs welcome!
Everything is up for grabs. I think "feature" is a little too specific, as a single development effort would very likely use many features. They aren't
It is known. But without a Q?2016 estimate of when the replacement will ship, folks that have built or want to build and deliver code on/around the incumbent mechanism, have knowledge debt that's not going anywhere in the timeframe where users need it. Being now. And until 5.x is shipped. And ready to deploy internally. Or as part of a bundled software project. And 4.x will be around for a while even after, longer if the deployment burden is noticeably larger. Let's use this as a way to avoid repeating history, and have something actionable we can argue about concretely.
Huzzah! It's got us covered as a first class citizen. An package.json is probably the metadata format most compatible with the shape of the rest of our data.
Yes, the basic intent is for each set of options to be ordered from "we have to, but we don't have to like it" to "this is a good opinion" up to "this would be awesome... PRs welcome!" Perhaps we can specify a few "opinion bundles"... or better still, "make me something like bqplot"... but that's a huge metadata debt. On the broader story: I think if it's worth developing, it's worth letting any member project from the ecosystem be able to get involved. An (atypical) example: nbpresent is a notebook nbextension, backend server extension (to configure the nbconvert service), a couple nbconvert exporters... and I really want to use the gamepad widget as a presenter mouse... and it might even make sense to throw the nbviewer piece in as well, and maybe add a PDF ContentManager, since it can ship PDF with embedded notebooks for archival. Okay, probably not the last thing, but still.
Gah, I thought I made the graph somewhat explicit by using the As to packaging... well, packaging is hell. I would agree with you that The Opinion was PyPi... but evidence suggests that the ecosystem is using conda all over the place. In npm land, I'll agree with you... but npm is only the beginning of that toolchain. So we have to keep digging.
Yeah. Well, we can try! By keeping the individual sets of options 7±2 (after maybe the first one), the choices shouldn't be overwhelming, and by bounding future questions by the compatibility matrix, there shouldn't be any silly questions by the end. A notional future GUI for this experience would be even better, especially one that let you interactively see what impact a decision has on the repository you end up with. That might be a killer app for a widgety notebook up on mybinder... run it in two panes, file browser and notebook, every keystroke re-runs the whole thing. Possibilities are endless.
Agreed! We're trying to show developers how to develop with the Jupyter ecosystem, not Just Write Code. |
@ellisonbg although we should probably discuss how we are going to transition from nbextensions to the new mechanism in a single code base. I am naturally especially interested into migrating pythreejs and bqplot, where a significant effort was put. |
This is actually a really big point... there are a lot of extension out there... and we should put some effort to make them/us suffer as less pain as possible with the transition... I know we don't have an official API, and peple know that we can break things... but there is a lot of work out there that will need some kind "easy" transition pathway and I think we should do the best to offer that if it is possible in the new infrastructure. |
@bollwyvl Thanks for putting this together. This would have been immensely helpful when bootstrapping the incubator projects as extensions. I know what we did there is still not ideal and I still don't know any better best practices (but suspect others do!) I don't know how to contribute here at the moment beyond listing what our incubator extensions currently require like you did with nbpresent. Maybe thinking about a set of existing extensions both in terms of what templates they would use if started today and what templates they would need when being ported to the new "workbench" pluggable base will help guide decision making about the yeoman options. Here's two. @lbustelo can cover the declarative widgets. jupyter-incubator/dashboardsCurrently includes both:
If picking from the template list currently in the pull request and assuming the templates are for Jupyter 4.x as it exists today, I guess it would be refactored into JavaScript Notebook (nbextension) for the frontend and Server Route (notebook) for the backend handler bit. In Jupyter 5.0+, I think (maybe incorrectly) dashboarding is going to become part of the workbench UI rather than something you do to a notebook. So there might not be any porting of this work there. But if I still wanted to plug-in the current idea of laying out a notebook as a dashboard and deploying it as a separate app, I'm guessing I'd still go with the JavaScript Notebook (nbextension) for the frontend and Server Route (notebook) options (but would expect a Phosphor plugin base for the former instead of the legacy jQuery based one above). jupyter-incubator/contentmanagementCurrently includes:
Like the above, I guess these would have to be refactored into three separate extension templates that would somehow get installed together and work together:
|
Perhaps it would also be useful to describe what nbgrader includes. nbgrader itself started out as an extension building on top of nbconvert, but I think it's complex enough at this point that it can be considered as just a standalone thing. It does, however, include two extensions to the notebook interface:
And I have been working on another extension as well that allows the formgrader to be accessed through the notebook server by hooking up it's tornado handlers to the notebook. |
Great feedback, all! For a developer, making the architectural choice of "what do i need to do" In addition to the first choice of "what", no doubt other choices were made Re: 5.0 changes: i moved versions to support higher in the list, and likely On 13:33, Wed, Dec 2, 2015 Jessica B. Hamrick notifications@github.com
|
jupyter-incubator/declarativewidgetsCurrently includes: Frontend JS for loading core set of elements on the page |
Started some of my exploration of things mentioned in this spreadsheet... sorry for the google doc, but i found markdown not the right tool for the job. Once I feel better about it, i'll add it to the PR as a CSV... or dump to markdown... but until then... anybody who'd like to slog through some data entry, and either fix what I did wrong or add other key things ping me up on gitter :) I'd like to add a ContentManager (ipymd, or jupyter-drive), some kernels, etc. but really anything anyone would like to volunteer would be greatly appreciated. I would consider the spreadsheet to be the canonical list of features, etc (vs the yeoman screenplay). I think, properly matured, this could be the beginning of a stub for the eventual repo. Exciting stuff! |
A few questions and comments about Python/Server side:
|
@bollwyvl I had a look at the spreadsheet and it isn't really obvious what information it is encoding. What are the rows? columns? Can you describe a bit more what you are after there? |
On the JavaScript/CSS/HTML side, I don't yet know if it will be possible for a single code base to support both the existing (4.x) and new (5.x and beyond) frontend APIs. My initial thought that is it will be so different that it is not going to be possible. I don't think anything will be the same (DOM structure, CSS classes, packaging, loading, JS APIs, etc.). In terms of transition, I think yeoman templates, demo extensions, and documentation are going to be how folks get going on writing to the new APIs. We do want to make that as easy as possible for sure. |
in theory, it's just a module that has
In practice, the pain of packaging for the myriad ways a user might want to install/configure the developer's extension is not relatively small. Each of the repositories listed has its own, separate way of dealing with this, as there isn't a standard way i.e.
Each row is a feature that someone might want to include in their product, or the process they can use to create that product.
Each In this section i describe how features can demand other features, and then the features may or may not create files. Filling out this matrix will be involved, so I wanted to do some validation of things I thought I had read/seen. For example, saying you want an
Can it be a design goal? It doesn't have to be free: If the answer is "start using npm and stealjs right now, and browserify" that's fine, but again, at least for a while maintainers are going to have to support both. On the css, start giving us some namespaces: |
The 4.x version won't be going away overnight. The workbench will live in a separate browser tab alongside the old version for a while. Would this be sufficient for easing the transition? |
We've been working with @bollwyvl @damianavila and others at Continuum to create a small tool-chain to support easy-installation and encapsulation of Jupyter 4.x extensions, along with a few extensions built using the tool-chain and a few existing ones ported over. My outline of what we've done:
If you dig around the repos for all of these are already public but the content is still WIP and lacks documentation or testing. But our next sprint goal is to get it to a place where we can do a limited circulation for "friendly" initial review and feedback, with a plan to have some blog posts and perhaps a webinar in January/February 2016 about the power of Notebooks for technical computing and (unsurprisingly) the benefits of integrating them with |
@ijstokes @bollwyvl @damianavila I think there are interesting directions here, but other aspects of what you are proposing that will increase the net pain of users of Jupyter and anaconda. The * generator* stuff could be very helpful to developers who want to write extensions. I think everyone's time at this point would be better spent working on the new 5.0 stuff, but I understand you have different goals that are served by this work. On the side of nbsetuptools and nbwrapper I think it would be a technical mistake to pursue the approach you describe. Here is why:
After talking with a few people, I think there is a way of addressing the packaging/installation challenges for 4.x nbextensions that doesn't have these problems. I propose:
We are already basically pursuing this approach for 5.0. The only new thing I am proposing is that we enable 4.x nbextensions to be managed in the same exact way (npm all the things!). Benefits:
Some technical notes:
|
@ellisonbg thanks for the quick reply. @damianavila understands the details of what we've done and historical, present, and future situation for Jupyter better than I do, so he said he plans to give a more detailed response, but from a high level I have a few comments and follow up questions: At the highest level @bollwyvl wrote this JEP about I think a lot of the rest of the discussion is a critique that goes beyond the JEP because I (probably mistakenly) ended up sharing the larger context of the work we're doing at Continuum which motivated this JEP around template-based extension creation. Be that as it may, the discussion is started and I do have some responses to the first half (spoiler: the second half of @ellisonbg critique, which outlines an NPM-centric packaging strategy, seems reasonable and we'd be happy to consider trying this in our implementation). On to responses to the first half:
That would be a bad outcome. We definitely want to avoid net pain. So it is a high priority for me to understand if that is really what we're setting ourselves up for. Sharing our plans here at an early stage is part of trying to get that feedback so we don't do something counterproductive.
We had hoped we were going to be able to do that, but I think 5.0 is maybe 3 months beyond what we need to support the user community we're working with right now. So we needed to harden and standardize a set of existing extensions. Furthermore, I think there is definitely some benefit to having a generator in place that we can talk about with a "known entity" which are the 4.x style extensions, rather than co-mingle the new 5.x extension format and attempts to create generators for that format. I think there would be a lot of debate about things that had nothing to do with the generator and instead were tied to people just shaking out opinions about how best to construct 5.x extensions.
I'm sorry for misleading anyone into thinking there was a fork. There is no fork. The solution we've developed does not just work with Anaconda, but getting it working with Anaconda with as little pain as possible is our primary goal.
Yes, we're very aware of that and have been dealing in an ad hoc way with those problems for the past 1+ years. That is why at this point we had hoped to invest time only in 5.x style extensions but given the timelines for 5.x and the relatively dramatic shift in foundation that will come with it we realized that we had a user base we will need to support through much of 2016 with 4.x style extensions, and those existing extensions we had implemented needed to be standardized and improved. We are not in a position to say either "You have to shift to 5.0" or to say "We aren't supporting Jupyter 4.x any more". At least not until the second half of 2016.
They will not only work with Anaconda. They will be "equivalently awkward" to install outside of Anaconda as any other existing Jupyter extension is. But with Anaconda they will be easy to install with simply
This is less pain for us right now, and will be for the next 3-6 months. And once 5.0 is out I know it will be less pain for us to use our existing tools with our maintenance of the old 4.x extensions, regardless of what processes and tooling is available for creating/porting/maintaining 5.x extensions. (our hope is that we can learn from our existing "standardization" and "tooling" of the 4.x extensions so that we can contribute to something even better and more informed to facilitate creation of 5.x extensions/plugins). BUT I do take your point and we have been discussing exactly the question of whether we should just keep these "quiet" and only promote the tools once 5.0 is out and we have adapted them in some way to the 5.x world, with 4.x support only available as a historical footnote.
We only expect the current implementation to work with Jupyter 4.x. When Jupyter 5.0 is released we would hope to figure out what the logical transition is in the tool chain to support the creation of 5.x extensions. I don't quite understand this criticism: most (all?) 4.x extensions will stop working in 4.x, I would imagine.
Great. We'd be happy to help create these npm modules from the tool chain as it evolves. Anaconda Cloud, incidentally, already supports npm modules and is an NPM package mirror: https://npm.anaconda.org/ (I share this just to make it clear that we are not conda-package-zealots). I don't know enough about npm to know what advantages it provides over Wheels or Conda packages for software distribution: mostly my experience with NPM is frustration and confusion, I have to admit, but I accept that npm and JS aren't going anywhere any time soon. I appreciate the insights into what is planned for 5.0 extensions and distribution of those extensions. We'll definitely consider your suggestions to evolve the tools we've written into something which is more "npm-package-centric". The situation we're in is that we've developed about half a dozen extensions that either have been in use for the past ~year, or recently have been developed to facilitate real user requirements. We need these extensions now, and the users of these extensions anticipate using Jupyter 4 "style" notebooks through 2016. We weren't happy with the ad hoc mechanisms we'd been using to construct extensions so we invested ~1-2 person weeks of effort to identify the common parts, create abstractions to capture those, refactor the existing extensions to use the common libraries, and then think about what we needed to do to make it easier to write (or re-write) the next half dozen extensions we needed to get through. For that last step we decided to write a generator off of some template files. Creating conda recipes for these (and auto-generating conda recipes from templates) allowed an extension to be installed simply with Finally we needed a way to encapsulate extensions so they were only installed in individual conda environments rather than "per-user". Basically not much more than a script that did: JUPYTER_CONFIG_DIR=$CONDA_ENV_PATH/etc/jupyter \
JUPYTER_DATA_DIR=$CONDA_ENV_PATH/share/jupyter \
jupyter notebook But we hope to figure out a way (probably necessitating a Jupyter PR) that will allow us to get rid of this wrapper script and have Jupyter search all the directories in |
Brian, several clarifications below:
We are just trying to avoid that 😉
We are just trying to have a solution for some very painful issues involving nbextension, server-extensions and nbserver-extensions (I mean, a server-extension + a client side component)
Let me be clear here... we are not forking the notebook, the notebook wrapper is just a short-term wrapper launching a notebook instance with the
I agree that right now the work we have done so far was centered around the conda/anaconda ecosystem, but the plan is to release some of these extensions (including nbsetuptools) as pypi packages, so people can eventually use it outside conda as well...
In fact, and now talking as a jupyter dev, we don't even have "our" approach... we only provide some mechanism to install the nbextensions, but we don't have anything for server-based extension with a JS conterpart (which is a difficult problem to solve because you need to install python and JS and enable/register the JS side).
Again, we are not forking the notebook, we are not going in that direction (I would not participate in something like that). We certainly need a kind of transition from the propose we are working on now and the next architecture, but at least people have something now to work with... if it not the case, they have to hit the wall until they come up with something workable and in that case, they will have to transition too... or even worst, they will have to wait until 5.x... that's something we should avoid because we miss traction in this case.
OK...
Sounds good...
Thas's great...
That could be probably achieved by our nbsetuptools proposal... The idea is to get it right now, so that when 5.0 comes, it helps with this...
I think this is pretty important to give user/devs enough time to transition...
In general, I almost completely agree with you view... we are just trying to give a solution for existing devs/users which are currently lost in the middle of a sea of confusion with multiple partial solutions...
👍
I agree on this...
Each env could have a kernelspec pointing to the python executable, so we need just to have node_modules in the env where we trigger the notebook server...
OK...
Yep, I agree... Just to summarize, and repeating myself, we just pretend to ship a simple solution until we evolve the package system into 5.x. I think this is pretty important to save frustration and help user/devs to work with the current release without having to wait a lot of time to see how the architecture is developed... |
@damianavila and @ijstokes thanks, this really helps and we can make some progress. It definitely helps to understand your usage case a bit better. Let me restate it and see if I have it right:
I full agree that the situation with the 4.x codebase is too painful (understatement). Let's try to fix that in 4.x releases in a backwards compatible manner that helps existing and new 4.x nbextensions to "just work" with the latest 4.x release of the notebook. I think we can do that. Thanks for clarifying your current approach, I understand much better what you are doing. Some comments though:
pip install nbgrader # this will install into my active conda env
nbgrader extension install # this installs it into standard Jupyter locations
nbgrader extension activate
anaconda-notebook # this disables those standard Jupyter locations
|
A separate post, looking forward... What is the minimal set of changes we could make to Jupyter 4.x to ease user/dev pain for developing, packaging and installing 4.x nbextensions, but only with latest 4.x stable releases (not 5.0)? Can we do this in a backwards compatible way so we can release it quickly in a 4.2 release? Can we make provide hooks/APIs for Jupyter that allows it to better play with conda and other environments? |
It would be awesome if the answer to @ellisonbg last question is yes so that a new release could include whatever changes we think are necessary to support these extensions in a way that works well with other extensions. |
We specifically decided against adding hooks to Jupyter to be aware of envs, at least as they pertain to kernels, since doing so would mean that we should support at least virtualenv, conda, rbenv, nodenv, and every language-specific env system there is. Right now, what we already do is support installation of extensions, specs, and the like in envs, by ensuring that we look at |
I think this is critical:
If we solve that, then we can probably eliminated 95%-100% of the issues @ellisonbg raised in his comments. We briefly discussed about this here: jupyter/notebook#331 I think that some way to "intelligent" read nbconfig from user, prefix and system and some way to "integrate" those configs (establishing a hierarchy, figuring out override policies, etc) will let us ship something working for make easy the 4.x nbextension/serverextsnion installation and registering, that could be used with conda, but also outside the conda/anaconda ecosystem, and make everyone happy 😉 |
You might like https://github.com/Cadair/jupyter_environment_kernels/ -> all conda envs (after PR7 in that repo is merged) and all virtualenv envs are visible as kernels. |
Min, thanks for the clarification. I had missed we already have For clarification, here are the paths that show up on a 4.x conda installed jupyter: In [12]: jupyter_path('nbextension')
Out[12]:
['/Users/bgranger/Library/Jupyter/nbextension',
'/Users/bgranger/anaconda/envs/python34/share/jupyter/nbextension',
'/usr/local/share/jupyter/nbextension',
'/usr/share/jupyter/nbextension'] In [8]: jupyter_config_path()
Out[8]:
['/Users/bgranger/.jupyter',
'/Users/bgranger/anaconda/envs/python34/etc/jupyter',
'/usr/local/etc/jupyter',
'/etc/jupyter'] The key entries in both of these are This issue of "Env aware locations" is one aspect that we need to figure out. But it sounds like that is already solved. @ijstokes @damianavila @bollwyvl can you investigate to see if you can install things there so you don't have to write a wrapper script that changes the env var based paths? |
@ellisonbg we are in fact installing in I am planning to work on this issue in the coming days @minrk @takluyver inputs on this will be very welcomed... I would like to come up with a discussed implementation to support this use case... |
@JanSchulz, I guess Brian was referring about some kind of API in the core, but as Min said:
Btw, I ended up writing a CondaKernelSpecManager which is mainly doing what Stuart did but only for conda envs... but that's another discussion, so I will comment on that project later...
|
@damianavila I think that's deliberate-ish. As I see it, we support installing nbextensions inside an environment - so you could e.g. make a conda package of livereveal - but they have to be enabled/disabled and configured at the user level. Of course, you could use post-install and pre-remove scripts to automatically enable extensions on install and disable them on uninstall. This also works for e.g. apt packages: an extension could be installed systemwide, and individual users could decide whether to enable it. It's very much deliberate that frontend config is stored in one place, because:
|
Ahh, I was getting confused myself about the situation. The line that causes this problem is here: https://github.com/jupyter/notebook/blob/master/notebook/services/config/manager.py#L17 Basically, even though the main notebook app knows about all of the On Tue, Dec 15, 2015 at 9:33 AM, Damián Avila notifications@github.com
Brian E. Granger |
Yep, I suspected that...
I see, but I am not sure it is best way to deal with this... if I see it from the "environment" perspective, installing the config part in the user space whereas the actual extension is save inside the environment, feels weird because you should expect to have everything under the
I understand...
I still think you should be able to load nbconfig from other locations...
I agree that this is a potential problem...
What about establish a hierarchy? So the
Yep, that's exactly @ellisonbg. |
I don't think config is something that should be 'installed'. The code and data for an extension gets installed, and then the user modifies config to enable it. However, I think there's a better way to approach this than installing config to an environment. I think we should have a mechanism, similar to kernelspecs, for extensions to advertise themselves to the notebook, using files that would be installed as part of the extension. Then users can enable/disable them from a GUI, or even configure the notebook to load all the advertised extensions, if they're confident that's what they want. |
I think there is another level of "configuration", you are putting all the responsibility to enable the thing on the user at the user space... I believe it should be a way to automatically enable/config it from a package... so, if the user trust the people writing the thing, lets go with it, and do "everything for me", but please do not "corrupt" my user space, do it inside the prefix, config the thing there, so it is isolated and I can remove it easily if I decide that...
The proposal is interesting but at the end is the same unless the advertised extension are loaded automatically... but you are suggesting to enable them by a config option, or from a UI in the notebook... so we need again a concrete "action" from the user... there would be not way to tell them "install this package and trigger |
@takluyver I'd like to use if [ -e /etc/bashrc ]; then
. /etc/bashrc
fi in a Another example which is automatic is I appreciate that global environment variables and But nonetheless both point to examples where there is clear value from being able to merge some "higher-level" configuration information. Our target audience (and if I had to guess, then I would also say the majority of Notebook users) are not going to want to edit The next topic is sandboxing: whatever your sandboxing mechanism, if you end up in a situation where some extensions are only installed in certain sandboxes then things are going to get weird fast if their configuration for all these sandboxes has to be combined into a single So to my thinking it is necessary to decide if "sandboxing" of extensions is going to be supported or not: If it is, then the configuration of the extensions needs to (optionally) be allowed to live in the sandbox. If "sandboxing" isn't allowed, OK, then just install the extensions in |
I'm genuinely not sure whether we should be using envs for configuration, in addition to installation. It does seem attractive in the There's also isolation, which is ambiguous to me. For instance, virtualenvs disable access to |
This I don't agree with. Enabling extensions at installation time is like |
Not sure about that, we should look into that...
I think the hierarchy should be something like user>prefix>system... but you can probably find other uses cases where other hierarchy is better... additionally I believe the system should be "inclusive" by default probably "collecting/mixing" the user config with the prefix config... but letting the option to be exclusive if there is a need for that...
I am not asking for that... I think these action have to be separated at the jupyter level... but you will probably find people building "auto-enabled" packages, because it is the quickest way to have the extensions running without intervation from the user... but this is a conda thing... not a jupyter one. I agree that at the jupyter level, it should be separated... |
Why the two steps to install? As a user, if I'm installing a package that is an extension, I'm already making the decision that I want the package/extension. I like the option of activating at install time, and I would argue that from the user's point of view, that should be the default. Gino B.
|
This is starting/had already merged with jupyter/notebook#878 (comment)
Here's a talk by doug hellman with a bunch of examples and analysis. OpenMDAO supports both, and won't even work outside of one. I have explicit experience with Apache Allura (what drives SourceForge). In the stack, TurboGears uses entry_points to enable modules. So no, not strictly the conda/virtual- environment, but that's what you'd find, with whatever the expected behavior is for Upon that, Apache Allura extends this further, and uses an in-app UI for enabling specific project-level packages with rich configuration options. This is also used for themes. The plugins are usually expected to be some class with a magic method, a la register_ew_resources. There is still some config (again, a maddening mix of code and some conf language). Going beyond the Allura pattern, we could create an optional, level-0, almost unconfigurable end user app, say
Perhaps one way to think about it would be to have a the ability to enable/disable feature entry_points by wildcard: {
"NotebookApp": {
"server_extensions": {
"*": true,
"somebadthing": false
}
}
} or, conversely: {
"NotebookApp": {
"server_extensions": {
"*": false,
"some good thing": true
}
}
} whichever string has fewer wildcards wins :) This gives a "real" deployer the full option to specify exactly what is enabled, while making the single-user local notebook case much more straightforward. |
Python packages:
nbextension
Suggesting that installation should imply activation is like saying that On Fri, Dec 18, 2015 at 7:04 AM, Nicholas Bollweg notifications@github.com
Brian E. Granger |
I don't think we can rely on setuptools entry points for any of this. On Fri, Dec 18, 2015 at 4:49 PM, Brian Granger ellisonbg@gmail.com wrote:
Brian E. Granger |
But, I am totally fine with conda doing both installation and activation of On Fri, Dec 18, 2015 at 4:49 PM, Brian Granger ellisonbg@gmail.com wrote:
Brian E. Granger |
Hi @bollwyvl 👋 We're working through old JEPs and closing proposals that are no longer active or may not be relevant anymore. Under Jupyter's new governance model, we have an active Software Steering Council who reviews JEPs weekly. We are catching up on the backlog now. Since there has been no active discussion on this JEP in awhile, I'd propose we close it here (we'll leave it open for two more weeks in case you'd like to revive the conversation). If you would like to re-open the discussion after we close it, you are welcome to do that too. I think most of the content in this JEP has already been implemented. Feel free to comment here if there are any points you'd like highlight or keep in active discussion. |
This proposes an extension scaffolding/generation approach, initially based on creating a new yeoman
generator-
package to be distributed onnpm
.Request for review (based on previous discussion):
@ellisonbg @jdfreder @sccolbert @rgbkrk @damianavila
Please ping others that may be interested! I will post this to the jupyter and ipython lists as well!