diff --git a/.github/workflows/daily_tests.yml b/.github/workflows/daily_tests.yml index 1d53aadf8..2b5223771 100644 --- a/.github/workflows/daily_tests.yml +++ b/.github/workflows/daily_tests.yml @@ -25,7 +25,7 @@ jobs: uses: ./.github/workflows/testing_dev_e2e_with_live_services.yml secrets: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - DANDI_STAGING_API_KEY: ${{ secrets.DANDI_STAGING_API_KEY }} + DANDI_SANDBOX_API_KEY: ${{ secrets.DANDI_SANDBOX_API_KEY }} BuildTests: uses: ./.github/workflows/testing_flask_build_and_dist.yml diff --git a/.github/workflows/deploy_tests_on_pull_request.yml b/.github/workflows/deploy_tests_on_pull_request.yml index 9d59d44c6..68819b0b5 100644 --- a/.github/workflows/deploy_tests_on_pull_request.yml +++ b/.github/workflows/deploy_tests_on_pull_request.yml @@ -23,7 +23,7 @@ jobs: uses: ./.github/workflows/testing_dev_e2e_with_live_services.yml secrets: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - DANDI_STAGING_API_KEY: ${{ secrets.DANDI_STAGING_API_KEY }} + DANDI_SANDBOX_API_KEY: ${{ secrets.DANDI_SANDBOX_API_KEY }} BuildTests: uses: ./.github/workflows/testing_flask_build_and_dist.yml diff --git a/.github/workflows/testing_dev_e2e_with_live_services.yml b/.github/workflows/testing_dev_e2e_with_live_services.yml index 6778d5bf3..07fe7faba 100644 --- a/.github/workflows/testing_dev_e2e_with_live_services.yml +++ b/.github/workflows/testing_dev_e2e_with_live_services.yml @@ -4,7 +4,7 @@ on: secrets: CODECOV_TOKEN: required: true - DANDI_STAGING_API_KEY: + DANDI_SANDBOX_API_KEY: required: true jobs: @@ -78,7 +78,7 @@ jobs: - name: Create env file run: | touch .env - echo DANDI_STAGING_API_KEY=${{ secrets.DANDI_STAGING_API_KEY }} >> .env + echo DANDI_SANDBOX_API_KEY=${{ secrets.DANDI_SANDBOX_API_KEY }} >> .env - if: matrix.os != 'ubuntu-latest' name: Run tests diff --git a/docs/assets/tutorials/dandi/api-token-added.png b/docs/assets/tutorials/dandi/api-token-added.png index 422caa053..6f620829c 100644 Binary files a/docs/assets/tutorials/dandi/api-token-added.png and b/docs/assets/tutorials/dandi/api-token-added.png differ diff --git a/docs/assets/tutorials/dandi/api-tokens.png b/docs/assets/tutorials/dandi/api-tokens.png index c30e5b055..d7b247958 100644 Binary files a/docs/assets/tutorials/dandi/api-tokens.png and b/docs/assets/tutorials/dandi/api-tokens.png differ diff --git a/docs/assets/tutorials/dandi/create-dandiset.png b/docs/assets/tutorials/dandi/create-dandiset.png index e32b1555a..8cea539af 100644 Binary files a/docs/assets/tutorials/dandi/create-dandiset.png and b/docs/assets/tutorials/dandi/create-dandiset.png differ diff --git a/docs/assets/tutorials/dandi/review-page.png b/docs/assets/tutorials/dandi/review-page.png index 365779e54..8414291f8 100644 Binary files a/docs/assets/tutorials/dandi/review-page.png and b/docs/assets/tutorials/dandi/review-page.png differ diff --git a/docs/assets/tutorials/home-page.png b/docs/assets/tutorials/home-page.png index f2d05252b..24bcdba7c 100644 Binary files a/docs/assets/tutorials/home-page.png and b/docs/assets/tutorials/home-page.png differ diff --git a/docs/assets/tutorials/multiple/fail-name.png b/docs/assets/tutorials/multiple/fail-name.png index c5324692e..6515bd585 100644 Binary files a/docs/assets/tutorials/multiple/fail-name.png and b/docs/assets/tutorials/multiple/fail-name.png differ diff --git a/docs/assets/tutorials/multiple/format-options.png b/docs/assets/tutorials/multiple/format-options.png index e51fffcf4..4c8824d4a 100644 Binary files a/docs/assets/tutorials/multiple/format-options.png and b/docs/assets/tutorials/multiple/format-options.png differ diff --git a/docs/assets/tutorials/multiple/home-page-complete.png b/docs/assets/tutorials/multiple/home-page-complete.png index 0655bfd0f..ca90f5d7b 100644 Binary files a/docs/assets/tutorials/multiple/home-page-complete.png and b/docs/assets/tutorials/multiple/home-page-complete.png differ diff --git a/docs/assets/tutorials/multiple/info-page.png b/docs/assets/tutorials/multiple/info-page.png index b9d965bdb..2189a6c54 100644 Binary files a/docs/assets/tutorials/multiple/info-page.png and b/docs/assets/tutorials/multiple/info-page.png differ diff --git a/docs/assets/tutorials/multiple/inspect-page.png b/docs/assets/tutorials/multiple/inspect-page.png index ebf1d02bf..66e9d6077 100644 Binary files a/docs/assets/tutorials/multiple/inspect-page.png and b/docs/assets/tutorials/multiple/inspect-page.png differ diff --git a/docs/assets/tutorials/multiple/metadata-nwbfile.png b/docs/assets/tutorials/multiple/metadata-nwbfile.png index 57b5ed4de..7a2dd400a 100644 Binary files a/docs/assets/tutorials/multiple/metadata-nwbfile.png and b/docs/assets/tutorials/multiple/metadata-nwbfile.png differ diff --git a/docs/assets/tutorials/multiple/metadata-page.png b/docs/assets/tutorials/multiple/metadata-page.png index e5e53b961..a96925eae 100644 Binary files a/docs/assets/tutorials/multiple/metadata-page.png and b/docs/assets/tutorials/multiple/metadata-page.png differ diff --git a/docs/assets/tutorials/multiple/preview-page.png b/docs/assets/tutorials/multiple/preview-page.png index a69a68e92..855add334 100644 Binary files a/docs/assets/tutorials/multiple/preview-page.png and b/docs/assets/tutorials/multiple/preview-page.png differ diff --git a/docs/assets/tutorials/multiple/search-behavior.png b/docs/assets/tutorials/multiple/search-behavior.png index e51fffcf4..4c8824d4a 100644 Binary files a/docs/assets/tutorials/multiple/search-behavior.png and b/docs/assets/tutorials/multiple/search-behavior.png differ diff --git a/docs/assets/tutorials/multiple/subject-error.png b/docs/assets/tutorials/multiple/subject-error.png index cb2cad1a5..a9637a122 100644 Binary files a/docs/assets/tutorials/multiple/subject-error.png and b/docs/assets/tutorials/multiple/subject-error.png differ diff --git a/docs/assets/tutorials/multiple/valid-name.png b/docs/assets/tutorials/multiple/valid-name.png index d6052b607..5dfd624f4 100644 Binary files a/docs/assets/tutorials/multiple/valid-name.png and b/docs/assets/tutorials/multiple/valid-name.png differ diff --git a/docs/assets/tutorials/single/fail-name.png b/docs/assets/tutorials/single/fail-name.png index ab9188bc9..ff199ef1d 100644 Binary files a/docs/assets/tutorials/single/fail-name.png and b/docs/assets/tutorials/single/fail-name.png differ diff --git a/docs/assets/tutorials/single/format-options.png b/docs/assets/tutorials/single/format-options.png index 9b04ffd89..29d779ab4 100644 Binary files a/docs/assets/tutorials/single/format-options.png and b/docs/assets/tutorials/single/format-options.png differ diff --git a/docs/assets/tutorials/single/home-page-complete.png b/docs/assets/tutorials/single/home-page-complete.png index 4eb2080d5..a9373cdf8 100644 Binary files a/docs/assets/tutorials/single/home-page-complete.png and b/docs/assets/tutorials/single/home-page-complete.png differ diff --git a/docs/assets/tutorials/single/metadata-nwbfile.png b/docs/assets/tutorials/single/metadata-nwbfile.png index 966aa7025..16ec243de 100644 Binary files a/docs/assets/tutorials/single/metadata-nwbfile.png and b/docs/assets/tutorials/single/metadata-nwbfile.png differ diff --git a/docs/assets/tutorials/single/preview-page.png b/docs/assets/tutorials/single/preview-page.png index f3b8bd487..732b53fe6 100644 Binary files a/docs/assets/tutorials/single/preview-page.png and b/docs/assets/tutorials/single/preview-page.png differ diff --git a/docs/assets/tutorials/single/search-behavior.png b/docs/assets/tutorials/single/search-behavior.png index 8e34a94b2..9432d201b 100644 Binary files a/docs/assets/tutorials/single/search-behavior.png and b/docs/assets/tutorials/single/search-behavior.png differ diff --git a/docs/conf_extlinks.py b/docs/conf_extlinks.py index a5963d846..8f6df892d 100644 --- a/docs/conf_extlinks.py +++ b/docs/conf_extlinks.py @@ -8,7 +8,7 @@ "guide-issues": ("https://github.com/NeurodataWithoutBorders/nwb-guide/issues/%s", "%s"), "request-format-support": ("https://github.com/catalystneuro/neuroconv/issues/new?assignees=&labels=enhancement%%2Cdata+interfaces&projects=&template=format_request.yml&title=%%5BNew+Format%%5D%%3A+%s", "%s"), "path-expansion-guide": ("https://neuroconv.readthedocs.io/en/main/user_guide/expand_path.html%s", "%s"), - "dandi-staging": ("https://gui-staging.dandiarchive.org/%s", "%s"), + "dandi-sandbox": ("https://sandbox.dandiarchive.org/%s", "%s"), "dandi-archive": ("https://dandiarchive.org/%s", "%s"), "conda-install": ( "https://docs.conda.io/projects/conda/en/latest/user-guide/install/index.html#regular-installation%s", @@ -19,7 +19,6 @@ "https://github.com/NeurodataWithoutBorders/nwbinspector/blob/dev/.github/CONTRIBUTING.md%s", None, ), - "dandi-archive": ("https://dandiarchive.org/%s", "%s"), "ros3-tutorial": ( "https://pynwb.readthedocs.io/en/stable/tutorials/advanced_io/streaming.html#streaming-method-2-ros3%s", None, diff --git a/docs/developer_guide.rst b/docs/developer_guide.rst index 24ec40d54..2ce6ffb5a 100644 --- a/docs/developer_guide.rst +++ b/docs/developer_guide.rst @@ -246,7 +246,7 @@ Updating Tutorial Screenshots Before a release, you'll want to update the tutorial screenshots to reflect the latest changes in the application. #. To regenerate the dataset, you'll need to change ``regenerateTestData`` in the ``tests/e2e/config.ts`` to ``true`` or delete the test dataset directory ``rm -rf ~/NWB_GUIDE/.test``. -#. Create a ``.env`` file with the following content: ``DANDI_STAGING_API_KEY={your_dandi_staging_api_key}`` where ``{your_dandi_staging_api_key}`` is your DANDI staging API key from https://gui-staging.dandiarchive.org. +#. Create a ``.env`` file with the following content: ``DANDI_SANDBOX_API_KEY={your_dandi_sandbox_api_key}`` where ``{your_dandi_sandbox_api_key}`` is your DANDI sandbox API key from https://sandbox.dandiarchive.org. #. Run the End-to-End Tests locally using ``npm run test:tutorial``. This will generate new screenshots in the ``docs/assets/tutorials`` directory. #. Review the new screenshots to ensure they are accurate. #. If the screenshots are accurate, commit them to the repository. Their paths should be consistent across runs—allowing the new versions to show up on the tutorial. diff --git a/docs/tutorials/dataset_publication.rst b/docs/tutorials/dataset_publication.rst index db6de6bf2..d5a3af374 100644 --- a/docs/tutorials/dataset_publication.rst +++ b/docs/tutorials/dataset_publication.rst @@ -4,9 +4,9 @@ Dataset Publication For this tutorial, we'll publish the NWB files created in :doc:`Multi-Session Tutorial ` as a Dandiset on the DANDI Archive. This workflow works for any collection of NWB files (2.1+), whether they were created by NWB GUIDE or not. .. note:: - Creating an account on DANDI requires approval from the archive administrators. Separate approval is required for both the main archive and the development server. + Creating an account on DANDI requires approval from the archive administrators. Separate approval is required for both the main archive and the sandbox server. - **This tutorial requires an account on the** :dandi-staging:`DANDI Development server <>`. You’ll want to publish your `real` data on the main archive, which will require a separate approval but otherwise follows the same workflow defined in this tutorial. + **This tutorial requires an account on the** :dandi-sandbox:`DANDI Sandbox server <>`. You’ll want to publish your `real` data on the main archive, which will require a separate approval but otherwise follows the same workflow defined in this tutorial. Once your account is approved, you can move on to the next steps. @@ -24,23 +24,23 @@ You'll now notice that the **Exit Pipeline** button has been replaced with **Nex DANDI Upload ------------ -You’ll need to specify your DANDI API keys if you haven’t uploaded from the GUIDE before. These keys are unique between the Main and Development servers. +You’ll need to specify your DANDI API keys if you haven’t uploaded from the GUIDE before. These keys are unique between the Main and Sandbox servers. .. figure:: ../assets/tutorials/dandi/api-tokens.png :align: center :alt: A pop-up asking for DANDI API keys -To get your API key, visit the :dandi-staging:`staging website <>` and click on the profile icon in the top-right corner. This will show a dropdown with a copy button, which will assign your API key to the clipboard. +To get your API key, visit the :dandi-sandbox:`sandbox website <>` and click on the profile icon in the top-right corner. This will show a dropdown with a copy button, which will assign your API key to the clipboard. .. figure:: ../assets/dandi/api-token-location.png :align: center - :alt: DANDI Development server API key added + :alt: DANDI Sandbox server API key added Provide this for the Development API Key value on the GUIDE. .. figure:: ../assets/tutorials/dandi/api-token-added.png :align: center - :alt: DANDI staging API key added + :alt: DANDI sandbox API key added Press the **Submit** button to save your API key. This will populate the **Dandiset** input with a list of Dandisets associated with your account, which you can search by title or ID. @@ -48,7 +48,7 @@ But what if you don't have any Dandisets to upload to? No problem! Creating a Dandiset ^^^^^^^^^^^^^^^^^^^ -If you don't already have a Dandiset on the Development server, you can create one directly from the GUIDE. +If you don't already have a Dandiset on the Sandbox server, you can create one directly from the GUIDE. Press the **Create New Dandiset** button to open a pop-up that guides you through the required fields for Dandiset creation. diff --git a/docs/tutorials/index.rst b/docs/tutorials/index.rst index d8e9d0302..156b3a565 100644 --- a/docs/tutorials/index.rst +++ b/docs/tutorials/index.rst @@ -9,17 +9,17 @@ In these tutorials, you'll follow along on a :doc:`local installation of the GUI Watch a video walkthrough of these tutorials `here `_. .. note:: - This tutorial focuses on uploading to the DANDI Development server. + This tutorial focuses on uploading to the DANDI Sandbox server. - **When working with real data, you'll want to publish to the Main Archive**. In this case, follow the same steps outlined here—except replace the Development server with the Main Archive. + **When working with real data, you'll want to publish to the Main Archive**. In this case, follow the same steps outlined here—except replace the Sandbox server with the Main Archive. .. note:: - If you intend to complete the Dataset Publication section of this tutorial, you'll need to create an account on the DANDI Archive. This will need to be approved by the archive administrators and will require separate approval for both the main archive and the development server. + If you intend to complete the Dataset Publication section of this tutorial, you'll need to create an account on the DANDI Archive. This will need to be approved by the archive administrators and will require separate approval for both the main archive and the sandbox server. - **This tutorial requires an account on the** :dandi-staging:`DANDI Development server <>`. + **This tutorial requires an account on the** :dandi-sandbox:`DANDI Sandbox server <>`. - We recommend that you create an account on the Development server before you begin the tutorials. + We recommend that you create an account on the Sandbox server before you begin the tutorials. Before you begin these tutorials, **you'll need to generate the tutorial dataset** using the instructions on the Dataset page. diff --git a/package-lock.json b/package-lock.json index 43a8bcb36..58a081f6b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "nwb-guide", - "version": "1.0.2", + "version": "1.0.7-beta", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "nwb-guide", - "version": "1.0.2", + "version": "1.0.7-beta", "hasInstallScript": true, "license": "MIT", "dependencies": { @@ -16,7 +16,7 @@ "@vitest/coverage-v8": "^1.6.0", "chokidar": "^3.5.3", "concurrently": "^7.6.0", - "dandi": "^0.0.6", + "dandi": "^0.0.8", "find-free-port": "^2.0.0", "fomantic-ui": "^2.8.8", "fs-extra": "^10.0.0", @@ -8825,9 +8825,9 @@ } }, "node_modules/dandi": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/dandi/-/dandi-0.0.6.tgz", - "integrity": "sha512-SiPqaFl7M/MYhWRdZQuAHu/8jgcgZYTMDg3X0IbplCyvWVO+yPVTCZmkY1PX2hPrz3hIkCgNVmYlL6IzNlBq2Q==" + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/dandi/-/dandi-0.0.8.tgz", + "integrity": "sha512-J63n7K4/HdZzFpm4GQKza9dGtjshgX8whl7u7b9kjRoX1WKW0UJJUTLMC5TcsIzdVtGyYjP1yU1E6Xkvd962YQ==" }, "node_modules/data-uri-to-buffer": { "version": "6.0.2", diff --git a/package.json b/package.json index 772d4b291..2b070e253 100644 --- a/package.json +++ b/package.json @@ -146,7 +146,7 @@ "@vitest/coverage-v8": "^1.6.0", "chokidar": "^3.5.3", "concurrently": "^7.6.0", - "dandi": "^0.0.6", + "dandi": "^0.0.8", "find-free-port": "^2.0.0", "fomantic-ui": "^2.8.8", "fs-extra": "^10.0.0", diff --git a/src/electron/frontend/core/components/DandiResults.js b/src/electron/frontend/core/components/DandiResults.js index 9c4360aef..41ff7e801 100644 --- a/src/electron/frontend/core/components/DandiResults.js +++ b/src/electron/frontend/core/components/DandiResults.js @@ -1,7 +1,7 @@ import { LitElement, css, html } from "lit"; import { get } from "dandi"; -import { isStaging, getAPIKey } from "../../utils/upload"; +import { isSandbox, getAPIKey } from "../../utils/upload"; export class DandiResults extends LitElement { static get styles() { @@ -38,9 +38,9 @@ export class DandiResults extends LitElement { const otherElIds = ["embargo_status"]; - const staging = isStaging(this.id); - const type = staging ? "staging" : undefined; - const api_key = await getAPIKey.call(this, staging); + const sandbox = isSandbox(this.id); + const type = sandbox ? "sandbox" : undefined; + const api_key = await getAPIKey.call(this, sandbox); const dandiset = await get(this.id, { type, diff --git a/src/electron/frontend/core/components/pages/guided-mode/options/GuidedUpload.js b/src/electron/frontend/core/components/pages/guided-mode/options/GuidedUpload.js index 0208317bc..e290fdcfe 100644 --- a/src/electron/frontend/core/components/pages/guided-mode/options/GuidedUpload.js +++ b/src/electron/frontend/core/components/pages/guided-mode/options/GuidedUpload.js @@ -89,7 +89,7 @@ export class GuidedUploadPage extends Page { formProps: { validateOnChange: async (name, parent) => { const value = parent[name]; - if (name.includes("api_key")) return await validateDANDIApiKey(value, name.includes("staging")); + if (name.includes("api_key")) return await validateDANDIApiKey(value, name.includes("sandbox")); }, }, }); diff --git a/src/electron/frontend/core/components/pages/settings/SettingsPage.js b/src/electron/frontend/core/components/pages/settings/SettingsPage.js index ac427a5c4..be8a51952 100644 --- a/src/electron/frontend/core/components/pages/settings/SettingsPage.js +++ b/src/electron/frontend/core/components/pages/settings/SettingsPage.js @@ -330,7 +330,7 @@ export class SettingsPage extends Page { onUpdate: () => (this.unsavedUpdates = true), validateOnChange: async (name, parent) => { const value = parent[name]; - if (name.includes("api_key")) return await validateDANDIApiKey(value, name.includes("staging")); + if (name.includes("api_key")) return await validateDANDIApiKey(value, name.includes("sandbox")); return true; }, onThrow, diff --git a/src/electron/frontend/core/components/pages/uploads/UploadsPage.js b/src/electron/frontend/core/components/pages/uploads/UploadsPage.js index 52181c059..8d18e8ecf 100644 --- a/src/electron/frontend/core/components/pages/uploads/UploadsPage.js +++ b/src/electron/frontend/core/components/pages/uploads/UploadsPage.js @@ -34,7 +34,7 @@ import keyIcon from "../../../../assets/icons/key.svg?raw"; import { AWARD_VALIDATION_FAIL_MESSAGE, awardNumberValidator, - isStaging, + isSandbox, validate, getAPIKey, } from "../../../../utils/upload"; @@ -120,13 +120,13 @@ export function createDandiset(results = {}) { }); const uploadToMain = form.resolved.archive === "main"; - const staging = !uploadToMain; + const sandbox = !uploadToMain; - const api_key = await getAPIKey.call(this, staging); + const api_key = await getAPIKey.call(this, sandbox); const api = new dandi.API({ token: api_key, - type: staging ? "staging" : undefined, + type: sandbox ? "sandbox" : undefined, }); await api.authorize(); @@ -185,14 +185,14 @@ export async function uploadToDandi(info, type = "project" in info ? "project" : const dandiset_id = dandiset; - const staging = isStaging(dandiset_id); // Automatically detect staging IDs + const sandbox = isSandbox(dandiset_id); // Automatically detect sandbox IDs - const api_key = await getAPIKey.call(this, staging); + const api_key = await getAPIKey.call(this, sandbox); const payload = { dandiset_id, ...info.additional_settings, - staging, + sandbox: sandbox, api_key, }; @@ -269,7 +269,7 @@ export class UploadsPage extends Page { formProps: { validateOnChange: async (name, parent) => { const value = parent[name]; - if (name.includes("api_key")) return await validateDANDIApiKey(value, name.includes("staging")); + if (name.includes("api_key")) return await validateDANDIApiKey(value, name.includes("sandbox")); }, }, })); diff --git a/src/electron/frontend/core/validation/dandi.ts b/src/electron/frontend/core/validation/dandi.ts index 7829b68f8..b92890f07 100644 --- a/src/electron/frontend/core/validation/dandi.ts +++ b/src/electron/frontend/core/validation/dandi.ts @@ -3,14 +3,14 @@ const dandiAPITokenRegex = /^[a-f0-9]{40}$/; import { validateToken } from 'dandi' -export const validateDANDIApiKey = async (apiKey: string, staging = false) => { +export const validateDANDIApiKey = async (apiKey: string, sandbox = false) => { if (apiKey) { if (!dandiAPITokenRegex.test(apiKey)) return [{ type: "error", message: `Invalid API key format. Must be a 40 character hexadecimal string` }]; - const authFailedError = {type: 'error', message: `Authorization failed. Make sure you're providing an API key for the ${staging ? 'staging' : 'main'} archive.`} + const authFailedError = {type: 'error', message: `Authorization failed. Make sure you're providing an API key for the ${sandbox ? 'sandbox' : 'main'} archive.`} - const isValid = validateToken({ token: apiKey, type: staging ? 'staging' : undefined }).catch(e => false) + const isValid = validateToken({ token: apiKey, type: sandbox ? 'sandbox' : undefined }).catch(e => false) if (!isValid) return [ authFailedError ] return true } diff --git a/src/electron/frontend/utils/upload.ts b/src/electron/frontend/utils/upload.ts index 9ead9720c..fa8bccb52 100644 --- a/src/electron/frontend/utils/upload.ts +++ b/src/electron/frontend/utils/upload.ts @@ -18,7 +18,7 @@ import { NotyfNotification } from "notyf"; import dandiGlobalSchema from "../../../schemas/json/dandi/global.json"; import { isNumericString } from "./typecheck"; -export const isStaging = (id: string) => parseInt(id) >= 100000; +export const isSandbox = (id: string) => parseInt(id) >= 100000; type NotificationType = { type: string; @@ -51,9 +51,9 @@ export async function validate( message: `Invalid ID – Dandiset ID must be 6 digits.` }] - const staging = isStaging(value) - const type = staging ? "staging" : undefined; - const token = await getAPIKey.call(this, staging); + const sandbox = isSandbox(value) + const type = sandbox ? "sandbox" : undefined; + const token = await getAPIKey.call(this, sandbox); const dandiset = await get(value, { type, @@ -106,14 +106,14 @@ export const AWARD_VALIDATION_FAIL_MESSAGE = 'Award number must be properly spac // this: export async function getAPIKey( this: Page, - staging = false + sandbox = false ) { - const whichAPIKey = staging ? "development_api_key" : "main_api_key"; + const whichAPIKey = sandbox ? "sandbox_api_key" : "main_api_key"; const DANDI = global.data.DANDI; let api_key = DANDI?.api_keys?.[whichAPIKey]; - const errors = await validateDANDIApiKey(api_key, staging); + const errors = await validateDANDIApiKey(api_key, sandbox); const isInvalid = Array.isArray(errors) ? errors.length : !errors; @@ -154,7 +154,7 @@ export async function getAPIKey( onClick: async () => { const value = input.value; if (value) { - const errors = await validateDANDIApiKey(input.value, staging); + const errors = await validateDANDIApiKey(input.value, sandbox); if (!errors || !errors.length) { modal.remove(); diff --git a/src/pyflask/manageNeuroconv/manage_neuroconv.py b/src/pyflask/manageNeuroconv/manage_neuroconv.py index b3463ac66..4491f36ed 100644 --- a/src/pyflask/manageNeuroconv/manage_neuroconv.py +++ b/src/pyflask/manageNeuroconv/manage_neuroconv.py @@ -1346,7 +1346,7 @@ def upload_folder_to_dandi( dandiset_id: str, api_key: str, nwb_folder_path: Optional[str] = None, - staging: Optional[bool] = None, # Override default staging=True + sandbox: Optional[bool] = None, # Override default staging=True cleanup: Optional[bool] = None, number_of_jobs: Optional[int] = None, number_of_threads: Optional[int] = None, @@ -1364,7 +1364,7 @@ def upload_folder_to_dandi( return automatic_dandi_upload( dandiset_id=dandiset_id, nwb_folder_path=Path(nwb_folder_path), - staging=staging, + staging=sandbox, # Map sandbox parameter to staging for external API cleanup=cleanup, number_of_jobs=number_of_jobs or 1, number_of_threads=number_of_threads or 1, @@ -1375,7 +1375,7 @@ def upload_project_to_dandi( dandiset_id: str, api_key: str, project: Optional[str] = None, - staging: Optional[bool] = None, # Override default staging=True + sandbox: Optional[bool] = None, # Override default staging=True cleanup: Optional[bool] = None, number_of_jobs: Optional[int] = None, number_of_threads: Optional[int] = None, @@ -1395,7 +1395,7 @@ def upload_project_to_dandi( return automatic_dandi_upload( dandiset_id=dandiset_id, nwb_folder_path=CONVERSION_SAVE_FOLDER_PATH / project, # Scope valid DANDI upload paths to GUIDE projects - staging=staging, + staging=sandbox, # Map sandbox parameter to staging for external API cleanup=cleanup, number_of_jobs=number_of_jobs, number_of_threads=number_of_threads, diff --git a/src/schemas/dandi-upload.schema.ts b/src/schemas/dandi-upload.schema.ts index 1554e224f..2cfd0271a 100644 --- a/src/schemas/dandi-upload.schema.ts +++ b/src/schemas/dandi-upload.schema.ts @@ -2,7 +2,7 @@ import { Dandiset, getMine } from 'dandi' import { global } from '../electron/frontend/core/progress' import upload from './json/dandi/upload.json' assert { type: "json" } -import { isStaging } from '../electron/frontend/utils/upload' +import { isSandbox } from '../electron/frontend/utils/upload' import { baseUrl, onServerOpen } from '../electron/frontend/core/server/globals' import { isStorybook } from '../electron/frontend/core/globals' @@ -54,16 +54,16 @@ export const regenerateDandisets = async () => { export const updateDandisets = async (main = true) => { - const staging = !main + const sandbox = !main // Fetch My Dandisets - const whichAPIKey = staging ? "development_api_key" : "main_api_key"; + const whichAPIKey = sandbox ? "sandbox_api_key" : "main_api_key"; const DANDI = global.data.DANDI; let token = DANDI?.api_keys?.[whichAPIKey]; if (!token) return [] - return await getMine({ token, type: staging ? 'staging' : undefined }, { embargoed: true }) + return await getMine({ token, type: sandbox ? 'sandbox' : undefined }, { embargoed: true }) .then((results) => results ? Promise.all(results.map(addDandiset)) : []) .catch(() => { return [] @@ -85,22 +85,22 @@ export const addDandiset = async (info) => { enumSet.add(id) idSchema.enum = Array.from(enumSet) - const staging = isStaging(id) + const sandbox = isSandbox(id) if (!idSchema.enumLabels) idSchema.enumLabels = {} if (!idSchema.enumKeywords) idSchema.enumKeywords = {} if (!idSchema.enumCategories) idSchema.enumCategories = {} - const token = global.data.DANDI.api_keys[staging ? "development_api_key" : "main_api_key"]; + const token = global.data.DANDI.api_keys[sandbox ? "sandbox_api_key" : "main_api_key"]; - info = new Dandiset(info, { type: staging ? "staging" : undefined, token }) + info = new Dandiset(info, { type: sandbox ? "sandbox" : undefined, token }) const latestVersionInfo = (info.most_recent_published_version ?? info.draft_version)! const enumLabels = `${id} — ${latestVersionInfo.name}` const isDraft = latestVersionInfo.version === 'draft' - const enumCategories = (isDraft ? 'Unpublished' : '') + (staging ? `${isDraft ? ` - ` : ''}Staging` : '') + const enumCategories = (isDraft ? 'Unpublished' : '') + (sandbox ? `${isDraft ? ` - ` : ''}Sandbox` : '') const fullInfo = await info.getInfo({ version: latestVersionInfo.version }); diff --git a/src/schemas/json/dandi/create.json b/src/schemas/json/dandi/create.json index 530960552..5bbdba30d 100644 --- a/src/schemas/json/dandi/create.json +++ b/src/schemas/json/dandi/create.json @@ -23,11 +23,11 @@ "archive": { "type": "string", "enumLabels": { - "staging": "Development Server", + "sandbox": "Sandbox Server", "main": "Main Archive" }, - "enum": ["main", "staging"], - "description": "Which DANDI server to upload to.
Note: The Development Server is recommended for developers, or users learning to use DANDI", + "enum": ["main", "sandbox"], + "description": "Which DANDI server to upload to.
Note: The Sandbox Server is recommended for developers, or users learning to use DANDI", "strict": true }, diff --git a/src/schemas/json/dandi/global.json b/src/schemas/json/dandi/global.json index 8c37c6494..68ba5c86f 100644 --- a/src/schemas/json/dandi/global.json +++ b/src/schemas/json/dandi/global.json @@ -1,5 +1,5 @@ { - "description": "Log in to DANDI, click on your user initials in the top-right corner, and copy your API key from the resulting pop-up.
Note: The main archive and the development server have different API keys.", + "description": "Log in to DANDI, click on your user initials in the top-right corner, and copy your API key from the resulting pop-up.
Note: The main archive and the sandbox server have different API keys.", "properties": { "api_keys": { "properties": { @@ -8,10 +8,10 @@ "format": "password", "description": "Your DANDI API key from the main archive" }, - "development_api_key": { + "sandbox_api_key": { "type": "string", "format": "password", - "description": "Your DANDI API key from the development server" + "description": "Your DANDI API key from the sandbox server" } }, "additionalProperties": false, diff --git a/tests/e2e/config.ts b/tests/e2e/config.ts index 8bf6e1cdb..af22166e0 100644 --- a/tests/e2e/config.ts +++ b/tests/e2e/config.ts @@ -107,7 +107,7 @@ export const regenerateTestData = !existsSync(testDataPath) || !existsSync(testD export const dandiInfo = { id: '215297', // this dandiset is used for testing and owned by Ryan - token: process.env.DANDI_STAGING_API_KEY + token: process.env.DANDI_SANDBOX_API_KEY } // ------------------------------------------------------- diff --git a/tests/e2e/workflow.ts b/tests/e2e/workflow.ts index 354a401d1..a1df2ea62 100644 --- a/tests/e2e/workflow.ts +++ b/tests/e2e/workflow.ts @@ -28,8 +28,8 @@ export const uploadToDandi = (subdirectory, forceSkip = false) => { const dashboard = document.querySelector('nwb-dashboard') const page = dashboard.page const modal = page.globalModal - const stagingKeyInput = modal.form.getFormElement(['development_api_key']) - stagingKeyInput.updateData(dandiAPIToken) + const sandboxKeyInput = modal.form.getFormElement(['sandbox_api_key']) + sandboxKeyInput.updateData(dandiAPIToken) }, dandiInfo.token) await takeScreenshot(join(subdirectory, 'api-token-added'), 100)