Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge next -> main #8

Merged
merged 24 commits into from
Feb 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
c715ae4
Multitumor and Nested Dichotomous (#264)
hausman-gdit Sep 13, 2023
a722e74
BMDS Desktop settings flag (#261)
shapiromatron Sep 21, 2023
aa073b9
UI updates for nested dichotomous and multitumor (#265)
shapiromatron Sep 27, 2023
516485f
293 mt min max datasets (#266)
hausman-gdit Oct 4, 2023
b72c1da
Complete nested dichotomous summary table (#267)
shapiromatron Oct 4, 2023
9cde81e
switch to ruff format (#271)
shapiromatron Oct 31, 2023
fbf2f0f
update python package versions (#268)
hausman-gdit Oct 31, 2023
c485cb5
integration tests - nested dichotomous + multitumor (#269)
hausman-gdit Oct 31, 2023
1e10519
297 dynamic word export (#270)
hausman-gdit Oct 31, 2023
13d1705
update to pydantic v2 (#273)
shapiromatron Nov 7, 2023
eedf582
multitumor display edits (#272)
shapiromatron Nov 8, 2023
c3ad4ed
add years context (#274)
hausman-gdit Nov 9, 2023
3fef58e
remove zenodo.org badge (#278)
shapiromatron Dec 7, 2023
59274be
283 polyk data link (#275)
hausman-gdit Dec 7, 2023
1470f3f
polyk - copy dataset to clipboard for bmds modeling (#276)
hausman-gdit Dec 7, 2023
b0ab6a0
Add Word and Excel reports to Poly K adjustments (#277)
shapiromatron Dec 11, 2023
e25d44d
add Desktop mode (#279)
shapiromatron Dec 13, 2023
c8ecff5
2, 6
hausman-gdit Dec 18, 2023
121396f
Revert "2, 6"
hausman-gdit Dec 19, 2023
c481860
Run tests in CI (#5)
shapiromatron Feb 1, 2024
c7a3cbd
324 random bootstrap seed (#1)
hausman-gdit Feb 1, 2024
2b91242
328 improve error message (#4)
hausman-gdit Feb 7, 2024
71786b7
321 improve nomenclature for statistical outputs (#2)
hausman-gdit Feb 9, 2024
0a705c3
332 remove bmds 2.7 (#6)
hausman-gdit Feb 12, 2024
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
15 changes: 6 additions & 9 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ jobs:
- name: Checkout bmds@main
uses: actions/checkout@v3
with:
repository: shapiromatron/bmds
repository: USEPA/bmds-private
path: venv
ref: main
lfs: true
token: ${{ secrets.USEPA_BMDS_PRIVATE_PAT }}
- uses: actions/setup-python@v4
with:
python-version: '3.11'
Expand Down Expand Up @@ -55,8 +55,7 @@ jobs:
export "LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib:/usr/lib"
sudo cp vendor/libnlopt.so /usr/local/lib/libnlopt.so.0
sudo ln -s /lib/x86_64-linux-gnu/libgsl.so /usr/local/lib/libgsl.so.25
export "BMD_DLL=$GITHUB_WORKSPACE/venv/bmds/bin/BMDS330/libDRBMD.so"
echo $BMD_DLL
export "BMD_DLL=$GITHUB_WORKSPACE/venv/bmds/bmdscore.cpython-*-x86_64-linux-gnu.so"
ldd $BMD_DLL
- name: lint
run: |
Expand All @@ -71,7 +70,6 @@ jobs:
run: |
export "LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH"
coverage run -m pytest --vcr-record=none
coverage html -d coverage_report
echo "# Python coverage report" >> $GITHUB_STEP_SUMMARY
coverage report --format=markdown >> $GITHUB_STEP_SUMMARY

Expand Down Expand Up @@ -145,10 +143,10 @@ jobs:
- name: Checkout bmds@main
uses: actions/checkout@v3
with:
repository: shapiromatron/bmds
repository: USEPA/bmds-private
path: venv
ref: main
lfs: true
token: ${{ secrets.USEPA_BMDS_PRIVATE_PAT }}
- uses: actions/setup-python@v4
with:
python-version: '3.11'
Expand Down Expand Up @@ -177,8 +175,7 @@ jobs:
export "LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib:/usr/lib"
sudo cp vendor/libnlopt.so /usr/local/lib/libnlopt.so.0
sudo ln -s /lib/x86_64-linux-gnu/libgsl.so /usr/local/lib/libgsl.so.25
export "BMD_DLL=$GITHUB_WORKSPACE/venv/bmds/bin/BMDS330/libDRBMD.so"
echo $BMD_DLL
export "BMD_DLL=$GITHUB_WORKSPACE/venv/bmds/bmdscore.cpython-*-x86_64-linux-gnu.so"
ldd $BMD_DLL
# https://github.community/t/how-to-retry-a-failed-step-in-github-actions-workflow/125880
- name: run integration tests
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
bmds_server/static/bundles/
build/
/data/
coverage_report/
dist/
docs/site/
node_modules/
Expand All @@ -20,7 +21,7 @@ venv/
# files
*.log
*.py[cod]
*.sqlite3
*.sqlite3*
*log
.coverage
.env
Expand Down
2 changes: 1 addition & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
recursive-include bmds_server/ *css *.js *.json *.html *.py
recursive-include bmds_server/ *css *.js *.json *.html *.md *.py
recursive-include bmds_server/static *
recursive-include bmds_server/templates *
global-exclude .DS_Store .gitkeep __pycache__ *.pyc
9 changes: 7 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ test-integration-debug: ## Run integration tests in debug mode (requires npm ru
@playwright install --with-deps chromium
@INTEGRATION_TESTS=1 PWDEBUG=1 py.test -sv tests/integration/

coverage: ## Run test coverage
coverage run -m pytest
coverage html -d coverage_report
$(BROWSER) coverage_report/index.html

docs: ## Build documentation
cd docs; mkdocs build --strict

Expand All @@ -75,10 +80,10 @@ lint: lint-py lint-js ## Check formatting issues
format: format-py format-js ## Fix formatting issues where possible

lint-py: ## Check python formatting issues
@black . --check && ruff .
@ruff format . --check && ruff .

format-py: ## Fix python formatting issues where possible
@black . && ruff . --fix --show-fixes
@ruff format . && ruff . --fix --show-fixes

lint-js: ## Check javascript formatting issues
@npm --prefix ./frontend run lint
Expand Down
3 changes: 0 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@ BMDS webserver
:target: https://bmds-server.readthedocs.io/en/master/
:alt: Documentation Status

.. image:: https://zenodo.org/badge/73124145.svg
:target: https://zenodo.org/badge/latestdoi/73124145

Run a webserver that will batch process dose-response data using the US EPA's
benchmark dose modeling software (`BMDS`_). Under the hood, this web application
uses the `BMDS Python interface`_.
Expand Down
5 changes: 5 additions & 0 deletions bmds_server/analysis/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,8 @@ def edit_url(self, obj):
class Content(VersionAdmin):
list_display = ("id", "content_type", "subject", "created", "last_updated")
list_filter = ("content_type",)


@admin.register(models.Collection)
class CollectionAdmin(VersionAdmin):
pass
87 changes: 74 additions & 13 deletions bmds_server/analysis/api.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
from bmds.datasets.transforms.polyk import PolyKAdjustment
from django.conf import settings
from django.core.exceptions import ValidationError
from rest_framework import exceptions, mixins, viewsets
from rest_framework.decorators import action, api_view
from rest_framework.decorators import action
from rest_framework.response import Response

from ..common import renderers
from ..common.renderers import BinaryFile
from ..common.serializers import UnusedSerializer
from ..common.task_cache import ReportStatus
from ..common.utils import get_bool
from ..common.validation import pydantic_validate
from . import models, schema, serializers, validators
from .reporting.cache import DocxReportCache, ExcelReportCache
from .reporting.docx import add_update_url
from .reporting.docx import add_update_url, build_polyk_docx


class AnalysisViewset(mixins.RetrieveModelMixin, viewsets.GenericViewSet):
serializer_class = serializers.AnalysisSerializer
queryset = models.Analysis.objects.all()
queryset = models.Analysis.objects.prefetch_related("collections").all()

@action(detail=False, url_path="default")
def default(self, request, *args, **kwargs):
Expand Down Expand Up @@ -133,7 +137,7 @@ def excel(self, request, *args, **kwargs):
data = renderers.BinaryFile(data=response.content, filename=instance.slug)
return Response(data)

return Response(response.dict(), content_type="application/json")
return Response(response.model_dump(), content_type="application/json")

@action(detail=True, renderer_classes=(renderers.DocxRenderer,))
def word(self, request, *args, **kwargs):
Expand All @@ -155,14 +159,71 @@ def word(self, request, *args, **kwargs):
data = add_update_url(instance, response.content, uri) if edit else response.content
return Response(renderers.BinaryFile(data=data, filename=instance.slug))

return Response(response.dict(), content_type="application/json")
return Response(response.model_dump(), content_type="application/json")

@action(detail=True, methods=("post",))
def star(self, request, *args, **kwargs):
instance = self.get_object()

# permissions check
if instance.password != request.data.get("editKey", ""):
raise exceptions.PermissionDenied()

# flip the star (but don't change last_updated)
if settings.IS_DESKTOP:
models.Analysis.objects.filter(id=instance.id).update(starred=not instance.starred)
instance.refresh_from_db()

serializer = self.get_serializer(instance)
return Response(serializer.data)

@action(detail=True, methods=("post",))
def collections(self, request, *args, **kwargs):
instance = self.get_object()

@api_view(["POST"])
def polyk_transform(request):
try:
settings = pydantic_validate(request.data, schema.PolyKInput)
except ValidationError as err:
raise exceptions.ValidationError(err.message)
(df, df2) = settings.calculate()
return Response({"df": df.to_dict(orient="list"), "df2": df2.to_dict(orient="list")})
# permissions check
if instance.password != request.data.get("editKey", ""):
raise exceptions.PermissionDenied()

# update collections
if settings.IS_DESKTOP:
ids = [d for d in request.data.get("collections", []) if isinstance(d, int)]
collections = models.Collection.objects.filter(id__in=ids)
instance.collections.set(collections)

serializer = self.get_serializer(instance)
return Response(serializer.data)


class PolyKViewset(viewsets.GenericViewSet):
queryset = models.Analysis.objects.none()
serializer_class = UnusedSerializer

def _run_analysis(self, request) -> PolyKAdjustment:
try:
settings = pydantic_validate(request.data, schema.PolyKInput)
except ValidationError as err:
raise exceptions.ValidationError(err.message)
return settings.calculate()

def create(self, request, *args, **kwargs):
analysis = self._run_analysis(request)
return Response(
{
"df": analysis.adjusted_data.to_dict(orient="list"),
"df2": analysis.summary.to_dict(orient="list"),
}
)

@action(detail=False, methods=["POST"], renderer_classes=(renderers.XlsxRenderer,))
def excel(self, request, *args, **kwargs):
analysis = self._run_analysis(request)
data = BinaryFile(analysis.to_excel(), "polyk-adjustment")
return Response(data)

@action(detail=False, methods=["POST"], renderer_classes=(renderers.DocxRenderer,))
def word(self, request, *args, **kwargs):
analysis = self._run_analysis(request)
f = build_polyk_docx(analysis)
data = BinaryFile(f, "polyk-adjustment")
return Response(data)
3 changes: 3 additions & 0 deletions bmds_server/analysis/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,6 @@

class Config(AppConfig):
name = "bmds_server.analysis"

def ready(self):
from .signals import init_command # noqa: F401
Loading
Loading