Skip to content
Snippets Groups Projects
Commit 42fcf07e authored by Xiao Gui's avatar Xiao Gui
Browse files

maint: clarify release ci, also checks code meta

maint: add service meta endpoint
feat: always listen on root
fix: angular material column name
doc: added regression notice
fix: added message when user activates cheat code
parent cba88a8d
No related branches found
No related tags found
No related merge requests found
......@@ -11,9 +11,9 @@ jobs:
steps:
- uses: actions/checkout@v4
- run: |
MASTER_VERSION=$(git show origin/master:package.json | jq '.version')
THIS_VERSION=$(jq '.version' < package.json)
test "$MASTER_VERSION" == "$THIS_VERSION" && exit 1 || exit 0
MASTER_VERSION=$(git show origin/master:package.json | jq -r '.version')
THIS_VERSION=$(jq -r '.version' < package.json)
test "$MASTER_VERSION" == "$THIS_VERSION" && exit 1
check_release:
if: always()
......@@ -21,10 +21,8 @@ jobs:
steps:
- uses: actions/checkout@v4
- run: |
VERSION_NUM=$(jq '.version' < package.json)
VERSION_NUM=${VERSION_NUM#\"}
VERSION_NUM=${VERSION_NUM%\"}
test -f docs/releases/v$VERSION_NUM.md && exit 0 || exit 1
VERSION_NUM=$(jq -r '.version' < package.json)
test -f docs/releases/v$VERSION_NUM.md || exit 1
release_linked_mkdocs:
if: always()
......@@ -32,11 +30,24 @@ jobs:
steps:
- uses: actions/checkout@v4
- run: |
VERSION_NUM=$(jq '.version' < package.json)
VERSION_NUM=${VERSION_NUM#\"}
VERSION_NUM=${VERSION_NUM%\"}
VERSION_NUM=$(jq -r '.version' < package.json)
echo "VERSION_NUM: $VERSION_NUM"
cat mkdocs.yml
GREP_VERSION_NUM=$(cat mkdocs.yml | grep $VERSION_NUM)
echo GREP_VERSION_NUM: $GREP_VERSION_NUM
test -z "$GREP_VERSION_NUM" && exit 1 || exit 0
\ No newline at end of file
test -z "$GREP_VERSION_NUM" && exit 1
check_code_meta:
if: always()
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: |
VERSION_NUM=$(jq -r '.version' < package.json)
CODEMETA_VERSION=$(jq -r '.version' < codemeta.json)
test "$VERSION_NUM" == "$CODEMETA_VERSION" && echo "Version matches" || exit 1
RELEASE_NOTES=$(< docs/releases/v${VERSION_NUM}.md)
CODEMETA_RELEASE_NOTES=$(jq -r '.["schema:releaseNotes"]' codemeta.json)
test "$RELEASE_NOTES" == "$CODEMETA_RELEASE_NOTES" || exit 1
......@@ -59,6 +59,7 @@ WORKDIR /iv-app
COPY --from=builder /iv/backend .
RUN pip install -r requirements.txt
COPY --from=builder /iv/dist/aot /iv/backend/public
COPY --from=builder /iv/codemeta.json /iv/backend/public/codemeta.json
ENV PATH_TO_PUBLIC=/iv/backend/public
......
from pathlib import Path
import json
from fastapi import FastAPI, Request
from fastapi.responses import RedirectResponse, Response
from fastapi.staticfiles import StaticFiles
......@@ -16,6 +18,7 @@ from app.config import HOST_PATHNAME
from app.logger import logger
from app.bkwdcompat import BkwdCompatMW
from app.version_header import VersionHeaderMW
from app.const import DOCUMENTATION_URL, INPUT_FORMAT, OUTPUT_FORMAT
app = FastAPI()
......@@ -25,6 +28,39 @@ ready_flag = False
def ready():
return Response(None, 204 if ready_flag else 500)
_cached_code_meta = None
@app.get("/about")
def about():
global _cached_code_meta
if _cached_code_meta is None:
try:
with open(Path(__file__).parent.parent.parent / "codemeta.json", "r") as fp:
_cached_code_meta = json.load(fp=fp)
except:
...
if _cached_code_meta is None:
try:
with open(Path(PATH_TO_PUBLIC) / "codemeta.json", "r") as fp:
_cached_code_meta = json.load(fp=fp)
except:
...
if _cached_code_meta is None:
raise Exception(f"codemeta.json not found, cannot populate service meta")
return {
"@context": "https://gitlab.ebrains.eu/lauramble/servicemeta/-/raw/main/data/contexts/servicemeta.jsonld",
"type": "WebApplication",
"author": _cached_code_meta["author"],
"dateModified": _cached_code_meta["dateModified"],
"documentation": DOCUMENTATION_URL,
"name": _cached_code_meta["name"],
"version": _cached_code_meta["version"],
"inputFormat": INPUT_FORMAT,
"outputFormat": OUTPUT_FORMAT
}
app.add_middleware(SessionMiddleware, secret_key=SESSION_SECRET)
app.add_middleware(BkwdCompatMW)
app.add_middleware(VersionHeaderMW)
......@@ -56,11 +92,14 @@ app.mount("/", StaticFiles(directory=Path(PATH_TO_PUBLIC)), name="static")
if HOST_PATHNAME:
assert HOST_PATHNAME[0] == "/", f"HOST_PATHNAME, if defined, must start with /: {HOST_PATHNAME!r}"
assert HOST_PATHNAME[-1] != "/", f"HOST_PATHNAME, if defined, must not end with /: {HOST_PATHNAME!r}"
logger.info(f"listening on path {HOST_PATHNAME}")
logger.info(f"listening on path {HOST_PATHNAME}, also falls back to root")
_app = app
app = FastAPI()
app.mount(HOST_PATHNAME, _app)
# fallback, also listen on root
app.mount("", _app)
ready_flag = True
DO_NOT_LOGS = (
......
......@@ -22,3 +22,8 @@ OVERWRITE_SAPI_ENDPOINT_ATTR = "x-sapi-base-url"
OVERWRITE_SPATIAL_BACKEND_ATTR = "x-spatial-backend-url"
DOCUMENTATION_URL = "https://siibra-explorer.readthedocs.io/en/stable/"
INPUT_FORMAT = ["nifti", "json", "swc"]
OUTPUT_FORMAT = ["json"]
{
"@context": "https://doi.org/10.5063/schema/codemeta-2.0",
"type": "SoftwareSourceCode",
"author": [
{
"id": "_:author_1",
"type": "Person",
"affiliation": {
"type": "Organization",
"name": "Forschungszentrum Juelich"
},
"email": "x.gui@fz-juelich.de",
"familyName": "Gui",
"givenName": "Xiaoyun"
},
{
"id": "_:author_2",
"type": "Person",
"affiliation": {
"type": "Organization",
"name": "Forshungszentrum Juelich"
},
"familyName": "Gogshelidze",
"givenName": "Daviti"
},
{
"id": "https://orcid.org/0000-0002-9051-3701",
"type": "Person",
"affiliation": {
"type": "Organization",
"name": "Forschungszentrum Juelich"
},
"email": "t.dickscheid@fz-juelich.de",
"familyName": "Dickscheid",
"givenName": "Timo"
}
],
"codeRepository": "git+https://github.com/fzj-inm1-bda/siibra-explorer.git",
"dateCreated": "2024-08-28",
"dateModified": "2024-08-28",
"datePublished": "2019-04-26",
"description": "`siibra-explorer` is a browser based 3D viewer for exploring brain atlases that cover different spatial resolutions and modalities. It is built around an interactive 3D view of the brain displaying a unique selection of detailed templates and parcellation maps for the human, macaque, rat or mouse brain, including BigBrain as a microscopic resolution human brain model at its full resolution of 20 micrometers. ",
"license": "https://spdx.org/licenses/Apache-2.0",
"name": "siibra-explorer",
"programmingLanguage": [
"python 3",
"typescript"
],
"schema:releaseNotes": "# v2.14.10\n\n## Bugfix\n\n- Fix deployment scripts\n- Fix region update to updated siibra-api endpoint\n\n## Behind the scenes\n\n- Re-enable siibra-api warning mismatch warning\n- Adapt to siibra-api v0.3.18 point assignment rhetoric\n- Enable cheat code, removing obsolete experimental flags\n",
"runtimePlatform": "docker",
"version": "2.14.10",
"contIntegration": "https://github.com/FZJ-INM1-BDA/siibra-explorer/actions",
"codemeta:continuousIntegration": {
"id": "https://github.com/FZJ-INM1-BDA/siibra-explorer/actions"
},
"issueTracker": "https://github.com/fzj-inm1-bda/siibra-explorer/issues"
}
......@@ -10,3 +10,9 @@
- Re-enable siibra-api warning mismatch warning
- Adapt to siibra-api v0.3.18 point assignment rhetoric
- Enable cheat code, removing obsolete experimental flags
- If `HOST_PATHNAME` env is provided, also listens on root path
- Added servicemeta endpoint
## Known regressions
- Labelled assignment now takes a little longer. Additionally, the assigned value does not match that of the index label. This will be addressed in a future update. (The temporary regression allows for significant performant statistical assignment, as well more accurate label assignment.)
......@@ -41,6 +41,9 @@
</ng-template>
</mat-action-list>
<div class="sxplr-m-2" *ngIf="warningMessage$ | async; let warningMessage">
<markdown-dom [markdown]="warningMessage"></markdown-dom>
</div>
<div class="sxplr-m-2" *ngIf="busy$ | async as busyMessage">
<spinner-cmp class="sxplr-d-inline-block"></spinner-cmp>
......@@ -62,7 +65,7 @@
matSort
class="sxplr-w-100"
#simpleTblSort="matSort"
matSortActive="map value"
matSortActive="map_value"
matSortDirection="desc">
<ng-container matColumnDef="region">
<th mat-header-cell *matHeaderCellDef mat-sort-header>
......@@ -78,7 +81,7 @@
</button>
</td>
</ng-container>
<ng-container matColumnDef="map value">
<ng-container matColumnDef="map_value">
<th mat-header-cell *matHeaderCellDef mat-sort-header>
map value
</th>
......@@ -98,7 +101,7 @@
<table mat-table [dataSource]="df$ | async | dfToDs : comphTableSort"
matSort
#comphTableSort="matSort"
matSortActive="map value"
matSortActive="map_value"
matSortDirection="desc">
<ng-container matColumnDef="region">
......
import { Component, Input, OnDestroy, Output, TemplateRef, EventEmitter } from '@angular/core';
import { Clipboard, MatDialog, MatDialogRef, MatSnackBar } from 'src/sharedModules/angularMaterial.exports';
import { BehaviorSubject, EMPTY, Observable, Subscription, combineLatest, concat, of } from 'rxjs';
import { catchError, map, shareReplay, switchMap, tap } from 'rxjs/operators';
import { catchError, filter, map, shareReplay, switchMap, take, tap } from 'rxjs/operators';
import { SAPI, EXPECTED_SIIBRA_API_VERSION } from 'src/atlasComponents/sapi/sapi.service';
import { SxplrParcellation, SxplrTemplate } from 'src/atlasComponents/sapi/sxplrTypes';
import { translateRegionName } from 'src/atlasComponents/sapi/translateV3';
......@@ -15,6 +15,10 @@ import { atlasSelection } from 'src/state';
const DOING_PROB_ASGMT = "Performing probabilistic assignment ..."
const DOING_LABEL_ASGMT = "Probabilistic assignment failed. Performing labelled assignment ..."
const LABELLED_MAP_ASSIGNMENT_REGRESSION = `Labelled point assignment is currently experiencing some regression. For more detail, please visit
[https://siibra-explorer.readthedocs.io/en/stable/releases/v2.14.10/](https://siibra-explorer.readthedocs.io/en/stable/releases/v2.14.10/)`
@Component({
selector: 'sxplr-point-assignment',
templateUrl: './point-assignment.component.html',
......@@ -24,7 +28,7 @@ export class PointAssignmentComponent implements OnDestroy {
SIMPLE_COLUMNS = [
"region",
"map value",
"map_value",
]
#busy$ = new BehaviorSubject<string>(null)
......@@ -58,6 +62,11 @@ export class PointAssignmentComponent implements OnDestroy {
@Output()
clickOnRegionName = new EventEmitter<{ target: string, event: MouseEvent }>()
warningMessage$ = this.busy$.pipe(
filter(busyWith => !!busyWith),
map(busyWith => busyWith === DOING_LABEL_ASGMT && LABELLED_MAP_ASSIGNMENT_REGRESSION)
)
df$: Observable<PathReturn<"/map/assign">> = combineLatest([
this.point$,
this.#parcellation,
......@@ -227,5 +236,5 @@ function generateCsv(df: PathReturn<"/map/assign">) {
return [
df.columns.map(escapeDoubleQuotes).map(v => `"${v}"`).join(","),
...df.data.map(processRow)
].join("\n")
].join("\r\n")
}
......@@ -7,6 +7,7 @@ import { ZipFilesOutputModule } from 'src/zipFilesOutput/module';
import { SandsToNumPipe } from "./sandsToNum.pipe"
import { SapiViewsUtilModule } from '../util';
import { AngularMaterialModule } from 'src/sharedModules';
import { MarkdownModule } from 'src/components/markdown';
......@@ -22,6 +23,7 @@ import { AngularMaterialModule } from 'src/sharedModules';
ZipFilesOutputModule,
SapiViewsUtilModule,
AngularMaterialModule,
MarkdownModule,
],
exports: [
PointAssignmentComponent
......
......@@ -2,6 +2,7 @@ import { DOCUMENT } from "@angular/common";
import { APP_INITIALIZER, InjectionToken, NgModule } from "@angular/core";
import { BehaviorSubject, fromEvent, Observable } from "rxjs";
import { filter, scan, take } from "rxjs/operators";
import { MatSnackBar } from "src/sharedModules";
const CODE_DICT = {
ArrowUp: "ArrowUp",
......@@ -41,7 +42,7 @@ const showXmptToggle = new BehaviorSubject<boolean>(false)
providers: [
{
provide: APP_INITIALIZER,
useFactory: (document: Document) => {
useFactory: (document: Document, snackbar: MatSnackBar) => {
fromEvent(document, "keydown", { capture: true }).pipe(
scan((acc, curr: KeyboardEvent) => {
const key = curr.key
......@@ -57,11 +58,12 @@ const showXmptToggle = new BehaviorSubject<boolean>(false)
take(1)
).subscribe(() => {
showXmptToggle.next(true)
snackbar.open(`Cheat mode activated`, "Dismiss", { duration: 5000 })
})
return () => Promise.resolve()
},
multi: true,
deps: [DOCUMENT]
deps: [DOCUMENT, MatSnackBar]
},
{
provide: SHOW_EXPERIMENTAL_TOKEN,
......
......@@ -2,6 +2,8 @@ Siibra explorer uses 'cookies' (text files placed on your computer) to verify lo
Siibra explorer uses at least the following cookies:
- **connect.sid** verify login details
- **MATOMO_SESSID**: used by ebrains hosted matomo instance to store whether user opt out of tracking
- **_pk_id**: used by ebrains hosted matommo instance to identify user
- **_pk_sess**: used by ebrains hosted matommo instance to identify user session
To find out more about cookies, including how to determine the cookies that have been set on your computer and how to manage or delete them, visit <www.aboutcookies.org>
\ No newline at end of file
To find out more about cookies, including how to determine the cookies that have been set on your computer and how to manage or delete them, visit <www.aboutcookies.org>
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment