Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
f8d5e4e
Remove user_migration scripts
brianhelba Oct 9, 2025
50b3790
[gh-actions](deps): Bump actions/checkout from 5 to 6
dependabot[bot] Nov 24, 2025
921b95b
[gh-actions](deps): Bump actions/upload-artifact from 5 to 6
dependabot[bot] Dec 15, 2025
85a5275
[gh-actions](deps): Bump actions/download-artifact from 6 to 7
dependabot[bot] Dec 15, 2025
8b8e87d
Merge pull request #2651 from dandi/dependabot/github_actions/actions…
jjnesbitt Dec 23, 2025
99aa909
Merge pull request #2675 from dandi/dependabot/github_actions/actions…
jjnesbitt Dec 23, 2025
ef6b10e
Merge pull request #2674 from dandi/dependabot/github_actions/actions…
jjnesbitt Dec 23, 2025
cf3ac4d
Merge pull request #2595 from dandi/user-migration
waxlamp Dec 31, 2025
f1cc28a
Update code snippet to show correct dandi instance in cli command dan…
NEStock Dec 31, 2025
729fa20
Merge pull request #155 from aplbrain/101-update-code-snippets-for-da…
NEStock Dec 31, 2025
f9175b3
Add basic throttle configuration
jjnesbitt Sep 11, 2025
056b767
Adjust throttling values
jjnesbitt Sep 15, 2025
5ab989b
Exclude admins from throttling
jjnesbitt Sep 17, 2025
149c590
Don't throttle authenticated users
jjnesbitt Dec 8, 2025
959474d
Update docs for database cache backend
jjnesbitt Dec 8, 2025
2ad2594
Update anonymous user rate limit
jjnesbitt Dec 8, 2025
0db3f89
Only apply rate limiting in prod
jjnesbitt Dec 8, 2025
6bc2aab
Mark tests as requiring the DB
jjnesbitt Jan 8, 2026
3633952
Create required cache table in frontend CI
jjnesbitt Jan 8, 2026
9696119
Merge pull request #2665 from dandi/rest-framework-throttling
jjnesbitt Jan 8, 2026
9fb2901
auto shipit - CHANGELOG.md etc
dandibot Jan 8, 2026
3338474
Add index to Asset.path column
jjnesbitt Jan 12, 2026
ff9387f
Use more efficient query when exact path is provided
jjnesbitt Jan 12, 2026
9932e9e
Merge pull request #2691 from dandi/improve-asset-list-exact-path
jjnesbitt Jan 13, 2026
9a4859d
auto shipit - CHANGELOG.md etc
dandibot Jan 13, 2026
dc99b0c
Disable throttling of unauthenticated users
jjnesbitt Jan 13, 2026
0e1db3c
Merge pull request #2694 from dandi/disable-throttling
jjnesbitt Jan 13, 2026
65c57bb
auto shipit - CHANGELOG.md etc
dandibot Jan 13, 2026
577303b
Merge branch 'master' into 156-sync-fork-jan-19th-week
NEStock Jan 21, 2026
b1a8fd6
Merge pull request #174 from aplbrain/156-sync-fork-jan-19th-week
NEStock Jan 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/backend-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ jobs:
DJANGO_DANDI_INSTANCE_IDENTIFIER: "RRID:SCR_026700"
DJANGO_DANDI_DOI_API_PREFIX: "10.82754"
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
with:
fetch-depth: 0 # fetch history for all branches and tags
fetch-tags: true
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/backend-production-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
# name: Update release branch
# runs-on: ubuntu-22.04
# steps:
# - uses: actions/checkout@v5
# - uses: actions/checkout@v6
# with:
# fetch-depth: 0 # fetch history for all branches and tags
# token: ${{ secrets.GH_TOKEN }} # TODO: switch to GITHUB_TOKEN
Expand All @@ -43,7 +43,7 @@ jobs:
runs-on: ubuntu-22.04
#needs: reset-release-branch
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
with:
fetch-depth: 0 # fetch history for all branches and tags
#ref: release
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/backend-staging-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
name: Deploy to Heroku
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
with:
fetch-depth: 0 # fetch history for all branches and tags

Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/cli-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Check out this repository
uses: actions/checkout@v5
uses: actions/checkout@v6
with:
fetch-depth: 0 # fetch history for all branches and tags

Expand All @@ -34,7 +34,7 @@ jobs:
docker image save -o dandiarchive-api.tgz dandiarchive/dandiarchive-api

- name: Upload Docker image tarball
uses: actions/upload-artifact@v5
uses: actions/upload-artifact@v6
with:
name: dandiarchive-api.tgz
path: dandiarchive-api.tgz
Expand All @@ -54,7 +54,7 @@ jobs:
DANDI_TESTS_PULL_DOCKER_COMPOSE: 0
steps:
- name: Download Docker image tarball
uses: actions/download-artifact@v6
uses: actions/download-artifact@v7
with:
name: dandiarchive-api.tgz

Expand Down
9 changes: 6 additions & 3 deletions .github/workflows/frontend-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
working-directory: web
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
with:
fetch-depth: 0 # fetch history for all branches and tags

Expand Down Expand Up @@ -87,7 +87,7 @@ jobs:
VITE_APP_OAUTH_API_ROOT: http://localhost:8000/oauth/
VITE_APP_OAUTH_CLIENT_ID: Dk0zosgt1GAAKfN8LT4STJmLJXwMDPbYWYzfNtAl
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
with:
fetch-depth: 0 # fetch history for all branches and tags

Expand All @@ -105,6 +105,9 @@ jobs:
- name: Apply migrations to API server
run: ./manage.py migrate

- name: Create any cache tables
run: ./manage.py createcachetable

- name: Install test data
run: ./manage.py loaddata playwright

Expand All @@ -130,7 +133,7 @@ jobs:
# run the tests
cd e2e && npx playwright test

- uses: actions/upload-artifact@v5
- uses: actions/upload-artifact@v6
if: always()
with:
name: playwright-report
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
if: "!contains(github.event.head_commit.message, 'ci skip') && !contains(github.event.head_commit.message, 'skip ci')"
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
with:
fetch-depth: 0 # fetch history for all branches and tags
token: ${{ secrets.GH_TOKEN }} # TODO: switch to GITHUB_TOKEN
Expand Down
48 changes: 48 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,51 @@
# v0.21.2 (Tue Jan 13 2026)

#### 🐛 Bug Fix

- Disable throttling of unauthenticated users [#2694](https://github.com/dandi/dandi-archive/pull/2694) ([@jjnesbitt](https://github.com/jjnesbitt))

#### Authors: 1

- Jacob Nesbitt ([@jjnesbitt](https://github.com/jjnesbitt))

---

# v0.21.1 (Tue Jan 13 2026)

#### 🐛 Bug Fix

- Improve performance of asset list endpoint when exact path is provided [#2691](https://github.com/dandi/dandi-archive/pull/2691) ([@jjnesbitt](https://github.com/jjnesbitt))

#### Authors: 1

- Jacob Nesbitt ([@jjnesbitt](https://github.com/jjnesbitt))

---

# v0.21.0 (Thu Jan 08 2026)

#### 🚀 Enhancement

- Add basic rate limit implementation [#2665](https://github.com/dandi/dandi-archive/pull/2665) ([@jjnesbitt](https://github.com/jjnesbitt))

#### 🐛 Bug Fix

- Remove user_migration scripts [#2595](https://github.com/dandi/dandi-archive/pull/2595) ([@brianhelba](https://github.com/brianhelba))

#### 🔩 Dependency Updates

- [gh-actions](deps): Bump actions/upload-artifact from 5 to 6 [#2674](https://github.com/dandi/dandi-archive/pull/2674) ([@dependabot[bot]](https://github.com/dependabot[bot]))
- [gh-actions](deps): Bump actions/download-artifact from 6 to 7 [#2675](https://github.com/dandi/dandi-archive/pull/2675) ([@dependabot[bot]](https://github.com/dependabot[bot]))
- [gh-actions](deps): Bump actions/checkout from 5 to 6 [#2651](https://github.com/dandi/dandi-archive/pull/2651) ([@dependabot[bot]](https://github.com/dependabot[bot]))

#### Authors: 3

- [@dependabot[bot]](https://github.com/dependabot[bot])
- Brian Helba ([@brianhelba](https://github.com/brianhelba))
- Jacob Nesbitt ([@jjnesbitt](https://github.com/jjnesbitt))

---

# v0.20.0 (Wed Dec 17 2025)

### Release Notes
Expand Down
3 changes: 3 additions & 0 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ This is the simplest configuration for developers to start with.

1. From VSCode, use `Ctrl-Shift-p` and run the command `Dev Containers: Reopen in Container`.
1. From the VSCode built-in terminal, run `./manage.py migrate`.
1. Run `docker compose run --rm django ./manage.py createcachetable`
1. From the VSCode built-in terminal, run `./manage.py createsuperuser --email $(git config user.email)` and follow the prompts.
1. From the VSCode built-in terminal, run `./manage.py create_dev_dandiset --owner $(git config user.email)`
to create a dummy dandiset to start working with.
Expand All @@ -37,6 +38,7 @@ This configuration also uses containers, but with Docker Compose instead of VSco
### Initial Setup
1. Install [Docker Compose](https://docs.docker.com/compose/install/)
1. Run `docker compose run --rm django ./manage.py migrate`
1. Run `docker compose run --rm django ./manage.py createcachetable`
1. Run `docker compose run --rm django ./manage.py createsuperuser --email $(git config user.email)`
and follow the prompts to create your own user.
This sets your username to your git email to ensure parity with how GitHub logins work. You can also replace the command substitution expression with a literal email address, or omit the `--email` option entirely to run the command in interactive mode.
Expand Down Expand Up @@ -67,6 +69,7 @@ but allows developers to run Python code on their native system.
1. [Install `uv`](https://docs.astral.sh/uv/getting-started/installation/)
1. Run `export UV_ENV_FILE=./dev/.env.docker-compose-native`
1. Run `./manage.py migrate`
1. Run `docker compose run --rm django ./manage.py createcachetable`
1. Run `./manage.py createsuperuser --email $(git config user.email)` and follow the prompts.
1. Run `./manage.py create_dev_dandiset --owner $(git config user.email)`
to create a dummy dandiset to start working with.
Expand Down
4 changes: 0 additions & 4 deletions dandiapi/api/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +0,0 @@
from __future__ import annotations

# TODO: remove this after migration is complete
import dandiapi.api.user_migration # noqa: F401
20 changes: 0 additions & 20 deletions dandiapi/api/management/commands/depose_placeholder.py

This file was deleted.

12 changes: 0 additions & 12 deletions dandiapi/api/management/commands/depose_placeholders.py

This file was deleted.

18 changes: 0 additions & 18 deletions dandiapi/api/management/commands/list_placeholders.py

This file was deleted.

25 changes: 25 additions & 0 deletions dandiapi/api/migrations/0030_alter_asset_path.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Generated by Django 5.2.7 on 2026-01-12 21:55
from __future__ import annotations

from django.db import migrations, models

import dandiapi.api.models.asset


class Migration(migrations.Migration):
dependencies = [
('api', '0029_merge'),
]

operations = [
migrations.AlterField(
model_name='asset',
name='path',
field=models.CharField(
db_collation='C',
db_index=True,
max_length=512,
validators=[dandiapi.api.models.asset.validate_asset_path],
),
),
]
4 changes: 3 additions & 1 deletion dandiapi/api/models/asset.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,9 @@ class Asset(PublishableMetadataMixin, TimeStampedModel):
UUID_REGEX = r'[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}'

asset_id = models.UUIDField(unique=True, default=uuid.uuid4)
path = models.CharField(max_length=512, validators=[validate_asset_path], db_collation='C')
path = models.CharField(
max_length=512, validators=[validate_asset_path], db_collation='C', db_index=True
)
blob = models.ForeignKey(
AssetBlob, related_name='assets', on_delete=models.CASCADE, null=True, blank=True
)
Expand Down
2 changes: 2 additions & 0 deletions dandiapi/api/tests/test_info.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
from __future__ import annotations

from dandischema.conf import get_instance_config
import pytest


@pytest.mark.django_db
def test_rest_info_instance_config_include_none(api_client):
resp = api_client.get('/api/info/')
assert resp.status_code == 200
Expand Down
2 changes: 2 additions & 0 deletions dandiapi/api/tests/test_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
PublishedAsset,
],
)
@pytest.mark.django_db
def test_schema_latest(api_client, model: CommonModel):
"""Test that the schema endpoints return valid schemas."""
resp = api_client.get('/api/schemas/', {'model': model.__name__})
Expand All @@ -30,6 +31,7 @@ def test_schema_latest(api_client, model: CommonModel):
assert schema == expected_schema


@pytest.mark.django_db
def test_schema_unsupported_model(api_client):
"""Test that the schema endpoint returns an error when passed invalid choice."""
resp = api_client.get('/api/schemas/', {'model': 'NotAValidModel'})
Expand Down
14 changes: 14 additions & 0 deletions dandiapi/api/throttling.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from __future__ import annotations

from rest_framework.throttling import UserRateThrottle


# This is not currently used, but if we ever choose to rate limit logged-in users,
# this is how we can accomplish that, without applying it to admins.
class DandiUserRateThrottle(UserRateThrottle):
def get_cache_key(self, request, view):
# Don't rate limit admin users
if request.user and (request.user.is_staff or request.user.is_superuser):
return None

return super().get_cache_key(request, view)
46 changes: 0 additions & 46 deletions dandiapi/api/user_migration.py

This file was deleted.

13 changes: 11 additions & 2 deletions dandiapi/api/views/asset.py
Original file line number Diff line number Diff line change
Expand Up @@ -423,9 +423,20 @@ def list(self, request, *args, **kwargs):
version=self.kwargs['versions__version'],
)

# Use custom pagination class to reduce unnecessary counts of assets
paginator = LazyPagination()

# Apply filtering from included filter class first
asset_queryset = self.filter_queryset(version.assets.all())

# Check if the path query arg is pointing at a direct path.
# If that's the case, just retrieve the single asset.
path = self.request.query_params.get('path')
if path:
assets = Asset.objects.filter(path=path, versions=version)
if assets.exists():
asset_queryset = assets

# Filter query to only zarr assets, if requested
zarr_only = serializer.validated_data['zarr']
if zarr_only:
Expand All @@ -442,8 +453,6 @@ def list(self, request, *args, **kwargs):
asset_queryset = asset_queryset.filter(path__iregex=glob_pattern.replace('\\*', '.*'))

# Retrieve just the first N asset IDs, and use them for pagination
# Use custom pagination class to reduce unnecessary counts of assets
paginator = LazyPagination()
qs = asset_queryset.values_list('id', flat=True)
page_of_asset_ids = paginator.paginate_queryset(qs, request=self.request, view=self)

Expand Down
Loading
Loading