From 48dde053e5315be43cff1236c9e12986e15fe253 Mon Sep 17 00:00:00 2001 From: Aaron Kanzer Date: Thu, 11 Jan 2024 14:38:36 -0500 Subject: [PATCH 1/5] Streamline local dev process with hot reloading, docker, and resolved fixtures --- DEVELOPMENT.md | 17 +++------- admin_dev_startup.sh | 31 +++++++++++++++++++ .../commands/create_dev_dandiset.py | 21 +++++++++---- web/Dockerfile.dev | 19 ++++++++++++ web/package.json | 2 +- 5 files changed, 71 insertions(+), 19 deletions(-) create mode 100644 admin_dev_startup.sh create mode 100644 web/Dockerfile.dev diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index b2695a990..fe8e88602 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -3,19 +3,12 @@ ## Develop with Docker (recommended quickstart) This is the simplest configuration for developers to start with. -### Initial Setup -1. Run `docker-compose run --rm django ./manage.py migrate` -2. Run `docker-compose run --rm django ./manage.py createcachetable` -3. Run `docker-compose run --rm django ./manage.py createsuperuser` - and follow the prompts to create your own user. - Set your username to your email to ensure parity with how GitHub logins work. -4. Run `docker-compose run --rm django ./manage.py create_dev_dandiset --owner your.email@email.com` - to create a dummy dandiset to start working with. +## Instructions for local development with front-end hot reloading -### Run Application -1. Run `docker-compose up` -2. Access the site, starting at http://localhost:8000/admin/ -3. When finished, use `Ctrl+C` +1. Ensure you have installed Docker on your local machine +2. Run `./admin_dev_startup.sh `. When prompted, enter an username and password in the command prompt. (If you run into local errors with the script, you may need to run `chmod +x admin_dev_startup.sh` first) +3. Navigate to `localhost:8000/admin`, and log in with the username and password you used in Step #2. Under the `User` section, select the username and change the `Status` from `Incomplete` to `Approved`. +4. Navigate to `localhost:8085` and select `LOG IN WITH GITHUB`. ### Application Maintenance Occasionally, new package dependencies or schema changes will necessitate diff --git a/admin_dev_startup.sh b/admin_dev_startup.sh new file mode 100644 index 000000000..6b3d352b7 --- /dev/null +++ b/admin_dev_startup.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +# This script can be used to launch both the frontend and backend with ease locally +# Happy developing! + +if [ $# -lt 2 ]; then + echo "Usage: $0 " + exit 1 +fi + +image_name=$1 +email=$2 + +cd web/ + +# Build Docker image (include the path to the Dockerfile's context) +docker build -t $image_name -f Dockerfile.dev . + +# Run the Docker container for frontend in background +docker run -d -v "$(pwd):/usr/src/app" -v /usr/src/app/node_modules -p 8085:8085 -e CHOKIDAR_USEPOLLING=true $image_name + +cd .. + +# Run Docker Compose commands for backend +docker-compose run --rm django ./manage.py migrate +docker-compose run --rm django ./manage.py createcachetable +docker-compose run --rm django ./manage.py createsuperuser +docker-compose run --rm django ./manage.py create_dev_dandiset --owner $email + +# Bring backend application to life! +docker-compose up diff --git a/dandiapi/api/management/commands/create_dev_dandiset.py b/dandiapi/api/management/commands/create_dev_dandiset.py index a07bfdc40..80092a7e4 100644 --- a/dandiapi/api/management/commands/create_dev_dandiset.py +++ b/dandiapi/api/management/commands/create_dev_dandiset.py @@ -1,3 +1,4 @@ +import hashlib from uuid import uuid4 from django.conf import settings @@ -15,8 +16,13 @@ @click.command() @click.option('--name', default='Development Dandiset') @click.option('--owner', 'email', required=True, help='The email address of the owner') -def create_dev_dandiset(*, name: str, email: str): +@click.option('--first_name', default='Randi The Admin') +@click.option('--last_name', default='Dandi') +def create_dev_dandiset(name: str, email: str, first_name: str, last_name: str): owner = User.objects.get(email=email) + owner.first_name = first_name + owner.last_name = last_name + owner.save() version_metadata = { 'description': 'An informative description', @@ -26,16 +32,19 @@ def create_dev_dandiset(*, name: str, email: str): user=owner, embargo=False, version_name=name, version_metadata=version_metadata ) - uploaded_file = SimpleUploadedFile(name='foo/bar.txt', content=b'A' * 20) + file_size = 20 + file_content = b'A' * file_size + uploaded_file = SimpleUploadedFile(name='foo/bar.txt', content=file_content) etag = '76d36e98f312e98ff908c8c82c8dd623-0' + try: asset_blob = AssetBlob.objects.get(etag=etag) except AssetBlob.DoesNotExist: + # Since the SimpleUploadedFile is non-zarr asset, validation fails + # without a sha2_256 initially provided. + sha256_hash = hashlib.sha256(file_content).hexdigest() asset_blob = AssetBlob( - blob_id=uuid4(), - blob=uploaded_file, - etag=etag, - size=20, + blob_id=uuid4(), blob=uploaded_file, etag=etag, size=file_size, sha256=sha256_hash ) asset_blob.save() asset_metadata = { diff --git a/web/Dockerfile.dev b/web/Dockerfile.dev new file mode 100644 index 000000000..03f579200 --- /dev/null +++ b/web/Dockerfile.dev @@ -0,0 +1,19 @@ +# Use node:16 due to project still being on Vue 2 and not Vue 3 - as of Jan 2024 +FROM node:16 + +# Set the working directory +WORKDIR /usr/src/app + +# Copy package.json and install dependencies +COPY package.json yarn.lock ./ +RUN yarn install --production=false + +# Copy the rest of your application's code +COPY . . + +# Expose the port the app runs on +EXPOSE 8085 + +# Start the application +CMD ["yarn", "run", "dev"] + diff --git a/web/package.json b/web/package.json index 9cf57db61..42e6356e4 100644 --- a/web/package.json +++ b/web/package.json @@ -2,7 +2,7 @@ "name": "dandi-archive", "version": "0.0.0", "scripts": { - "dev": "vite", + "dev": "vite --host 0.0.0.0", "build": "vite build", "preview": "vite preview --port 4173", "type-check": "vue-tsc --noEmit", From ccfd739f19188f9c22f7028dadcf33768d6aa835 Mon Sep 17 00:00:00 2001 From: Aaron Kanzer Date: Thu, 11 Jan 2024 15:17:34 -0500 Subject: [PATCH 2/5] make command less error-prone --- dandiapi/api/management/commands/create_dev_dandiset.py | 9 +++++---- web/Dockerfile.dev | 3 +-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dandiapi/api/management/commands/create_dev_dandiset.py b/dandiapi/api/management/commands/create_dev_dandiset.py index 80092a7e4..057783520 100644 --- a/dandiapi/api/management/commands/create_dev_dandiset.py +++ b/dandiapi/api/management/commands/create_dev_dandiset.py @@ -19,10 +19,11 @@ @click.option('--first_name', default='Randi The Admin') @click.option('--last_name', default='Dandi') def create_dev_dandiset(name: str, email: str, first_name: str, last_name: str): - owner = User.objects.get(email=email) - owner.first_name = first_name - owner.last_name = last_name - owner.save() + owner, is_created = User.objects.get_or_create(email=email) + if not is_created: + owner.first_name = first_name + owner.last_name = last_name + owner.save() version_metadata = { 'description': 'An informative description', diff --git a/web/Dockerfile.dev b/web/Dockerfile.dev index 03f579200..058e4b6b0 100644 --- a/web/Dockerfile.dev +++ b/web/Dockerfile.dev @@ -1,5 +1,4 @@ -# Use node:16 due to project still being on Vue 2 and not Vue 3 - as of Jan 2024 -FROM node:16 +FROM node:20 # Set the working directory WORKDIR /usr/src/app From 14cb1a3ed40d3a74918ff5e35387b260bdbcbf9b Mon Sep 17 00:00:00 2001 From: Aaron Kanzer Date: Thu, 11 Jan 2024 15:26:22 -0500 Subject: [PATCH 3/5] bump --- admin_dev_startup.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 admin_dev_startup.sh diff --git a/admin_dev_startup.sh b/admin_dev_startup.sh old mode 100644 new mode 100755 From 25e01d661b9a060db930fda6c5410f91c0342166 Mon Sep 17 00:00:00 2001 From: Aaron Kanzer Date: Thu, 11 Jan 2024 15:29:41 -0500 Subject: [PATCH 4/5] bump readme for code bases in different states --- DEVELOPMENT.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index fe8e88602..607016213 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -7,8 +7,8 @@ This is the simplest configuration for developers to start with. 1. Ensure you have installed Docker on your local machine 2. Run `./admin_dev_startup.sh `. When prompted, enter an username and password in the command prompt. (If you run into local errors with the script, you may need to run `chmod +x admin_dev_startup.sh` first) -3. Navigate to `localhost:8000/admin`, and log in with the username and password you used in Step #2. Under the `User` section, select the username and change the `Status` from `Incomplete` to `Approved`. -4. Navigate to `localhost:8085` and select `LOG IN WITH GITHUB`. +3. If not routed to `localhost:8000` upon clicking `LOG IN WITH GITHUB` (If routed appropriately, just log in), navigate to `localhost:8000/admin`, and log in with the username and password you used in Step #2. Under the `User` section, select the username and change the `Status` from `Incomplete` to `Approved`. +4. Return to `localhost:8085` and if not logged in yet, select `LOG IN WITH GITHUB`. ### Application Maintenance Occasionally, new package dependencies or schema changes will necessitate From 31789a552494d1b76072ef87cb136714c7ea5129 Mon Sep 17 00:00:00 2001 From: Aaron Kanzer Date: Wed, 17 Jan 2024 16:51:15 -0500 Subject: [PATCH 5/5] include kabi review with minor adjustment to gitignore --- .gitignore | 3 ++- admin_dev_startup.sh | 10 +++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 63dc29fef..89c8ded57 100644 --- a/.gitignore +++ b/.gitignore @@ -123,4 +123,5 @@ dmypy.json # End of https://www.gitignore.io/api/django # Editor settings -.vscode +.vscode +.idea/ diff --git a/admin_dev_startup.sh b/admin_dev_startup.sh index 6b3d352b7..d37a644e3 100755 --- a/admin_dev_startup.sh +++ b/admin_dev_startup.sh @@ -22,10 +22,10 @@ docker run -d -v "$(pwd):/usr/src/app" -v /usr/src/app/node_modules -p 8085:8085 cd .. # Run Docker Compose commands for backend -docker-compose run --rm django ./manage.py migrate -docker-compose run --rm django ./manage.py createcachetable -docker-compose run --rm django ./manage.py createsuperuser -docker-compose run --rm django ./manage.py create_dev_dandiset --owner $email +docker compose run --rm django ./manage.py migrate +docker compose run --rm django ./manage.py createcachetable +docker compose run --rm django ./manage.py createsuperuser +docker compose run --rm django ./manage.py create_dev_dandiset --owner $email # Bring backend application to life! -docker-compose up +docker compose up