Developer Guide#
We welcome contributions from the community! If you are interested in contributing, please read the following guide to get started.
Installation#
Clone the Repo#
Start by cloning the repository
git clone https://github.com/NeurodataWithoutBorders/nwb-guide
cd nwb-guide
Install Python Dependencies#
Install the appropriate Python dependencies for your operating system.
Windows
conda env create -f ./environments/environment-Windows.yml
Mac with x64 architecture
conda env create -f ./environments/environment-MAC-intel.yml
Mac with arm64 architecture
conda env create -f ./environments/environment-MAC-apple-silicon.yml
Linux
conda env create -f ./environments/environment-Linux.yml
Activate the Python Environment#
Before starting NWB GUIDE, you’ll need to ensure that the Python environment is activated.
conda activate nwb-guide
Install JavaScript Dependencies#
Next, install all JavaScript dependencies based on the package-lock.json file.
npm ci
Run the Application#
You can now run the following command to start the application using Electron.
npm start
Repo Structure#
- src/renderer/src - Contains all the source code for the frontend
index.js - The entry point for the application
pages.js - The main code that controls which pages are rendered and how they are linked together
stories - Contains all the Web Components and related Storybook stories
electron - Contains all the Electron-related code to enable conditional inclusion for development mode
src/renderer/assets - Contains all the frontend-facing assets (e.g. images, css, etc.)
pyflask - Contains all the source code for the backend
Starting a New Feature#
Create a new branch off of the
main
branch. The branch name should be descriptive of the feature you are working on.
Note
For example, if you are working on a feature to add a new page, you could name the branch add-new-metadata-page
.
Make your changes on the new branch.
Important
When you are ready to commit, make sure to add tests for your new code as well.
Push your changes to the remote branch. Then, open a pull request to merge your branch into the
main
branch.
Note
Make sure to add a description of the changes you made in the pull request.
Once the pull request is approved, merge it into the
main
branch. You can then delete the branch you created in step 1.
Adding a New Page#
New pages can be added by linking a component in the src/pages.js
file. For example, if you wanted to
add a new page called NewPage
, you would add the following to the configuration file:
import NewPage from "./stories/pages/NewPage";
// ...
const pages = {
// ...
'guided': new GuidedHomePage({
label: "Guided Mode",
icon: guidedIcon,
pages: {
start: new GuidedStartPage({
label: "Start",
}),
// ...
newpage: new NewPage({
label: "New Page", // This is the label that will be displayed in the sidebar
}),
// ...
},
})
// ...
}
// ...
This will automatically add the new page to the sidebar. The page itself can be defined in the
src/stories/pages/NewPage.js
file. For example, if you wanted to add a new page that displays
a simple message, you could add the following to the src/stories/pages/NewPage.js
file:
import { html } from "lit";
import { Page } from '../../Page.js';
export default class NewPage extends Page {
constructor(...args) {
super(...args);
console.log(this.info.globalState) // This will print the global state that is currently being passed between subpages
}
render() {
return html`
<div>
<h1>${this.info.label}</h1>
<p>This is a new page!</p>
</div>
`;
}
}
Extending the Page
class rather than the LitElement
class provides each page with standard properties and
methods that allow for uniform handling across the application.
Discover Existing Components#
While developing NWB GUIDE, you may find that you need to use a component that already exists in the codebase. To
find a component, you can manually peruse the src/stories
directory or run the project’s Storybook instance to
see all of the components in action.
To run Storybook, simply run npm run storybook
in the root directory of the repository. This will start a local
server that you can access using the link provided on the command line.
To see if someone else has developed a third-party component to fit your needs, you can refer to WebComponents.org and search based on your particular needs. https://www.npmjs.com/NPM may also be useful to search for third-party packages (e.g. Handsontable) that implement the feature you need.
Testing#
We use Chromatic on the Storybook to test changes to front-end components as well as to demonstrate example cases of what those components would look like on a real project.
We use pytest for testing the back-end manager and REST API. To run the tests, simply run pytest
in
the root directory of the repository.
Coding Style#
For all JavaScript code on the frontend, we use the prettier code formatter with
parameters defined in the prettier.config.js
configuration file.
For all Python code on the backend, we use the black coding style with parameters defined
in the pyproject.toml
configuration file.
Pre-Commit#
We use an automated pre-commit bot to enforce these on the main repo, but contributions from external forks would either have to grant bot permissions on their own fork (via the pre-commit bot website) or run pre-commit manually.
For instructions to install pre-commit, as well as some other minor coding styles we follow, refer to the NeuroConv style guide.
Code signing on Mac OS#
Sign up for an Apple Developer account (99 USD annual fee).
- Follow steps in https://developer.apple.com/help/account/create-certificates/create-developer-id-certificates/
Browse current Certificates at https://developer.apple.com/account/resources/certificates/list.
Click Certificates in the sidebar. On the top left, click the add button (+).
Under Software, select Developer ID Application.
Select Profile Type: G2 Sub-CA (Xcode 11.4.1 or later).
- Create a certificate signing request (CSR) by following the steps in https://developer.apple.com/help/account/create-certificates/create-a-certificate-signing-request
Open Keychain Access.
Choose Keychain Access > Certificate Assistant > Request a Certificate from a Certificate Authority.
In the Certificate Assistant dialog, enter an email address in the User Email Address field.
In the Common Name field, enter a name for the key (for example, John Doe Dev Key). Ryan entered “Ryan Ly”.
Leave the CA Email Address field empty.
Choose “Saved to disk”, and click Continue.
Save the certificate request file to disk.
Select the certificate request file (a file with a .certSigningRequest file extension), then click Choose.
Click Continue, click Download - The certificate file (.cer file) appears in your Downloads folder.
To install the certificate in your keychain, double-click the downloaded certificate file.
The certificate appears in the My Certificates category in Keychain Access, but may not be trusted.
For local development, download the appropriate Apple Intermediate Certificate.
from https://www.apple.com/certificateauthority/ to make certificate trusted/valid.
For this, it is Developer ID - G2 (Expiring 09/17/2031 00:00:00 UTC).
Double-click the downloaded file.
Confirm that the certificate now shows up as trusted in Keychain Access.
- Provide a p12 file for notarizing via GitHub Action.
Open Keychain Access.
Select the Developer ID Application certificate.
Choose Keychain Access > Export Items…
Export the certificate to a file with a password.
Get a base64 version of the certificate by running: base64 -i Certificate.p12 -o base64.txt
Open base64.txt and copy the contents to the nwb-guide repository secret MACOS_CERTIFICATE.
Set the password for the certificate in the nwb-guide repository secret MACOS_CERTIFICATE_PASSWORD.
- Create an app-specific password for building locally and via the GitHub Action.
Follow the steps to create an App-Specific Password.
Use that for local building and in the secrets.APPLE_PASSWORD repository secret.
- Review and agree to any pending agreements.
Go to https://appstoreconnect.apple.com/agreements/#/ and agree to pending agreements for Free Apps.
Review and agree to the Apple Developer Program License Agreement, which updates periodically.
Updating the Documentation#
The documentation is generated by Sphinx with the PyData Sphinx theme.
To build the documentation locally, run:
cd docs
make html
You can also run make clean
from the docs
directory to remove all files in the docs/build directory.
The documentation is hosted online using ReadTheDocs. An automation rule was set up so that
new tags will automatically be activated; however, these versions are not automatically listed in the version
switcher. docs/_static/switcher.json
must be manually updated to specify new versions, remove versions
that are too old, label a particular version as stable in the name, and identify which version is
“preferred” for use in version warning banners. See
PyData Sphinx theme user guide for instructions and more information.