Merge branch 'release_25.1' into release_26.0

This commit is contained in:
mvdbeek
2026-05-29 16:42:50 +02:00
9 changed files with 44 additions and 48 deletions
@@ -81,7 +81,7 @@ et-xmlfile==2.0.0
eval-type-backport==0.3.1
exceptiongroup==1.3.1
executing==2.2.1
fastapi==0.128.0
fastapi==0.136.3
fastavro==1.12.1 ; sys_platform != 'emscripten'
fastmcp==3.0.2
filelock==3.20.3
@@ -225,7 +225,7 @@ pysam==0.23.3
python-dateutil==2.9.0.post0
python-dotenv==1.2.1
python-magic==0.4.27
python-multipart==0.0.22
python-multipart==0.0.29
python-slugify==8.0.4
python3-openid==3.2.0
pytz==2025.2
@@ -265,8 +265,8 @@ spython==0.3.14
sqlalchemy==2.0.46
sqlparse==0.5.5
sse-starlette==3.2.0
starlette==0.50.0
starlette-context==0.4.0
starlette==1.1.0
starlette-context==0.5.1
supervisor==4.3.0
svgwrite==1.4.3
temporalio==1.20.0
-12
View File
@@ -6,7 +6,6 @@ from typing import (
)
from pydantic import BaseModel
from pydantic.json_schema import GenerateJsonSchema
from typing_extensions import override
from galaxy.schema.fields import (
@@ -42,17 +41,6 @@ class GenericModel(BaseModel):
return suffix
class CustomJsonSchema(GenerateJsonSchema):
def get_defs_ref(self, core_mode_ref):
full_def = super().get_defs_ref(core_mode_ref)
choices = self._prioritized_defsref_choices[full_def]
ref, mode = core_mode_ref
if ref in ref_to_name:
for i, choice in enumerate(choices):
choices[i] = choice.replace(choices[0], ref_to_name[ref]) # type: ignore[call-overload]
return full_def
class PatchGenericPickle:
"""A mixin that allows generic pydantic models to be serialized and deserialized with pickle.
+20 -1
View File
@@ -1,5 +1,6 @@
from typing import (
Any,
TYPE_CHECKING,
)
from urllib.parse import urljoin
@@ -19,7 +20,7 @@ from starlette.datastructures import MutableHeaders
from starlette.middleware.cors import CORSMiddleware
from tuspyserver import create_tus_router
from galaxy.schema.generics import CustomJsonSchema
from galaxy.schema.generics import ref_to_name
from galaxy.version import VERSION
from galaxy.webapps.base.api import (
add_exception_handler,
@@ -30,8 +31,15 @@ from galaxy.webapps.base.api import (
include_all_package_routers,
)
from galaxy.webapps.base.webapp import config_allows_origin
from galaxy.webapps.openapi._compat.v2 import GenerateJsonSchema
from galaxy.webapps.openapi.utils import get_openapi
if TYPE_CHECKING:
from pydantic.json_schema import (
CoreModeRef,
DefsRef,
)
# https://fastapi.tiangolo.com/tutorial/metadata/#metadata-for-tags
api_tags_metadata = [
{
@@ -186,6 +194,17 @@ def get_fastapi_instance(root_path="") -> FastAPI:
)
class CustomJsonSchema(GenerateJsonSchema):
def get_defs_ref(self, core_mode_ref: "CoreModeRef") -> "DefsRef":
full_def = super().get_defs_ref(core_mode_ref)
choices = self._prioritized_defsref_choices[full_def]
ref, mode = core_mode_ref
if ref in ref_to_name:
for i, choice in enumerate(choices):
choices[i] = choice.replace(choices[0], ref_to_name[ref]) # type: ignore[call-overload]
return full_def
def get_openapi_schema() -> dict[str, Any]:
"""
Dumps openAPI schema without starting a full app and webserver.
+1 -1
View File
@@ -8,6 +8,7 @@ from typing import (
from fastapi._compat.v2 import (
_has_computed_fields,
GenerateJsonSchema as GenerateJsonSchema,
get_flat_models_from_fields,
ModelField,
)
@@ -15,7 +16,6 @@ from fastapi.openapi.constants import REF_TEMPLATE
from fastapi.types import ModelNameMap
from pydantic.fields import FieldInfo as FieldInfo
from pydantic.json_schema import (
GenerateJsonSchema as GenerateJsonSchema,
JsonSchemaValue as JsonSchemaValue,
)
+7 -19
View File
@@ -11,19 +11,10 @@ from typing import (
)
from fastapi import routing
try:
from fastapi._compat import ( # type: ignore[attr-defined,unused-ignore]
get_flat_models_from_fields,
get_model_name_map,
)
GET_FLAT_MODELS_FROM_FIELDS_AVAILABLE = True
except ImportError:
# FastAPI <0.128.4
GET_FLAT_MODELS_FROM_FIELDS_AVAILABLE = False
from fastapi._compat import get_compat_model_name_map # type: ignore[attr-defined,unused-ignore]
from fastapi._compat import ( # type: ignore[attr-defined,unused-ignore]
get_flat_models_from_fields,
get_model_name_map,
)
from fastapi.encoders import jsonable_encoder
from fastapi.openapi.constants import REF_TEMPLATE
from fastapi.openapi.models import OpenAPI
@@ -31,10 +22,10 @@ from fastapi.openapi.utils import (
get_fields_from_routes,
get_openapi_path,
)
from pydantic.json_schema import GenerateJsonSchema
from starlette.routing import BaseRoute
from ._compat import get_definitions
from ._compat.v2 import GenerateJsonSchema
def get_openapi(
@@ -74,11 +65,8 @@ def get_openapi(
webhook_paths: dict[str, dict[str, Any]] = {}
operation_ids: set[str] = set()
all_fields = get_fields_from_routes(list(routes or []) + list(webhooks or []))
if GET_FLAT_MODELS_FROM_FIELDS_AVAILABLE:
flat_models = get_flat_models_from_fields(all_fields, known_models=set())
model_name_map = get_model_name_map(flat_models)
else:
model_name_map = get_compat_model_name_map(all_fields)
flat_models = get_flat_models_from_fields(all_fields, known_models=set())
model_name_map = get_model_name_map(flat_models)
schema_generator = schema_generator or GenerateJsonSchema(ref_template=REF_TEMPLATE)
field_mapping, definitions = get_definitions(
fields=all_fields,
+6 -5
View File
@@ -21,7 +21,6 @@ from requests import (
delete,
get,
post,
put,
)
from galaxy.exceptions import error_codes
@@ -9358,11 +9357,11 @@ outer_input:
invocation_step_details = invocation_step_response.json()
return invocation_step_details
def _execute_invocation_step_action(self, workflow_id, invocation_id, step_id, action):
def _execute_invocation_step_action(self, workflow_id: str, invocation_id: str, step_id: str, action: bool):
raw_url = f"workflows/{workflow_id}/usage/{invocation_id}/steps/{step_id}"
url = self._api_url(raw_url, use_key=True)
payload = dumps(dict(action=action))
action_response = put(url, data=payload)
payload = {"action": action}
action_response = self._put(url, data=payload, json=True)
self._assert_status_code_is(action_response, 200)
invocation_step_details = action_response.json()
return invocation_step_details
@@ -9398,7 +9397,9 @@ outer_input:
)
return workflow_request, history_id, uploaded_workflow_id
def __review_paused_steps(self, uploaded_workflow_id, invocation_id, order_index, action=True):
def __review_paused_steps(
self, uploaded_workflow_id: str, invocation_id: str, order_index: int, action: bool = True
) -> None:
invocation = self._invocation_details(uploaded_workflow_id, invocation_id)
invocation_steps = invocation["steps"]
pause_steps = [s for s in invocation_steps if s["order_index"] == order_index]
+2 -2
View File
@@ -41,7 +41,7 @@ install_requires =
galaxy-web-apps
a2wsgi
alembic
fastapi>=0.124.0
fastapi>=0.133.0
Mako
MarkupSafe
mercurial>=6.8.2
@@ -50,7 +50,7 @@ install_requires =
Routes
SQLAlchemy>=2.0.37,<2.1,!=2.0.41
slowapi
starlette
starlette>=1.0.1
starlette-context
typing-extensions
WebOb
+2 -2
View File
@@ -42,7 +42,7 @@ install_requires =
apispec
Babel
CT3>=3.3.3
fastapi>=0.124.0
fastapi>=0.133.0
gunicorn
httpx
gxformat2>=0.23.0
@@ -58,7 +58,7 @@ install_requires =
Routes
slowapi
SQLAlchemy>=2.0.37,<2.1,!=2.0.41
starlette
starlette>=1.0.1
starlette-context
tuspyserver
typing-extensions
+2 -2
View File
@@ -37,7 +37,7 @@ dependencies = [
"docutils!=0.17,!=0.17.1",
"dparse",
"edam-ontology",
"fastapi>=0.124.0", # https://github.com/fastapi/fastapi/pull/14453
"fastapi>=0.133.0", # First version compatible with starlette>=1.0.0
"fissix",
"fs",
"future>=1.0.0", # Python 3.12 support
@@ -101,7 +101,7 @@ dependencies = [
"sortedcontainers",
"SQLAlchemy>=2.0.37,<2.1,!=2.0.41", # https://github.com/sqlalchemy/sqlalchemy/issues/12019 , https://github.com/sqlalchemy/sqlalchemy/issues/12600
"sqlparse",
"starlette",
"starlette>=1.0.1", # CVE-2026-48710 BadHost
"starlette-context",
"svgwrite",
"tifffile",