Merge pull request #22206 from galaxybot/dev_auto_update_dependencies

Update Python dependencies
This commit is contained in:
Nicola Soranzo
2026-04-09 16:12:47 +01:00
committed by GitHub
44 changed files with 344 additions and 219 deletions
+1
View File
@@ -401,6 +401,7 @@ class Data(metaclass=DataMeta):
self, trans, data: DatasetHasHidProtocol, headers: Headers, do_action: str = "zip"
) -> tuple[Union[ZipstreamWrapper, str], Headers]:
# save a composite object into a compressed archive for downloading
assert data.name
outfname = data.name[0:150]
outfname = "".join(c in FILENAME_VALID_CHARS and c or "_" for c in outfname)
archive = ZipstreamWrapper(
+1 -1
View File
@@ -51,7 +51,7 @@ class HasMetadata(Protocol):
class HasName(Protocol):
name: str
name: str | None
class HasExtraFilesAndMetadata(HasExtraFilesPath, HasMetadata, Protocol): ...
+46 -46
View File
@@ -1,33 +1,33 @@
# This file was autogenerated by uv via the following command:
# uv export --frozen --no-annotate --no-hashes --only-group=dev
aiohappyeyeballs==2.6.1
aiohttp==3.13.4
aiohttp==3.13.5
aiosignal==1.4.0
alabaster==1.0.0
ase==3.27.0
ase==3.28.0
async-timeout==5.0.1 ; python_full_version < '3.11'
attrs==25.4.0
attrs==26.1.0
axe-selenium-python==2.1.6
babel==2.18.0
backports-asyncio-runner==1.2.0 ; python_full_version < '3.11'
backports-tarfile==1.2.0 ; python_full_version < '3.12' and platform_machine != 'ppc64le' and platform_machine != 's390x'
black==26.3.1
boto3==1.42.61
botocore==1.42.61
build==1.4.0
boto3==1.42.70
botocore==1.42.70
build==1.4.2
cachecontrol==0.14.4
cachetools==7.0.5
cattrs==26.1.0
certifi==2026.2.25
cffi==2.0.0 ; (implementation_name != 'pypy' and os_name == 'nt') or platform_python_implementation != 'PyPy'
charset-normalizer==3.4.5
click==8.3.1
charset-normalizer==3.4.7
click==8.3.2
codespell==2.4.2
colorama==0.4.6 ; os_name == 'nt' or sys_platform == 'win32'
colorlog==6.10.1
contourpy==1.3.2 ; python_full_version < '3.11'
contourpy==1.3.3 ; python_full_version >= '3.11'
coverage==7.13.4
coverage==7.13.5
cryptography==46.0.7
cwltest==2.6.20251216093331
cycler==0.12.1
@@ -44,22 +44,22 @@ filelock==3.25.2
fluent-logger==0.11.1
fonttools==4.62.1
frozenlist==1.8.0
fsspec==2026.2.0
fsspec==2026.3.0
galaxy-release-util==0.3.2
gcsfs==2026.2.0
google-api-core==2.30.0
gcsfs==2026.3.0
google-api-core==2.30.2
google-auth==2.49.1
google-auth-oauthlib==1.3.0
google-cloud-core==2.5.0
google-cloud-storage==3.9.0
google-cloud-storage-control==1.10.0
google-auth-oauthlib==1.3.1
google-cloud-core==2.5.1
google-cloud-storage==3.10.1
google-cloud-storage-control==1.11.0
google-crc32c==1.8.0
google-resumable-media==2.8.0
googleapis-common-protos==1.73.0
google-resumable-media==2.8.2
googleapis-common-protos==1.74.0
greenlet==3.3.2
grpc-google-iam-v1==0.14.3
grpcio==1.78.0
grpcio-status==1.78.0
grpc-google-iam-v1==0.14.4
grpcio==1.80.0
grpcio-status==1.80.0
h11==0.16.0
html5rdf==1.2.1
hvac==2.4.0
@@ -72,13 +72,13 @@ inquirerpy==0.3.4
isodate==0.7.2 ; python_full_version < '3.11'
isort==8.0.1
jaraco-classes==3.4.0 ; platform_machine != 'ppc64le' and platform_machine != 's390x'
jaraco-context==6.1.1 ; platform_machine != 'ppc64le' and platform_machine != 's390x'
jaraco-context==6.1.2 ; platform_machine != 'ppc64le' and platform_machine != 's390x'
jaraco-functools==4.4.0 ; platform_machine != 'ppc64le' and platform_machine != 's390x'
jeepney==0.9.0 ; platform_machine != 'ppc64le' and platform_machine != 's390x' and sys_platform == 'linux'
jinja2==3.1.6
jmespath==1.1.0
jsonpatch==1.33
jsonpointer==3.0.0
jsonpointer==3.1.1
jsonschema==4.26.0
jsonschema-specifications==2025.9.1
junit-xml==1.9
@@ -94,17 +94,17 @@ matplotlib==3.10.8
mdit-py-plugins==0.5.0
mdurl==0.1.2
mirakuru==3.0.2
mistune==3.1.4
more-itertools==10.8.0 ; platform_machine != 'ppc64le' and platform_machine != 's390x'
mistune==3.2.0
more-itertools==11.0.1 ; platform_machine != 'ppc64le' and platform_machine != 's390x'
msgpack==1.1.2
multidict==6.7.1
mypy==1.19.1
mypy==1.20.0
mypy-extensions==1.1.0
myst-parser==4.0.1 ; python_full_version < '3.11'
myst-parser==5.0.0 ; python_full_version >= '3.11'
nh3==0.3.3
nh3==0.3.4
numpy==2.2.6 ; python_full_version < '3.11'
numpy==2.4.3 ; python_full_version >= '3.11'
numpy==2.4.4 ; python_full_version >= '3.11'
oauthlib==3.3.1
onedatafilerestclient==21.2.5.2
outcome==1.3.0.post0
@@ -112,7 +112,7 @@ owlrl==7.1.4
packaging==25.0
pathspec==1.0.4
pfzy==0.3.4
pillow==12.1.1
pillow==12.2.0
pkce==1.0.3
platformdirs==4.9.4
playwright==1.58.0
@@ -121,15 +121,15 @@ port-for==1.0.0
prettytable==3.17.0
prompt-toolkit==3.0.52
propcache==0.4.1
proto-plus==1.27.1
protobuf==6.33.5
proto-plus==1.27.2
protobuf==6.33.6
psutil==7.2.2 ; sys_platform != 'cygwin'
psycopg==3.3.3
pyasn1==0.6.3
pyasn1-modules==0.4.2
pycparser==3.0 ; (implementation_name != 'PyPy' and implementation_name != 'pypy' and os_name == 'nt') or (implementation_name != 'PyPy' and platform_python_implementation != 'PyPy')
pyee==13.0.1
pygithub==2.8.1
pygithub==2.9.0
pygments==2.20.0
pyjwt==2.12.1
pynacl==1.6.2
@@ -140,7 +140,7 @@ pysocks==1.7.1
pytest==9.0.2
pytest-asyncio==1.3.0
pytest-base-url==2.1.0
pytest-cov==7.0.0
pytest-cov==7.1.0
pytest-html==4.2.0
pytest-httpserver==1.1.5
pytest-json-report==1.5.0
@@ -150,30 +150,30 @@ pytest-playwright==0.7.2
pytest-postgresql==8.0.0
pytest-shard==0.1.2
python-dateutil==2.9.0.post0
python-irodsclient==3.2.0
python-irodsclient==3.3.0
python-slugify==8.0.4
pytokens==0.4.1
pywin32-ctypes==0.2.3 ; platform_machine != 'ppc64le' and platform_machine != 's390x' and sys_platform == 'win32'
pyyaml==6.0.3
rdflib==7.5.0
rdflib==7.6.0
readme-renderer==44.0
referencing==0.37.0
requests==2.33.0
requests==2.33.1
requests-cache==1.3.1
requests-oauthlib==2.0.0
requests-toolbelt==1.0.0
responses==0.26.0
rfc3986==2.0.0
rich==13.9.4
rich-argparse==1.7.2
rich-click==1.9.7
roc-validator==0.8.1
roman-numerals==4.1.0 ; python_full_version >= '3.11'
rpds-py==0.30.0
ruamel-yaml==0.18.17
ruamel-yaml-clib==0.2.15 ; python_full_version < '3.15' and platform_python_implementation == 'CPython'
ruamel-yaml==0.19.1
rucio-clients==39.4.1
s3transfer==0.16.0
schema-salad==8.9.20251102115403
schema-salad==8.9.20260327095315
scipy==1.15.3 ; python_full_version < '3.11'
scipy==1.17.1 ; python_full_version >= '3.11'
secretstorage==3.5.0 ; platform_machine != 'ppc64le' and platform_machine != 's390x' and sys_platform == 'linux'
@@ -202,23 +202,23 @@ testfixtures==11.0.0 ; python_full_version >= '3.11'
text-unidecode==1.3
tinydb==4.8.2
toml==0.10.2
tomli==2.4.0 ; python_full_version <= '3.11'
total-perspective-vortex==3.1.3
tomli==2.4.1 ; python_full_version <= '3.11'
total-perspective-vortex==3.2.0
trio==0.33.0
trio-websocket==0.12.2
tuspy==1.1.0
twine==6.2.0
types-cachetools==6.2.0.20251022
types-requests==2.32.4.20260107
types-cachetools==6.2.0.20260317
types-requests==2.33.0.20260402
typing-extensions==4.15.0
typos==1.44.0
tzdata==2025.3 ; sys_platform == 'win32'
typos==1.45.0
tzdata==2026.1 ; sys_platform == 'win32'
url-normalize==2.2.1
urllib3==2.6.3
watchdog==6.0.0
wcwidth==0.6.0
websocket-client==1.9.0
werkzeug==3.1.6
werkzeug==3.1.8
wsproto==1.3.2
yarl==1.23.0
zipp==3.23.0 ; python_full_version < '3.12'
@@ -1,7 +1,7 @@
attrs==25.4.0
attrs==26.1.0
flake8==7.3.0
flake8-bugbear==25.11.29
mccabe==0.7.0
pycodestyle==2.14.0
pyflakes==3.4.0
ruff==0.15.6
ruff==0.15.9
+71 -70
View File
@@ -2,26 +2,26 @@
# uv export --frozen --no-annotate --no-hashes --no-dev
a2wsgi==1.10.10
adal==1.2.7
ag-ui-protocol==0.1.13
aiobotocore==3.2.1
ag-ui-protocol==0.1.15
aiobotocore==3.3.0
aiofile==3.9.0
aiofiles==25.1.0
aiohappyeyeballs==2.6.1
aiohttp==3.13.4
aiohttp==3.13.5
aioitertools==0.13.0
aiosignal==1.4.0
alembic==1.18.4
amqp==5.3.1
annotated-doc==0.0.4
annotated-types==0.7.0
anthropic==0.84.0
anyio==4.12.1
anthropic==0.89.0
anyio==4.13.0
apispec==6.10.0
appdirs==1.4.4
arcp==0.2.1
argcomplete==3.6.3
async-timeout==5.0.1 ; python_full_version < '3.11'
attrs==25.4.0
attrs==26.1.0
authlib==1.6.9
babel==2.18.0
backports-tarfile==1.2.0 ; python_full_version < '3.12'
@@ -36,33 +36,33 @@ bioblend==1.8.0
bleach==6.3.0
boltons==25.0.0
boto==2.49.0
boto3==1.42.61
botocore==1.42.61
boto3==1.42.70
botocore==1.42.70
bx-python==0.14.0
cachecontrol==0.14.4
cachetools==7.0.5
caio==0.9.25
celery==5.6.2
celery==5.6.3
certifi==2026.2.25
cffi==2.0.0 ; implementation_name == 'pypy' or platform_python_implementation != 'PyPy'
charset-normalizer==3.4.5
charset-normalizer==3.4.7
circus==0.19.0
click==8.3.1
click==8.3.2
click-didyoumean==0.3.1
click-plugins==1.1.1.2
click-repl==0.3.0
cloudauthz==0.6.0
cloudbridge==3.2.0
cohere==5.20.7 ; sys_platform != 'emscripten'
cohere==5.21.1 ; sys_platform != 'emscripten'
colorama==0.4.6 ; sys_platform == 'win32'
coloredlogs==15.0.1
conda-package-streaming==0.12.0
cryptography==46.0.7
ct3==3.4.0.post5
cwl-upgrader==1.2.14
cwl-utils==0.40
cwltool==3.1.20260108082145
cyclopts==4.9.0
cwl-upgrader==1.2.15
cwl-utils==0.41
cwltool==3.1.20260315121657
cyclopts==4.10.1
defusedxml==0.7.1
deprecated==1.3.1
deprecation==2.1.0
@@ -80,37 +80,37 @@ et-xmlfile==2.0.0
eval-type-backport==0.3.1
exceptiongroup==1.3.1
executing==2.2.1
fastapi==0.135.1
fastapi==0.135.3
fastavro==1.12.1 ; sys_platform != 'emscripten'
fastmcp==3.2.0
filelock==3.25.2
fissix==24.4.24
frozenlist==1.8.0
fs==2.4.16
fsspec==2026.2.0
fsspec==2026.3.0
future==1.0.0
genai-prices==0.0.55
google-api-core==2.30.0
genai-prices==0.0.56
google-api-core==2.30.2
google-auth==2.49.1
google-cloud-batch==0.20.0
google-genai==1.67.0
googleapis-common-protos==1.73.0
google-cloud-batch==0.21.0
google-genai==1.70.0
googleapis-common-protos==1.74.0
gravity==1.2.0
greenlet==3.3.2 ; platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64'
griffelib==2.0.0
groq==1.1.1
grpcio==1.78.0
grpcio-status==1.78.0
gunicorn==25.0.3
gxformat2==0.23.0
griffelib==2.0.2
groq==1.1.2
grpcio==1.80.0
grpcio-status==1.80.0
gunicorn==25.3.0
gxformat2==0.24.0
h11==0.16.0
h5grove==3.0.0
h5py==3.16.0
hf-xet==1.4.2 ; platform_machine == 'AMD64' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'arm64' or platform_machine == 'x86_64'
hf-xet==1.4.3 ; platform_machine == 'AMD64' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'arm64' or platform_machine == 'x86_64'
httpcore==1.0.9
httpx==0.28.1
httpx-sse==0.4.3
huggingface-hub==1.7.1
huggingface-hub==1.9.0
humanfriendly==10.0
idna==3.11
ijson==3.5.0
@@ -121,12 +121,13 @@ isa-rwval==0.10.11
isal==1.8.0
isodate==0.7.2 ; python_full_version < '3.11'
jaraco-classes==3.4.0
jaraco-context==6.1.1
jaraco-context==6.1.2
jaraco-functools==4.4.0
jeepney==0.9.0 ; sys_platform == 'linux'
jinja2==3.1.6
jiter==0.13.0
jmespath==1.1.0
jsonpath-python==1.1.5
jsonref==1.1.0
jsonschema==4.26.0
jsonschema-path==0.4.5
@@ -136,20 +137,20 @@ kombu==5.6.2
lagom==2.7.7
legacy-cgi==2.6.4 ; python_full_version >= '3.13'
limits==5.8.0
logfire==4.29.0
logfire-api==4.29.0
logfire==4.31.0
logfire-api==4.31.0
lxml==6.0.2
mako==1.3.10
markdown==3.10.2
markdown-it-py==3.0.0 ; python_full_version < '3.11'
markdown-it-py==4.0.0 ; python_full_version >= '3.11'
markupsafe==3.0.3
mcp==1.26.0
mcp==1.27.0
mdurl==0.1.2
mercurial==7.2
mistralai==2.0.2
mistune==3.1.4
more-itertools==10.8.0
mercurial==7.2.1
mistralai==2.3.0
mistune==3.2.0
more-itertools==11.0.1
mrcfile==1.5.4
msal==1.35.1
msgpack==1.1.2
@@ -157,13 +158,13 @@ multidict==6.7.1
mypy-extensions==1.1.0
networkx==3.4.2 ; python_full_version < '3.11'
networkx==3.6.1 ; python_full_version >= '3.11'
nexus-rpc==1.2.0
nexus-rpc==1.4.0
nodejs-wheel==22.20.0
nodejs-wheel-binaries==22.20.0
numpy==2.2.6 ; python_full_version < '3.11'
numpy==2.4.3 ; python_full_version >= '3.11'
numpy==2.4.4 ; python_full_version >= '3.11'
oauthlib==3.3.1
openai==2.28.0
openai==2.30.0
openapi-pydantic==0.5.1
openpyxl==3.1.5
opentelemetry-api==1.39.1
@@ -175,7 +176,7 @@ opentelemetry-proto==1.39.1
opentelemetry-sdk==1.39.1
opentelemetry-semantic-conventions==0.60b1
opentelemetry-util-http==0.60b1
orjson==3.11.7
orjson==3.11.8
packaging==25.0
paramiko==4.0.0
parsley==1.3
@@ -183,12 +184,12 @@ paste==3.10.1
pastedeploy==3.1.0
pathable==0.5.0
pebble==5.2.0
pillow==12.1.1
pillow==12.2.0
platformdirs==4.9.4
prompt-toolkit==3.0.52
propcache==0.4.1
proto-plus==1.27.1
protobuf==6.33.5
proto-plus==1.27.2
protobuf==6.33.6
prov==1.5.1
psutil==7.2.2
pulsar-galaxy-lib==0.15.14
@@ -198,17 +199,18 @@ pyasn1-modules==0.4.2
pycparser==3.0 ; (implementation_name != 'PyPy' and platform_python_implementation != 'PyPy') or (implementation_name == 'pypy' and platform_python_implementation == 'PyPy')
pycryptodome==3.23.0
pydantic==2.12.5
pydantic-ai==1.68.0
pydantic-ai-slim==1.68.0
pydantic-ai==1.77.0
pydantic-ai-slim==1.77.0
pydantic-core==2.41.5
pydantic-evals==1.68.0
pydantic-graph==1.68.0
pydantic-evals==1.77.0
pydantic-graph==1.77.0
pydantic-handlebars==0.1.0
pydantic-settings==2.13.1
pydantic-tes==0.3.0
pydicom==3.0.2
pydot==4.0.1
pyeventsystem==0.1.0
pyfaidx==0.9.0.3
pyfaidx==0.9.0.4
pygments==2.20.0
pyjwt==2.12.1
pykwalify==1.8.0
@@ -230,12 +232,12 @@ pywin32==311 ; sys_platform == 'win32'
pywin32-ctypes==0.2.3 ; sys_platform == 'win32'
pyyaml==6.0.3
pyzmq==27.1.0
rdflib==7.5.0
rdflib==7.6.0
referencing==0.37.0
refgenconf==0.13.0
regex==2026.2.28
refgenconf==0.13.1
regex==2026.4.4
repoze-lru==0.7
requests==2.33.0
requests==2.33.1
requests-oauthlib==2.0.0
requests-toolbelt==1.0.0
requests-unixsocket==0.4.1
@@ -245,11 +247,10 @@ rich-rst==1.3.2
rocrate==0.14.2
routes==2.5.1
rpds-py==0.30.0
ruamel-yaml==0.18.17
ruamel-yaml-clib==0.2.15 ; python_full_version < '3.15' and platform_python_implementation == 'CPython'
s3fs==2026.2.0
ruamel-yaml==0.19.1
s3fs==2026.3.0
s3transfer==0.16.0
schema-salad==8.9.20251102115403
schema-salad==8.9.20260327095315
secretstorage==3.5.0 ; sys_platform == 'linux'
setuptools==81.0.0
shellingham==1.5.4
@@ -259,14 +260,14 @@ sniffio==1.3.1
social-auth-core==4.8.5
sortedcontainers==2.4.0
spython==0.3.14
sqlalchemy==2.0.48
sqlalchemy==2.0.49
sqlparse==0.5.5
sse-starlette==3.3.2
starlette==0.52.1
sse-starlette==3.3.4
starlette==1.0.0
starlette-context==0.5.1
supervisor==4.3.0
svgwrite==1.4.3
temporalio==1.20.0
temporalio==1.24.0
tenacity==9.1.4
text-unidecode==1.3
tifffile==2025.5.10 ; python_full_version < '3.11'
@@ -274,22 +275,22 @@ tifffile==2026.3.3 ; python_full_version >= '3.11'
tiktoken==0.12.0
tinydb==4.8.2
tokenizers==0.22.2 ; sys_platform != 'emscripten'
tomli==2.4.0 ; python_full_version < '3.11'
tomli==2.4.1 ; python_full_version < '3.11'
tornado==6.5.5
tqdm==4.67.3
tuspy==1.1.0
tuspyserver==4.2.3
typer==0.24.1
types-protobuf==6.32.1.20260221
types-requests==2.32.4.20260107 ; sys_platform != 'emscripten'
types-protobuf==7.34.1.20260403
types-requests==2.33.0.20260402 ; sys_platform != 'emscripten'
typing-extensions==4.15.0
typing-inspection==0.4.2
tzdata==2025.3
tzdata==2026.1
tzlocal==5.3.1
ubiquerg==0.9.1
ubiquerg==0.9.3
uncalled-for==0.2.0
urllib3==2.6.3
uvicorn==0.41.0
uvicorn==0.43.0
uvloop==0.22.1
vine==5.1.0
watchfiles==1.1.1
@@ -299,7 +300,7 @@ webob==1.8.9
websockets==16.0
whoosh==2.7.4
wrapt==1.17.3
xai-sdk==1.8.1
xai-sdk==1.11.0
yacman==1.0.0
yarl==1.23.0
zipp==3.23.0
@@ -1,27 +1,27 @@
# This file was autogenerated by uv via the following command:
# uv export --frozen --no-annotate --no-hashes --only-group=test
aiohappyeyeballs==2.6.1
aiohttp==3.13.4
aiohttp==3.13.5
aiosignal==1.4.0
ase==3.27.0
ase==3.28.0
async-timeout==5.0.1 ; python_full_version < '3.11'
attrs==25.4.0
attrs==26.1.0
axe-selenium-python==2.1.6
backports-asyncio-runner==1.2.0 ; python_full_version < '3.11'
boto3==1.42.61
botocore==1.42.61
boto3==1.42.70
botocore==1.42.70
cachecontrol==0.14.4
cachetools==7.0.5
cattrs==26.1.0
certifi==2026.2.25
cffi==2.0.0 ; (implementation_name != 'pypy' and os_name == 'nt') or platform_python_implementation != 'PyPy'
charset-normalizer==3.4.5
click==8.3.1
charset-normalizer==3.4.7
click==8.3.2
colorama==0.4.6 ; sys_platform == 'win32'
colorlog==6.10.1
contourpy==1.3.2 ; python_full_version < '3.11'
contourpy==1.3.3 ; python_full_version >= '3.11'
coverage==7.13.4
coverage==7.13.5
cryptography==46.0.7
cwltest==2.6.20251216093331
cycler==0.12.1
@@ -34,21 +34,21 @@ filelock==3.25.2
fluent-logger==0.11.1
fonttools==4.62.1
frozenlist==1.8.0
fsspec==2026.2.0
gcsfs==2026.2.0
google-api-core==2.30.0
fsspec==2026.3.0
gcsfs==2026.3.0
google-api-core==2.30.2
google-auth==2.49.1
google-auth-oauthlib==1.3.0
google-cloud-core==2.5.0
google-cloud-storage==3.9.0
google-cloud-storage-control==1.10.0
google-auth-oauthlib==1.3.1
google-cloud-core==2.5.1
google-cloud-storage==3.10.1
google-cloud-storage-control==1.11.0
google-crc32c==1.8.0
google-resumable-media==2.8.0
googleapis-common-protos==1.73.0
google-resumable-media==2.8.2
googleapis-common-protos==1.74.0
greenlet==3.3.2
grpc-google-iam-v1==0.14.3
grpcio==1.78.0
grpcio-status==1.78.0
grpc-google-iam-v1==0.14.4
grpcio==1.80.0
grpcio-status==1.80.0
h11==0.16.0
html5rdf==1.2.1
hvac==2.4.0
@@ -60,7 +60,7 @@ isodate==0.7.2 ; python_full_version < '3.11'
jinja2==3.1.6
jmespath==1.1.0
jsonpatch==1.33
jsonpointer==3.0.0
jsonpointer==3.1.1
jsonschema==4.26.0
jsonschema-specifications==2025.9.1
junit-xml==1.9
@@ -73,13 +73,13 @@ markupsafe==3.0.3
matplotlib==3.10.8
mdurl==0.1.2
mirakuru==3.0.2
mistune==3.1.4
mistune==3.2.0
msgpack==1.1.2
multidict==6.7.1
mypy==1.19.1
mypy==1.20.0
mypy-extensions==1.1.0
numpy==2.2.6 ; python_full_version < '3.11'
numpy==2.4.3 ; python_full_version >= '3.11'
numpy==2.4.4 ; python_full_version >= '3.11'
oauthlib==3.3.1
onedatafilerestclient==21.2.5.2
outcome==1.3.0.post0
@@ -87,7 +87,7 @@ owlrl==7.1.4
packaging==25.0
pathspec==1.0.4
pfzy==0.3.4
pillow==12.1.1
pillow==12.2.0
pkce==1.0.3
platformdirs==4.9.4
playwright==1.58.0
@@ -96,8 +96,8 @@ port-for==1.0.0
prettytable==3.17.0
prompt-toolkit==3.0.52
propcache==0.4.1
proto-plus==1.27.1
protobuf==6.33.5
proto-plus==1.27.2
protobuf==6.33.6
psutil==7.2.2 ; sys_platform != 'cygwin'
psycopg==3.3.3
pyasn1==0.6.3
@@ -111,7 +111,7 @@ pysocks==1.7.1
pytest==9.0.2
pytest-asyncio==1.3.0
pytest-base-url==2.1.0
pytest-cov==7.0.0
pytest-cov==7.1.0
pytest-html==4.2.0
pytest-httpserver==1.1.5
pytest-json-report==1.5.0
@@ -121,24 +121,24 @@ pytest-playwright==0.7.2
pytest-postgresql==8.0.0
pytest-shard==0.1.2
python-dateutil==2.9.0.post0
python-irodsclient==3.2.0
python-irodsclient==3.3.0
python-slugify==8.0.4
pyyaml==6.0.3
rdflib==7.5.0
rdflib==7.6.0
referencing==0.37.0
requests==2.33.0
requests==2.33.1
requests-cache==1.3.1
requests-oauthlib==2.0.0
responses==0.26.0
rich==13.9.4
rich-argparse==1.7.2
rich-click==1.9.7
roc-validator==0.8.1
rpds-py==0.30.0
ruamel-yaml==0.18.17
ruamel-yaml-clib==0.2.15 ; python_full_version < '3.15' and platform_python_implementation == 'CPython'
ruamel-yaml==0.19.1
rucio-clients==39.4.1
s3transfer==0.16.0
schema-salad==8.9.20251102115403
schema-salad==8.9.20260327095315
scipy==1.15.3 ; python_full_version < '3.11'
scipy==1.17.1 ; python_full_version >= '3.11'
selenium==4.41.0
@@ -154,22 +154,22 @@ testfixtures==11.0.0 ; python_full_version >= '3.11'
text-unidecode==1.3
tinydb==4.8.2
toml==0.10.2
tomli==2.4.0 ; python_full_version <= '3.11'
total-perspective-vortex==3.1.3
tomli==2.4.1 ; python_full_version <= '3.11'
total-perspective-vortex==3.2.0
trio==0.33.0
trio-websocket==0.12.2
tuspy==1.1.0
types-cachetools==6.2.0.20251022
types-requests==2.32.4.20260107
types-cachetools==6.2.0.20260317
types-requests==2.33.0.20260402
typing-extensions==4.15.0
typos==1.44.0
tzdata==2025.3 ; sys_platform == 'win32'
typos==1.45.0
tzdata==2026.1 ; sys_platform == 'win32'
url-normalize==2.2.1
urllib3==2.6.3
watchdog==6.0.0
wcwidth==0.6.0
websocket-client==1.9.0
werkzeug==3.1.6
werkzeug==3.1.8
wsproto==1.3.2
yarl==1.23.0
zipp==3.23.0 ; python_full_version < '3.12'
@@ -1,35 +1,35 @@
# This file was autogenerated by uv via the following command:
# uv export --frozen --no-annotate --no-hashes --only-group=typecheck
annotated-types==0.7.0
boto3-stubs==1.42.68
boto3-stubs==1.42.83
botocore-stubs==1.42.41
cffi==2.0.0 ; platform_python_implementation != 'PyPy'
cryptography==46.0.7
librt==0.8.1 ; platform_python_implementation != 'PyPy'
lxml-stubs==0.5.1
mypy==1.19.1
mypy-boto3-s3==1.42.67
mypy==1.20.0
mypy-boto3-s3==1.42.80
mypy-extensions==1.1.0
pathspec==1.0.4
pycparser==3.0 ; implementation_name != 'PyPy' and platform_python_implementation != 'PyPy'
pydantic==2.12.5
pydantic-core==2.41.5
tomli==2.4.0 ; python_full_version < '3.11'
tomli==2.4.1 ; python_full_version < '3.11'
types-awscrt==0.31.3
types-bleach==6.3.0.20251115
types-bleach==6.3.0.20260402
types-boto==2.49.18.20241019
types-contextvars==2.4.7.3
types-dataclasses==0.6.6
types-docutils==0.22.3.20260223
types-html5lib==1.1.11.20251117
types-docutils==0.22.3.20260322
types-html5lib==1.1.11.20260402
types-markdown==3.10.2.20260211
types-paramiko==4.0.0.20250822
types-python-dateutil==2.9.0.20260305
types-paramiko==4.0.0.20260402
types-python-dateutil==2.9.0.20260402
types-python-slugify==8.0.2.20240310
types-pyyaml==6.0.12.20250915
types-requests==2.32.4.20260107
types-requests==2.33.0.20260402
types-s3transfer==0.16.0
types-setuptools==82.0.0.20260210
types-setuptools==82.0.0.20260402
types-six==1.17.0.20251009
types-webencodings==0.5.0.20251108
typing-extensions==4.15.0
+1 -1
View File
@@ -530,7 +530,7 @@ class DataverseRepositoryInteractor(RDMRepositoryInteractor):
if hash_value and hash_type in supported_hashes:
return [
RemoteFileHash(
hash_function=cast(HashFunctionNames, hash_type),
hash_function=hash_type,
hash_value=str(hash_value),
)
]
+4 -1
View File
@@ -6,6 +6,7 @@ import operator
import os
import re
from collections.abc import Callable
from decimal import Decimal
from tempfile import NamedTemporaryFile
from typing import (
Any,
@@ -388,6 +389,7 @@ def collect_primary_datasets(job_context: BaseJobContext, output: dict[str, Data
):
job_context.increment_discovered_file_count()
filenames[discovered_file.path] = discovered_file
assert outdata.dataset is not None
for filename_index, (filename, discovered_file) in enumerate(filenames.items()):
extra_file_collector = discovered_file.collector
fields_match = discovered_file.match
@@ -450,8 +452,9 @@ def collect_primary_datasets(job_context: BaseJobContext, output: dict[str, Data
# Associate new dataset with job
job_context.add_output_dataset_association(f"__new_primary_file_{name}|{designation}__", primary_data)
except JobOutputNameTooLongError:
assert primary_data.dataset is not None
primary_data.dataset.state = Dataset.states.DISCARDED
primary_data.dataset.file_size = 0
primary_data.dataset.file_size = Decimal(0)
job_context.add_datasets_to_history([primary_data], for_output_dataset=outdata)
raise
job_context.add_datasets_to_history([primary_data], for_output_dataset=outdata)
+2
View File
@@ -245,6 +245,7 @@ class JobIO(UsesDictVisibleKeys):
def get_input_path(self, dataset: DatasetInstance) -> DatasetPath:
real_path = dataset.get_file_name()
false_path = self.dataset_path_rewriter.rewrite_dataset_path(dataset, "input")
assert dataset.dataset is not None
return DatasetPath(
dataset.dataset.id,
real_path=real_path,
@@ -290,6 +291,7 @@ class JobIO(UsesDictVisibleKeys):
with open(da_false_path, "ab"):
pass
real_path = da.dataset.get_file_name(sync_cache=False)
assert da.dataset.dataset is not None
false_extra_files_path = os.path.join(
os.path.dirname(da_false_path or real_path), da.dataset.dataset.extra_files_path_name
)
+17 -6
View File
@@ -82,6 +82,7 @@ from galaxy.model import (
Dataset,
Job,
JobOutputNameTooLongError,
LibraryDatasetDatasetAssociation,
store,
Task,
)
@@ -121,7 +122,7 @@ from galaxy.work.context import WorkRequestContext
if TYPE_CHECKING:
from galaxy.jobs.handler import BaseJobHandlerQueue
from galaxy.model import DatasetInstance
from galaxy.model import HistoryDatasetAssociation
from galaxy.tools import Tool
from galaxy.util import (
Element,
@@ -1499,9 +1500,9 @@ class MinimalJobWrapper(HasResourceParameters):
except Exception:
# Failure to update the output of a failed job should not prevent completion of the failure method
log.exception(
"(%s) fail(): Failed to update job output dataset with id: %s",
"(%s) fail(): Failed to update job output dataset instance with id: %s",
self.get_id_tag(),
dataset.dataset.id,
dataset.id,
)
# Pause any dependent jobs (and those jobs' outputs)
for dep_job_assoc in dataset.dependent_jobs:
@@ -1930,9 +1931,16 @@ class MinimalJobWrapper(HasResourceParameters):
self._setup_working_directory(job=job)
def _finish_dataset(
self, output_name, dataset: "DatasetInstance", job: Job, context, final_job_state, remote_metadata_directory
self,
output_name: str,
dataset: "HistoryDatasetAssociation | LibraryDatasetDatasetAssociation",
job: Job,
context,
final_job_state,
remote_metadata_directory,
):
implicit_collection_jobs = job.implicit_collection_jobs_association
assert dataset.dataset is not None
purged = dataset.dataset.purged
if not purged and dataset.dataset.external_filename is None:
trynum = 0
@@ -2692,7 +2700,9 @@ class MinimalJobWrapper(HasResourceParameters):
else:
return "anonymous@unknown"
def __update_output(self, job, hda, clean_only=False):
def __update_output(
self, job: Job, hda: "HistoryDatasetAssociation | LibraryDatasetDatasetAssociation", clean_only: bool = False
):
"""Handle writing outputs to the object store.
This should be called regardless of whether the job was failed or not so
@@ -2700,8 +2710,9 @@ class MinimalJobWrapper(HasResourceParameters):
cleaned up if the dataset has been purged.
"""
dataset = hda.dataset
assert dataset is not None
dataset.set_total_size()
if dataset not in job.output_library_datasets:
if not isinstance(hda, LibraryDatasetDatasetAssociation):
purged = dataset.purged
if not purged and not clean_only:
self.object_store.update_from_file(dataset, create=True)
+1
View File
@@ -580,6 +580,7 @@ class JobHandlerQueue(BaseJobHandlerQueue):
log.info("(%d) User (%s) is over total walltime limit: job paused", job.id, job.user_id)
job.set_state(model.Job.states.PAUSED)
for dataset_assoc in job.output_datasets + job.output_library_datasets:
assert dataset_assoc.dataset.dataset is not None
dataset_assoc.dataset.dataset.state = model.Dataset.states.PAUSED
dataset_assoc.dataset.info = "Execution of this dataset's job is paused because you were over your total job runtime at the time it was ready to run"
self.sa_session.add(dataset_assoc.dataset.dataset)
+1
View File
@@ -425,6 +425,7 @@ class BaseJobRunner:
def _walk_dataset_outputs(self, job: model.Job):
for dataset_assoc in job.output_datasets + job.output_library_datasets:
assert dataset_assoc.dataset.dataset is not None
for dataset in (
dataset_assoc.dataset.dataset.history_associations + dataset_assoc.dataset.dataset.library_associations
):
+4 -1
View File
@@ -251,13 +251,14 @@ class HDAManager(
"""
Purge this HDA and the dataset underlying it.
"""
user = hda.history.user or None
user = hda.history.user if hda.history is not None else None
if user:
# Need to calculate this before purging
quota_amount_reduction = hda.quota_amount(user)
super().purge(hda, flush=flush)
# decrease the user's space used
if user:
assert hda.dataset is not None
quota_source_info = hda.dataset.quota_source_info
if quota_amount_reduction and quota_source_info.use:
user.adjust_total_disk_usage(
@@ -363,6 +364,7 @@ def dereference_input_to_hda(
) -> HistoryDatasetAssociation:
permissions = trans.app.security_agent.history_get_default_permissions(history)
hda = dereference_to_model(trans.sa_session, trans.user, history, data_request)
assert hda.dataset is not None
trans.app.security_agent.set_all_dataset_permissions(hda.dataset, permissions, new=True, flush=False)
trans.sa_session.commit()
return hda
@@ -461,6 +463,7 @@ class HDAStorageCleanerManager(base.StorageCleanerManager):
hda: HistoryDatasetAssociation = self.hda_manager.get_owned(hda_id, user)
hda.deleted = True
quota_amount = int(hda.quota_amount(user))
assert hda.dataset is not None
hda.purge_usage_from_quota(user, hda.dataset.quota_source_info)
hda.purged = True
dataset_ids_to_remove.add(hda.dataset.id)
+2 -1
View File
@@ -214,7 +214,8 @@ class TourGenerator:
step.content = f"Select dataset: <b>{hid}: {dataset}</b>"
else:
step.content = "Select a dataset"
elif input.type == "conditional" and isinstance(input, Conditional):
elif input.type == "conditional":
assert isinstance(input, Conditional)
test_param = input.test_param
if test_param is None:
param_id = f"{input.name}|"
+1
View File
@@ -96,6 +96,7 @@ def push_if_necessary(object_store: ObjectStore, dataset: DatasetInstance, exter
# or a remote object store from its cache path.
# empty files could happen when outputs are discovered from working dir,
# empty file check needed for e.g. test/integration/test_extended_metadata_outputs_to_working_directory.py::test_tools[multi_output_assign_primary]
assert dataset.dataset is not None
if not dataset.dataset.purged and os.path.getsize(external_filename):
object_store.update_from_file(dataset.dataset, file_name=external_filename, create=True)
+29 -12
View File
@@ -2047,6 +2047,7 @@ class Job(Base, JobLike, UsesCreateAndUpdateTime, Dictifiable, Serializable):
def add_output_dataset(self, name: str, dataset: "HistoryDatasetAssociation"):
self._check_name_length(name)
joda = JobToOutputDatasetAssociation(name, dataset)
assert dataset.dataset is not None
if dataset.dataset.job is None:
# Only set job if dataset doesn't already have associated job.
# database operation tools that make copies should not modify the job here.
@@ -3496,7 +3497,7 @@ class History(Base, HasTags, Dictifiable, UsesAnnotations, HasName, Serializable
archive_export_id: Mapped[Optional[int]] = mapped_column(ForeignKey("store_export_association.id"), default=None)
datasets: Mapped[list["HistoryDatasetAssociation"]] = relationship(
back_populates="history", order_by=lambda: asc(HistoryDatasetAssociation.hid) # type: ignore[has-type]
back_populates="history", order_by=lambda: asc(HistoryDatasetAssociation.hid)
)
exports: Mapped[list["JobExportHistoryArchive"]] = relationship(
back_populates="history",
@@ -3510,7 +3511,7 @@ class History(Base, HasTags, Dictifiable, UsesAnnotations, HasName, Serializable
not_(HistoryDatasetAssociation.deleted),
)
),
order_by=lambda: asc(HistoryDatasetAssociation.hid), # type: ignore[has-type]
order_by=lambda: asc(HistoryDatasetAssociation.hid),
viewonly=True,
)
dataset_collections: Mapped[list["HistoryDatasetCollectionAssociation"]] = relationship(back_populates="history")
@@ -3531,10 +3532,10 @@ class History(Base, HasTags, Dictifiable, UsesAnnotations, HasName, Serializable
lambda: and_(
HistoryDatasetAssociation.history_id == History.id,
not_(HistoryDatasetAssociation.deleted),
HistoryDatasetAssociation.visible, # type: ignore[has-type]
HistoryDatasetAssociation.visible,
)
),
order_by=lambda: asc(HistoryDatasetAssociation.hid), # type: ignore[has-type]
order_by=lambda: asc(HistoryDatasetAssociation.hid),
viewonly=True,
)
visible_dataset_collections: Mapped[list["HistoryDatasetCollectionAssociation"]] = relationship(
@@ -4685,10 +4686,10 @@ class Dataset(Base, StorableObject, Serializable):
return self.object_store.size(self)
@overload
def get_size(self, nice_size: Literal[False], calculate_size: bool = True) -> int: ...
def get_size(self, nice_size: Literal[True], calculate_size: bool = True) -> str: ...
@overload
def get_size(self, nice_size: Literal[True], calculate_size: bool = True) -> str: ...
def get_size(self, nice_size: Literal[False] = False, calculate_size: bool = True) -> int: ...
def get_size(self, nice_size: bool = False, calculate_size: bool = True) -> Union[int, str]:
"""Returns the size of the data on disk"""
@@ -4706,7 +4707,7 @@ class Dataset(Base, StorableObject, Serializable):
else:
return cast(int, self.file_size) or 0
def set_size(self, no_extra_files=False):
def set_size(self, no_extra_files: bool = False) -> None:
"""Sets the size of the data on disk.
If the caller is sure there are no extra files, pass no_extra_files as True to optimize subsequent
@@ -4714,7 +4715,7 @@ class Dataset(Base, StorableObject, Serializable):
the file system.
"""
if not self.file_size:
self.file_size = self._calculate_size()
self.file_size = Decimal(self._calculate_size())
if no_extra_files:
self.total_size = self.file_size
@@ -5135,7 +5136,10 @@ def datatype_for_extension(extension, datatypes_registry=None) -> "Data":
class DatasetInstance(RepresentById, UsesCreateAndUpdateTime, _HasTable):
"""A base class for all 'dataset instances', HDAs, LDDAs, etc"""
copied_from_history_dataset_association_id: Mapped[Optional[int]]
name: Mapped[Optional[str]]
purged: Mapped[Optional[bool]]
visible: Mapped[bool]
deleted: Mapped[bool]
dataset_id: Mapped[Optional[int]]
_state: Mapped[Optional[str]]
@@ -5143,6 +5147,7 @@ class DatasetInstance(RepresentById, UsesCreateAndUpdateTime, _HasTable):
conversion_messages = Dataset.conversion_messages
permitted_actions = Dataset.permitted_actions
creating_job_associations: list[Union[JobToOutputDatasetCollectionAssociation, JobToOutputDatasetAssociation]]
dataset: Mapped[Optional[Dataset]]
copied_from_history_dataset_association: Optional["HistoryDatasetAssociation"]
copied_from_library_dataset_dataset_association: Optional["LibraryDatasetDatasetAssociation"]
dependent_jobs: list[JobToInputLibraryDatasetAssociation]
@@ -5233,7 +5238,7 @@ class DatasetInstance(RepresentById, UsesCreateAndUpdateTime, _HasTable):
@property
def has_deferred_data(self) -> bool:
return self.dataset and self.dataset.state == Dataset.states.DEFERRED
return self.dataset is not None and self.dataset.state == Dataset.states.DEFERRED
@property
def deferred_source_uri(self):
@@ -5292,6 +5297,7 @@ class DatasetInstance(RepresentById, UsesCreateAndUpdateTime, _HasTable):
replacement.object_store_id = self.dataset.object_store_id
self.dataset = replacement
self.dataset_id = None
assert self.dataset.object_store is not None
self.dataset.object_store.create(self.dataset)
self.extension = "expression.json"
self.state = self.states.OK
@@ -5304,9 +5310,11 @@ class DatasetInstance(RepresentById, UsesCreateAndUpdateTime, _HasTable):
self.set_total_size()
def get_file_name(self, sync_cache: bool = True) -> str:
assert self.dataset is not None
return self.dataset.get_file_name(sync_cache=sync_cache)
def set_file_name(self, filename: str):
assert self.dataset is not None
return self.dataset.set_file_name(filename)
def link_to(self, path):
@@ -5829,9 +5837,13 @@ class HistoryDatasetAssociation(DatasetInstance, HasTags, Dictifiable, UsesAnnot
history_id: Mapped[Optional[int]]
dataset_id: Mapped[Optional[int]]
extension: Mapped[str]
_metadata: Mapped[Optional[dict[str, Any]]]
version: Mapped[Optional[int]]
hid: Mapped[Optional[int]]
hidden_beneath_collection_instance: Mapped[Optional["HistoryDatasetCollectionAssociation"]]
tags: Mapped[list["HistoryDatasetAssociationTagAssociation"]]
copied_to_history_dataset_associations: Mapped[list["HistoryDatasetAssociation"]]
history: Mapped[Optional["History"]]
def __init__(
self,
@@ -5987,6 +5999,7 @@ class HistoryDatasetAssociation(DatasetInstance, HasTags, Dictifiable, UsesAnnot
"""
Copy this HDA to a library optionally replacing an existing LDDA.
"""
assert self.dataset is not None
if not self.dataset.shareable:
raise Exception(CANNOT_SHARE_PRIVATE_DATASET_MESSAGE)
@@ -5999,7 +6012,9 @@ class HistoryDatasetAssociation(DatasetInstance, HasTags, Dictifiable, UsesAnnot
# applied to the new LibraryDataset, and the current user's DefaultUserPermissions will be applied
# to the associated Dataset.
library_dataset = LibraryDataset(folder=target_folder, name=self.name, info=self.info)
user = trans.user or self.history.user
user = trans.user
if not user and self.history is not None:
user = self.history.user
ldda = LibraryDatasetDatasetAssociation(
name=element_identifier or self.name,
info=self.info,
@@ -10932,9 +10947,9 @@ class MetadataFile(Base, StorableObject, Serializable):
self.name = name
@property
def dataset(self) -> Optional["DatasetInstance"]:
def dataset(self) -> Dataset | None:
da = self.history_dataset or self.library_dataset
return da and da.dataset
return da.dataset if da is not None else None
def update_from_file(self, file_name):
if not self.dataset:
@@ -10953,9 +10968,11 @@ class MetadataFile(Base, StorableObject, Serializable):
try:
da = self.history_dataset or self.library_dataset
assert da is not None
assert da.dataset is not None
if self.object_store_id is None:
self.object_store_id = da.dataset.object_store_id
object_store = da.dataset.object_store
assert object_store is not None
store_by = object_store.get_store_by(da.dataset)
if store_by == "id" and self.id is None:
self.flush() # type: ignore[unreachable]
@@ -158,6 +158,7 @@ class PromoteDatasetToCollection(CollectionAdapter):
@property
def dataset_action_tuples(self):
hda = self._hda
assert hda.dataset is not None
return [(permission.action, permission.role_id) for permission in hda.dataset.actions]
@property
@@ -165,6 +166,7 @@ class PromoteDatasetToCollection(CollectionAdapter):
hda = self._hda
dbkeys = [hda.dbkey] if hda.dbkey else []
extensions = [hda.extension] if hda.extension else []
assert hda.dataset is not None
states = {hda.dataset.state: 1} if hda.dataset.state else {}
deleted = 1 if hda.deleted or (hda.dataset and hda.dataset.deleted) else 0
return CollectionStateSummary(dbkeys=dbkeys, extensions=extensions, states=states, deleted=deleted)
@@ -601,7 +601,7 @@ def _list_to_sample_sheet_collection_type(input_collection_type: str) -> SampleS
"""
# Pass through existing sample_sheet types unchanged
if input_collection_type in SAMPLE_SHEET_COLLECTION_TYPES:
return cast(SampleSheetCollectionType, input_collection_type)
return input_collection_type
# Convert list types to sample_sheet types
if input_collection_type == "list":
+3 -2
View File
@@ -106,6 +106,7 @@ class DatasetInstanceMaterializer:
"""
attached = self._attached
dataset = dataset_instance.dataset
assert dataset is not None
if dataset.state != Dataset.states.DEFERRED and isinstance(dataset_instance, HistoryDatasetAssociation):
return dataset_instance
@@ -117,7 +118,7 @@ class DatasetInstanceMaterializer:
materialized_dataset_hashes = [h.copy() for h in dataset.hashes]
if in_place:
materialized_dataset = dataset_instance.dataset
materialized_dataset = dataset
materialized_dataset.state = Dataset.states.OK
else:
materialized_dataset = Dataset()
@@ -130,7 +131,7 @@ class DatasetInstanceMaterializer:
# legacy dataset being copied, new paradigm is to treat transform as
# what happened and requested_transform as what should happen - so lets
# swap these in this new dataset.
source.requested_transform = source.transform
source.requested_transform = source.transform # type: ignore[assignment]
# we have not applied any transforms yet, so we can clear these
source.transform = None
+1 -1
View File
@@ -239,7 +239,7 @@ def get_replacement_dataset(
dataset_sources: list[DatasetSource],
dataset_hashes: Sequence[Union[DatasetHash, DatasetSourceHash]],
extension: str,
object_store_id: str,
object_store_id: str | None,
created_from_basename: Optional[str] = None,
) -> Optional[HistoryDatasetAssociation]:
"""
+2
View File
@@ -649,6 +649,8 @@ class FileParameter(MetadataParameter):
if target_context.parent is None:
return None
target_dataset = target_context.parent.dataset
assert target_dataset is not None
assert target_dataset.object_store is not None
if value and target_dataset.object_store.exists(target_dataset):
# Only copy MetadataFile if the target dataset has been created in an object store.
# All current datatypes re-generate MetadataFile objects when setting metadata,
+1 -2
View File
@@ -870,14 +870,13 @@ WHERE history.user_id != :user_id and history_dataset_association.dataset_id = :
permissions[action] = [dhp.role]
return permissions
def set_all_dataset_permissions(self, dataset, permissions=None, new=False, flush=True):
def set_all_dataset_permissions(self, dataset: Dataset, permissions: dict, new: bool = False, flush: bool = True):
"""
Set new full permissions on a dataset, eliminating all current permissions.
Permission looks like: { Action : [ Role, Role ] }
"""
# Make sure that DATASET_MANAGE_PERMISSIONS is associated with at least 1 role
has_dataset_manage_permissions = False
permissions = permissions or {}
for _ in _walk_action_roles(permissions, self.permitted_actions.DATASET_MANAGE_PERMISSIONS):
has_dataset_manage_permissions = True
break
+9 -4
View File
@@ -435,13 +435,15 @@ class ModelImportStore(metaclass=abc.ABCMeta):
dataset_or_file_attrs: dict[str, Any],
dataset_instance: model.DatasetInstance,
) -> None:
dataset = dataset_instance.dataset
assert dataset is not None
if "hashes" in dataset_or_file_attrs:
for hash_attrs in dataset_or_file_attrs["hashes"]:
hash_obj = model.DatasetHash()
hash_obj.hash_value = hash_attrs["hash_value"]
hash_obj.hash_function = hash_attrs["hash_function"]
hash_obj.extra_files_path = hash_attrs["extra_files_path"]
dataset_instance.dataset.hashes.append(hash_obj)
dataset.hashes.append(hash_obj)
def _attach_dataset_sources(
self,
@@ -472,6 +474,7 @@ class ModelImportStore(metaclass=abc.ABCMeta):
hash_obj.hash_function = hash_attrs["hash_function"]
source_obj.hashes.append(hash_obj)
assert dataset_instance.dataset is not None
dataset_instance.dataset.sources.append(source_obj)
def _import_datasets(
@@ -611,6 +614,7 @@ class ModelImportStore(metaclass=abc.ABCMeta):
dataset_instance.metadata = metadata
self._attach_raw_id_if_editing(dataset_instance, dataset_attrs)
assert dataset_instance.dataset is not None
# Older style...
if self.import_options.allow_edit:
if "uuid" in dataset_attrs:
@@ -671,7 +675,6 @@ class ModelImportStore(metaclass=abc.ABCMeta):
dataset_instance.deleted = False
if isinstance(dataset_instance, model.HistoryDatasetAssociation):
dataset_instance.purged = False
assert dataset_instance.dataset
dataset_instance.dataset.deleted = False
dataset_instance.dataset.purged = False
elif (
@@ -688,7 +691,6 @@ class ModelImportStore(metaclass=abc.ABCMeta):
dataset_instance.deleted = deleted
if isinstance(dataset_instance, model.HistoryDatasetAssociation):
dataset_instance.purged = deleted
assert dataset_instance.dataset
dataset_instance.dataset.state = target_state
dataset_instance.dataset.deleted = deleted
dataset_instance.dataset.purged = deleted
@@ -2062,6 +2064,7 @@ class DirectoryModelExportStore(ModelExportStore):
dir_name = "datasets"
dir_path = os.path.join(export_directory, dir_name)
assert dataset.dataset is not None
if dataset.dataset.id in self.dataset_id_to_path:
file_name, extra_files_path = self.dataset_id_to_path[dataset.dataset.id]
if file_name is not None:
@@ -2432,6 +2435,7 @@ class DirectoryModelExportStore(ModelExportStore):
self.included_datasets[dataset] = (dataset, include_files)
def _ensure_dataset_file_exists(self, dataset: model.DatasetInstance) -> None:
assert dataset.dataset is not None
state = dataset.dataset.state
if state in [model.Dataset.states.OK] and not dataset.get_file_name():
log.error(
@@ -2644,7 +2648,7 @@ class WriteCrates:
with open(markdown_path, "w") as f:
f.write(self._generate_markdown_readme())
properties = {
properties: dict[str, Any] = {
"name": "README.md",
"encodingFormat": "text/markdown",
"about": {"@id": "./"},
@@ -2656,6 +2660,7 @@ class WriteCrates:
)
for dataset, _ in self.included_datasets.values():
assert dataset.dataset is not None
if dataset.dataset.id in self.dataset_id_to_path:
file_name, _ = self.dataset_id_to_path[dataset.dataset.id]
if file_name is None:
+5 -2
View File
@@ -13,6 +13,7 @@ from collections.abc import (
Callable,
Iterable,
)
from decimal import Decimal
from typing import (
Any,
NamedTuple,
@@ -172,6 +173,7 @@ class ModelPersistenceContext(metaclass=abc.ABCMeta):
if metadata_element and metadata_element.set_in_upload:
setattr(primary_data.metadata, key, value)
assert primary_data.dataset is not None
for source_dict in sources:
source = galaxy.model.DatasetSource()
source.source_uri = source_dict["source_uri"]
@@ -250,10 +252,11 @@ class ModelPersistenceContext(metaclass=abc.ABCMeta):
output_name,
init_from,
):
assert primary_data.dataset is not None
if primary_data.dataset.purged:
# metadata won't be set, maybe we should do that, then purge ?
primary_data.dataset.file_size = 0
primary_data.dataset.total_size = 0
primary_data.dataset.file_size = Decimal(0)
primary_data.dataset.total_size = Decimal(0)
return
# Move data from temp location to dataset location
if not link_data:
+2
View File
@@ -102,6 +102,7 @@ class WorkflowRunCrateProfileBuilder:
return crate
def _add_file(self, dataset: HistoryDatasetAssociation, properties: dict[Any, Any], crate: ROCrate) -> File:
assert dataset.dataset is not None
if dataset.dataset.id in self.model_store.dataset_id_to_path:
filename, _ = self.model_store.dataset_id_to_path[dataset.dataset.id]
description = ""
@@ -576,6 +577,7 @@ class WorkflowRunCrateProfileBuilder:
)
def _add_dataset_formal_parameter(self, hda: HistoryDatasetAssociation, crate: ROCrate):
assert hda.dataset is not None
return crate.add(
ContextEntity(
crate,
+2 -1
View File
@@ -2104,6 +2104,7 @@ class ObjectStorePopulator:
self.user = user
def set_object_store_id(self, data: "DatasetInstance", require_shareable: bool = False) -> None:
assert data.dataset is not None
self.set_dataset_object_store_id(data.dataset, require_shareable=require_shareable)
def set_dataset_object_store_id(self, dataset: "Dataset", require_shareable: bool = True) -> None:
@@ -2126,8 +2127,8 @@ def persist_extra_files(
primary_data: "DatasetInstance",
extra_files_path_name: Optional[str] = None,
) -> None:
assert primary_data.dataset is not None
if not primary_data.dataset.purged and os.path.exists(src_extra_files_path):
assert primary_data.dataset
if not extra_files_path_name:
extra_files_path_name = primary_data.dataset.extra_files_path_name_from(object_store)
assert extra_files_path_name
@@ -171,7 +171,7 @@ class DataManagerHandler:
if data_manager:
rval.append(data_manager)
elif elem.tag is etree.Comment: # type: ignore[comparison-overlap]
pass
pass # type: ignore[unreachable]
else:
log.warning(f"Encountered unexpected element '{elem.tag}':\n{xml_to_string(elem)}")
config_elems.append(elem)
+6 -1
View File
@@ -3227,7 +3227,8 @@ class Tool(UsesDictVisibleKeys, MaybeToolParameterBundle):
# Map dataset or collection to current history
def map_to_history(value):
if isinstance(value, HistoryDatasetAssociation):
id: int = value.dataset.id
assert value.dataset is not None
id = value.dataset.id
source: Union[
dict[Union[int, str], HistoryDatasetAssociation],
dict[Union[int, str], HistoryDatasetCollectionAssociation],
@@ -3378,6 +3379,7 @@ class OutputParameterJSONTool(Tool):
# allow multiple files to be created
file_name = str(wrapped_data)
extra_files_path = str(wrapped_data.files_path)
assert data.dataset is not None
data_dict = dict(
out_data_name=out_name,
ext=data.ext,
@@ -3592,6 +3594,7 @@ class DataSourceTool(OutputParameterJSONTool):
data.extension = cur_data_type
file_name = str(wrapped_data)
extra_files_path = str(wrapped_data.files_path)
assert data.dataset is not None
data_dict = dict(
out_data_name=out_name,
ext=data.ext,
@@ -3766,6 +3769,8 @@ class DataManagerTool(OutputParameterJSONTool):
elif data_manager_mode == "bundle":
for bundle_path, dataset in data_manager.write_bundle(out_data).items():
hda = cast(HistoryDatasetAssociation, dataset)
assert hda.dataset is not None
assert hda.dataset.object_store is not None
hda.dataset.object_store.update_from_file(
hda.dataset,
extra_dir=hda.dataset.extra_files_path_name,
+1
View File
@@ -591,6 +591,7 @@ class DefaultToolAction(ToolAction):
data = HistoryDatasetAssociation(
extension=ext, dataset=dataset, create_dataset=create_datasets, flush=False
)
assert data.dataset is not None
if create_datasets:
from_work_dir = output.from_work_dir
if from_work_dir is not None:
+1
View File
@@ -2898,6 +2898,7 @@ def raw_to_galaxy(
)
primary_data.state = Dataset.states.DEFERRED
permissions = app.security_agent.history_get_default_permissions(history)
assert primary_data.dataset is not None
app.security_agent.set_all_dataset_permissions(primary_data.dataset, permissions, new=True, flush=False)
app.model.session.add(primary_data)
history.stage_addition(primary_data)
+2 -2
View File
@@ -99,7 +99,7 @@ def setup_for_runtimeify(
hda_entry, index = hdas_by_id[hda_id]
if not hda_entry:
raise ValueError(f"Could not find HDA for dataset id {hda_id}")
size = hda_entry.dataset.get_size() if hda_entry and hda_entry.dataset else 0
assert hda_entry.dataset is not None
properties: dict[str, Any] = {
"class": "File",
"location": f"step_input://{index}",
@@ -107,7 +107,7 @@ def setup_for_runtimeify(
"path": (
compute_environment.input_path_rewrite(hda_entry) if compute_environment else hda_entry.get_file_name()
),
"size": int(size),
"size": hda_entry.dataset.get_size(),
"listing": [],
}
set_basename_and_derived_properties(properties, hda_entry.dataset.created_from_basename or hda_entry.name)
@@ -736,7 +736,8 @@ class DatasetsService(ServiceBase, UsesVisualizationMixin):
if metadata_spec is None:
raise galaxy_exceptions.RequestParameterInvalidException(f"Unknown metadata file: {metadata_file}")
file_ext = metadata_spec.get("file_ext", metadata_file)
fname = "".join(c in util.FILENAME_VALID_CHARS and c or "_" for c in hda.name)[0:150]
hda_name = hda.name or "Unnamed dataset"
fname = "".join(c in util.FILENAME_VALID_CHARS and c or "_" for c in hda_name)[0:150]
headers = {}
headers["Content-Type"] = "application/octet-stream"
headers["Content-Disposition"] = f'attachment; filename="Galaxy{hda.hid}-[{fname}].{file_ext}"'
@@ -375,6 +375,8 @@ class HistoriesContentsService(ServiceBase, ServesExportStores, ConsumesModelSto
content_name = dataset_collection_instance.name
else:
raise exceptions.UnknownContentsType(f"Unknown contents type: {contents_type}")
if not content_name:
raise exceptions.RequestParameterInvalidException("Content must have a name")
short_term_storage_target = model_store_storage_target(
self.short_term_storage_allocator,
content_name,
@@ -615,6 +617,7 @@ class HistoriesContentsService(ServiceBase, ServesExportStores, ConsumesModelSto
payload_dict = payload.model_dump(by_alias=True)
hda = self.hda_manager.get_owned(history_content_id, trans.user, current_history=trans.history, trans=trans)
assert hda is not None
assert hda.history is not None
self.history_manager.error_unless_mutable(hda.history)
self.hda_manager.update_permissions(trans, hda, **payload_dict)
roles = self.hda_manager.serialize_dataset_association_roles(hda)
@@ -881,6 +884,7 @@ class HistoriesContentsService(ServiceBase, ServesExportStores, ConsumesModelSto
def __delete_dataset(self, trans, id: DecodedDatabaseIdField, purge: bool, stop_job: bool):
hda = self.hda_manager.get_owned(id, trans.user, current_history=trans.history)
assert hda.history is not None
self.history_manager.error_unless_mutable(hda.history)
self.hda_manager.error_if_uploading(hda)
@@ -1237,6 +1241,7 @@ class HistoriesContentsService(ServiceBase, ServesExportStores, ConsumesModelSto
def __create_hda_from_copy(self, trans, history: History, original_hda_id: int):
original = self.hda_manager.get_accessible(original_hda_id, trans.user)
assert original.history is not None
# check for access on history that contains the original hda as well
self.history_manager.error_unless_accessible(original.history, trans.user, current_history=trans.history)
hda = self.hda_manager.copy(original, history=history)
@@ -1508,6 +1513,7 @@ class HistoryItemOperator:
self.hda_manager.ensure_can_change_datatype(item)
self.hda_manager.ensure_can_set_metadata(item)
is_deferred = item.has_deferred_data
assert item.dataset is not None
item.state = item.dataset.states.SETTING_METADATA
if is_deferred:
if params.datatype == "auto": # if `auto` just keep the original guessed datatype
+1
View File
@@ -385,6 +385,7 @@ class WorkflowSummary:
return
hid_in_history = dataset.hid
assert hid_in_history is not None
original_hda = self.__original_hda(dataset)
self.hda_hid_in_history[original_hda.id] = hid_in_history
+1
View File
@@ -172,6 +172,7 @@ def to_cwl(
element_identifier = value.element_identifier
value = value.element_object
if isinstance(value, model.HistoryDatasetAssociation):
assert value.dataset is not None
# I think the following two checks are needed but they may
# not be needed.
if step:
@@ -1224,7 +1224,7 @@ def get_repository_metadata(session, repository_id):
stmt = (
select(RepositoryMetadata)
.where(RepositoryMetadata.repository_id == repository_id)
.order_by(RepositoryMetadata.changeset_revision, RepositoryMetadata.update_time.desc()) # type: ignore[attr-defined] # mapped attribute
.order_by(RepositoryMetadata.changeset_revision, RepositoryMetadata.update_time.desc())
)
return session.scalars(stmt)
+9 -4
View File
@@ -385,13 +385,14 @@ class Repository(Base, Dictifiable):
user = relationship("User", back_populates="active_repositories")
downloadable_revisions = relationship(
"RepositoryMetadata",
primaryjoin=lambda: (Repository.id == RepositoryMetadata.repository_id) & (RepositoryMetadata.downloadable == true()), # type: ignore[has-type]
primaryjoin=lambda: (Repository.id == RepositoryMetadata.repository_id)
& (RepositoryMetadata.downloadable == true()),
viewonly=True,
order_by=lambda: desc(RepositoryMetadata.update_time), # type: ignore[attr-defined]
order_by=lambda: desc(RepositoryMetadata.update_time),
)
metadata_revisions = relationship(
"RepositoryMetadata",
order_by=lambda: desc(RepositoryMetadata.update_time), # type: ignore[attr-defined]
order_by=lambda: desc(RepositoryMetadata.update_time),
back_populates="repository",
)
roles = relationship("RepositoryRoleAssociation", back_populates="repository")
@@ -687,7 +688,11 @@ class Tag(Base):
class RepositoryMetadata(Dictifiable):
repository: "Repository"
update_time: Mapped[DateTime]
repository_id: Mapped[Optional[int]]
changeset_revision: Mapped[Optional[str]]
downloadable: Mapped[bool]
repository: Mapped["Repository"]
# Once the class has been mapped, all Column items in this table will be available
# as instrumented class attributes on RepositoryMetadata.
@@ -25,7 +25,7 @@ execution:
GALAXY_SLOTS: '{cores}'
scheduling:
accept:
- support_user_defined
- tool_type_user_defined
params:
remote_metadata: true
docker_enabled: true
@@ -41,4 +41,4 @@ execution:
user_defined-*:
scheduling:
require:
- support_user_defined
- tool_type_user_defined
+1
View File
@@ -59,6 +59,7 @@ def create_model_collection(collection_type, elements_data):
hda = HistoryDatasetAssociation(create_dataset=True, flush=False, name=content)
hda.id = i + 100 # Fake ID for testing
# Also satisfy accessing hda.dataset.created_from_basename or hda.name in generic adapt if needed
assert hda.dataset is not None
hda.dataset.id = i + 1000
dce = DatasetCollectionElement(collection=collection, element_identifier=name, element_index=i, element=hda)
+2
View File
@@ -212,6 +212,7 @@ def test_import_export_history_with_implicit_conversion_and_extra_files():
app.object_store.update_from_file(implicit_hda.dataset, file_name=TEST_PATH_2_CONVERTED, create=True)
d2.dataset.create_extra_files_path()
assert implicit_hda.dataset is not None
implicit_hda.dataset.create_extra_files_path()
app.write_primary_file(d2, "cool primary file 1")
@@ -296,6 +297,7 @@ def test_import_from_dict():
assert imported_hda.state == "deferred"
assert not imported_hda.deleted
assert imported_hda.dataset is not None
assert len(imported_hda.dataset.hashes) == 1
assert len(imported_hda.dataset.sources) == 1
assert imported_hda.dataset.created_from_basename == "dataset.txt"
@@ -47,10 +47,12 @@ def test_deferred_hdas_basic_attached():
deferred_hda = fixture_context.history.datasets[0]
assert deferred_hda
_assert_2_bed_metadata(deferred_hda)
assert deferred_hda.dataset is not None
assert deferred_hda.dataset.state == "deferred"
materializer = materializer_factory(True, object_store=fixture_context.app.object_store)
materialized_hda = materializer.ensure_materialized(deferred_hda)
materialized_dataset = materialized_hda.dataset
assert materialized_dataset is not None
assert materialized_dataset.state == "ok"
# only detached datasets would be created with an external_filename
assert not materialized_dataset.external_filename
@@ -68,10 +70,12 @@ def test_hash_validate():
deferred_hda = fixture_context.history.datasets[0]
assert deferred_hda
_assert_2_bed_metadata(deferred_hda)
assert deferred_hda.dataset is not None
assert deferred_hda.dataset.state == "deferred"
materializer = materializer_factory(True, object_store=fixture_context.app.object_store)
materialized_hda = materializer.ensure_materialized(deferred_hda)
materialized_dataset = materialized_hda.dataset
assert materialized_dataset is not None
assert materialized_dataset.state == "ok"
@@ -83,10 +87,12 @@ def test_hash_invalid():
deferred_hda = fixture_context.history.datasets[0]
assert deferred_hda
_assert_2_bed_metadata(deferred_hda)
assert deferred_hda.dataset is not None
assert deferred_hda.dataset.state == "deferred"
materializer = materializer_factory(True, object_store=fixture_context.app.object_store)
materialized_hda = materializer.ensure_materialized(deferred_hda)
materialized_dataset = materialized_hda.dataset
assert materialized_dataset is not None
assert materialized_dataset.state == "error"
@@ -101,6 +107,7 @@ def test_legacy_transform_actions_on_deferred_hdas_become_requested_actions():
perform_import_from_store_dict(fixture_context, store_dict)
deferred_hda = fixture_context.history.datasets[0]
deferred_dataset = deferred_hda.dataset
assert deferred_dataset is not None
assert deferred_dataset.sources[0].transform is None
assert deferred_dataset.sources[0].requested_transform == [{"action": "spaces_to_tabs"}]
@@ -114,6 +121,7 @@ def test_requested_transform_actions_on_deferred_hdas_preserved():
perform_import_from_store_dict(fixture_context, store_dict)
deferred_hda = fixture_context.history.datasets[0]
deferred_dataset = deferred_hda.dataset
assert deferred_dataset is not None
assert deferred_dataset.sources[0].transform is None
assert deferred_dataset.sources[0].requested_transform == [{"action": "spaces_to_tabs"}]
@@ -128,10 +136,12 @@ def test_hash_validate_source_of_download():
deferred_hda = fixture_context.history.datasets[0]
assert deferred_hda
_assert_2_bed_metadata(deferred_hda)
assert deferred_hda.dataset is not None
assert deferred_hda.dataset.state == "deferred"
materializer = materializer_factory(True, object_store=fixture_context.app.object_store)
materialized_hda = materializer.ensure_materialized(deferred_hda)
materialized_dataset = materialized_hda.dataset
assert materialized_dataset is not None
assert materialized_dataset.state == "ok", materialized_hda.info
@@ -145,10 +155,12 @@ def test_hash_invalid_source_of_download():
deferred_hda = fixture_context.history.datasets[0]
assert deferred_hda
_assert_2_bed_metadata(deferred_hda)
assert deferred_hda.dataset is not None
assert deferred_hda.dataset.state == "deferred"
materializer = materializer_factory(True, object_store=fixture_context.app.object_store)
materialized_hda = materializer.ensure_materialized(deferred_hda)
materialized_dataset = materialized_hda.dataset
assert materialized_dataset is not None
assert materialized_dataset.state == "error", materialized_hda.info
@@ -160,10 +172,12 @@ def test_deferred_hdas_basic_attached_store_by_uuid():
deferred_hda = fixture_context.history.datasets[0]
assert deferred_hda
_assert_2_bed_metadata(deferred_hda)
assert deferred_hda.dataset is not None
assert deferred_hda.dataset.state == "deferred"
materializer = materializer_factory(True, object_store=fixture_context.app.object_store)
materialized_hda = materializer.ensure_materialized(deferred_hda)
materialized_dataset = materialized_hda.dataset
assert materialized_dataset is not None
assert materialized_dataset.state == "ok"
# only detached datasets would be created with an external_filename
assert not materialized_dataset.external_filename
@@ -180,10 +194,12 @@ def test_deferred_hdas_basic_detached(tmpdir):
deferred_hda = fixture_context.history.datasets[0]
assert deferred_hda
_assert_2_bed_metadata(deferred_hda)
assert deferred_hda.dataset is not None
assert deferred_hda.dataset.state == "deferred"
materializer = materializer_factory(False, transient_directory=tmpdir)
materialized_hda = materializer.ensure_materialized(deferred_hda)
materialized_dataset = materialized_hda.dataset
assert materialized_dataset is not None
assert materialized_dataset.state == "ok"
external_filename = materialized_dataset.external_filename
assert external_filename
@@ -198,12 +214,14 @@ def test_deferred_datasets_with_legacy_transforms_respect_transform(tmpdir):
perform_import_from_store_dict(fixture_context, store_dict)
deferred_hda = fixture_context.history.datasets[0]
assert deferred_hda
assert deferred_hda.dataset is not None
assert deferred_hda.dataset.state == "deferred"
assert deferred_hda.dataset.sources[0].transform is None
assert deferred_hda.dataset.sources[0].requested_transform == [{"action": "spaces_to_tabs"}]
materializer = materializer_factory(False, transient_directory=tmpdir)
materialized_hda = materializer.ensure_materialized(deferred_hda)
materialized_dataset = materialized_hda.dataset
assert materialized_dataset is not None
assert materialized_dataset.sources[0].transform == [{"action": "spaces_to_tabs"}]
assert materialized_dataset.sources[0].requested_transform == [{"action": "spaces_to_tabs"}]
assert materialized_dataset.state == "ok"
@@ -219,6 +237,7 @@ def test_deferred_datasets_with_requested_transforms_respect_transform(tmpdir):
perform_import_from_store_dict(fixture_context, store_dict)
deferred_hda = fixture_context.history.datasets[0]
assert deferred_hda
assert deferred_hda.dataset is not None
assert deferred_hda.dataset.state == "deferred"
assert deferred_hda.dataset.sources[0].transform is None
assert deferred_hda.dataset.sources[0].requested_transform == [
@@ -228,6 +247,7 @@ def test_deferred_datasets_with_requested_transforms_respect_transform(tmpdir):
materializer = materializer_factory(False, transient_directory=tmpdir)
materialized_hda = materializer.ensure_materialized(deferred_hda)
materialized_dataset = materialized_hda.dataset
assert materialized_dataset is not None
assert materialized_dataset.sources[0].transform == [{"action": "spaces_to_tabs"}]
assert materialized_dataset.sources[0].requested_transform == [
{"action": "datatype_groom"},
@@ -246,12 +266,14 @@ def test_deferred_datasets_do_not_apply_unspecified_transforms_legacy(tmpdir):
perform_import_from_store_dict(fixture_context, store_dict)
deferred_hda = fixture_context.history.datasets[0]
assert deferred_hda
assert deferred_hda.dataset is not None
assert deferred_hda.dataset.state == "deferred"
assert deferred_hda.dataset.sources[0].transform is None
assert deferred_hda.dataset.sources[0].requested_transform == []
materializer = materializer_factory(False, transient_directory=tmpdir)
materialized_hda = materializer.ensure_materialized(deferred_hda)
materialized_dataset = materialized_hda.dataset
assert materialized_dataset is not None
assert materialized_dataset.sources[0].transform == []
assert materialized_dataset.sources[0].requested_transform == []
assert materialized_dataset.state == "ok"
@@ -267,12 +289,14 @@ def test_deferred_datasets_do_not_apply_unspecified_transforms(tmpdir):
perform_import_from_store_dict(fixture_context, store_dict)
deferred_hda = fixture_context.history.datasets[0]
assert deferred_hda
assert deferred_hda.dataset is not None
assert deferred_hda.dataset.state == "deferred"
assert deferred_hda.dataset.sources[0].transform is None
assert deferred_hda.dataset.sources[0].requested_transform == [{"action": "datatype_groom"}]
materializer = materializer_factory(False, transient_directory=tmpdir)
materialized_hda = materializer.ensure_materialized(deferred_hda)
materialized_dataset = materialized_hda.dataset
assert materialized_dataset is not None
assert materialized_dataset.sources[0].transform == []
assert materialized_dataset.sources[0].requested_transform == [{"action": "datatype_groom"}]
assert materialized_dataset.state == "ok"
@@ -291,10 +315,12 @@ def test_deferred_hdas_basic_detached_from_detached_hda(tmpdir):
_ensure_relations_attached_and_expunge(deferred_hda, fixture_context)
assert deferred_hda.dataset is not None
assert deferred_hda.dataset.state == "deferred"
materializer = materializer_factory(False, transient_directory=tmpdir)
materialized_hda = materializer.ensure_materialized(deferred_hda)
materialized_dataset = materialized_hda.dataset
assert materialized_dataset is not None
assert materialized_dataset.state == "ok"
external_filename = materialized_dataset.external_filename
assert external_filename
@@ -312,12 +338,14 @@ def test_deferred_hdas_basic_attached_from_detached_hda():
_ensure_relations_attached_and_expunge(deferred_hda, fixture_context)
assert deferred_hda.dataset is not None
assert deferred_hda.dataset.state == "deferred"
materializer = materializer_factory(
True, object_store=fixture_context.app.object_store, sa_session=fixture_context.sa_session()
)
materialized_hda = materializer.ensure_materialized(deferred_hda)
materialized_dataset = materialized_hda.dataset
assert materialized_dataset is not None
assert materialized_dataset.state == "ok"
# only detached datasets would be created with an external_filename
assert not materialized_dataset.external_filename
@@ -337,12 +365,14 @@ def test_deferred_ldda_basic_attached():
perform_import_from_store_dict(fixture_context, store_dict, import_options=import_options)
deferred_ldda = fixture_context.sa_session.scalars(select(LibraryDatasetDatasetAssociation)).all()[0]
assert deferred_ldda
assert deferred_ldda.dataset is not None
assert deferred_ldda.dataset.state == "deferred"
materializer = materializer_factory(True, object_store=fixture_context.app.object_store)
materialized_hda = materializer.ensure_materialized(deferred_ldda)
assert materialized_hda.history is None
materialized_dataset = materialized_hda.dataset
assert materialized_dataset is not None
assert materialized_dataset.state == "ok"
# only detached datasets would be created with an external_filename
assert not materialized_dataset.external_filename
@@ -365,10 +395,12 @@ def test_deferred_hdas_basic_attached_file_sources(tmpdir):
perform_import_from_store_dict(fixture_context, store_dict)
deferred_hda = fixture_context.history.datasets[0]
assert deferred_hda
assert deferred_hda.dataset is not None
assert deferred_hda.dataset.state == "deferred"
materializer = materializer_factory(True, object_store=fixture_context.app.object_store, file_sources=file_sources)
materialized_hda = materializer.ensure_materialized(deferred_hda)
materialized_dataset = materialized_hda.dataset
assert materialized_dataset is not None
assert materialized_dataset.state == "ok"
# only detached datasets would be created with an external_filename
assert not materialized_dataset.external_filename
@@ -385,10 +417,12 @@ def test_deferred_hdas_with_deferred_metadata():
perform_import_from_store_dict(fixture_context, store_dict)
deferred_hda = fixture_context.history.datasets[0]
assert deferred_hda
assert deferred_hda.dataset is not None
assert deferred_hda.dataset.state == "deferred"
materializer = materializer_factory(True, object_store=fixture_context.app.object_store)
materialized_hda = materializer.ensure_materialized(deferred_hda)
materialized_dataset = materialized_hda.dataset
assert materialized_dataset is not None
assert not materialized_hda.metadata_deferred
assert materialized_dataset.state == "ok"
# only detached datasets would be created with an external_filename
@@ -448,6 +482,7 @@ def _test_hdca(
perform_import_from_store_dict(fixture_context, store_dict)
deferred_hda = fixture_context.history.datasets[0]
sa_session.add(deferred_hda)
assert deferred_hda.dataset is not None
assert deferred_hda.dataset.state == "deferred"
hda_fh = tmpdir.join("file.txt")
hda_fh.write("Moo Cow")
@@ -503,6 +538,7 @@ def _deferred_element_count(dataset_collection: DatasetCollection) -> int:
def _ensure_relations_attached_and_expunge(deferred_hda: HistoryDatasetAssociation, fixture_context) -> None:
# make sure everything needed is in session (sources, hashes, and metadata)...
# point here is exercise deferred_hda.history throws a detached error.
assert deferred_hda.dataset is not None
[s.hashes for s in deferred_hda.dataset.sources]
deferred_hda.dataset.hashes # noqa: B018
deferred_hda._metadata # noqa: B018
+5
View File
@@ -14,6 +14,7 @@ def test_dereference():
uri_request = DataRequestUri(url=TEST_URI, ext="bed")
hda = dereference_to_model(sa_session, user, history, uri_request)
assert hda.name == "1.bed"
assert hda.dataset is not None
assert hda.dataset.sources[0].source_uri == TEST_URI
assert hda.ext == "bed"
@@ -23,6 +24,7 @@ def test_dereference_dbkey():
uri_request = DataRequestUri(url=TEST_URI, ext="bed", dbkey="hg19")
hda = dereference_to_model(sa_session, user, history, uri_request)
assert hda.name == "1.bed"
assert hda.dataset is not None
assert hda.dataset.sources[0].source_uri == TEST_URI
assert hda.dbkey == "hg19"
@@ -40,6 +42,7 @@ def test_dereference_md5():
)
hda = dereference_to_model(sa_session, user, history, uri_request)
assert hda.name == "foobar.txt"
assert hda.dataset is not None
assert hda.dataset.sources[0].source_uri == TEST_BASE64_URI
assert hda.dataset.sources[0].hashes[0]
assert hda.dataset.sources[0].hashes[0].hash_function == "MD5"
@@ -53,7 +56,9 @@ def test_dereference_to_posix():
)
hda = dereference_to_model(sa_session, user, history, uri_request)
assert hda.name == "foobar.txt"
assert hda.dataset is not None
assert hda.dataset.sources[0].source_uri == TEST_BASE64_URI
assert hda.dataset.sources[0].requested_transform is not None
assert hda.dataset.sources[0].requested_transform[0]["action"] == "datatype_groom"
assert hda.dataset.sources[0].requested_transform[1]["action"] == "spaces_to_tabs"
assert hda.dataset.state == hda.states.DEFERRED
+4 -1
View File
@@ -37,7 +37,8 @@ class TestPurgeUsage(BaseModelTestCase):
d1 = model.HistoryDatasetAssociation(
extension="txt", history=self.h, create_dataset=True, sa_session=self.model.session
)
d1.dataset.total_size = 10
assert d1.dataset is not None
d1.dataset.total_size = Decimal(10)
self.persist(d1)
return d1
@@ -86,6 +87,7 @@ class TestCalculateUsage(BaseModelTestCase):
d1 = model.HistoryDatasetAssociation(
extension="txt", history=self.h, create_dataset=True, sa_session=self.model.session
)
assert d1.dataset is not None
d1.dataset.total_size = total_size
d1.dataset.object_store_id = object_store_id
self.persist(d1)
@@ -567,6 +569,7 @@ backends:
d1 = model.HistoryDatasetAssociation(
extension="txt", history=self.h, create_dataset=True, sa_session=self.model.session
)
assert d1.dataset is not None
d1.dataset.total_size = total_size
d1.dataset.object_store_id = object_store_id
self.persist(d1)