mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
and the deleted field in the response. Rationale: it is not particularly useful, but both: GET /api/categories GET /api/categories/<encoded_id>/repositories work on TS 2.0, so it's weird that this one is missing. Also, it was breaking BioBlend's https://bioblend.readthedocs.io/en/latest/api_docs/toolshed/all.html#bioblend.toolshed.categories.ToolShedCategoryClient.show_category
486 lines
12 KiB
Python
486 lines
12 KiB
Python
from typing import (
|
|
Any,
|
|
cast,
|
|
Dict,
|
|
List,
|
|
Optional,
|
|
Tuple,
|
|
Union,
|
|
)
|
|
|
|
from pydantic import (
|
|
BaseModel,
|
|
Field,
|
|
)
|
|
from typing_extensions import (
|
|
Literal,
|
|
TypedDict,
|
|
)
|
|
|
|
|
|
class Repository(BaseModel):
|
|
# element/collection view on the backend have same keys/impl
|
|
id: str
|
|
name: str
|
|
owner: str
|
|
type: str # TODO: enum
|
|
remote_repository_url: Optional[str]
|
|
homepage_url: Optional[str]
|
|
description: str
|
|
user_id: str
|
|
private: bool
|
|
deleted: bool
|
|
times_downloaded: int
|
|
deprecated: bool
|
|
create_time: str
|
|
update_time: str
|
|
|
|
|
|
class DetailedRepository(Repository):
|
|
long_description: Optional[str]
|
|
|
|
|
|
class RepositoryPermissions(BaseModel):
|
|
allow_push: List[str]
|
|
can_manage: bool # can the requesting user manage the repository
|
|
can_push: bool
|
|
|
|
|
|
class RepositoryRevisionReadmes(BaseModel):
|
|
__root__: Dict[str, str]
|
|
|
|
|
|
class CreateUserRequest(BaseModel):
|
|
username: str
|
|
email: str
|
|
password: str
|
|
|
|
|
|
class User(BaseModel):
|
|
id: str
|
|
username: str
|
|
|
|
|
|
class UserV2(User):
|
|
is_admin: bool
|
|
|
|
|
|
class Category(BaseModel):
|
|
id: str
|
|
name: str
|
|
description: str
|
|
deleted: bool
|
|
repositories: int
|
|
|
|
|
|
class CreateCategoryRequest(BaseModel):
|
|
name: str
|
|
description: Optional[str] = None
|
|
|
|
|
|
class ValidRepostiroyUpdateMessage(BaseModel):
|
|
message: str
|
|
|
|
|
|
class FailedRepositoryUpdateMessage(BaseModel):
|
|
err_msg: str
|
|
|
|
|
|
class GetOrderedInstallableRevisionsRequest(BaseModel):
|
|
name: str
|
|
owner: str
|
|
|
|
|
|
class OrderedInstallableRevisions(BaseModel):
|
|
__root__: List[str]
|
|
|
|
|
|
RepositoryType = Literal[
|
|
"repository_suite_definition",
|
|
"tool_dependency_definition",
|
|
"unrestricted",
|
|
]
|
|
|
|
|
|
class CreateRepositoryRequest(BaseModel):
|
|
name: str
|
|
synopsis: str
|
|
description: Optional[str] = None
|
|
remote_repository_url: Optional[str] = None
|
|
homepage_url: Optional[str] = None
|
|
type_: RepositoryType = Field(
|
|
"unrestricted",
|
|
alias="type",
|
|
title="Type",
|
|
)
|
|
category_ids: str = Field(
|
|
...,
|
|
alias="category_ids[]",
|
|
title="Category IDs",
|
|
)
|
|
|
|
class Config:
|
|
allow_population_by_field_name = True
|
|
|
|
|
|
class RepositoryUpdateRequest(BaseModel):
|
|
commit_message: Optional[str] = None
|
|
|
|
|
|
class RepositoryUpdate(BaseModel):
|
|
__root__: Union[ValidRepostiroyUpdateMessage, FailedRepositoryUpdateMessage]
|
|
|
|
@property
|
|
def is_ok(self):
|
|
return isinstance(self.__root__, ValidRepostiroyUpdateMessage)
|
|
|
|
|
|
class RepositoryTool(BaseModel):
|
|
# Added back in post v2 in order for the frontend to render
|
|
# tool descriptions on the repository page.
|
|
description: str
|
|
guid: str
|
|
id: str
|
|
name: str
|
|
requirements: list
|
|
tool_config: str
|
|
tool_type: str
|
|
version: str
|
|
# add_to_tool_panel: bool
|
|
# tests: list
|
|
# version_string_cmd: Optional[str]
|
|
|
|
|
|
class RepositoryRevisionMetadata(BaseModel):
|
|
id: str
|
|
repository: Repository
|
|
repository_dependencies: List["RepositoryDependency"]
|
|
tools: Optional[List["RepositoryTool"]]
|
|
invalid_tools: List[str] # added for rendering list of invalid tools in 2.0 frontend
|
|
repository_id: str
|
|
numeric_revision: int
|
|
changeset_revision: str
|
|
malicious: bool
|
|
downloadable: bool
|
|
missing_test_components: bool
|
|
has_repository_dependencies: bool
|
|
includes_tools: bool
|
|
includes_tools_for_display_in_tool_panel: bool
|
|
# Deprecate these...
|
|
includes_tool_dependencies: Optional[bool]
|
|
includes_datatypes: Optional[bool]
|
|
includes_workflows: Optional[bool]
|
|
|
|
|
|
class RepositoryDependency(RepositoryRevisionMetadata):
|
|
# This only needs properties for tests it seems?
|
|
# e.g. test_0550_metadata_updated_dependencies.py
|
|
pass
|
|
|
|
|
|
RepositoryRevisionMetadata.update_forward_refs()
|
|
|
|
|
|
class RepositoryMetadata(BaseModel):
|
|
__root__: Dict[str, RepositoryRevisionMetadata]
|
|
|
|
@property
|
|
def latest_revision(self) -> RepositoryRevisionMetadata:
|
|
return list(self.__root__.values())[-1]
|
|
|
|
@property
|
|
def tip(self) -> str:
|
|
if self.is_new:
|
|
return "000000000000"
|
|
else:
|
|
return self.latest_revision.changeset_revision
|
|
|
|
@property
|
|
def is_new(self) -> bool:
|
|
return len(self.__root__) == 0
|
|
|
|
|
|
class ResetMetadataOnRepositoryRequest(BaseModel):
|
|
repository_id: str
|
|
|
|
|
|
class ResetMetadataOnRepositoryResponse(BaseModel):
|
|
status: str # TODO: enum...
|
|
repository_status: List[str]
|
|
start_time: str
|
|
stop_time: str
|
|
|
|
|
|
class ToolSearchRequest(BaseModel):
|
|
q: str
|
|
page: Optional[int]
|
|
page_size: Optional[int]
|
|
|
|
|
|
class ToolSearchHitTool(BaseModel):
|
|
id: str
|
|
repo_owner_username: str
|
|
repo_name: str
|
|
name: str
|
|
description: str
|
|
|
|
|
|
class ToolSearchHit(BaseModel):
|
|
tool: ToolSearchHitTool
|
|
matched_terms: Dict[str, Any]
|
|
score: float
|
|
|
|
|
|
class ToolSearchResults(BaseModel):
|
|
# These next three really should be ints :<
|
|
total_results: str
|
|
page: str
|
|
page_size: str
|
|
hostname: str
|
|
hits: List[ToolSearchHit]
|
|
|
|
def find_search_hit(self, repository: Repository) -> Optional[ToolSearchHit]:
|
|
matching_hit: Optional[ToolSearchHit] = None
|
|
|
|
for hit in self.hits:
|
|
owner_matches = hit.tool.repo_owner_username == repository.owner
|
|
name_matches = hit.tool.repo_name == repository.name
|
|
if owner_matches and name_matches:
|
|
matching_hit = hit
|
|
break
|
|
|
|
return matching_hit
|
|
|
|
|
|
class RepositoryIndexRequest(BaseModel):
|
|
owner: Optional[str]
|
|
name: Optional[str]
|
|
deleted: str = "false"
|
|
|
|
|
|
class RepositoriesByCategory(BaseModel):
|
|
id: str
|
|
name: str
|
|
description: str
|
|
repository_count: int
|
|
repositories: List[Repository]
|
|
|
|
|
|
class RepositoryIndexResponse(BaseModel):
|
|
__root__: List[Repository]
|
|
|
|
|
|
class RepositorySearchRequest(BaseModel):
|
|
q: str
|
|
page: Optional[int]
|
|
page_size: Optional[int]
|
|
|
|
|
|
class RepositorySearchResult(BaseModel):
|
|
id: str
|
|
name: str
|
|
repo_owner_username: str
|
|
description: str
|
|
long_description: Optional[str]
|
|
remote_repository_url: Optional[str]
|
|
homepage_url: Optional[str]
|
|
last_update: Optional[str]
|
|
full_last_updated: str
|
|
repo_lineage: str
|
|
approved: bool
|
|
times_downloaded: int
|
|
categories: str
|
|
|
|
|
|
class RepositorySearchHit(BaseModel):
|
|
score: float
|
|
repository: RepositorySearchResult
|
|
|
|
|
|
class RepositorySearchResults(BaseModel):
|
|
total_results: str
|
|
page: str
|
|
page_size: str
|
|
hostname: str
|
|
hits: List[RepositorySearchHit]
|
|
|
|
|
|
class GetInstallInfoRequest(BaseModel):
|
|
owner: str
|
|
name: str
|
|
changeset_revision: str
|
|
|
|
|
|
class ValidToolDict(TypedDict):
|
|
add_to_tool_panel: bool
|
|
description: str
|
|
guid: str
|
|
id: str
|
|
name: str
|
|
requirements: list
|
|
tests: list
|
|
tool_config: str
|
|
tool_type: str
|
|
version: str
|
|
version_string_cmd: Optional[str]
|
|
|
|
|
|
class RepositoryMetadataInstallInfoDict(TypedDict):
|
|
changeset_revision: str
|
|
downloadable: bool
|
|
has_repository_dependencies: bool
|
|
has_repository_dependencies_only_if_compiling_contained_td: bool
|
|
id: str
|
|
includes_datatypes: bool
|
|
includes_tool_dependencies: bool
|
|
includes_tools: bool
|
|
includes_tools_for_display_in_tool_panel: bool
|
|
includes_workflows: bool
|
|
malicious: bool
|
|
repository_id: str
|
|
url: str
|
|
valid_tools: List[ValidToolDict]
|
|
|
|
|
|
# So hard to type this... the keys are repo names and the elements
|
|
# are tuples that have been list-ified.
|
|
ExtraRepoInfo = Dict[str, List]
|
|
# {
|
|
# "add_column": [
|
|
# "add_column hello",
|
|
# "http://test@localhost:9009/repos/test/add_column",
|
|
# "3a08cc21466f",
|
|
# "1",
|
|
# "test",
|
|
# {},
|
|
# {}
|
|
# ]
|
|
# }
|
|
|
|
|
|
class EmptyDict(TypedDict):
|
|
pass
|
|
|
|
|
|
LegacyInstallInfoTuple = Tuple[
|
|
Optional[Dict], Union[RepositoryMetadataInstallInfoDict, EmptyDict], Union[ExtraRepoInfo, EmptyDict]
|
|
]
|
|
|
|
|
|
class RepositoryExtraInstallInfo(BaseModel):
|
|
name: str
|
|
description: str
|
|
repository_clone_url: str
|
|
changeset_revision: str
|
|
ctx_rev: str
|
|
repository_owner: str
|
|
repository_dependencies: Optional[Dict]
|
|
# tool dependencies not longer work so don't transmit them in v2?
|
|
# tool_dependencies: Optional[Dict]
|
|
|
|
@staticmethod
|
|
def from_legacy_dict(as_dict: ExtraRepoInfo) -> "RepositoryExtraInstallInfo":
|
|
assert len(as_dict) == 1
|
|
repo_name = next(iter(as_dict.keys()))
|
|
info_indexable = as_dict[repo_name]
|
|
return RepositoryExtraInstallInfo(
|
|
name=repo_name,
|
|
description=info_indexable[0],
|
|
repository_clone_url=info_indexable[1],
|
|
changeset_revision=info_indexable[2],
|
|
ctx_rev=info_indexable[3],
|
|
repository_owner=info_indexable[4],
|
|
repository_dependencies=info_indexable[5],
|
|
)
|
|
|
|
|
|
class ValidTool(BaseModel):
|
|
add_to_tool_panel: bool
|
|
description: str
|
|
guid: str
|
|
id: str
|
|
name: str
|
|
requirements: list
|
|
tests: list
|
|
tool_config: str
|
|
tool_type: str
|
|
version: str
|
|
version_string_cmd: Optional[str]
|
|
|
|
@staticmethod
|
|
def from_legacy_dict(as_dict: ValidToolDict) -> "ValidTool":
|
|
return ValidTool(**as_dict)
|
|
|
|
@staticmethod
|
|
def from_legacy_list(as_dicts: List[ValidToolDict]) -> List["ValidTool"]:
|
|
return list(ValidTool.from_legacy_dict(d) for d in as_dicts)
|
|
|
|
|
|
class RepositoryMetadataInstallInfo(BaseModel):
|
|
id: str
|
|
changeset_revision: str
|
|
downloadable: bool
|
|
has_repository_dependencies: bool
|
|
includes_tools: bool
|
|
includes_tools_for_display_in_tool_panel: bool
|
|
malicious: bool
|
|
repository_id: str
|
|
url: str
|
|
valid_tools: List[ValidToolDict]
|
|
# no longer used, don't transmit.
|
|
# has_repository_dependencies_only_if_compiling_contained_td: bool
|
|
# includes_datatypes: bool
|
|
# includes_tool_dependencies: bool
|
|
# includes_workflows: bool
|
|
|
|
@staticmethod
|
|
def from_legacy_dict(as_dict: RepositoryMetadataInstallInfoDict) -> "RepositoryMetadataInstallInfo":
|
|
return RepositoryMetadataInstallInfo(
|
|
id=as_dict["id"],
|
|
changeset_revision=as_dict["changeset_revision"],
|
|
downloadable=as_dict["downloadable"],
|
|
has_repository_dependencies=as_dict["has_repository_dependencies"],
|
|
includes_tools=as_dict["includes_tools"],
|
|
includes_tools_for_display_in_tool_panel=as_dict["includes_tools_for_display_in_tool_panel"],
|
|
malicious=as_dict["malicious"],
|
|
repository_id=as_dict["repository_id"],
|
|
url=as_dict["url"],
|
|
valid_tools=ValidTool.from_legacy_list(as_dict.get("valid_tools", [])),
|
|
)
|
|
|
|
|
|
class InstallInfo(BaseModel):
|
|
metadata_info: Optional[RepositoryMetadataInstallInfo]
|
|
repo_info: Optional[RepositoryExtraInstallInfo]
|
|
|
|
|
|
def from_legacy_install_info(legacy_install_info: LegacyInstallInfoTuple) -> InstallInfo:
|
|
repo_metadata_install_info: Union[RepositoryMetadataInstallInfoDict, EmptyDict]
|
|
extra_info: Union[ExtraRepoInfo, EmptyDict]
|
|
_, repo_metadata_install_info, extra_info = legacy_install_info
|
|
if repo_metadata_install_info:
|
|
metadata_info = RepositoryMetadataInstallInfo.from_legacy_dict(
|
|
cast(RepositoryMetadataInstallInfoDict, repo_metadata_install_info)
|
|
)
|
|
else:
|
|
metadata_info = None
|
|
if extra_info:
|
|
repo_info = RepositoryExtraInstallInfo.from_legacy_dict(extra_info)
|
|
else:
|
|
repo_info = None
|
|
return InstallInfo(
|
|
metadata_info=metadata_info,
|
|
repo_info=repo_info,
|
|
)
|
|
|
|
|
|
class BuildSearchIndexResponse(BaseModel):
|
|
repositories_indexed: int
|
|
tools_indexed: int
|
|
|
|
|
|
class Version(BaseModel):
|
|
version_major: str
|
|
version: str
|
|
api_version: str = "v1"
|