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#

  1. 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

  2. src/renderer/assets - Contains all the frontend-facing assets (e.g. images, css, etc.)

  3. pyflask - Contains all the source code for the backend

Starting a New Feature#

  1. 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.

  1. 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.

  1. 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.

  1. 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#

  1. Sign up for an Apple Developer account (99 USD annual fee).

  2. Follow steps in https://developer.apple.com/help/account/create-certificates/create-developer-id-certificates/
    1. Browse current Certificates at https://developer.apple.com/account/resources/certificates/list.

    2. Click Certificates in the sidebar. On the top left, click the add button (+).

    3. Under Software, select Developer ID Application.

    4. Select Profile Type: G2 Sub-CA (Xcode 11.4.1 or later).

    5. Create a certificate signing request (CSR) by following the steps in https://developer.apple.com/help/account/create-certificates/create-a-certificate-signing-request
      1. Open Keychain Access.

      2. Choose Keychain Access > Certificate Assistant > Request a Certificate from a Certificate Authority.

      3. In the Certificate Assistant dialog, enter an email address in the User Email Address field.

      4. In the Common Name field, enter a name for the key (for example, John Doe Dev Key). Ryan entered “Ryan Ly”.

      5. Leave the CA Email Address field empty.

      6. Choose “Saved to disk”, and click Continue.

      7. Save the certificate request file to disk.

    6. Select the certificate request file (a file with a .certSigningRequest file extension), then click Choose.

    7. Click Continue, click Download - The certificate file (.cer file) appears in your Downloads folder.

    8. To install the certificate in your keychain, double-click the downloaded certificate file.

    9. The certificate appears in the My Certificates category in Keychain Access, but may not be trusted.

    10. For local development, download the appropriate Apple Intermediate Certificate.

    11. from https://www.apple.com/certificateauthority/ to make certificate trusted/valid.

    12. For this, it is Developer ID - G2 (Expiring 09/17/2031 00:00:00 UTC).

    13. Double-click the downloaded file.

    14. Confirm that the certificate now shows up as trusted in Keychain Access.

  3. Provide a p12 file for notarizing via GitHub Action.
    1. Open Keychain Access.

    2. Select the Developer ID Application certificate.

    3. Choose Keychain Access > Export Items…

    4. Export the certificate to a file with a password.

    5. Get a base64 version of the certificate by running: base64 -i Certificate.p12 -o base64.txt

    6. Open base64.txt and copy the contents to the nwb-guide repository secret MACOS_CERTIFICATE.

    7. Set the password for the certificate in the nwb-guide repository secret MACOS_CERTIFICATE_PASSWORD.

  4. Create an app-specific password for building locally and via the GitHub Action.
    1. Go to https://appleid.apple.com/account/manage.

    2. Follow the steps to create an App-Specific Password.

    3. Use that for local building and in the secrets.APPLE_PASSWORD repository secret.

  5. Review and agree to any pending agreements.
    1. Go to https://appstoreconnect.apple.com/agreements/#/ and agree to pending agreements for Free Apps.

    2. 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.