Skip to content

Commit 1386325

Browse files
authored
Merge pull request #945 from cortex-lab/dev
3.3.0
2 parents 8bd3e2b + 37705d8 commit 1386325

File tree

83 files changed

+12729
-3369
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+12729
-3369
lines changed

.flake8

Lines changed: 0 additions & 7 deletions
This file was deleted.

.github/workflows/main.yml

Lines changed: 13 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
runs-on: ubuntu-latest
1616
services:
1717
postgres:
18-
image: postgres:16
18+
image: postgres:17
1919
env:
2020
POSTGRES_PASSWORD: postgres
2121
POSTGRES_USER: postgres
@@ -34,7 +34,7 @@ jobs:
3434
- name: Set up Python
3535
uses: actions/setup-python@v2
3636
with:
37-
python-version: '3.12'
37+
python-version: '3.13'
3838

3939
- name: Checkout branch
4040
uses: actions/checkout@v3
@@ -46,49 +46,27 @@ jobs:
4646
pip install coverage coveralls pyarrow pandas # for one_cache tests
4747
env:
4848
PIP_USE_MIRRORS: true
49-
49+
- name: Ruff
50+
run: |
51+
ruff check ./alyx
5052
- name: Run tests
5153
run: |
52-
sudo touch /var/log/alyx.log; sudo chmod 666 /var/log/alyx.log
53-
sudo touch /var/log/alyx_json.log; sudo chmod 666 /var/log/alyx_json.log
54+
sudo mkdir /var/log/alyx
55+
sudo touch /var/log/alyx/django.log
56+
sudo chmod 666 /var/log/alyx/django.log
5457
cd alyx
55-
cp alyx/settings_ci.py alyx/settings.py
58+
cp ./alyx/environment_template.env ./alyx/.env
59+
cp ../deploy/docker/settings-deploy.py alyx/settings.py
60+
cp ../deploy/docker/settings_lab-deploy.py alyx/settings_lab.py
5661
python manage.py collectstatic --noinput --link
5762
coverage run manage.py test -n
5863
coveralls --service=github
5964
env:
6065
DJANGO_SETTINGS_MODULE: alyx.settings
6166
PYTHONPATH: $HOME/builds/cortexlab/alyx
6267
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
63-
- name: Flake
64-
run: |
65-
cd alyx
66-
flake8 .
67-
68-
- name: Generate new requirements_frozen.txt if needed
69-
# Only runs when branch pushed to directly OR when a PR is merged
70-
if: ${{ github.event_name == 'push' }}
71-
run: |
72-
pip freeze > requirements_frozen_temp.txt
73-
if diff requirements_frozen.txt requirements_frozen_temp.txt > /dev/null; then
74-
echo "requirements_frozen.txt unchanged"
75-
rm requirements_frozen_temp.txt
76-
echo "GIT_PUSH_NEEDED=false" >> "$GITHUB_ENV"
77-
else
78-
echo "requirements_frozen.txt is different, git push needed"
79-
mv requirements_frozen_temp.txt requirements_frozen.txt
80-
echo "GIT_PUSH_NEEDED=true" >> "$GITHUB_ENV"
81-
fi
82-
83-
- name: Setup git/commit/push for requirements_frozen.txt if needed
84-
# Only runs when requirements_frozen.txt is updated
85-
if: env.GIT_PUSH_NEEDED == 'true'
86-
run: |
87-
git config user.name github-actions
88-
git config user.email [email protected]
89-
git add requirements_frozen.txt
90-
git commit -m "GitHub Actions generated requirements_frozen.txt"
91-
git push
68+
APACHE_LOG_DIR: /var/log/alyx
69+
POSTGRES_HOST: localhost
9270

9371
# Docker steps only run when master branch pushed to directly OR when a PR is merged
9472
- name: Set Docker conditional value if needed

.gitignore

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,23 @@
1+
# environment files for deployments
2+
.env*
3+
# all of the iblreports sym links
4+
alyx/data/management/commands/*ibl*
5+
alyx/data/management/commands/sync_patcher.py
6+
alyx/ibl_reports
7+
alyx/templates/ibl_reports
8+
# setting files
9+
alyx/alyx/settings_secret.py
10+
alyx/alyx/settings_lab.py
11+
alyx/alyx/settings.py
12+
alyx/static/*/*
13+
scripts/deployment_examples/docker-apache/settings*
14+
# this is a custom lab settings to be provided by the user rebuilding the head docker
15+
deploy/docker/settings_lab-user.py
16+
17+
# package if installed
18+
alyx/alyx.egg-info
19+
20+
# other
121
*.pyc
222
.DS_Store
323
*~
@@ -24,14 +44,6 @@ build
2444
.cache/
2545
alyx/alyx_full.sql.gz
2646
.vscode/
27-
alyx/data/management/commands/*ibl*
28-
alyx/ibl_reports
29-
alyx/templates/ibl_reports
30-
alyx/alyx/settings_secret.py
31-
alyx/alyx/settings_lab.py
32-
alyx/alyx/settings.py
33-
alyx/static/*/*
34-
scripts/deployment_examples/docker-apache/settings*
3547

3648
alyx/.idea/
3749

.readthedocs.yaml

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,9 @@ version: 2
77

88
# Set the version of Python and other tools you might need
99
build:
10-
os: ubuntu-20.04
10+
os: ubuntu-24.04
1111
tools:
12-
python: "3.9"
13-
# You can also specify other tool versions:
14-
# nodejs: "16"
15-
# rust: "1.55"
16-
# golang: "1.17"
12+
python: "3.12"
1713

1814
# Build documentation in the docs/ directory with Sphinx
1915
sphinx:

CHANGELOG.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7+
8+
## [Unreleased]
9+
10+
### Added
11+
12+
13+
### Changed
14+
15+
- The documentation endpoint `/docs` is only for the browser and uses openapiv3. The database schemes are accessed through `/api/schema`. For compatibility, if the headers require `coreapi`, the endpoint returns a frozen set of endpoint to the client. [#929](https://github.com/cortex-lab/alyx/pull/929)
16+
17+
- narrative template is now available on the base action instead of only for surgeries [#938](https://github.com/cortex-lab/alyx/pull/938)
18+
19+
20+
### Removed
21+
22+
- coreapi dependency is removed

README.md

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,30 +5,53 @@
55

66
Database for experimental neuroscience laboratories
77

8-
Documentation: [Installation and getting started](http://alyx.readthedocs.io), [Alyx usage guide](https://docs.google.com/document/d/1cx3XLZiZRh3lUzhhR_p65BggEqTKpXHUDkUDagvf9Kc/edit?usp=sharing)
8+
[Documentation](https://alyx.readthedocs.io)
9+
10+
[Alyx Experimenter Guide](https://docs.google.com/document/d/1cx3XLZiZRh3lUzhhR_p65BggEqTKpXHUDkUDagvf9Kc/edit?usp=sharing)
911

1012

1113
## Installation
12-
Alyx has only been tested on Ubuntu (16.04 / 18.04 / 20.04), the latest is recommended. There are no guarantees that
13-
this setup will work on other systems. Assumptions made are that you have sudo permissions under an account named
1414

15-
[The getting started](docs/gettingstarted.md) section of the documentation details the steps for
15+
[The getting started](https://alyx.readthedocs.io/en/latest/gettingstarted.html) section of the documentation details the steps for
1616
- installing the Python/Django environment
17-
- serving a local database
17+
- running the app with a development server
1818
- registering local data
1919
- accessing local data using [ONE](https://one.internationalbrainlab.org)
2020

21+
More complex deployments scenarios using web servers and Cloud applications are in the [how-to guides section of the documtentaiton](docs/how-to-guides)
22+
2123
## Contribution
2224

2325
* Development happens on the **dev** branch
2426
* alyx is sync with the **master** branch
2527
* alyx-dev is sync with the **dev** branch
26-
* Migrations files are provided by the repository
27-
* Continuous integration is setup, to run tests locally:
28+
* Migrations files are always provided by the repository
29+
30+
Contribution checklist:
31+
- [ ] lint using ruff `ruff check .` at the root of the repository
32+
- [ ] tests pass (see below how to run tests)
33+
- [ ] migrations are provided with the commit
34+
- [ ] update version number in `./alyx/alyx/__init__.py`
35+
- [ ] update `CHANGELOG.md`
36+
37+
38+
### Running tests
39+
40+
Continuous integration is setup. But before submitting a PR or commit,the tests can run locally.
2841
- `./manage.py test -n` test without migrations (faster)
2942
- `./manage.py test` test with migrations (recommended if model changes)
30-
- NB: When running tests ensure `DEBUG = True` in the settings.py file (specifically `SECURE_SSL_REDIRECT = True` causes REST tests to fail)
3143

32-
```shell
33-
./manage.py test -n
44+
### Documentation contribution guide
45+
46+
#### Dependencies
47+
```
48+
pip install myst-parser sphinx_rtd_theme sphinx-autobuild
3449
```
50+
51+
#### Build documentation locally
52+
53+
From the root of the repository.
54+
````shell
55+
sphinx-autobuild -b html ./docs ./docs/_build/ --port 8700
56+
````
57+
https://www.scan.co.uk/products/3xs-evolve-studio-pro-intel-core-ultra-9-285k-64gb-ddr5-16gb-nvidia-rtx-5070-ti-super-1tb-ssd-2tb-ss

alyx/actions/admin.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import base64
22
import json
3-
import structlog
3+
import logging
44

55
from django import forms
66
from django.conf import settings
@@ -27,7 +27,7 @@
2727
from experiments.models import ProbeInsertion, FOV
2828
from jobs.models import Task
2929

30-
logger = structlog.get_logger(__name__)
30+
logger = logging.getLogger(__name__)
3131

3232

3333
# Filters
@@ -213,6 +213,17 @@ def get_form(self, request, obj=None, **kwargs):
213213
form.last_subject_id = self._get_last_subject(request)
214214
return form
215215

216+
def change_view(self, request, object_id, extra_context=None, **kwargs):
217+
context = extra_context or {}
218+
context = _pass_narrative_templates(context)
219+
return super(BaseActionAdmin, self).change_view(
220+
request, object_id, extra_context=context, **kwargs)
221+
222+
def add_view(self, *args, extra_context=None):
223+
context = extra_context or {}
224+
context = _pass_narrative_templates(context)
225+
return super(BaseActionAdmin, self).add_view(*args, extra_context=context)
226+
216227
def formfield_for_foreignkey(self, db_field, request, **kwargs):
217228
# Logged-in user by default.
218229
if db_field.name == 'user':
@@ -616,17 +627,6 @@ def get_form(self, request, obj=None, **kwargs):
616627
).distinct()
617628
return form
618629

619-
def change_view(self, request, object_id, extra_context=None, **kwargs):
620-
context = extra_context or {}
621-
context = _pass_narrative_templates(context)
622-
return super(SessionAdmin, self).change_view(
623-
request, object_id, extra_context=context, **kwargs)
624-
625-
def add_view(self, request, extra_context=None):
626-
context = extra_context or {}
627-
context = _pass_narrative_templates(context)
628-
return super(SessionAdmin, self).add_view(request, extra_context=context)
629-
630630
def project_(self, obj):
631631
return [getattr(p, 'name', None) for p in obj.projects.all()]
632632

alyx/actions/models.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from datetime import timedelta
22
from math import inf
33

4-
import structlog
4+
import logging
55
from one.alf.spec import QC
66

77
from django.conf import settings
@@ -13,7 +13,7 @@
1313
from misc.models import Lab, LabLocation, LabMember, Note
1414

1515

16-
logger = structlog.get_logger(__name__)
16+
logger = logging.getLogger(__name__)
1717

1818

1919
def _default_water_type():
@@ -387,7 +387,7 @@ class OtherAction(BaseAction):
387387

388388
def delay_since_last_notification(notification_type, title, subject):
389389
"""Return the delay since the last notification corresponding to the given
390-
type, title, subject, in seconds, wheter it was actually sent or not."""
390+
type, title, subject, in seconds, whether it was actually sent or not."""
391391
last_notif = Notification.objects.filter(
392392
notification_type=notification_type,
393393
title=title,

alyx/actions/notifications.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import structlog
1+
import logging
22
from textwrap import dedent
33

44
from django.utils import timezone
55

66
from actions.models import create_notification
77

88

9-
logger = structlog.get_logger(__name__)
9+
logger = logging.getLogger(__name__)
1010

1111

1212
def responsible_user_changed(subject, old_user, new_user):

alyx/actions/tests.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,8 +219,8 @@ def test_notif_water_1(self):
219219
def test_notif_water_2(self):
220220
# If the last water admin was on June 3 at 12pm, the notification
221221
# should be created after June 4 at 11am.
222-
l = ((9, False), (10, False), (11, True), (12, True))
223-
for (h, r) in l:
222+
teupeul = ((9, False), (10, False), (11, True), (12, True))
223+
for (h, r) in teupeul:
224224
date = timezone.datetime(2018, 6, 4, h, 0, 0)
225225
check_water_administration(self.subject, date=date)
226226
notif = Notification.objects.last()

0 commit comments

Comments
 (0)