Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
299a42c
First attempt export as ELN
BenjaminCharmes Oct 6, 2025
dd9194a
Use APScheduler
BenjaminCharmes Oct 7, 2025
1085c0e
Return only 404 if no access and set user_only=False
BenjaminCharmes Oct 21, 2025
27218d8
Add raw data to .eln
BenjaminCharmes Oct 21, 2025
810a4a4
Fix item graph displaying too many items (#1367)
BenjaminCharmes Oct 28, 2025
98c7021
Allow item creation endpoints to use `PUT` (#1387)
ml-evs Oct 28, 2025
5027732
Add file-size in the filelist (#1380)
DianaAliabieva Oct 28, 2025
28f5a58
Add support for PSTrace EIS output txt files (#1383)
ml-evs Oct 28, 2025
d30bada
Fix collection creation modal error display for duplicate IDs (#1382)
BenjaminCharmes Oct 29, 2025
2f77f01
First attempt to sample ELN export button
BenjaminCharmes Oct 29, 2025
40b914f
Dropdown for sample only or related sample + col
BenjaminCharmes Oct 30, 2025
58be50f
Re-add docstring
BenjaminCharmes Oct 30, 2025
b058649
Merge branch 'main' into bc/eln-button
BenjaminCharmes Oct 30, 2025
e3054d6
Fix pytest
BenjaminCharmes Oct 30, 2025
8187b86
Add itemGraph in ExportModal and depth control for related items
BenjaminCharmes Oct 31, 2025
1ced5a2
Add asynchronous data block processing with APScheduler
BenjaminCharmes Dec 11, 2025
0da0642
Merge branch 'main' into bc/async-block
BenjaminCharmes Dec 12, 2025
f524079
resolve conflicts
BenjaminCharmes Dec 12, 2025
49911a0
Add async to XRDInsituBlock.vue
BenjaminCharmes Dec 12, 2025
f025070
resolve conflicts
BenjaminCharmes Dec 12, 2025
a22a7c3
Add block processing 'stages' and display it in the UI
BenjaminCharmes Dec 15, 2025
0944578
Merge branch 'main' into bc/async-block
BenjaminCharmes Dec 15, 2025
793c9b0
remove console.log
BenjaminCharmes Dec 15, 2025
cdbdd50
Add status field to JSON schemas
BenjaminCharmes Dec 15, 2025
24c0906
Fix JSON schema filenames
BenjaminCharmes Dec 15, 2025
d2da519
Unify BlockTask and ExportTask into single Task model
BenjaminCharmes Dec 16, 2025
7070313
Unify BlockTask and ExportTask into single Task model
BenjaminCharmes Dec 16, 2025
c5b2ba4
Unify BlockTask and ExportTask into single Task model
BenjaminCharmes Dec 16, 2025
c1af4df
Regenerate JSON schemas for item models
BenjaminCharmes Dec 16, 2025
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
1 change: 1 addition & 0 deletions pydatalab/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ server = [
"Flask-PyMongo ~= 2.3",
"Flask-Mail ~= 0.10",
"Flask-Compress ~= 1.15",
"APScheduler ~= 3.10",
"Werkzeug ~= 3.0",
"python-dotenv ~= 1.0",
"pillow ~= 11.0",
Expand Down
363 changes: 363 additions & 0 deletions pydatalab/schemas/collections.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,363 @@
{
"title": "Collection",
"description": "An Entry is an abstract base class for any model that can be\ndeserialized and stored in the database.",
"type": "object",
"properties": {
"blocks_obj": {
"title": "Blocks Obj",
"default": {},
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/DataBlockResponse"
}
},
"display_order": {
"title": "Display Order",
"default": [],
"type": "array",
"items": {
"type": "string"
}
},
"creator_ids": {
"title": "Creator Ids",
"default": [],
"type": "array",
"items": {
"type": "string"
}
},
"creators": {
"title": "Creators",
"type": "array",
"items": {
"$ref": "#/definitions/Person"
}
},
"type": {
"title": "Type",
"default": "collections",
"const": "collections",
"pattern": "^collections$",
"type": "string"
},
"immutable_id": {
"title": "Immutable ID",
"format": "uuid",
"type": "string"
},
"last_modified": {
"title": "Last Modified",
"type": "string",
"format": "date-time"
},
"relationships": {
"title": "Relationships",
"type": "array",
"items": {
"$ref": "#/definitions/TypedRelationship"
}
},
"collection_id": {
"title": "Collection Id",
"minLength": 1,
"maxLength": 40,
"pattern": "^(?:[a-zA-Z0-9]+|[a-zA-Z0-9][a-zA-Z0-9._-]+[a-zA-Z0-9])$",
"type": "string"
},
"title": {
"title": "Title",
"type": "string"
},
"description": {
"title": "Description",
"type": "string"
},
"num_items": {
"title": "Num Items",
"type": "integer"
}
},
"definitions": {
"DataBlockResponse": {
"title": "DataBlockResponse",
"description": "A generic response model for a block, i.e., what is stored in `self.data`\nin the corresponding DataBlock class.\n\nIt is expected but not mandatory that this model will be extended by the specific block type\nwhere possible.",
"type": "object",
"properties": {
"blocktype": {
"title": "Blocktype",
"type": "string"
},
"block_id": {
"title": "Block Id",
"type": "string"
},
"item_id": {
"title": "Item Id",
"type": "string"
},
"collection_id": {
"title": "Collection Id",
"type": "string"
},
"title": {
"title": "Title",
"type": "string"
},
"freeform_comment": {
"title": "Freeform Comment",
"type": "string"
},
"file_id": {
"title": "File Id",
"type": "string"
},
"file_ids": {
"title": "File Ids",
"type": "array",
"items": {
"type": "string"
}
},
"errors": {
"title": "Errors",
"type": "array",
"items": {
"type": "string"
}
},
"warnings": {
"title": "Warnings",
"type": "array",
"items": {
"type": "string"
}
},
"b64_encoded_image": {
"title": "B64 Encoded Image",
"datalab_exclude_from_db": true,
"datalab_exclude_from_load": true,
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"bokeh_plot_data": {
"title": "Bokeh Plot Data",
"datalab_exclude_from_db": true,
"datalab_exclude_from_load": true,
"type": "object"
},
"computed": {
"title": "Computed",
"datalab_exclude_from_load": true,
"type": "object"
},
"metadata": {
"title": "Metadata",
"datalab_exclude_from_load": true,
"type": "object"
}
},
"required": [
"blocktype",
"block_id"
]
},
"RelationshipType": {
"title": "RelationshipType",
"description": "An enumeration of the possible types of relationship between two entries.\n\n```mermaid\nclassDiagram\nclass entryC\nentryC --|> entryA: parent\nentryC ..|> entryD\nentryA <..> entryD: sibling\nentryA --|> entryB : child\n```",
"enum": [
"parent",
"child",
"sibling",
"is_part_of",
"other"
],
"type": "string"
},
"KnownType": {
"title": "KnownType",
"description": "An enumeration of the types of entry known by this implementation, should be made dynamic in the future.",
"enum": [
"samples",
"starting_materials",
"blocks",
"files",
"people",
"collections"
],
"type": "string"
},
"TypedRelationship": {
"title": "TypedRelationship",
"type": "object",
"properties": {
"description": {
"title": "Description",
"type": "string"
},
"relation": {
"$ref": "#/definitions/RelationshipType"
},
"type": {
"$ref": "#/definitions/KnownType"
},
"immutable_id": {
"title": "Immutable Id",
"type": "string"
},
"item_id": {
"title": "Item Id",
"minLength": 1,
"maxLength": 40,
"pattern": "^(?:[a-zA-Z0-9]+|[a-zA-Z0-9][a-zA-Z0-9._-]+[a-zA-Z0-9])$",
"type": "string"
},
"refcode": {
"title": "Refcode",
"minLength": 1,
"maxLength": 40,
"pattern": "^[a-z]{2,10}:(?:[a-zA-Z0-9]+|[a-zA-Z0-9][a-zA-Z0-9._-]+[a-zA-Z0-9])$",
"type": "string"
}
},
"required": [
"type"
]
},
"IdentityType": {
"title": "IdentityType",
"description": "A string enum representing the supported verifiable identity types.",
"enum": [
"email",
"orcid",
"github"
],
"type": "string"
},
"Identity": {
"title": "Identity",
"description": "A model for identities that can be provided by external systems\nand associated with a given user.",
"type": "object",
"properties": {
"identity_type": {
"$ref": "#/definitions/IdentityType"
},
"identifier": {
"title": "Identifier",
"type": "string"
},
"name": {
"title": "Name",
"type": "string"
},
"verified": {
"title": "Verified",
"default": false,
"type": "boolean"
},
"display_name": {
"title": "Display Name",
"type": "string"
}
},
"required": [
"identity_type",
"identifier",
"name"
]
},
"UserRole": {
"title": "UserRole",
"description": "An enumeration.",
"enum": [
"user",
"admin",
"manager"
],
"type": "string"
},
"AccountStatus": {
"title": "AccountStatus",
"description": "A string enum representing the account status.",
"enum": [
"active",
"unverified",
"deactivated"
],
"type": "string"
},
"Person": {
"title": "Person",
"description": "A model that describes an individual and their digital identities.",
"type": "object",
"properties": {
"type": {
"title": "Type",
"default": "people",
"const": "people",
"type": "string"
},
"immutable_id": {
"title": "Immutable ID",
"format": "uuid",
"type": "string"
},
"last_modified": {
"title": "Last Modified",
"type": "string",
"format": "date-time"
},
"relationships": {
"title": "Relationships",
"type": "array",
"items": {
"$ref": "#/definitions/TypedRelationship"
}
},
"identities": {
"title": "Identities",
"type": "array",
"items": {
"$ref": "#/definitions/Identity"
}
},
"display_name": {
"title": "Display Name",
"minLength": 1,
"maxLength": 150,
"type": "string"
},
"contact_email": {
"title": "Contact Email",
"type": "string",
"format": "email"
},
"managers": {
"title": "Managers",
"type": "array",
"items": {
"type": "string"
}
},
"role": {
"default": "user",
"allOf": [
{
"$ref": "#/definitions/UserRole"
}
]
},
"account_status": {
"default": "unverified",
"allOf": [
{
"$ref": "#/definitions/AccountStatus"
}
]
}
}
}
}
}
3 changes: 2 additions & 1 deletion pydatalab/src/pydatalab/apps/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ def load_app_blocks():

try:
# A dummy block that is used to check that bad blocks do not break the import
from pydatalab.apps._canary import CanaryBlock
from pydatalab.apps._canary import AsyncCanaryBlock, CanaryBlock

app_blocks.append(CanaryBlock)
app_blocks.append(AsyncCanaryBlock)
except ImportError as e:
_check_error(e)

Expand Down
Loading