commit 1cf124a5a3f19d4f93f07af23fc796373461fdf3 Author: claudi Date: Tue Mar 3 12:55:22 2026 +0100 initial commit after automated creating diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..7d0e2d6 --- /dev/null +++ b/.env.example @@ -0,0 +1,14 @@ +# Copy this file to .env and fill in your values. +# All variables are prefixed with AGRAVITY_. + +# Required: your x-functions-key API key +AGRAVITY_API_KEY=your-api-key-here + +# Optional: override the base API URL +# AGRAVITY_BASE_URL=https://devagravitypublic.azurewebsites.net/api + +# Optional: HTTP request timeout in seconds +# AGRAVITY_TIMEOUT=60.0 + +# Optional: set to false to disable SSL certificate verification (not recommended) +# AGRAVITY_VERIFY_SSL=true diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..480521a --- /dev/null +++ b/.gitignore @@ -0,0 +1,37 @@ +# Python +__pycache__/ +*.py[cod] +*.pyo +*.pyd +*.egg +*.egg-info/ +dist/ +build/ +.eggs/ + +# Virtual environments +.venv/ +venv/ +env/ + +# Type checking +.mypy_cache/ +.dmypy.json +dmypy.json + +# Linting +.ruff_cache/ + +# Environment files +.env + +# pytest +.pytest_cache/ +.coverage +htmlcov/ + +# VS Code +.vscode/ + +# macOS +.DS_Store diff --git a/README.md b/README.md new file mode 100644 index 0000000..c02a6c9 --- /dev/null +++ b/README.md @@ -0,0 +1,141 @@ +# agravity-client + +A fully **Pythonic, Pydantic v2–driven, async** REST client for the +[Agravity DAM API](https://agravity.io) (v10.3.0). + +Built on [`httpx`](https://www.python-httpx.org/) and +[Pydantic](https://docs.pydantic.dev/), this library gives you: + +- **Typed return values** – every endpoint returns a validated Pydantic model. +- **Async-first** – all network calls are `async def` using `httpx.AsyncClient`. +- **Context-manager support** – clean connection lifecycle. +- **Auto-configuration** – reads `AGRAVITY_*` env vars or a `.env` file via + `pydantic-settings`. + + +## Installation + +```bash +pip install agravity-client +``` + +_Or in development mode:_ + +```bash +pip install -e ".[dev]" +``` + + +## Quick start + +```python +import asyncio +from agravity_client import AgravityClient, AgravityConfig + +async def main(): + config = AgravityConfig(api_key="YOUR_API_KEY") # or set AGRAVITY_API_KEY env var + + async with AgravityClient(config) as client: + # ------------------------------------------------------------------ + # Version & capabilities + # ------------------------------------------------------------------ + version = await client.general.get_version() + print(version.version) + + # ------------------------------------------------------------------ + # List assets in a collection + # ------------------------------------------------------------------ + page = await client.assets.list_assets( + collection_id="your-collection-id", + limit=25, + ) + for asset in page.assets or []: + print(asset.id, asset.name) + + # ------------------------------------------------------------------ + # Upload an asset + # ------------------------------------------------------------------ + with open("photo.jpg", "rb") as fh: + new_asset = await client.assets.upload_asset( + fh.read(), + "photo.jpg", + name="My photo", + collection_id="your-collection-id", + ) + print("Created:", new_asset.id) + + # ------------------------------------------------------------------ + # Search + # ------------------------------------------------------------------ + from agravity_client.models import AzSearchOptions + results = await client.search.search( + AzSearchOptions(searchterm="sunset", limit=10) + ) + print(results.count, "results") + +asyncio.run(main()) +``` + + +## Configuration + +| Setting | Env variable | Default | +|---------|-------------|---------| +| `base_url` | `AGRAVITY_BASE_URL` | `https://devagravitypublic.azurewebsites.net/api` | +| `api_key` | `AGRAVITY_API_KEY` | _(empty)_ | +| `timeout` | `AGRAVITY_TIMEOUT` | `60.0` | +| `verify_ssl` | `AGRAVITY_VERIFY_SSL` | `true` | + +Copy `.env.example` to `.env` and fill in your values. + + +## API modules + +| Attribute | Endpoints covered | +|-----------|-------------------| +| `client.assets` | `/assets`, `/assetsupload`, `/assetsbulkupdate`, all sub-resources | +| `client.collections` | `/collections` CRUD, ancestors, descendants, preview, bynames | +| `client.collection_types` | `/collectiontypes` | +| `client.relations` | `/relations`, `/assetrelationtypes` | +| `client.search` | `/search`, `/search/facette`, `/search/adminstatus`, `/savedsearch` | +| `client.sharing` | `/sharing`, `/sharing/quickshares` | +| `client.portals` | `/portals` | +| `client.workspaces` | `/workspaces` | +| `client.auth` | `/auth/containerwrite`, `/auth/inbox`, `/auth/users` | +| `client.download_formats` | `/downloadformats` | +| `client.static_lists` | `/staticdefinedlists` | +| `client.translations` | `/translations` | +| `client.publishing` | `/publish` | +| `client.secure_upload` | `/secureupload` | +| `client.helper` | `/helper/*` | +| `client.webappdata` | `/webappdata` | +| `client.general` | `/version`, `/deleted`, `/durable`, `/negotiate`, `/public`, `/config` | +| `client.ai` | `/ai/reverseassetsearch` | + + +## Development + +```bash +# Create and activate a virtual environment +python -m venv .venv +.venv\Scripts\activate # Windows +# source .venv/bin/activate # Unix + +# Install in editable mode with all dev dependencies +pip install -e ".[dev]" + +# Lint & format +ruff check . +ruff format . + +# Type-check +mypy agravity_client + +# Run tests +pytest +``` + + +## Licence + +MIT diff --git a/agravity_client.code-workspace b/agravity_client.code-workspace new file mode 100644 index 0000000..57f05fa --- /dev/null +++ b/agravity_client.code-workspace @@ -0,0 +1,120 @@ +{ + "folders": [ + { + "path": "." + } + ], + "settings": { + // Python environment + "python.defaultInterpreterPath": "${workspaceFolder}/.venv/Scripts/python.exe", + "python.terminal.activateEnvironment": true, + + // Editor + "editor.formatOnSave": true, + "editor.rulers": [100], + "editor.tabSize": 4, + + // Ruff (linter + formatter) + "[python]": { + "editor.defaultFormatter": "charliermarsh.ruff", + "editor.formatOnSave": true, + "editor.codeActionsOnSave": { + "source.fixAll.ruff": "explicit", + "source.organizeImports.ruff": "explicit" + } + }, + + // Pylance / Pyright + "python.analysis.typeCheckingMode": "basic", + "python.analysis.autoImportCompletions": true, + "python.analysis.indexing": true, + + // Test discovery + "python.testing.pytestEnabled": true, + "python.testing.unittestEnabled": false, + "python.testing.pytestArgs": ["tests"], + + // File associations + "files.associations": { + "*.env.example": "dotenv" + }, + + // Exclude noise from explorer + "files.exclude": { + "**/__pycache__": true, + "**/*.pyc": true, + "**/.mypy_cache": true, + "**/.ruff_cache": true, + "**/*.egg-info": true, + ".venv": false + } + }, + "extensions": { + "recommendations": [ + "ms-python.python", + "ms-python.vscode-pylance", + "charliermarsh.ruff", + "ms-python.mypy-type-checker", + "tamasfe.even-better-toml", + "mikestead.dotenv" + ] + }, + "launch": { + "version": "0.2.0", + "configurations": [ + { + "name": "Python: Current File", + "type": "debugpy", + "request": "launch", + "program": "${file}", + "console": "integratedTerminal", + "justMyCode": true + } + ] + }, + "tasks": { + "version": "2.0.0", + "tasks": [ + { + "label": "Install (editable)", + "type": "shell", + "command": "pip install -e \".[dev]\"", + "group": "build", + "presentation": { "reveal": "always" }, + "problemMatcher": [] + }, + { + "label": "Ruff: lint", + "type": "shell", + "command": "ruff check .", + "group": "test", + "presentation": { "reveal": "always" }, + "problemMatcher": [] + }, + { + "label": "Ruff: format", + "type": "shell", + "command": "ruff format .", + "group": "build", + "presentation": { "reveal": "always" }, + "problemMatcher": [] + }, + { + "label": "mypy: type-check", + "type": "shell", + "command": "mypy agravity_client", + "group": "test", + "presentation": { "reveal": "always" }, + "problemMatcher": ["$mypy"] + }, + { + "label": "pytest", + "type": "shell", + "command": "pytest -v", + "group": { "kind": "test", "isDefault": true }, + "presentation": { "reveal": "always" }, + "problemMatcher": [] + } + ] + } +} diff --git a/agravity_client/__init__.py b/agravity_client/__init__.py new file mode 100644 index 0000000..ffea7e6 --- /dev/null +++ b/agravity_client/__init__.py @@ -0,0 +1,29 @@ +"""Agravity DAM Python client – public API surface.""" +from __future__ import annotations + +from agravity_client.client import AgravityClient +from agravity_client.config import AgravityConfig +from agravity_client.exceptions import ( + AgravityAPIError, + AgravityAuthenticationError, + AgravityConnectionError, + AgravityError, + AgravityNotFoundError, + AgravityTimeoutError, + AgravityValidationError, +) +from agravity_client.models import * # noqa: F403 – re-export all model symbols + +__version__ = "0.1.0" +__all__ = [ + "AgravityClient", + "AgravityConfig", + # Exceptions + "AgravityError", + "AgravityAPIError", + "AgravityAuthenticationError", + "AgravityConnectionError", + "AgravityNotFoundError", + "AgravityTimeoutError", + "AgravityValidationError", +] diff --git a/agravity_client/api/__init__.py b/agravity_client/api/__init__.py new file mode 100644 index 0000000..65e9bf8 --- /dev/null +++ b/agravity_client/api/__init__.py @@ -0,0 +1,42 @@ +"""Agravity API client sub-modules.""" +from __future__ import annotations + +from agravity_client.api.ai import AiApi +from agravity_client.api.assets import AssetsApi +from agravity_client.api.auth import AuthApi +from agravity_client.api.collection_types import CollectionTypesApi +from agravity_client.api.collections import CollectionsApi +from agravity_client.api.download_formats import DownloadFormatsApi +from agravity_client.api.general import GeneralApi +from agravity_client.api.helper import HelperApi +from agravity_client.api.portals import PortalsApi +from agravity_client.api.publishing import PublishingApi +from agravity_client.api.relations import RelationsApi +from agravity_client.api.search import SearchApi +from agravity_client.api.secure_upload import SecureUploadApi +from agravity_client.api.sharing import SharingApi +from agravity_client.api.static_lists import StaticListsApi +from agravity_client.api.translations import TranslationsApi +from agravity_client.api.webappdata import WebAppDataApi +from agravity_client.api.workspaces import WorkspacesApi + +__all__ = [ + "AiApi", + "AssetsApi", + "AuthApi", + "CollectionTypesApi", + "CollectionsApi", + "DownloadFormatsApi", + "GeneralApi", + "HelperApi", + "PortalsApi", + "PublishingApi", + "RelationsApi", + "SearchApi", + "SecureUploadApi", + "SharingApi", + "StaticListsApi", + "TranslationsApi", + "WebAppDataApi", + "WorkspacesApi", +] diff --git a/agravity_client/api/ai.py b/agravity_client/api/ai.py new file mode 100644 index 0000000..a129ddc --- /dev/null +++ b/agravity_client/api/ai.py @@ -0,0 +1,37 @@ +"""AI Operations API module (reverse asset search).""" +from __future__ import annotations + +from typing import Optional + +from agravity_client.api.base import AgravityBaseApi +from agravity_client.models.asset import Asset + + +class AiApi(AgravityBaseApi): + """Covers all /ai endpoints.""" + + async def reverse_asset_search( + self, + image_file: bytes, + filename: str, + *, + limit: Optional[int] = None, + content_type: str = "application/octet-stream", + ) -> list[Asset]: + """POST /ai/reverseassetsearch – find similar assets by image. + + Args: + image_file: Raw image bytes to use as the search query. + filename: Original filename for the image. + limit: Maximum number of results to return. + content_type: MIME type of the uploaded image. + + Returns: + A list of matching :class:`~agravity_client.models.asset.Asset` objects. + """ + files = {"image_file": (filename, image_file, content_type)} + data = {} + if limit is not None: + data["limit"] = str(limit) + resp = await self._post("/ai/reverseassetsearch", data=data, files=files) + return [Asset.model_validate(item) for item in resp.json()] diff --git a/agravity_client/api/assets.py b/agravity_client/api/assets.py new file mode 100644 index 0000000..126bea1 --- /dev/null +++ b/agravity_client/api/assets.py @@ -0,0 +1,420 @@ +"""Asset Management and Operations API module.""" +from __future__ import annotations + +from pathlib import Path +from typing import Any, Optional + +from agravity_client.api.base import AgravityBaseApi +from agravity_client.models.asset import ( + Asset, + AssetAvailability, + AssetBlob, + AssetBulkUpdate, + AssetIdFormat, + AssetPageResult, +) +from agravity_client.models.collection import Collection +from agravity_client.models.common import AgravityInfoResponse +from agravity_client.models.download import DynamicImageOperation +from agravity_client.models.publish import PublishEntity, PublishedAsset +from agravity_client.models.relation import AssetRelation +from agravity_client.models.versioning import VersionedAsset, VersionEntity + + +class AssetsApi(AgravityBaseApi): + """Covers all /assets endpoints.""" + + # ------------------------------------------------------------------ + # Asset CRUD + # ------------------------------------------------------------------ + + async def list_assets( + self, + *, + collection_id: Optional[str] = None, + collection_type_id: Optional[str] = None, + fields: Optional[str] = None, + expose: Optional[bool] = None, + continuation_token: Optional[str] = None, + limit: Optional[int] = None, + orderby: Optional[str] = None, + filter: Optional[str] = None, + items: Optional[bool] = None, + translations: Optional[bool] = None, + accept_language: Optional[str] = None, + ) -> AssetPageResult: + """GET /assets – list assets (optionally filtered/paginated).""" + params: dict[str, Any] = { + "collectionid": collection_id, + "collectiontypeid": collection_type_id, + "fields": fields, + "expose": expose, + "continuation_token": continuation_token, + "limit": limit, + "orderby": orderby, + "filter": filter, + "items": items, + "translations": translations, + } + headers = {"Accept-Language": accept_language} if accept_language else None + resp = await self._get("/assets", params=params, extra_headers=headers) + return AssetPageResult.model_validate(resp.json()) + + async def create_asset(self, payload: dict[str, Any]) -> Asset: + """POST /assets – create a new asset.""" + resp = await self._post("/assets", json=payload) + return Asset.model_validate(resp.json()) + + async def get_asset( + self, + asset_id: str, + *, + fields: Optional[str] = None, + items: Optional[bool] = None, + translations: Optional[bool] = None, + accept_language: Optional[str] = None, + ) -> Asset: + """GET /assets/{id}.""" + params: dict[str, Any] = { + "fields": fields, + "items": items, + "translations": translations, + } + headers = {"Accept-Language": accept_language} if accept_language else None + resp = await self._get(f"/assets/{asset_id}", params=params, extra_headers=headers) + return Asset.model_validate(resp.json()) + + async def update_asset(self, asset_id: str, payload: dict[str, Any]) -> Asset: + """POST /assets/{id} – update asset metadata.""" + resp = await self._post(f"/assets/{asset_id}", json=payload) + return Asset.model_validate(resp.json()) + + async def delete_asset(self, asset_id: str) -> None: + """DELETE /assets/{id}.""" + await self._delete(f"/assets/{asset_id}") + + # ------------------------------------------------------------------ + # Upload + # ------------------------------------------------------------------ + + async def upload_asset( + self, + file: bytes, + filename: str, + *, + name: Optional[str] = None, + collection_id: Optional[str] = None, + preview_of: Optional[str] = None, + content_type: str = "application/octet-stream", + ) -> Asset: + """POST /assetsupload – upload a new asset file (multipart).""" + files: dict[str, Any] = { + "file": (filename, file, content_type), + } + data: dict[str, Any] = {} + if name: + data["name"] = name + if collection_id: + data["collectionid"] = collection_id + if filename: + data["filename"] = filename + if preview_of: + data["previewof"] = preview_of + resp = await self._post("/assetsupload", data=data, files=files) + return Asset.model_validate(resp.json()) + + async def upload_asset_from_path( + self, + path: Path | str, + *, + name: Optional[str] = None, + collection_id: Optional[str] = None, + preview_of: Optional[str] = None, + ) -> Asset: + """Convenience wrapper: read a local file and call :meth:`upload_asset`.""" + path = Path(path) + return await self.upload_asset( + path.read_bytes(), + path.name, + name=name, + collection_id=collection_id, + preview_of=preview_of, + ) + + # ------------------------------------------------------------------ + # Bulk update + # ------------------------------------------------------------------ + + async def bulk_update_assets(self, payload: AssetBulkUpdate) -> AgravityInfoResponse: + """POST /assetsbulkupdate.""" + resp = await self._post("/assetsbulkupdate", json=payload.model_dump(by_alias=True, exclude_none=True)) + return AgravityInfoResponse.model_validate(resp.json()) + + async def bulk_upsert_assets(self, payload: AssetBulkUpdate) -> AgravityInfoResponse: + """PUT /assetsbulkupdate.""" + resp = await self._put("/assetsbulkupdate", json=payload.model_dump(by_alias=True, exclude_none=True)) + return AgravityInfoResponse.model_validate(resp.json()) + + async def bulk_delete_assets(self, asset_ids: list[str]) -> AgravityInfoResponse: + """DELETE /assetsbulkupdate.""" + resp = await self._delete("/assetsbulkupdate", params={"ids": ",".join(asset_ids)}) + return AgravityInfoResponse.model_validate(resp.json()) + + # ------------------------------------------------------------------ + # Blobs / binary operations + # ------------------------------------------------------------------ + + async def get_asset_blob( + self, + asset_id: str, + c: str, + *, + portal_id: Optional[str] = None, + key: Optional[str] = None, + ) -> AssetBlob: + """GET /assets/{id}/blobs – get a specific blob by format key.""" + resp = await self._get( + f"/assets/{asset_id}/blobs", + params={"c": c, "portal_id": portal_id, "key": key}, + ) + return AssetBlob.model_validate(resp.json()) + + async def get_shared_asset_blob( + self, + asset_id: str, + share_id: str, + format: str, + *, + password: Optional[str] = None, + ) -> AssetBlob: + """GET /assets/{id}/blob – retrieve a blob via share token.""" + headers = {"ay-password": password} if password else None + resp = await self._get( + f"/assets/{asset_id}/blob", + params={"share_id": share_id, "format": format}, + extra_headers=headers, + ) + return AssetBlob.model_validate(resp.json()) + + async def download_asset( + self, + asset_id: str, + *, + format: Optional[str] = None, + c: Optional[str] = None, + ) -> AssetBlob: + """GET /assets/{id}/download – resolve download URL for an asset.""" + resp = await self._get( + f"/assets/{asset_id}/download", + params={"format": format, "c": c}, + ) + return AssetBlob.model_validate(resp.json()) + + async def resize_asset( + self, + asset_id: str, + *, + width: Optional[int] = None, + height: Optional[int] = None, + mode: Optional[str] = None, + format: Optional[str] = None, + bgcolor: Optional[str] = None, + dpi: Optional[int] = None, + depth: Optional[int] = None, + ) -> bytes: + """GET /assets/{id}/resize – return resized image bytes.""" + resp = await self._get( + f"/assets/{asset_id}/resize", + params={ + "width": width, + "height": height, + "mode": mode, + "format": format, + "bgcolor": bgcolor, + "dpi": dpi, + "depth": depth, + }, + ) + return resp.content + + async def imageedit_asset( + self, + asset_id: str, + *, + width: Optional[int] = None, + height: Optional[int] = None, + mode: Optional[str] = None, + target: Optional[str] = None, + bgcolor: Optional[str] = None, + dpi: Optional[int] = None, + depth: Optional[int] = None, + quality: Optional[int] = None, + colorspace: Optional[str] = None, + crop_x: Optional[int] = None, + crop_y: Optional[int] = None, + crop_width: Optional[int] = None, + crop_height: Optional[int] = None, + filter: Optional[str] = None, + original: Optional[bool] = None, + ) -> bytes: + """GET /assets/{id}/imageedit – apply image transformations.""" + resp = await self._get( + f"/assets/{asset_id}/imageedit", + params={ + "width": width, "height": height, "mode": mode, "target": target, + "bgcolor": bgcolor, "dpi": dpi, "depth": depth, "quality": quality, + "colorspace": colorspace, "crop_x": crop_x, "crop_y": crop_y, + "crop_width": crop_width, "crop_height": crop_height, + "filter": filter, "original": original, + }, + ) + return resp.content + + async def imageedit_asset_operations( + self, + asset_id: str, + operations: list[DynamicImageOperation], + ) -> bytes: + """POST /assets/{id}/imageedit – apply a sequence of image operations.""" + payload = [op.model_dump(by_alias=True, exclude_none=True) for op in operations] + resp = await self._post(f"/assets/{asset_id}/imageedit", json=payload) + return resp.content + + async def imageedit_asset_by_format( + self, + asset_id: str, + download_format_id: str, + ) -> bytes: + """GET /assets/{id}/imageedit/{download_format_id}.""" + resp = await self._get(f"/assets/{asset_id}/imageedit/{download_format_id}") + return resp.content + + # ------------------------------------------------------------------ + # Collections membership + # ------------------------------------------------------------------ + + async def get_asset_collections(self, asset_id: str) -> list[Collection]: + """GET /assets/{id}/collections.""" + resp = await self._get(f"/assets/{asset_id}/collections") + return [Collection.model_validate(item) for item in resp.json()] + + async def add_asset_to_collection( + self, + asset_id: str, + *, + collection_id: Optional[str] = None, + ) -> None: + """POST /assets/{id}/tocollection.""" + await self._post( + f"/assets/{asset_id}/tocollection", + params={"collectionid": collection_id}, + ) + + # ------------------------------------------------------------------ + # Availability + # ------------------------------------------------------------------ + + async def update_asset_availability( + self, asset_id: str, availability: AssetAvailability + ) -> AssetAvailability: + """PUT /assets/{id}/availability.""" + resp = await self._put( + f"/assets/{asset_id}/availability", + json=availability.model_dump(by_alias=True, exclude_none=True), + ) + return AssetAvailability.model_validate(resp.json()) + + # ------------------------------------------------------------------ + # Relations + # ------------------------------------------------------------------ + + async def get_asset_relations(self, asset_id: str) -> list[AssetRelation]: + """GET /assets/{id}/relations.""" + resp = await self._get(f"/assets/{asset_id}/relations") + return [AssetRelation.model_validate(item) for item in resp.json()] + + # ------------------------------------------------------------------ + # Publishing (per-asset) + # ------------------------------------------------------------------ + + async def get_asset_publish(self, asset_id: str) -> PublishEntity: + """GET /assets/{id}/publish.""" + resp = await self._get(f"/assets/{asset_id}/publish") + return PublishEntity.model_validate(resp.json()) + + async def create_asset_publish( + self, + asset_id: str, + payload: Optional[dict[str, Any]] = None, + ) -> PublishedAsset: + """POST /assets/{id}/publish.""" + resp = await self._post(f"/assets/{asset_id}/publish", json=payload) + return PublishedAsset.model_validate(resp.json()) + + async def get_asset_published_by_id( + self, asset_id: str, pub_id: str + ) -> PublishedAsset: + """GET /assets/{id}/publish/{pid}.""" + resp = await self._get(f"/assets/{asset_id}/publish/{pub_id}") + return PublishedAsset.model_validate(resp.json()) + + # ------------------------------------------------------------------ + # Versioning (per-asset) + # ------------------------------------------------------------------ + + async def get_asset_versions(self, asset_id: str) -> VersionEntity: + """GET /assets/{id}/versions.""" + resp = await self._get(f"/assets/{asset_id}/versions") + return VersionEntity.model_validate(resp.json()) + + async def create_asset_version( + self, + asset_id: str, + payload: Optional[dict[str, Any]] = None, + ) -> VersionedAsset: + """POST /assets/{id}/versions – create a new version snapshot.""" + resp = await self._post(f"/assets/{asset_id}/versions", json=payload) + return VersionedAsset.model_validate(resp.json()) + + async def upload_asset_version( + self, + asset_id: str, + file: bytes, + filename: str, + *, + content_type: str = "application/octet-stream", + ) -> VersionedAsset: + """POST /assets/{id}/versionsupload – upload a new version file.""" + files = {"file": (filename, file, content_type)} + resp = await self._post(f"/assets/{asset_id}/versionsupload", files=files) + return VersionedAsset.model_validate(resp.json()) + + async def restore_asset_version( + self, asset_id: str, version_nr: int + ) -> dict[str, Any]: + """POST /assets/{id}/versions/{vNr}/restore.""" + resp = await self._post(f"/assets/{asset_id}/versions/{version_nr}/restore") + return resp.json() + + async def delete_asset_version(self, asset_id: str, version_nr: int) -> None: + """DELETE /assets/{id}/versions/{vNr}.""" + await self._delete(f"/assets/{asset_id}/versions/{version_nr}") + + async def update_asset_version( + self, + asset_id: str, + version_nr: int, + payload: Optional[dict[str, Any]] = None, + ) -> VersionedAsset: + """POST /assets/{id}/versions/{vNr} – update version metadata.""" + resp = await self._post( + f"/assets/{asset_id}/versions/{version_nr}", json=payload + ) + return VersionedAsset.model_validate(resp.json()) + + async def get_asset_version_blob( + self, asset_id: str, version_nr: int + ) -> AssetBlob: + """GET /assets/{id}/versions/{vNr}/blobs.""" + resp = await self._get(f"/assets/{asset_id}/versions/{version_nr}/blobs") + return AssetBlob.model_validate(resp.json()) diff --git a/agravity_client/api/auth.py b/agravity_client/api/auth.py new file mode 100644 index 0000000..06a92aa --- /dev/null +++ b/agravity_client/api/auth.py @@ -0,0 +1,35 @@ +"""Auth API module (SAS tokens, users).""" +from __future__ import annotations + +from typing import Optional + +from agravity_client.api.base import AgravityBaseApi +from agravity_client.models.auth import AgravityUser, SasToken + + +class AuthApi(AgravityBaseApi): + """Covers all /auth endpoints.""" + + async def get_container_write_sas_token( + self, + container: str, + blob: str, + *, + permission: Optional[str] = None, + ) -> SasToken: + """GET /auth/containerwrite.""" + resp = await self._get( + "/auth/containerwrite", + params={"container": container, "blob": blob, "permission": permission}, + ) + return SasToken.model_validate(resp.json()) + + async def get_inbox_sas_token(self) -> SasToken: + """GET /auth/inbox (deprecated).""" + resp = await self._get("/auth/inbox") + return SasToken.model_validate(resp.json()) + + async def get_users(self) -> list[AgravityUser]: + """GET /auth/users.""" + resp = await self._get("/auth/users") + return [AgravityUser.model_validate(item) for item in resp.json()] diff --git a/agravity_client/api/base.py b/agravity_client/api/base.py new file mode 100644 index 0000000..6ad91f8 --- /dev/null +++ b/agravity_client/api/base.py @@ -0,0 +1,160 @@ +"""Base HTTP client shared by all Agravity API modules.""" +from __future__ import annotations + +from typing import Any, Optional + +import httpx + +from agravity_client.config import AgravityConfig +from agravity_client.exceptions import ( + AgravityAPIError, + AgravityAuthenticationError, + AgravityConnectionError, + AgravityNotFoundError, + AgravityTimeoutError, + AgravityValidationError, +) +from agravity_client.models.common import AgravityErrorResponse + + +class AgravityBaseApi: + """Low-level async HTTP wrapper around ``httpx.AsyncClient``. + + Every high-level API module subclasses this and calls the + ``_get`` / ``_post`` / ``_put`` / ``_delete`` / ``_patch`` helpers, + which centralise auth header injection and error mapping. + """ + + def __init__(self, http: httpx.AsyncClient, config: AgravityConfig) -> None: + self._http = http + self._config = config + + # ------------------------------------------------------------------ + # Private helpers + # ------------------------------------------------------------------ + + def _auth_headers(self) -> dict[str, str]: + """Return the authentication headers for every request.""" + if self._config.api_key: + return {"x-functions-key": self._config.api_key} + return {} + + def _full_url(self, path: str) -> str: + """Combine base URL with a relative path.""" + return f"{self._config.base_url}/{path.lstrip('/')}" + + @staticmethod + def _raise_for_status(response: httpx.Response) -> None: + """Map HTTP error codes to typed exceptions.""" + if response.is_success: + return + + error_response: Optional[AgravityErrorResponse] = None + raw_body: Optional[str] = None + + try: + data = response.json() + error_response = AgravityErrorResponse.model_validate(data) + except Exception: + raw_body = response.text + + status = response.status_code + if status == 401: + raise AgravityAuthenticationError(status, error_response, raw_body) + if status == 404: + raise AgravityNotFoundError(status, error_response, raw_body) + if status in (400, 422): + raise AgravityValidationError(status, error_response, raw_body) + raise AgravityAPIError(status, error_response, raw_body) + + # ------------------------------------------------------------------ + # HTTP verbs + # ------------------------------------------------------------------ + + async def _request( + self, + method: str, + path: str, + *, + params: Optional[dict[str, Any]] = None, + json: Optional[Any] = None, + data: Optional[dict[str, Any]] = None, + files: Optional[dict[str, Any]] = None, + content: Optional[bytes] = None, + extra_headers: Optional[dict[str, str]] = None, + ) -> httpx.Response: + """Dispatch a request and raise on error.""" + headers = {**self._auth_headers(), **(extra_headers or {})} + # Remove None-valued query params + if params: + params = {k: v for k, v in params.items() if v is not None} + + try: + response = await self._http.request( + method, + self._full_url(path), + params=params or None, + json=json, + data=data, + files=files, + content=content, + headers=headers, + timeout=self._config.timeout, + ) + except httpx.TimeoutException as exc: + raise AgravityTimeoutError(str(exc)) from exc + except httpx.TransportError as exc: + raise AgravityConnectionError(str(exc)) from exc + + self._raise_for_status(response) + return response + + async def _get( + self, + path: str, + params: Optional[dict[str, Any]] = None, + extra_headers: Optional[dict[str, str]] = None, + ) -> httpx.Response: + return await self._request("GET", path, params=params, extra_headers=extra_headers) + + async def _post( + self, + path: str, + json: Optional[Any] = None, + data: Optional[dict[str, Any]] = None, + files: Optional[dict[str, Any]] = None, + content: Optional[bytes] = None, + params: Optional[dict[str, Any]] = None, + extra_headers: Optional[dict[str, str]] = None, + ) -> httpx.Response: + return await self._request( + "POST", path, + json=json, data=data, files=files, content=content, + params=params, extra_headers=extra_headers, + ) + + async def _put( + self, + path: str, + json: Optional[Any] = None, + params: Optional[dict[str, Any]] = None, + extra_headers: Optional[dict[str, str]] = None, + ) -> httpx.Response: + return await self._request("PUT", path, json=json, params=params, extra_headers=extra_headers) + + async def _patch( + self, + path: str, + json: Optional[Any] = None, + params: Optional[dict[str, Any]] = None, + extra_headers: Optional[dict[str, str]] = None, + ) -> httpx.Response: + return await self._request("PATCH", path, json=json, params=params, extra_headers=extra_headers) + + async def _delete( + self, + path: str, + params: Optional[dict[str, Any]] = None, + extra_headers: Optional[dict[str, str]] = None, + ) -> httpx.Response: + return await self._request("DELETE", path, params=params, extra_headers=extra_headers) diff --git a/agravity_client/api/collection_types.py b/agravity_client/api/collection_types.py new file mode 100644 index 0000000..d24e199 --- /dev/null +++ b/agravity_client/api/collection_types.py @@ -0,0 +1,24 @@ +"""Collection Type Management API module.""" +from __future__ import annotations + +from agravity_client.api.base import AgravityBaseApi +from agravity_client.models.collection import CollectionType, CollTypeItem + + +class CollectionTypesApi(AgravityBaseApi): + """Covers all /collectiontypes endpoints.""" + + async def list_collection_types(self) -> list[CollectionType]: + """GET /collectiontypes.""" + resp = await self._get("/collectiontypes") + return [CollectionType.model_validate(item) for item in resp.json()] + + async def get_collection_type(self, type_id: str) -> CollectionType: + """GET /collectiontypes/{id}.""" + resp = await self._get(f"/collectiontypes/{type_id}") + return CollectionType.model_validate(resp.json()) + + async def get_collection_type_items(self, type_id: str) -> list[CollTypeItem]: + """GET /collectiontypes/{id}/items.""" + resp = await self._get(f"/collectiontypes/{type_id}/items") + return [CollTypeItem.model_validate(item) for item in resp.json()] diff --git a/agravity_client/api/collections.py b/agravity_client/api/collections.py new file mode 100644 index 0000000..7d8fbcd --- /dev/null +++ b/agravity_client/api/collections.py @@ -0,0 +1,106 @@ +"""Collection Management API module.""" +from __future__ import annotations + +from typing import Any, Optional + +from agravity_client.api.base import AgravityBaseApi +from agravity_client.models.collection import ( + Collection, + EntityListResult, + EntityNamesRequest, + MoveCollectionBody, +) + + +class CollectionsApi(AgravityBaseApi): + """Covers all /collections endpoints.""" + + async def list_collections( + self, + *, + accept_language: Optional[str] = None, + ) -> list[Collection]: + """GET /collections.""" + headers = {"Accept-Language": accept_language} if accept_language else None + resp = await self._get("/collections", extra_headers=headers) + return [Collection.model_validate(item) for item in resp.json()] + + async def create_collection( + self, payload: dict[str, Any] + ) -> Collection: + """POST /collections.""" + resp = await self._post("/collections", json=payload) + return Collection.model_validate(resp.json()) + + async def get_collection( + self, + collection_id: str, + *, + accept_language: Optional[str] = None, + ) -> Collection: + """GET /collections/{id}.""" + headers = {"Accept-Language": accept_language} if accept_language else None + resp = await self._get(f"/collections/{collection_id}", extra_headers=headers) + return Collection.model_validate(resp.json()) + + async def update_collection( + self, collection_id: str, payload: dict[str, Any] + ) -> Collection: + """POST /collections/{id}.""" + resp = await self._post(f"/collections/{collection_id}", json=payload) + return Collection.model_validate(resp.json()) + + async def delete_collection(self, collection_id: str) -> None: + """DELETE /collections/{id}.""" + await self._delete(f"/collections/{collection_id}") + + async def get_collection_ancestors( + self, + collection_id: str, + *, + accept_language: Optional[str] = None, + ) -> list[Collection]: + """GET /collections/{id}/ancestors.""" + headers = {"Accept-Language": accept_language} if accept_language else None + resp = await self._get(f"/collections/{collection_id}/ancestors", extra_headers=headers) + return [Collection.model_validate(item) for item in resp.json()] + + async def get_collection_descendants( + self, + collection_id: str, + *, + accept_language: Optional[str] = None, + ) -> list[Collection]: + """GET /collections/{id}/descendants.""" + headers = {"Accept-Language": accept_language} if accept_language else None + resp = await self._get(f"/collections/{collection_id}/descendants", extra_headers=headers) + return [Collection.model_validate(item) for item in resp.json()] + + async def get_collection_preview( + self, + collection_id: str, + ) -> bytes: + """GET /collections/{id}/preview – returns image bytes.""" + resp = await self._get(f"/collections/{collection_id}/preview") + return resp.content + + async def get_collections_by_names( + self, + request: EntityNamesRequest, + ) -> EntityListResult: + """POST /collections/bynames.""" + resp = await self._post( + "/collections/bynames", + json=request.model_dump(by_alias=True, exclude_none=True), + ) + return EntityListResult.model_validate(resp.json()) + + async def move_collection( + self, + payload: MoveCollectionBody, + ) -> None: + """POST /movecolltocoll – move a collection to another parent.""" + await self._post( + "/movecolltocoll", + json=payload.model_dump(by_alias=True, exclude_none=True), + ) diff --git a/agravity_client/api/download_formats.py b/agravity_client/api/download_formats.py new file mode 100644 index 0000000..82063ee --- /dev/null +++ b/agravity_client/api/download_formats.py @@ -0,0 +1,21 @@ +"""Download Format Management API module.""" +from __future__ import annotations + +from agravity_client.api.base import AgravityBaseApi +from agravity_client.models.download import DownloadFormat + + +class DownloadFormatsApi(AgravityBaseApi): + """Covers all /downloadformats endpoints.""" + + async def list_download_formats(self) -> list[DownloadFormat]: + """GET /downloadformats.""" + resp = await self._get("/downloadformats") + return [DownloadFormat.model_validate(item) for item in resp.json()] + + async def list_download_formats_from_shared( + self, share_id: str + ) -> list[DownloadFormat]: + """GET /downloadformats/{shareId} – formats available for a share token.""" + resp = await self._get(f"/downloadformats/{share_id}") + return [DownloadFormat.model_validate(item) for item in resp.json()] diff --git a/agravity_client/api/general.py b/agravity_client/api/general.py new file mode 100644 index 0000000..2292c4e --- /dev/null +++ b/agravity_client/api/general.py @@ -0,0 +1,50 @@ +"""General / utility endpoints (version, deleted, durable, signalR, public).""" +from __future__ import annotations + +from typing import Any, Optional + +from agravity_client.api.base import AgravityBaseApi +from agravity_client.models.auth import AgravityVersion +from agravity_client.models.common import DeletedEntities, SignalRConnectionInfo + + +class GeneralApi(AgravityBaseApi): + """Covers miscellaneous top-level endpoints.""" + + async def get_version(self) -> AgravityVersion: + """GET /version – API version and capabilities.""" + resp = await self._get("/version") + return AgravityVersion.model_validate(resp.json()) + + async def get_deleted_entities(self) -> list[DeletedEntities]: + """GET /deleted – list recently deleted entities.""" + resp = await self._get("/deleted") + return [DeletedEntities.model_validate(item) for item in resp.json()] + + async def get_durable_status( + self, + instance_id: Optional[str] = None, + ) -> dict[str, Any]: + """GET /durable – check status of a durable function instance.""" + resp = await self._get("/durable", params={"instanceId": instance_id}) + return resp.json() + + async def get_signalr_connection_info(self) -> SignalRConnectionInfo: + """GET /negotiate – retrieve SignalR connection details.""" + resp = await self._get("/negotiate") + return SignalRConnectionInfo.model_validate(resp.json()) + + async def get_public_asset(self, asset_id: str) -> dict[str, Any]: + """GET /public/{id} – publicly accessible asset metadata.""" + resp = await self._get(f"/public/{asset_id}") + return resp.json() + + async def view_public_asset(self, asset_id: str) -> bytes: + """GET /public/{id}/view – publicly accessible asset binary.""" + resp = await self._get(f"/public/{asset_id}/view") + return resp.content + + async def get_frontend_config(self) -> list[dict[str, Any]]: + """GET /config – retrieve frontend configuration entries.""" + resp = await self._get("/config") + return resp.json() diff --git a/agravity_client/api/helper.py b/agravity_client/api/helper.py new file mode 100644 index 0000000..6521958 --- /dev/null +++ b/agravity_client/api/helper.py @@ -0,0 +1,38 @@ +"""Helper Tools API module (searchable/filterable item metadata).""" +from __future__ import annotations + +from typing import Any, Optional + +from agravity_client.api.base import AgravityBaseApi +from agravity_client.models.search import SearchableItem + + +class HelperApi(AgravityBaseApi): + """Covers all /helper endpoints.""" + + async def get_user_defined_lists( + self, + *, + collection_type_id: Optional[str] = None, + ) -> list[dict[str, Any]]: + """GET /helper/userdefinedlists.""" + resp = await self._get( + "/helper/userdefinedlists", + params={"collectiontypeid": collection_type_id}, + ) + return resp.json() + + async def get_searchable_item_names(self) -> list[str]: + """GET /helper/searchableitemnames – list names of searchable fields.""" + resp = await self._get("/helper/searchableitemnames") + return resp.json() + + async def get_searchable_items(self) -> list[SearchableItem]: + """GET /helper/searchableitems – full searchable field definitions.""" + resp = await self._get("/helper/searchableitems") + return [SearchableItem.model_validate(item) for item in resp.json()] + + async def get_filterable_items(self) -> list[SearchableItem]: + """GET /helper/filterableitems – fields that can be used as filters.""" + resp = await self._get("/helper/filterableitems") + return [SearchableItem.model_validate(item) for item in resp.json()] diff --git a/agravity_client/api/portals.py b/agravity_client/api/portals.py new file mode 100644 index 0000000..f3ce5b9 --- /dev/null +++ b/agravity_client/api/portals.py @@ -0,0 +1,73 @@ +"""Portal Management API module.""" +from __future__ import annotations + +from typing import Any, Optional + +from agravity_client.api.base import AgravityBaseApi +from agravity_client.models.download import DownloadZipRequest, DownloadZipStatus +from agravity_client.models.portal import Portal, PortalConfiguration + + +class PortalsApi(AgravityBaseApi): + """Covers all /portals endpoints.""" + + async def list_portals(self) -> list[Portal]: + """GET /portals.""" + resp = await self._get("/portals") + return [Portal.model_validate(item) for item in resp.json()] + + async def get_portal(self, portal_id: str) -> Portal: + """GET /portals/{id}.""" + resp = await self._get(f"/portals/{portal_id}") + return Portal.model_validate(resp.json()) + + async def get_portal_config(self, portal_id: str) -> PortalConfiguration: + """GET /portals/{id}/config.""" + resp = await self._get(f"/portals/{portal_id}/config") + return PortalConfiguration.model_validate(resp.json()) + + async def enhance_portal_token( + self, + portal_id: str, + payload: Optional[dict[str, Any]] = None, + ) -> dict[str, Any]: + """POST /portals/{id}/enhancetoken – augment the auth token claims.""" + resp = await self._post( + f"/portals/{portal_id}/enhancetoken", + json=payload, + ) + return resp.json() + + async def save_portal_user_attributes( + self, + portal_id: str, + payload: dict[str, Any], + ) -> dict[str, Any]: + """POST /portals/{id}/saveuserattributes.""" + resp = await self._post( + f"/portals/{portal_id}/saveuserattributes", + json=payload, + ) + return resp.json() + + async def get_portal_zip_status(self, portal_id: str) -> DownloadZipStatus: + """GET /portals/{id}/zip.""" + resp = await self._get(f"/portals/{portal_id}/zip") + return DownloadZipStatus.model_validate(resp.json()) + + async def create_portal_zip( + self, + portal_id: str, + payload: DownloadZipRequest, + ) -> DownloadZipStatus: + """POST /portals/{id}/zip.""" + resp = await self._post( + f"/portals/{portal_id}/zip", + json=payload.model_dump(by_alias=True, exclude_none=True), + ) + return DownloadZipStatus.model_validate(resp.json()) + + async def get_portal_asset_ids(self, portal_id: str) -> list[str]: + """GET /portals/{id}/assetids.""" + resp = await self._get(f"/portals/{portal_id}/assetids") + return resp.json() diff --git a/agravity_client/api/publishing.py b/agravity_client/api/publishing.py new file mode 100644 index 0000000..25d0e06 --- /dev/null +++ b/agravity_client/api/publishing.py @@ -0,0 +1,14 @@ +"""Publishing API module (global published assets list).""" +from __future__ import annotations + +from agravity_client.api.base import AgravityBaseApi +from agravity_client.models.publish import PublishEntity + + +class PublishingApi(AgravityBaseApi): + """Covers the /publish endpoint.""" + + async def list_published(self) -> list[PublishEntity]: + """GET /publish – list all published entities across assets.""" + resp = await self._get("/publish") + return [PublishEntity.model_validate(item) for item in resp.json()] diff --git a/agravity_client/api/relations.py b/agravity_client/api/relations.py new file mode 100644 index 0000000..cadad73 --- /dev/null +++ b/agravity_client/api/relations.py @@ -0,0 +1,57 @@ +"""Asset Relation and Asset Relation Type API modules.""" +from __future__ import annotations + +from typing import Any, Optional + +from agravity_client.api.base import AgravityBaseApi +from agravity_client.models.relation import AssetRelation, AssetRelationType + + +class RelationsApi(AgravityBaseApi): + """Covers /relations and /assetrelationtypes endpoints.""" + + # ------------------------------------------------------------------ + # Asset Relations (CRUD) + # ------------------------------------------------------------------ + + async def list_relations(self) -> list[AssetRelation]: + """GET /relations.""" + resp = await self._get("/relations") + return [AssetRelation.model_validate(item) for item in resp.json()] + + async def create_relation(self, payload: dict[str, Any]) -> AssetRelation: + """POST /relations.""" + resp = await self._post("/relations", json=payload) + return AssetRelation.model_validate(resp.json()) + + async def get_relation(self, relation_id: str) -> AssetRelation: + """GET /relations/{id}.""" + resp = await self._get(f"/relations/{relation_id}") + return AssetRelation.model_validate(resp.json()) + + async def update_relation( + self, + relation_id: str, + payload: dict[str, Any], + ) -> AssetRelation: + """POST /relations/{id}.""" + resp = await self._post(f"/relations/{relation_id}", json=payload) + return AssetRelation.model_validate(resp.json()) + + async def delete_relation(self, relation_id: str) -> None: + """DELETE /relations/{id}.""" + await self._delete(f"/relations/{relation_id}") + + # ------------------------------------------------------------------ + # Asset Relation Types (read-only) + # ------------------------------------------------------------------ + + async def list_relation_types(self) -> list[AssetRelationType]: + """GET /assetrelationtypes.""" + resp = await self._get("/assetrelationtypes") + return [AssetRelationType.model_validate(item) for item in resp.json()] + + async def get_relation_type(self, type_id: str) -> AssetRelationType: + """GET /assetrelationtypes/{id}.""" + resp = await self._get(f"/assetrelationtypes/{type_id}") + return AssetRelationType.model_validate(resp.json()) diff --git a/agravity_client/api/search.py b/agravity_client/api/search.py new file mode 100644 index 0000000..7ec9502 --- /dev/null +++ b/agravity_client/api/search.py @@ -0,0 +1,42 @@ +"""Search Management API module.""" +from __future__ import annotations + +from typing import Optional + +from agravity_client.api.base import AgravityBaseApi +from agravity_client.models.search import ( + AzSearchOptions, + SavedSearch, + SearchAdminStatus, + SearchResult, +) + + +class SearchApi(AgravityBaseApi): + """Covers /search and /savedsearch endpoints.""" + + async def search(self, options: AzSearchOptions) -> SearchResult: + """POST /search – perform a full-text/faceted search.""" + resp = await self._post( + "/search", + json=options.model_dump(by_alias=True, exclude_none=True), + ) + return SearchResult.model_validate(resp.json()) + + async def search_facette(self, options: AzSearchOptions) -> SearchResult: + """POST /search/facette – faceted search.""" + resp = await self._post( + "/search/facette", + json=options.model_dump(by_alias=True, exclude_none=True), + ) + return SearchResult.model_validate(resp.json()) + + async def get_search_admin_status(self) -> SearchAdminStatus: + """GET /search/adminstatus.""" + resp = await self._get("/search/adminstatus") + return SearchAdminStatus.model_validate(resp.json()) + + async def list_saved_searches(self) -> list[SavedSearch]: + """GET /savedsearch.""" + resp = await self._get("/savedsearch") + return [SavedSearch.model_validate(item) for item in resp.json()] diff --git a/agravity_client/api/secure_upload.py b/agravity_client/api/secure_upload.py new file mode 100644 index 0000000..a07c830 --- /dev/null +++ b/agravity_client/api/secure_upload.py @@ -0,0 +1,28 @@ +"""Secure Upload API module.""" +from __future__ import annotations + +from typing import Optional + +from agravity_client.api.base import AgravityBaseApi +from agravity_client.models.secure_upload import SecureUploadEntity + + +class SecureUploadApi(AgravityBaseApi): + """Covers all /secureupload endpoints.""" + + async def check_secure_upload( + self, + *, + token: Optional[str] = None, + ) -> dict: + """GET /secureupload – check status / retrieve upload config.""" + resp = await self._get("/secureupload", params={"token": token}) + return resp.json() + + async def create_secure_upload( + self, + payload: Optional[dict] = None, + ) -> SecureUploadEntity: + """POST /secureupload – create a secure upload entity.""" + resp = await self._post("/secureupload", json=payload) + return SecureUploadEntity.model_validate(resp.json()) diff --git a/agravity_client/api/sharing.py b/agravity_client/api/sharing.py new file mode 100644 index 0000000..c698149 --- /dev/null +++ b/agravity_client/api/sharing.py @@ -0,0 +1,79 @@ +"""Sharing Management API module.""" +from __future__ import annotations + +from typing import Optional + +from agravity_client.api.base import AgravityBaseApi +from agravity_client.models.download import DownloadZipRequest, DownloadZipStatus +from agravity_client.models.sharing import QuickShareFull, SharedCollectionFull + + +class SharingApi(AgravityBaseApi): + """Covers all /sharing endpoints.""" + + # ------------------------------------------------------------------ + # Shared collections + # ------------------------------------------------------------------ + + async def list_shared_collections(self) -> list[SharedCollectionFull]: + """GET /sharing.""" + resp = await self._get("/sharing") + return [SharedCollectionFull.model_validate(item) for item in resp.json()] + + async def get_shared_collection( + self, + token: str, + *, + password: Optional[str] = None, + ) -> SharedCollectionFull: + """GET /sharing/{token}.""" + headers = {"ay-password": password} if password else None + resp = await self._get(f"/sharing/{token}", extra_headers=headers) + return SharedCollectionFull.model_validate(resp.json()) + + async def get_shared_collection_zip_status( + self, + token: str, + *, + password: Optional[str] = None, + ) -> DownloadZipStatus: + """GET /sharing/{token}/zip.""" + headers = {"ay-password": password} if password else None + resp = await self._get(f"/sharing/{token}/zip", extra_headers=headers) + return DownloadZipStatus.model_validate(resp.json()) + + async def create_shared_collection_zip( + self, + token: str, + payload: DownloadZipRequest, + *, + password: Optional[str] = None, + ) -> DownloadZipStatus: + """POST /sharing/{token}/zip.""" + headers = {"ay-password": password} if password else None + resp = await self._post( + f"/sharing/{token}/zip", + json=payload.model_dump(by_alias=True, exclude_none=True), + extra_headers=headers, + ) + return DownloadZipStatus.model_validate(resp.json()) + + # ------------------------------------------------------------------ + # Quick shares + # ------------------------------------------------------------------ + + async def list_quickshares(self) -> list[QuickShareFull]: + """GET /sharing/quickshares.""" + resp = await self._get("/sharing/quickshares") + return [QuickShareFull.model_validate(item) for item in resp.json()] + + async def get_quickshare( + self, + token: str, + *, + password: Optional[str] = None, + ) -> QuickShareFull: + """GET /sharing/quickshares/{token}.""" + headers = {"ay-password": password} if password else None + resp = await self._get(f"/sharing/quickshares/{token}", extra_headers=headers) + return QuickShareFull.model_validate(resp.json()) diff --git a/agravity_client/api/static_lists.py b/agravity_client/api/static_lists.py new file mode 100644 index 0000000..65c8ceb --- /dev/null +++ b/agravity_client/api/static_lists.py @@ -0,0 +1,30 @@ +"""Static Defined Lists API module.""" +from __future__ import annotations + +from typing import Any + +from agravity_client.api.base import AgravityBaseApi +from agravity_client.models.static_lists import StaticDefinedList + + +class StaticListsApi(AgravityBaseApi): + """Covers all /staticdefinedlists endpoints.""" + + async def list_static_defined_lists(self) -> list[StaticDefinedList]: + """GET /staticdefinedlists.""" + resp = await self._get("/staticdefinedlists") + return [StaticDefinedList.model_validate(item) for item in resp.json()] + + async def get_static_defined_list(self, list_id: str) -> StaticDefinedList: + """GET /staticdefinedlists/{id}.""" + resp = await self._get(f"/staticdefinedlists/{list_id}") + return StaticDefinedList.model_validate(resp.json()) + + async def update_static_defined_list( + self, + list_id: str, + payload: dict[str, Any], + ) -> StaticDefinedList: + """PUT /staticdefinedlists/{id}.""" + resp = await self._put(f"/staticdefinedlists/{list_id}", json=payload) + return StaticDefinedList.model_validate(resp.json()) diff --git a/agravity_client/api/translations.py b/agravity_client/api/translations.py new file mode 100644 index 0000000..8a44e8f --- /dev/null +++ b/agravity_client/api/translations.py @@ -0,0 +1,43 @@ +"""Translation Management API module.""" +from __future__ import annotations + +from typing import Any + +from agravity_client.api.base import AgravityBaseApi +from agravity_client.models.common import DictionaryObject + + +class TranslationsApi(AgravityBaseApi): + """Covers all /translations endpoints.""" + + async def get_translation(self, entity_id: str) -> DictionaryObject: + """GET /translations/{id} – retrieve all translations for an entity.""" + resp = await self._get(f"/translations/{entity_id}") + return DictionaryObject.model_validate(resp.json()) + + async def update_translation_property( + self, + entity_id: str, + property_name: str, + payload: dict[str, Any], + ) -> DictionaryObject: + """PUT /translations/{id}/{property}.""" + resp = await self._put( + f"/translations/{entity_id}/{property_name}", + json=payload, + ) + return DictionaryObject.model_validate(resp.json()) + + async def update_translation_custom_field( + self, + entity_id: str, + property_name: str, + custom_field: str, + payload: dict[str, Any], + ) -> DictionaryObject: + """PUT /translations/{id}/{property}/{custom_field}.""" + resp = await self._put( + f"/translations/{entity_id}/{property_name}/{custom_field}", + json=payload, + ) + return DictionaryObject.model_validate(resp.json()) diff --git a/agravity_client/api/webappdata.py b/agravity_client/api/webappdata.py new file mode 100644 index 0000000..498f9d0 --- /dev/null +++ b/agravity_client/api/webappdata.py @@ -0,0 +1,45 @@ +"""Web App Data API module.""" +from __future__ import annotations + +from typing import Optional, Union + +from agravity_client.api.base import AgravityBaseApi +from agravity_client.models.search import AllWebAppData, GroupAllAppData + + +class WebAppDataApi(AgravityBaseApi): + """Covers all /webappdata endpoints.""" + + async def get_web_app_data( + self, + *, + collection_type_id: Optional[str] = None, + accept_language: Optional[str] = None, + ) -> Union[AllWebAppData, GroupAllAppData]: + """GET /webappdata – retrieve structured data for web app initialization. + + If *collection_type_id* is supplied the API may return a + :class:`GroupAllAppData` instead of :class:`AllWebAppData`. + """ + params = {"collectiontypeid": collection_type_id} + headers = {"Accept-Language": accept_language} if accept_language else None + resp = await self._get("/webappdata", params=params, extra_headers=headers) + data = resp.json() + # Heuristic: GroupAllAppData has a "collection_type" key + if "collection_type" in data or "collectionType" in data: + return GroupAllAppData.model_validate(data) + return AllWebAppData.model_validate(data) + + async def get_web_app_data_by_collection_type( + self, + collection_type_id: str, + *, + accept_language: Optional[str] = None, + ) -> GroupAllAppData: + """GET /webappdata/{collectionTypeId}.""" + headers = {"Accept-Language": accept_language} if accept_language else None + resp = await self._get( + f"/webappdata/{collection_type_id}", + extra_headers=headers, + ) + return GroupAllAppData.model_validate(resp.json()) diff --git a/agravity_client/api/workspaces.py b/agravity_client/api/workspaces.py new file mode 100644 index 0000000..06421fc --- /dev/null +++ b/agravity_client/api/workspaces.py @@ -0,0 +1,19 @@ +"""Workspaces API module.""" +from __future__ import annotations + +from agravity_client.api.base import AgravityBaseApi +from agravity_client.models.workspace import Workspace + + +class WorkspacesApi(AgravityBaseApi): + """Covers all /workspaces endpoints.""" + + async def list_workspaces(self) -> list[Workspace]: + """GET /workspaces.""" + resp = await self._get("/workspaces") + return [Workspace.model_validate(item) for item in resp.json()] + + async def get_workspace(self, workspace_id: str) -> Workspace: + """GET /workspaces/{id}.""" + resp = await self._get(f"/workspaces/{workspace_id}") + return Workspace.model_validate(resp.json()) diff --git a/agravity_client/client.py b/agravity_client/client.py new file mode 100644 index 0000000..0e311a6 --- /dev/null +++ b/agravity_client/client.py @@ -0,0 +1,114 @@ +"""Top-level AgravityClient – the single entry point for users.""" +from __future__ import annotations + +from types import TracebackType +from typing import Optional, Type + +import httpx + +from agravity_client.api.ai import AiApi +from agravity_client.api.assets import AssetsApi +from agravity_client.api.auth import AuthApi +from agravity_client.api.collection_types import CollectionTypesApi +from agravity_client.api.collections import CollectionsApi +from agravity_client.api.download_formats import DownloadFormatsApi +from agravity_client.api.general import GeneralApi +from agravity_client.api.helper import HelperApi +from agravity_client.api.portals import PortalsApi +from agravity_client.api.publishing import PublishingApi +from agravity_client.api.relations import RelationsApi +from agravity_client.api.search import SearchApi +from agravity_client.api.secure_upload import SecureUploadApi +from agravity_client.api.sharing import SharingApi +from agravity_client.api.static_lists import StaticListsApi +from agravity_client.api.translations import TranslationsApi +from agravity_client.api.webappdata import WebAppDataApi +from agravity_client.api.workspaces import WorkspacesApi +from agravity_client.config import AgravityConfig + + +class AgravityClient: + """Fully async Agravity DAM API client. + + Usage example:: + + import asyncio + from agravity_client import AgravityClient, AgravityConfig + + async def main(): + config = AgravityConfig(api_key="your-key") + async with AgravityClient(config) as client: + version = await client.general.get_version() + print(version) + + asyncio.run(main()) + + The client can also be used without the context-manager idiom – just + remember to call :meth:`aclose` when you are done. + """ + + def __init__( + self, + config: Optional[AgravityConfig] = None, + *, + http_client: Optional[httpx.AsyncClient] = None, + ) -> None: + self._config = config or AgravityConfig() + self._http = http_client or httpx.AsyncClient( + verify=self._config.verify_ssl, + timeout=self._config.timeout, + ) + self._init_api_modules() + + # ------------------------------------------------------------------ + # Context-manager support + # ------------------------------------------------------------------ + + async def __aenter__(self) -> "AgravityClient": + return self + + async def __aexit__( + self, + exc_type: Optional[Type[BaseException]], + exc_val: Optional[BaseException], + exc_tb: Optional[TracebackType], + ) -> None: + await self.aclose() + + async def aclose(self) -> None: + """Close the underlying HTTP transport.""" + await self._http.aclose() + + # ------------------------------------------------------------------ + # API module initialisation + # ------------------------------------------------------------------ + + def _init_api_modules(self) -> None: + args = (self._http, self._config) + self.ai = AiApi(*args) + self.assets = AssetsApi(*args) + self.auth = AuthApi(*args) + self.collection_types = CollectionTypesApi(*args) + self.collections = CollectionsApi(*args) + self.download_formats = DownloadFormatsApi(*args) + self.general = GeneralApi(*args) + self.helper = HelperApi(*args) + self.portals = PortalsApi(*args) + self.publishing = PublishingApi(*args) + self.relations = RelationsApi(*args) + self.search = SearchApi(*args) + self.secure_upload = SecureUploadApi(*args) + self.sharing = SharingApi(*args) + self.static_lists = StaticListsApi(*args) + self.translations = TranslationsApi(*args) + self.webappdata = WebAppDataApi(*args) + self.workspaces = WorkspacesApi(*args) + + # ------------------------------------------------------------------ + # Convenience read-only properties + # ------------------------------------------------------------------ + + @property + def config(self) -> AgravityConfig: + """The current client configuration.""" + return self._config diff --git a/agravity_client/config.py b/agravity_client/config.py new file mode 100644 index 0000000..b546f70 --- /dev/null +++ b/agravity_client/config.py @@ -0,0 +1,48 @@ +"""Agravity client configuration using Pydantic Settings.""" +from __future__ import annotations + +from pydantic import Field, field_validator +from pydantic_settings import BaseSettings, SettingsConfigDict + + +class AgravityConfig(BaseSettings): + """Configuration for the Agravity API client. + + Values can be provided via environment variables or directly in code. + + Environment variable names: + AGRAVITY_BASE_URL + AGRAVITY_API_KEY + AGRAVITY_TIMEOUT + AGRAVITY_VERIFY_SSL + """ + + model_config = SettingsConfigDict( + env_prefix="AGRAVITY_", + env_file=".env", + env_file_encoding="utf-8", + case_sensitive=False, + extra="ignore", + ) + + base_url: str = Field( + default="https://devagravitypublic.azurewebsites.net/api", + description="The base URL for the Agravity API (without trailing slash).", + ) + api_key: str = Field( + default="", + description="The API key (x-functions-key) used for authentication.", + ) + timeout: float = Field( + default=60.0, + description="Default HTTP request timeout in seconds.", + ) + verify_ssl: bool = Field( + default=True, + description="Whether to verify SSL certificates.", + ) + + @field_validator("base_url") + @classmethod + def strip_trailing_slash(cls, v: str) -> str: + return v.rstrip("/") diff --git a/agravity_client/exceptions.py b/agravity_client/exceptions.py new file mode 100644 index 0000000..f1ffe8a --- /dev/null +++ b/agravity_client/exceptions.py @@ -0,0 +1,59 @@ +"""Custom exceptions for the Agravity API client.""" +from __future__ import annotations + +from typing import Optional + +from agravity_client.models.common import AgravityErrorResponse + + +class AgravityError(Exception): + """Base exception for all Agravity client errors.""" + + +class AgravityAPIError(AgravityError): + """Raised when the API returns a non-2xx response. + + Attributes: + status_code: The HTTP status code returned by the server. + error_response: The parsed AgravityErrorResponse body, if available. + raw_body: The raw response text, if parsing failed. + """ + + def __init__( + self, + status_code: int, + error_response: Optional[AgravityErrorResponse] = None, + raw_body: Optional[str] = None, + ) -> None: + self.status_code = status_code + self.error_response = error_response + self.raw_body = raw_body + + if error_response and error_response.error_message: + msg = f"HTTP {status_code}: {error_response.error_message}" + elif raw_body: + msg = f"HTTP {status_code}: {raw_body[:200]}" + else: + msg = f"HTTP {status_code}" + + super().__init__(msg) + + +class AgravityAuthenticationError(AgravityAPIError): + """Raised when the API returns a 401 Unauthorized response.""" + + +class AgravityNotFoundError(AgravityAPIError): + """Raised when the API returns a 404 Not Found response.""" + + +class AgravityValidationError(AgravityAPIError): + """Raised when the API returns a 400 Bad Request / 422 response.""" + + +class AgravityTimeoutError(AgravityError): + """Raised when an HTTP request times out.""" + + +class AgravityConnectionError(AgravityError): + """Raised when a network-level connection error occurs.""" diff --git a/agravity_client/models/__init__.py b/agravity_client/models/__init__.py new file mode 100644 index 0000000..f3f7c58 --- /dev/null +++ b/agravity_client/models/__init__.py @@ -0,0 +1,138 @@ +"""Agravity DAM – Pydantic models (re-exported from sub-modules).""" + +from agravity_client.models.asset import ( + Asset, + AssetAvailability, + AssetBlob, + AssetBlobOrientation, + AssetBlobType, + AssetBulkUpdate, + AssetCheckout, + AssetIconRule, + AssetIdFormat, + AssetPageResult, + AssetRole, +) +from agravity_client.models.auth import ( + AgravityUser, + AgravityUserOnlineStatus, + AgravityVersion, + SasToken, +) +from agravity_client.models.collection import ( + CollTypeItem, + Collection, + CollectionType, + CollectionUDL, + CollectionUDLListEntity, + CollectionUDLReference, + EntityListResult, + EntityNamesRequest, + MoveCollectionBody, + PermissionEntity, + PermissionRole, +) +from agravity_client.models.common import ( + AgravityErrorResponse, + AgravityInfoResponse, + DataResult, + DeletedEntities, + DictionaryObject, + EntityId, + EntityIdName, + FrontendAppConfig, + SignalRConnectionInfo, + WhereParam, + WhereParamOperator, + WhereParamValueType, +) +from agravity_client.models.download import ( + DistZipResponse, + DownloadFormat, + DownloadZipRequest, + DownloadZipStatus, + DynamicImageOperation, + SharedAllowedFormat, + ZipType, +) +from agravity_client.models.portal import ( + Portal, + PortalAuthentication, + PortalAuthMethod, + PortalConfiguration, + PortalFields, + PortalLinks, + PortalTheme, + PortalUserContext, +) +from agravity_client.models.publish import PublishedAsset, PublishEntity +from agravity_client.models.relation import AssetRelation, AssetRelationType, RelatedAsset +from agravity_client.models.search import ( + AllWebAppData, + AzSearchOptions, + GroupAllAppData, + SavedSearch, + SearchableItem, + SearchAdminDataSourceStatus, + SearchAdminIndexerLastRun, + SearchAdminIndexerStatus, + SearchAdminIndexStatus, + SearchAdminSkillStatus, + SearchAdminStatistics, + SearchAdminStatus, + SearchFacet, + SearchFacetEntity, + SearchResult, +) +from agravity_client.models.secure_upload import SecureUploadEntity +from agravity_client.models.sharing import ( + QuickShareFull, + SharedAsset, + SharedCollectionFull, +) +from agravity_client.models.static_lists import StaticDefinedList +from agravity_client.models.versioning import VersionedAsset, VersionEntity +from agravity_client.models.workspace import Workspace + +__all__ = [ + # asset + "Asset", "AssetAvailability", "AssetBlob", "AssetBlobOrientation", + "AssetBlobType", "AssetBulkUpdate", "AssetCheckout", "AssetIconRule", + "AssetIdFormat", "AssetPageResult", "AssetRole", + # auth + "AgravityUser", "AgravityUserOnlineStatus", "AgravityVersion", "SasToken", + # collection + "CollTypeItem", "Collection", "CollectionType", "CollectionUDL", + "CollectionUDLListEntity", "CollectionUDLReference", "EntityListResult", + "EntityNamesRequest", "MoveCollectionBody", "PermissionEntity", "PermissionRole", + # common + "AgravityErrorResponse", "AgravityInfoResponse", "DataResult", "DeletedEntities", + "DictionaryObject", "EntityId", "EntityIdName", "FrontendAppConfig", + "SignalRConnectionInfo", "WhereParam", "WhereParamOperator", "WhereParamValueType", + # download + "DistZipResponse", "DownloadFormat", "DownloadZipRequest", "DownloadZipStatus", + "DynamicImageOperation", "SharedAllowedFormat", "ZipType", + # portal + "Portal", "PortalAuthentication", "PortalAuthMethod", "PortalConfiguration", + "PortalFields", "PortalLinks", "PortalTheme", "PortalUserContext", + # publish + "PublishedAsset", "PublishEntity", + # relation + "AssetRelation", "AssetRelationType", "RelatedAsset", + # search + "AllWebAppData", "AzSearchOptions", "GroupAllAppData", "SavedSearch", + "SearchableItem", "SearchAdminDataSourceStatus", "SearchAdminIndexerLastRun", + "SearchAdminIndexerStatus", "SearchAdminIndexStatus", "SearchAdminSkillStatus", + "SearchAdminStatistics", "SearchAdminStatus", "SearchFacet", "SearchFacetEntity", + "SearchResult", + # secure upload + "SecureUploadEntity", + # sharing + "QuickShareFull", "SharedAsset", "SharedCollectionFull", + # static lists + "StaticDefinedList", + # versioning + "VersionedAsset", "VersionEntity", + # workspace + "Workspace", +] diff --git a/agravity_client/models/asset.py b/agravity_client/models/asset.py new file mode 100644 index 0000000..e6c0791 --- /dev/null +++ b/agravity_client/models/asset.py @@ -0,0 +1,208 @@ +"""Asset-related Pydantic models.""" +from __future__ import annotations + +from enum import Enum +from typing import Any, Optional + +from pydantic import ConfigDict, Field + +from agravity_client.models.common import DictionaryObject, WhereParam, _Base + + +# --------------------------------------------------------------------------- +# Enums +# --------------------------------------------------------------------------- +class AssetBlobType(str, Enum): + unknown = "UNKNOWN" + image = "IMAGE" + video = "VIDEO" + audio = "AUDIO" + document = "DOCUMENT" + text = "TEXT" + other = "OTHER" + + +class AssetBlobOrientation(str, Enum): + portrait = "PORTRAIT" + landscape = "LANDSCAPE" + square = "SQUARE" + + +class AssetRole(str, Enum): + none = "NONE" + viewer = "VIEWER" + editor = "EDITOR" + + +# --------------------------------------------------------------------------- +# AssetBlob +# --------------------------------------------------------------------------- +class AssetBlob(_Base): + blob_type: Optional[AssetBlobType] = AssetBlobType.unknown + name: Optional[str] = None + container: Optional[str] = None + size: Optional[int] = None + extension: Optional[str] = None + content_type: Optional[str] = None + md5: Optional[str] = None + add_data: Optional[dict[str, Any]] = None + + # image metadata + width: Optional[int] = None + height: Optional[int] = None + maxwidthheight: Optional[int] = None + quality: Optional[float] = None + orientation: Optional[AssetBlobOrientation] = AssetBlobOrientation.portrait + colorspace: Optional[str] = None + profile: Optional[str] = None + transparency: Optional[bool] = None + mode: Optional[str] = None + target: Optional[str] = None + filter: Optional[str] = None + dpi_x: Optional[float] = None + dpi_y: Optional[float] = None + perhash: Optional[str] = None + dominantcolor: Optional[str] = None + depth: Optional[int] = None + animated: Optional[bool] = None + + # video metadata + duration: Optional[int] = None + videocodec: Optional[str] = None + videobitrate: Optional[int] = None + fps: Optional[float] = None + colormode: Optional[str] = None + + # audio metadata + audiocodec: Optional[str] = None + audiosamplerate: Optional[str] = None + audiochanneloutput: Optional[str] = None + audiobitrate: Optional[int] = None + + # document metadata + author: Optional[str] = None + title: Optional[str] = None + language: Optional[str] = None + wordcount: Optional[int] = None + pages: Optional[int] = None + encoding_name: Optional[str] = None + encoding_code: Optional[str] = None + + # URL / download info + url: Optional[str] = None + size_readable: Optional[str] = None + downloadable: Optional[bool] = None + expires: Optional[str] = Field(None, description="ISO 8601 date-time string") + uploaded_date: Optional[str] = Field(None, description="ISO 8601 date-time string") + uploaded_by: Optional[str] = None + + +# --------------------------------------------------------------------------- +# AssetCheckout +# --------------------------------------------------------------------------- +class AssetCheckout(_Base): + user_id: Optional[str] = None + checkout_date: Optional[str] = Field(None, description="ISO 8601 date-time string") + + +# --------------------------------------------------------------------------- +# AssetIconRule +# --------------------------------------------------------------------------- +class AssetIconRule(_Base): + id: Optional[str] = None + entity_type: Optional[str] = None + type: Optional[str] = None + path: Optional[str] = None + color: Optional[str] = None + value: Optional[str] = None + icon: Optional[str] = None + operator: Optional[str] = None + translations: Optional[dict[str, DictionaryObject]] = None + name: Optional[str] = None + description: Optional[str] = None + add_properties: Optional[dict[str, Any]] = None + status: Optional[str] = None + created_date: Optional[str] = None + created_by: Optional[str] = None + modified_date: Optional[str] = None + modified_by: Optional[str] = None + pk: Optional[str] = None + etag: Optional[str] = Field(None, alias="_etag") + + model_config = ConfigDict(extra="allow", populate_by_name=True) + + +# --------------------------------------------------------------------------- +# Asset (core entity) +# --------------------------------------------------------------------------- +class Asset(_Base): + id: Optional[str] = None + entity_type: Optional[str] = None + name: Optional[str] = None + asset_type: Optional[str] = None + duplicates: Optional[list[str]] = None + keywords: Optional[list[str]] = None + orig_blob: Optional[AssetBlob] = None + blobs: Optional[list[AssetBlob]] = None + collections: Optional[list[str]] = None + failed_reason: Optional[str] = None + quality_gate: Optional[list[str]] = None + region_of_origin: Optional[str] = None + availability: Optional[str] = None + available_from: Optional[str] = Field(None, description="ISO 8601 date-time string") + available_to: Optional[str] = Field(None, description="ISO 8601 date-time string") + checkout: Optional[AssetCheckout] = None + fs_synced: Optional[bool] = None + custom: Optional[dict[str, Any]] = None + items: Optional[list[Any]] = None # List[CollTypeItem] – to avoid circular import + translations: Optional[dict[str, DictionaryObject]] = None + role: Optional[AssetRole] = AssetRole.none + description: Optional[str] = None + add_properties: Optional[dict[str, Any]] = None + status: Optional[str] = None + created_date: Optional[str] = None + created_by: Optional[str] = None + modified_date: Optional[str] = None + modified_by: Optional[str] = None + pk: Optional[str] = None + etag: Optional[str] = Field(None, alias="_etag") + + model_config = ConfigDict(extra="allow", populate_by_name=True) + + +# --------------------------------------------------------------------------- +# AssetAvailability +# --------------------------------------------------------------------------- +class AssetAvailability(_Base): + availability: Optional[str] = None + available_from: Optional[str] = Field(None, description="ISO 8601 date-time string") + available_to: Optional[str] = Field(None, description="ISO 8601 date-time string") + + +# --------------------------------------------------------------------------- +# AssetBulkUpdate +# --------------------------------------------------------------------------- +class AssetBulkUpdate(_Base): + collection_id: Optional[str] = None + ref_asset: Optional[Asset] = None + asset_ids: Optional[list[str]] = None + + +# --------------------------------------------------------------------------- +# AssetPageResult +# --------------------------------------------------------------------------- +class AssetPageResult(_Base): + page: Optional[list[Asset]] = None + page_size: Optional[int] = None + size: Optional[int] = None + continuation_token: Optional[str] = None + filter: Optional[list[WhereParam]] = None + + +# --------------------------------------------------------------------------- +# AssetIdFormat (used in QuickShareFull) +# --------------------------------------------------------------------------- +class AssetIdFormat(_Base): + id: Optional[str] = None + name: Optional[str] = None + format: Optional[str] = None diff --git a/agravity_client/models/auth.py b/agravity_client/models/auth.py new file mode 100644 index 0000000..b793184 --- /dev/null +++ b/agravity_client/models/auth.py @@ -0,0 +1,58 @@ +"""Auth-related Pydantic models.""" +from __future__ import annotations + +from typing import Optional + +from pydantic import ConfigDict, Field + +from agravity_client.models.common import _Base + + +class AgravityUserOnlineStatus(_Base): + status: Optional[str] = None + last_connection: Optional[str] = Field(None, description="ISO 8601 date-time string") + + +class AgravityUser(_Base): + id: Optional[str] = None + entity_type: Optional[str] = None + name: Optional[str] = None + email: Optional[str] = None + impersonation: Optional[str] = None + apikey: Optional[str] = None + online_status: Optional[AgravityUserOnlineStatus] = None + roles: Optional[list[str]] = None + groups: Optional[list[str]] = None + status: Optional[str] = None + created_date: Optional[str] = None + created_by: Optional[str] = None + modified_date: Optional[str] = None + modified_by: Optional[str] = None + pk: Optional[str] = None + etag: Optional[str] = Field(None, alias="_etag") + + model_config = ConfigDict(extra="allow", populate_by_name=True) + + +class AgravityVersion(_Base): + name: Optional[str] = None + company: Optional[str] = None + customer: Optional[str] = None + contact: Optional[str] = None + updated: Optional[str] = Field(None, description="ISO 8601 date-time string") + client_id: Optional[str] = None + tenant_id: Optional[str] = None + subscription_id: Optional[str] = None + base: Optional[str] = None + version: Optional[str] = None + enabled_features: Optional[list[str]] = None + region: Optional[str] = None + + +class SasToken(_Base): + token: Optional[str] = None + container: Optional[str] = None + blob: Optional[str] = None + url: Optional[str] = None + fulltoken: Optional[str] = None + expires: Optional[str] = Field(None, description="ISO 8601 date-time string") diff --git a/agravity_client/models/collection.py b/agravity_client/models/collection.py new file mode 100644 index 0000000..0ca1862 --- /dev/null +++ b/agravity_client/models/collection.py @@ -0,0 +1,166 @@ +"""Collection-related Pydantic models.""" +from __future__ import annotations + +from enum import Enum +from typing import Any, Optional + +from pydantic import ConfigDict, Field + +from agravity_client.models.common import DictionaryObject, _Base + + +# --------------------------------------------------------------------------- +# Enums +# --------------------------------------------------------------------------- +class PermissionRole(str, Enum): + none = "NONE" + viewer = "VIEWER" + editor = "EDITOR" + + +# --------------------------------------------------------------------------- +# PermissionEntity +# --------------------------------------------------------------------------- +class PermissionEntity(_Base): + id: Optional[str] = None + role: Optional[PermissionRole] = PermissionRole.none + + +# --------------------------------------------------------------------------- +# CollTypeItem +# --------------------------------------------------------------------------- +class CollTypeItem(_Base): + id: Optional[str] = None + entity_type: Optional[str] = None + name: Optional[str] = None + item_type: Optional[str] = None + format: Optional[str] = None + label: Optional[str] = None + default_value: Optional[Any] = None + mandatory: Optional[bool] = None + searchable: Optional[bool] = None + onlyasset: Optional[bool] = None + multi: Optional[bool] = None + md5: Optional[str] = None + group: Optional[str] = None + order: Optional[int] = None + translations: Optional[dict[str, DictionaryObject]] = None + status: Optional[str] = None + created_date: Optional[str] = None + created_by: Optional[str] = None + modified_date: Optional[str] = None + modified_by: Optional[str] = None + pk: Optional[str] = None + etag: Optional[str] = Field(None, alias="_etag") + + model_config = ConfigDict(extra="allow", populate_by_name=True) + + +# --------------------------------------------------------------------------- +# Collection +# --------------------------------------------------------------------------- +class Collection(_Base): + id: Optional[str] = None + entity_type: Optional[str] = None + parent: Optional[str] = None + path: Optional[str] = None + level: Optional[int] = None + custom: Optional[dict[str, Any]] = None + items: Optional[list[CollTypeItem]] = None + translations: Optional[dict[str, DictionaryObject]] = None + role: Optional[PermissionRole] = PermissionRole.none + name: Optional[str] = None + description: Optional[str] = None + add_properties: Optional[dict[str, Any]] = None + status: Optional[str] = None + created_date: Optional[str] = None + created_by: Optional[str] = None + modified_date: Optional[str] = None + modified_by: Optional[str] = None + pk: Optional[str] = None + etag: Optional[str] = Field(None, alias="_etag") + + model_config = ConfigDict(extra="allow", populate_by_name=True) + + +# --------------------------------------------------------------------------- +# CollectionType +# --------------------------------------------------------------------------- +class CollectionType(_Base): + id: Optional[str] = None + entity_type: Optional[str] = None + name: Optional[str] = None + items: Optional[list[CollTypeItem]] = None + translations: Optional[dict[str, DictionaryObject]] = None + order: Optional[int] = None + permissions: Optional[list[PermissionEntity]] = None + permissionless: Optional[bool] = None + role: Optional[PermissionRole] = PermissionRole.none + description: Optional[str] = None + add_properties: Optional[dict[str, Any]] = None + status: Optional[str] = None + created_date: Optional[str] = None + created_by: Optional[str] = None + modified_date: Optional[str] = None + modified_by: Optional[str] = None + pk: Optional[str] = None + etag: Optional[str] = Field(None, alias="_etag") + + model_config = ConfigDict(extra="allow", populate_by_name=True) + + +# --------------------------------------------------------------------------- +# CollectionUDL (user-defined list) +# --------------------------------------------------------------------------- +class CollectionUDL(_Base): + id: Optional[str] = None + pk: Optional[str] = None + name: Optional[str] = None + entity_type: Optional[str] = None + status: Optional[str] = None + translations: Optional[dict[str, DictionaryObject]] = None + children: Optional[list[Any]] = None # List[EntityIdName] + + +class CollectionUDLReference(_Base): + parent: Optional[str] = None + coll_types: Optional[list[str]] = None + permissions: Optional[list[PermissionEntity]] = None + + +class CollectionUDLListEntity(_Base): + id: Optional[str] = None + entity_type: Optional[str] = None + udl_refs: Optional[list[CollectionUDLReference]] = None + udl_entries: Optional[list[CollectionUDL]] = None + status: Optional[str] = None + created_date: Optional[str] = None + created_by: Optional[str] = None + modified_date: Optional[str] = None + modified_by: Optional[str] = None + pk: Optional[str] = None + etag: Optional[str] = Field(None, alias="_etag") + + model_config = ConfigDict(extra="allow", populate_by_name=True) + + +# --------------------------------------------------------------------------- +# EntityNamesRequest / EntityListResult +# --------------------------------------------------------------------------- +class EntityNamesRequest(_Base): + names: Optional[list[str]] = None + filter: Optional[str] = None + + +class EntityListResult(_Base): + entities: Optional[list[Any]] = None # List[EntityIdName] + notfounds: Optional[list[str]] = None + + +# --------------------------------------------------------------------------- +# MoveCollectionBody +# --------------------------------------------------------------------------- +class MoveCollectionBody(_Base): + from_collection_id: Optional[str] = None + to_collection_id: Optional[str] = None + operation: Optional[str] = None diff --git a/agravity_client/models/common.py b/agravity_client/models/common.py new file mode 100644 index 0000000..1a48aca --- /dev/null +++ b/agravity_client/models/common.py @@ -0,0 +1,131 @@ +"""Common / shared Pydantic models for the Agravity API.""" +from __future__ import annotations + +from enum import Enum +from typing import Any, Optional + +from pydantic import BaseModel, ConfigDict, Field + + +# --------------------------------------------------------------------------- +# Shared Config mixin: allow extra fields (the API may return undocumented ones) +# --------------------------------------------------------------------------- +class _Base(BaseModel): + model_config = ConfigDict(extra="allow", populate_by_name=True) + + +# --------------------------------------------------------------------------- +# Error / Info responses +# --------------------------------------------------------------------------- +class AgravityErrorResponse(_Base): + error_id: Optional[str] = None + error_message: Optional[str] = None + exception: Optional[str] = None + + +class AgravityInfoResponse(_Base): + info_id: Optional[str] = None + info_message: Optional[str] = None + info_object: Optional[Any] = None + + +# --------------------------------------------------------------------------- +# Dictionary helper +# --------------------------------------------------------------------------- +class DictionaryObject(_Base): + """A freeform dictionary of key -> any value (used for translations etc.)""" + + model_config = ConfigDict(extra="allow") + + def to_dict(self) -> dict[str, Any]: + return dict(self.model_extra or {}) + + +# --------------------------------------------------------------------------- +# EntityId / EntityIdName +# --------------------------------------------------------------------------- +class EntityId(_Base): + id: Optional[str] = None + pk: Optional[str] = None + + +class EntityIdName(_Base): + id: Optional[str] = None + pk: Optional[str] = None + name: Optional[str] = None + entity_type: Optional[str] = None + status: Optional[str] = None + translations: Optional[dict[str, DictionaryObject]] = None + + +# --------------------------------------------------------------------------- +# Frontend config +# --------------------------------------------------------------------------- +class FrontendAppConfig(_Base): + key: Optional[str] = None + value: Optional[str] = None + description: Optional[str] = None + contentType: Optional[str] = None + sinceApiVersion: Optional[str] = None + + +# --------------------------------------------------------------------------- +# SignalR +# --------------------------------------------------------------------------- +class SignalRConnectionInfo(_Base): + url: Optional[str] = None + accessToken: Optional[str] = None + + +# --------------------------------------------------------------------------- +# Deleted Entities +# --------------------------------------------------------------------------- +class DeletedEntities(_Base): + id: Optional[str] = None + name: Optional[str] = None + deleted: Optional[str] = Field(None, description="ISO 8601 date-time string") + entity_type: Optional[str] = None + + +# --------------------------------------------------------------------------- +# DataResult (search sub-model) +# --------------------------------------------------------------------------- +class DataResult(_Base): + asset: Optional[list[Any]] = None # List[Asset] – forward ref resolved later + sum_asset_results: Optional[int] = None + collection: Optional[list[Any]] = None # List[Collection] + sum_collection_results: Optional[int] = None + + +# --------------------------------------------------------------------------- +# WhereParam (filter parameter in AssetPageResult) +# --------------------------------------------------------------------------- +class WhereParamOperator(str, Enum): + equals = "Equals" + not_equals = "NotEquals" + greater_than = "GreaterThan" + less_than = "LessThan" + greater_than_or_equal = "GreaterThanOrEqual" + less_than_or_equal = "LessThanOrEqual" + contains = "Contains" + starts_with = "StartsWith" + array_contains = "ArrayContains" + array_contains_partial = "ArrayContainsPartial" + is_defined = "IsDefined" + is_not_defined = "IsNotDefined" + is_empty = "IsEmpty" + is_not_empty = "IsNotEmpty" + + +class WhereParamValueType(str, Enum): + string = "String" + bool = "Bool" + number = "Number" + + +class WhereParam(_Base): + operator: Optional[WhereParamOperator] = WhereParamOperator.equals + field: Optional[str] = None + value: Optional[Any] = None + notPrefix: Optional[bool] = None + valueType: Optional[WhereParamValueType] = WhereParamValueType.string diff --git a/agravity_client/models/download.py b/agravity_client/models/download.py new file mode 100644 index 0000000..4e29a25 --- /dev/null +++ b/agravity_client/models/download.py @@ -0,0 +1,104 @@ +"""Download-format and ZIP-related Pydantic models.""" +from __future__ import annotations + +from enum import Enum +from typing import Any, Optional + +from pydantic import ConfigDict, Field + +from agravity_client.models.common import DictionaryObject, _Base +from agravity_client.models.collection import PermissionEntity + + +# --------------------------------------------------------------------------- +# Enums +# --------------------------------------------------------------------------- +class ZipType(str, Enum): + download = "DOWNLOAD" + shared = "SHARED" + quickshare = "QUICKSHARE" + portal = "PORTAL" + + +# --------------------------------------------------------------------------- +# DynamicImageOperation +# --------------------------------------------------------------------------- +class DynamicImageOperation(_Base): + operation: Optional[str] = None + params: Optional[list[Any]] = None + + +# --------------------------------------------------------------------------- +# SharedAllowedFormat +# --------------------------------------------------------------------------- +class SharedAllowedFormat(_Base): + asset_type: Optional[str] = None + format: Optional[str] = None + + +# --------------------------------------------------------------------------- +# DownloadFormat +# --------------------------------------------------------------------------- +class DownloadFormat(_Base): + id: Optional[str] = None + entity_type: Optional[str] = None + operations: Optional[list[DynamicImageOperation]] = None + extension: Optional[str] = None + asset_type: Optional[str] = None + origin: Optional[str] = None + fallback_thumb: Optional[bool] = None + target_filename: Optional[str] = None + translations: Optional[dict[str, DictionaryObject]] = None + permissions: Optional[list[PermissionEntity]] = None + name: Optional[str] = None + description: Optional[str] = None + add_properties: Optional[dict[str, Any]] = None + status: Optional[str] = None + created_date: Optional[str] = None + created_by: Optional[str] = None + modified_date: Optional[str] = None + modified_by: Optional[str] = None + pk: Optional[str] = None + etag: Optional[str] = Field(None, alias="_etag") + + model_config = ConfigDict(extra="allow", populate_by_name=True) + + +# --------------------------------------------------------------------------- +# DownloadZipRequest +# --------------------------------------------------------------------------- +class DownloadZipRequest(_Base): + id: Optional[str] = None + zip_type: Optional[ZipType] = ZipType.download + asset_ids: Optional[list[str]] = None + allowed_formats: Optional[list[SharedAllowedFormat]] = None + zipname: Optional[str] = None + email_to: Optional[list[str]] = None + message: Optional[str] = None + valid_until: Optional[str] = Field(None, description="ISO 8601 date-time string") + + +# --------------------------------------------------------------------------- +# DownloadZipStatus +# --------------------------------------------------------------------------- +class DownloadZipStatus(_Base): + id: Optional[str] = None + user: Optional[str] = None + percent: Optional[float] = None + part: Optional[float] = None + count: Optional[int] = None + message: Optional[str] = None + status: Optional[str] = None + zip_type: Optional[ZipType] = ZipType.download + zipname: Optional[str] = None + size: Optional[str] = None + url: Optional[str] = None + + +# --------------------------------------------------------------------------- +# DistZipResponse (used in GroupAllAppData) +# --------------------------------------------------------------------------- +class DistZipResponse(_Base): + url: Optional[str] = None + modified_date: Optional[str] = Field(None, description="ISO 8601 date-time string") + size: Optional[int] = None diff --git a/agravity_client/models/portal.py b/agravity_client/models/portal.py new file mode 100644 index 0000000..17f2655 --- /dev/null +++ b/agravity_client/models/portal.py @@ -0,0 +1,175 @@ +"""Portal-related Pydantic models.""" +from __future__ import annotations + +from enum import Enum +from typing import Any, Optional + +from pydantic import ConfigDict, Field + +from agravity_client.models.collection import CollTypeItem, PermissionEntity +from agravity_client.models.common import DictionaryObject, FrontendAppConfig, _Base +from agravity_client.models.download import SharedAllowedFormat +from agravity_client.models.asset import AssetIconRule +from agravity_client.models.static_lists import StaticDefinedList +from agravity_client.models.collection import CollectionUDL + + +# --------------------------------------------------------------------------- +# Enums +# --------------------------------------------------------------------------- +class PortalAuthMethod(str, Enum): + undefined = "UNDEFINED" + none = "NONE" + password = "PASSWORD" + eeid = "EEID" + auth0 = "AUTH0" + + +# --------------------------------------------------------------------------- +# PortalAuthentication +# --------------------------------------------------------------------------- +class PortalAuthentication(_Base): + method: Optional[PortalAuthMethod] = PortalAuthMethod.undefined + issuer: Optional[str] = None + client_id: Optional[str] = None + tenant_id: Optional[str] = None + password: Optional[str] = None + + +# --------------------------------------------------------------------------- +# PortalUserContext +# --------------------------------------------------------------------------- +class PortalUserContext(_Base): + key: Optional[str] = None + mandatory: Optional[bool] = None + mapping: Optional[dict[str, str]] = None + options: Optional[list[str]] = None + + +# --------------------------------------------------------------------------- +# PortalFields +# --------------------------------------------------------------------------- +class PortalFields(_Base): + name: Optional[str] = None + detail_order: Optional[int] = None + facet_order: Optional[int] = None + labels: Optional[dict[str, str]] = None + user_context: Optional[PortalUserContext] = None + format: Optional[str] = None + + +# --------------------------------------------------------------------------- +# PortalLinks +# --------------------------------------------------------------------------- +class PortalLinks(_Base): + conditions: Optional[str] = None + privacy: Optional[str] = None + impressum: Optional[str] = None + + +# --------------------------------------------------------------------------- +# PortalTheme +# --------------------------------------------------------------------------- +class PortalTheme(_Base): + logo_url: Optional[str] = None + topbar_color: Optional[str] = None + background_url: Optional[str] = None + fav_icon: Optional[str] = None + icon_empty: Optional[str] = None + icon_active: Optional[str] = None + colors: Optional[dict[str, Any]] = None + + +# --------------------------------------------------------------------------- +# Portal (base entity) +# --------------------------------------------------------------------------- +class _PortalBase(_Base): + """Shared fields between Portal and PortalConfiguration.""" + + id: Optional[str] = None + entity_type: Optional[str] = None + authentication: Optional[PortalAuthentication] = None + languages: Optional[str] = None + fields: Optional[list[PortalFields]] = None + filter: Optional[str] = None + limit_ids: Optional[list[str]] = None + allowed_formats: Optional[list[SharedAllowedFormat]] = None + asset_icon_rules: Optional[list[AssetIconRule]] = None + allowed_origins: Optional[list[str]] = None + links: Optional[PortalLinks] = None + theme: Optional[PortalTheme] = None + name: Optional[str] = None + description: Optional[str] = None + add_properties: Optional[dict[str, Any]] = None + status: Optional[str] = None + created_date: Optional[str] = None + created_by: Optional[str] = None + modified_date: Optional[str] = None + modified_by: Optional[str] = None + pk: Optional[str] = None + etag: Optional[str] = Field(None, alias="_etag") + + model_config = ConfigDict(extra="allow", populate_by_name=True) + + +class Portal(_PortalBase): + pass + + +# --------------------------------------------------------------------------- +# PortalConfiguration (extends Portal with full config data) +# --------------------------------------------------------------------------- +class PortalConfiguration(_PortalBase): + download_formats: Optional[list[Any]] = None # List[DownloadFormat] + sdls: Optional[list[StaticDefinedList]] = None + udls: Optional[list[CollectionUDL]] = None + items: Optional[list[CollTypeItem]] = None + configs: Optional[list[FrontendAppConfig]] = None + + +# --------------------------------------------------------------------------- +# Custom claims provider response models (token issuance / attribute collection) +# --------------------------------------------------------------------------- +class CustomClaimsProviderClaims(_Base): + userContext: Optional[list[str]] = None + role: Optional[str] = None + + +class CustomClaimsProviderActionTokenIssuanceStart(_Base): + claims: Optional[CustomClaimsProviderClaims] = None + odata_type: Optional[str] = Field(None, alias="@odata.type") + model_config = ConfigDict(extra="allow", populate_by_name=True) + + +class CustomClaimsProviderActionAttributeCollectionSubmit(_Base): + odata_type: Optional[str] = Field(None, alias="@odata.type") + model_config = ConfigDict(extra="allow", populate_by_name=True) + + +class CustomClaimsProviderDataTokenIssuanceStart(_Base): + actions: Optional[list[CustomClaimsProviderActionTokenIssuanceStart]] = None + odata_type: Optional[str] = Field(None, alias="@odata.type") + model_config = ConfigDict(extra="allow", populate_by_name=True) + + +class CustomClaimsProviderDataAttributeCollectionSubmit(_Base): + actions: Optional[list[CustomClaimsProviderActionAttributeCollectionSubmit]] = None + odata_type: Optional[str] = Field(None, alias="@odata.type") + model_config = ConfigDict(extra="allow", populate_by_name=True) + + +class CustomClaimsProviderResponseContentTokenIssuanceStart(_Base): + data: Optional[CustomClaimsProviderDataTokenIssuanceStart] = None + + +class CustomClaimsProviderResponseContentAttributeCollectionSubmit(_Base): + data: Optional[CustomClaimsProviderDataAttributeCollectionSubmit] = None + + +# Convenience alias used by the API client +from typing import Union as _Union # noqa: E402 + +CustomClaimsProviderResponse = _Union[ + CustomClaimsProviderResponseContentTokenIssuanceStart, + CustomClaimsProviderResponseContentAttributeCollectionSubmit, +] diff --git a/agravity_client/models/publish.py b/agravity_client/models/publish.py new file mode 100644 index 0000000..fde2dc6 --- /dev/null +++ b/agravity_client/models/publish.py @@ -0,0 +1,39 @@ +"""Publish-related Pydantic models.""" +from __future__ import annotations + +from typing import Any, Optional + +from pydantic import ConfigDict, Field + +from agravity_client.models.common import _Base + + +class PublishedAsset(_Base): + id: Optional[str] = None + name: Optional[str] = None + target: Optional[str] = None + description: Optional[str] = None + usecases: Optional[list[str]] = None + created_date: Optional[str] = None + created_by: Optional[str] = None + url: Optional[str] = None + cdn: Optional[str] = None + status_table_id: Optional[str] = None + format: Optional[str] = None + properties: Optional[dict[str, Any]] = None + + +class PublishEntity(_Base): + id: Optional[str] = None + entity_type: Optional[str] = None + published: Optional[list[PublishedAsset]] = None + region_of_origin: Optional[str] = None + status: Optional[str] = None + created_date: Optional[str] = None + created_by: Optional[str] = None + modified_date: Optional[str] = None + modified_by: Optional[str] = None + pk: Optional[str] = None + etag: Optional[str] = Field(None, alias="_etag") + + model_config = ConfigDict(extra="allow", populate_by_name=True) diff --git a/agravity_client/models/relation.py b/agravity_client/models/relation.py new file mode 100644 index 0000000..3283df1 --- /dev/null +++ b/agravity_client/models/relation.py @@ -0,0 +1,51 @@ +"""Asset relation Pydantic models.""" +from __future__ import annotations + +from typing import Any, Optional + +from pydantic import ConfigDict, Field + +from agravity_client.models.collection import PermissionEntity +from agravity_client.models.common import DictionaryObject, _Base + + +class RelatedAsset(_Base): + id: Optional[str] = None + parent: Optional[bool] = None + + +class AssetRelation(_Base): + id: Optional[str] = None + entity_type: Optional[str] = None + assets: Optional[list[RelatedAsset]] = None + status: Optional[str] = None + created_date: Optional[str] = None + created_by: Optional[str] = None + modified_date: Optional[str] = None + modified_by: Optional[str] = None + pk: Optional[str] = None + etag: Optional[str] = Field(None, alias="_etag") + + model_config = ConfigDict(extra="allow", populate_by_name=True) + + +class AssetRelationType(_Base): + id: Optional[str] = None + entity_type: Optional[str] = None + hierarchical: Optional[bool] = None + sequential: Optional[bool] = None + unique_per_asset: Optional[bool] = None + translations: Optional[dict[str, DictionaryObject]] = None + permissions: Optional[list[PermissionEntity]] = None + name: Optional[str] = None + description: Optional[str] = None + add_properties: Optional[dict[str, Any]] = None + status: Optional[str] = None + created_date: Optional[str] = None + created_by: Optional[str] = None + modified_date: Optional[str] = None + modified_by: Optional[str] = None + pk: Optional[str] = None + etag: Optional[str] = Field(None, alias="_etag") + + model_config = ConfigDict(extra="allow", populate_by_name=True) diff --git a/agravity_client/models/search.py b/agravity_client/models/search.py new file mode 100644 index 0000000..ff6ffc0 --- /dev/null +++ b/agravity_client/models/search.py @@ -0,0 +1,172 @@ +"""Search-related Pydantic models (includes web-app data and saved searches).""" +from __future__ import annotations + +from typing import Any, Optional + +from pydantic import ConfigDict, Field + +from agravity_client.models.asset import Asset +from agravity_client.models.collection import Collection, CollectionType +from agravity_client.models.common import DictionaryObject, _Base +from agravity_client.models.download import DistZipResponse +from agravity_client.models.publish import PublishedAsset + + +# --------------------------------------------------------------------------- +# AzSearchOptions +# --------------------------------------------------------------------------- +class AzSearchOptions(_Base): + searchString: Optional[str] = None + limit: Optional[int] = None + skip: Optional[int] = None + collectiontypeid: Optional[str] = None + collectionid: Optional[str] = None + filter: Optional[str] = None + orderby: Optional[str] = None + mode: Optional[str] = None + broadness: Optional[int] = None + rel_id: Optional[str] = None + ids: Optional[str] = None + portal_id: Optional[str] = None + scopefilter: Optional[str] = None + + +# --------------------------------------------------------------------------- +# SearchFacet +# --------------------------------------------------------------------------- +class SearchFacetEntity(_Base): + count: Optional[int] = None + value: Optional[str] = None + name: Optional[str] = None + + +class SearchFacet(_Base): + name: Optional[str] = None + entities: Optional[list[SearchFacetEntity]] = None + + +# --------------------------------------------------------------------------- +# DataResult → SearchResult +# --------------------------------------------------------------------------- +class _DataResult(_Base): + asset: Optional[list[Asset]] = None + sum_asset_results: Optional[int] = None + collection: Optional[list[Collection]] = None + sum_collection_results: Optional[int] = None + + +class SearchResult(_Base): + data_result: Optional[_DataResult] = None + options: Optional[AzSearchOptions] = None + facets: Optional[list[SearchFacet]] = None + count: Optional[int] = None + + +# --------------------------------------------------------------------------- +# SearchableItem +# --------------------------------------------------------------------------- +class SearchableItem(_Base): + name: Optional[str] = None + is_key: Optional[bool] = None + filterable: Optional[bool] = None + hidden: Optional[bool] = None + searchable: Optional[bool] = None + facetable: Optional[bool] = None + sortable: Optional[bool] = None + is_collection: Optional[bool] = None + searchtype: Optional[str] = None + fields: Optional[list["SearchableItem"]] = None + + +# --------------------------------------------------------------------------- +# SearchAdmin* models +# --------------------------------------------------------------------------- +class SearchAdminStatistics(_Base): + documentcount: Optional[int] = None + storagesizebytes: Optional[int] = None + + +class SearchAdminIndexStatus(_Base): + name: Optional[str] = None + status: Optional[str] = None + statistics: Optional[SearchAdminStatistics] = None + + +class SearchAdminIndexerLastRun(_Base): + status: Optional[str] = None + starttime: Optional[str] = None + endtime: Optional[str] = None + itemcount: Optional[int] = None + faileditemcount: Optional[int] = None + + +class SearchAdminIndexerStatus(_Base): + name: Optional[str] = None + status: Optional[str] = None + error: Optional[str] = None + lastrun: Optional[SearchAdminIndexerLastRun] = None + history: Optional[list[SearchAdminIndexerLastRun]] = None + + +class SearchAdminDataSourceStatus(_Base): + name: Optional[str] = None + status: Optional[str] = None + + +class SearchAdminSkillStatus(_Base): + name: Optional[str] = None + skills: Optional[list[str]] = None + + +class SearchAdminStatus(_Base): + index: Optional[SearchAdminIndexStatus] = None + indexer: Optional[SearchAdminIndexerStatus] = None + datasource: Optional[SearchAdminDataSourceStatus] = None + skillsets: Optional[list[SearchAdminSkillStatus]] = None + + +# --------------------------------------------------------------------------- +# SavedSearch +# --------------------------------------------------------------------------- +class SavedSearch(_Base): + id: Optional[str] = None + entity_type: Optional[str] = None + searchstring: Optional[str] = None + external: Optional[bool] = None + translations: Optional[dict[str, DictionaryObject]] = None + name: Optional[str] = None + description: Optional[str] = None + add_properties: Optional[dict[str, Any]] = None + status: Optional[str] = None + created_date: Optional[str] = None + created_by: Optional[str] = None + modified_date: Optional[str] = None + modified_by: Optional[str] = None + pk: Optional[str] = None + etag: Optional[str] = Field(None, alias="_etag") + + model_config = ConfigDict(extra="allow", populate_by_name=True) + + +# --------------------------------------------------------------------------- +# Web App Data +# --------------------------------------------------------------------------- +class AllWebAppData(_Base): + root_collection: Optional[Collection] = None + subcollections: Optional[list[Collection]] = None + assets: Optional[list[Asset]] = None + pub_assets: Optional[list[PublishedAsset]] = None + created_date: Optional[str] = None + + +class KeyValuePairObject(_Base): + model_config = ConfigDict(extra="allow") + + +class GroupAllAppData(_Base): + collection_type: Optional[CollectionType] = None + collections: Optional[list[Collection]] = None + assets: Optional[list[Asset]] = None + created_date: Optional[str] = None + add_info: Optional[list[KeyValuePairObject]] = None + dist: Optional[DistZipResponse] = None diff --git a/agravity_client/models/secure_upload.py b/agravity_client/models/secure_upload.py new file mode 100644 index 0000000..285dd98 --- /dev/null +++ b/agravity_client/models/secure_upload.py @@ -0,0 +1,35 @@ +"""Secure Upload Pydantic model.""" +from __future__ import annotations + +from typing import Optional + +from pydantic import ConfigDict, Field + +from agravity_client.models.common import _Base + + +class CreateSftpUserResult(_Base): + url: Optional[str] = None + password: Optional[str] = None + + +class SecureUploadEntity(_Base): + id: Optional[str] = None + entity_type: Optional[str] = None + collection_id: Optional[str] = None + url: Optional[str] = None + valid_until: Optional[str] = Field(None, description="ISO 8601 date-time string") + password: Optional[str] = None + asset_tags: Optional[list[str]] = None + message: Optional[str] = None + sftp_connection: Optional[CreateSftpUserResult] = None + check_name_for_version: Optional[bool] = None + status: Optional[str] = None + created_date: Optional[str] = None + created_by: Optional[str] = None + modified_date: Optional[str] = None + modified_by: Optional[str] = None + pk: Optional[str] = None + etag: Optional[str] = Field(None, alias="_etag") + + model_config = ConfigDict(extra="allow", populate_by_name=True) diff --git a/agravity_client/models/sharing.py b/agravity_client/models/sharing.py new file mode 100644 index 0000000..8605df2 --- /dev/null +++ b/agravity_client/models/sharing.py @@ -0,0 +1,71 @@ +"""Sharing-related Pydantic models (shared collections and quick shares).""" +from __future__ import annotations + +from typing import Any, Optional + +from pydantic import ConfigDict, Field + +from agravity_client.models.asset import AssetBlob, AssetIdFormat +from agravity_client.models.common import EntityId, _Base +from agravity_client.models.download import SharedAllowedFormat + + +class SharedAsset(_Base): + id: Optional[str] = None + name: Optional[str] = None + description: Optional[str] = None + created_date: Optional[str] = None + modified_date: Optional[str] = None + asset_type: Optional[str] = None + orig_blob: Optional[AssetBlob] = None + blobs: Optional[list[AssetBlob]] = None + + +class SharedCollectionFull(_Base): + page: Optional[list[SharedAsset]] = None + page_size: Optional[int] = None + size: Optional[int] = None + continuation_token: Optional[str] = None + id: Optional[str] = None + entity_type: Optional[str] = None + collection_id: Optional[str] = None + url: Optional[str] = None + valid_until: Optional[str] = Field(None, description="ISO 8601 date-time string") + valid_for: Optional[str] = None + message: Optional[str] = None + global_: Optional[bool] = Field(None, alias="global") + allowed_formats: Optional[list[SharedAllowedFormat]] = None + password: Optional[str] = None + status: Optional[str] = None + created_date: Optional[str] = None + created_by: Optional[str] = None + modified_date: Optional[str] = None + modified_by: Optional[str] = None + pk: Optional[str] = None + etag: Optional[str] = Field(None, alias="_etag") + + model_config = ConfigDict(extra="allow", populate_by_name=True) + + +class QuickShareFull(_Base): + page: Optional[list[SharedAsset]] = None + page_size: Optional[int] = None + size: Optional[int] = None + continuation_token: Optional[str] = None + id: Optional[str] = None + entity_type: Optional[str] = None + name: Optional[str] = None + assets: Optional[list[AssetIdFormat]] = None + users: Optional[list[EntityId]] = None + expires: Optional[str] = Field(None, description="ISO 8601 date-time string") + url: Optional[str] = None + zip_url: Optional[str] = None + status: Optional[str] = None + created_date: Optional[str] = None + created_by: Optional[str] = None + modified_date: Optional[str] = None + modified_by: Optional[str] = None + pk: Optional[str] = None + etag: Optional[str] = Field(None, alias="_etag") + + model_config = ConfigDict(extra="allow", populate_by_name=True) diff --git a/agravity_client/models/static_lists.py b/agravity_client/models/static_lists.py new file mode 100644 index 0000000..8b906b9 --- /dev/null +++ b/agravity_client/models/static_lists.py @@ -0,0 +1,27 @@ +"""Static Defined List Pydantic model.""" +from __future__ import annotations + +from typing import Any, Optional + +from pydantic import ConfigDict, Field + +from agravity_client.models.common import DictionaryObject, _Base + + +class StaticDefinedList(_Base): + id: Optional[str] = None + entity_type: Optional[str] = None + translations: Optional[dict[str, DictionaryObject]] = None + values: Optional[list[str]] = None + name: Optional[str] = None + description: Optional[str] = None + add_properties: Optional[dict[str, Any]] = None + status: Optional[str] = None + created_date: Optional[str] = None + created_by: Optional[str] = None + modified_date: Optional[str] = None + modified_by: Optional[str] = None + pk: Optional[str] = None + etag: Optional[str] = Field(None, alias="_etag") + + model_config = ConfigDict(extra="allow", populate_by_name=True) diff --git a/agravity_client/models/versioning.py b/agravity_client/models/versioning.py new file mode 100644 index 0000000..6a67e88 --- /dev/null +++ b/agravity_client/models/versioning.py @@ -0,0 +1,36 @@ +"""Asset versioning Pydantic models.""" +from __future__ import annotations + +from typing import Optional + +from pydantic import ConfigDict, Field + +from agravity_client.models.asset import AssetBlob +from agravity_client.models.common import _Base + + +class VersionedAsset(_Base): + version_nr: Optional[int] = None + until_date: Optional[str] = Field(None, description="ISO 8601 date-time string") + version_info: Optional[str] = None + created_date: Optional[str] = None + created_by: Optional[str] = None + blob_data: Optional[AssetBlob] = None + blob_uploaded: Optional[str] = Field(None, description="ISO 8601 date-time string") + mime_type: Optional[str] = None + + +class VersionEntity(_Base): + id: Optional[str] = None + entity_type: Optional[str] = None + versions: Optional[list[VersionedAsset]] = None + region_of_origin: Optional[str] = None + status: Optional[str] = None + created_date: Optional[str] = None + created_by: Optional[str] = None + modified_date: Optional[str] = None + modified_by: Optional[str] = None + pk: Optional[str] = None + etag: Optional[str] = Field(None, alias="_etag") + + model_config = ConfigDict(extra="allow", populate_by_name=True) diff --git a/agravity_client/models/workspace.py b/agravity_client/models/workspace.py new file mode 100644 index 0000000..89e7949 --- /dev/null +++ b/agravity_client/models/workspace.py @@ -0,0 +1,30 @@ +"""Workspace Pydantic model.""" +from __future__ import annotations + +from typing import Any, Optional + +from pydantic import ConfigDict, Field + +from agravity_client.models.collection import CollectionType, PermissionEntity +from agravity_client.models.common import DictionaryObject, _Base + + +class Workspace(_Base): + id: Optional[str] = None + entity_type: Optional[str] = None + name: Optional[str] = None + collection_types: Optional[list[CollectionType]] = None + translations: Optional[dict[str, DictionaryObject]] = None + order: Optional[int] = None + permissions: Optional[list[PermissionEntity]] = None + description: Optional[str] = None + add_properties: Optional[dict[str, Any]] = None + status: Optional[str] = None + created_date: Optional[str] = None + created_by: Optional[str] = None + modified_date: Optional[str] = None + modified_by: Optional[str] = None + pk: Optional[str] = None + etag: Optional[str] = Field(None, alias="_etag") + + model_config = ConfigDict(extra="allow", populate_by_name=True) diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..b39df68 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,70 @@ +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[project] +name = "agravity-client" +version = "0.1.0" +description = "Pythonic, Pydantic-driven async REST client for the Agravity DAM API (v10.3.0)." +readme = "README.md" +requires-python = ">=3.10" +license = { text = "MIT" } +keywords = ["agravity", "dam", "rest", "api", "client", "pydantic", "httpx"] +classifiers = [ + "Development Status :: 3 - Alpha", + "Intended Audience :: Developers", + "License :: OSI Approved :: MIT License", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Topic :: Software Development :: Libraries :: Python Modules", + "Typing :: Typed", +] +dependencies = [ + "httpx>=0.27", + "pydantic>=2.6", + "pydantic-settings>=2.2", +] + +[project.optional-dependencies] +dev = [ + "pytest>=8.1", + "pytest-asyncio>=0.23", + "pytest-httpx>=0.30", + "ruff>=0.4", + "mypy>=1.10", +] + +[tool.hatch.build.targets.wheel] +packages = ["agravity_client"] + +# --------------------------------------------------------------------------- +# Ruff +# --------------------------------------------------------------------------- +[tool.ruff] +target-version = "py310" +line-length = 100 + +[tool.ruff.lint] +select = ["E", "F", "I", "N", "UP", "ANN", "B", "C4", "T20"] +ignore = [ + "ANN101", # missing type annotation for self + "ANN102", # missing type annotation for cls + "ANN401", # Dynamically typed expressions (Any) are disallowed +] + +# --------------------------------------------------------------------------- +# mypy +# --------------------------------------------------------------------------- +[tool.mypy] +python_version = "3.10" +strict = true +ignore_missing_imports = true + +# --------------------------------------------------------------------------- +# pytest +# --------------------------------------------------------------------------- +[tool.pytest.ini_options] +asyncio_mode = "auto" +testpaths = ["tests"] diff --git a/swagger.json b/swagger.json new file mode 100644 index 0000000..5f5852a --- /dev/null +++ b/swagger.json @@ -0,0 +1,8501 @@ +{ + "swagger": "2.0", + "info": { + "title": "Agravity OpenAPI Documentation - Public Functions", + "description": "

The Agravity Public API provides comprehensive access to digital asset management functionality for technical integrations, portals, and third-party applications. These endpoints are designed for programmatic access with API key authentication.


Access & Security


API key is required to access these endpoints.

Core Features & Operations

Available Endpoints by Category

Typical Use Cases

Key Capabilities

Authentication & Authorization

All endpoints (except public share endpoints) require API key authentication. The API key can be provided:

Portal endpoints may have additional authentication methods (OAuth, Azure AD, Auth0, password) depending on portal configuration.

Support

For technical support or integration questions, contact support@agravity.io or visit https://agravity.io.


Copyright © Agravity GmbH 2026. All Rights Reserved

", + "contact": { + "name": "Agravity GmbH", + "url": "https://agravity.io", + "email": "support@agravity.io" + }, + "version": "10.3.0" + }, + "host": "devagravitypublic.azurewebsites.net", + "basePath": "/api", + "schemes": [ + "https" + ], + "paths": { + "/portals/{id}": { + "get": { + "tags": [ + "Public Portal Management" + ], + "description": "This endpoint return the created portal by ID.", + "operationId": "HttpPortalsGetById", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the portal.", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "Returns on portal from database.", + "schema": { + "$ref": "#/definitions/portal" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/portals/{id}/config": { + "get": { + "tags": [ + "Public Portal Management" + ], + "description": "This endpoint returns a full configuration of the portal. Incl. download formats, SDLs, UDLs, etc.", + "operationId": "HttpPortalsConfigurationGetById", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the portal.", + "required": true, + "type": "string" + }, + { + "in": "query", + "name": "translations", + "description": "When default language should be returned and the translation dictionary is delivered. (Ignores the \"Accept-Language\" header)", + "type": "boolean" + }, + { + "in": "header", + "name": "Accept-Language", + "description": "The requested language of the response. If not matching it falls back to default language.", + "type": "string" + } + ], + "responses": { + "200": { + "description": "Returns a full configuration of a portal.", + "schema": { + "$ref": "#/definitions/portalConfiguration" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/portalsenhancetoken": { + "post": { + "tags": [ + "Public Portal Management" + ], + "description": "This endpoint saves the portal user and returns CustomClaimsProviderResponseContentTokenIssuanceStart which is used to enhance the token with user context,...", + "operationId": "HttpPortalsEnhanceToken", + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Returns CustomClaimsProviderResponseContentTokenIssuanceStart.", + "schema": { + "$ref": "#/definitions/customClaimsProviderResponseContentTokenIssuanceStart" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/portalssaveuserattributes": { + "post": { + "tags": [ + "Public Portal Management" + ], + "description": "This endpoint saves the portal user attributes", + "operationId": "HttpPortalsSavePortalUserAttributes", + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Returns CustomClaimsProviderResponseContentAttributeCollectionSubmit", + "schema": { + "$ref": "#/definitions/customClaimsProviderResponseContentAttributeCollectionSubmit" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/portals/{id}/zip": { + "post": { + "tags": [ + "Public Portal Management" + ], + "description": "Initiates the ZIP creation of an asset basket from an portal.", + "operationId": "HttpPortalRequestZipById", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the portal.", + "required": true, + "type": "string" + }, + { + "in": "body", + "name": "body", + "description": "The allowed formats are the input which could be added.", + "required": true, + "schema": { + "$ref": "#/definitions/downloadZipRequest" + } + } + ], + "responses": { + "201": { + "description": "Returns the portal with the given ID.", + "schema": { + "$ref": "#/definitions/downloadZipRequest" + } + }, + "400": { + "description": "Not valid portal id! (Code: 00b410fe-97d1-4952-ba0b-327d22514934)
Object is not a valid DownloadZipRequest. (Code: a51d1697-f56e-4fa3-bde8-3ab44e6cbb0a)
No allowed formats are given! (Code: 684df4b1-e0c5-4b07-8c81-cb9835e0bd00)
No asset ids are given! (Code: e8361816-fcc9-48b9-99d4-2133dfed7721)
Not all asset ids are valid! (Code: 0619480f-fa10-4c45-a60d-cb269d8be7b4)
Portal not found in database! (Code: 50a49113-cbcf-470c-ab8c-098dcd23cd0f)
Not all allowed formats are in the portal allowed formats! (Code: c679981e-fbaa-4941-90aa-3b99b1d5a748)
Not all asset ids are valid for this portal! (Code: 01e22b3a-13f9-4d5a-a777-2c69ce7b5b05)
No matching allowed formats for requested assets. (Code: bd27176f-9a4d-44ac-9055-9359b405558e)
Not all asset types have an allowed format in this request! (Code: 2289c7b1-0351-4815-b280-ce4628bdb3dd)
Error on upsert zipRequest in database - max retry count is reached. (Code:7a627b8f-11f8-4bbb-bcbd-9f6f5726557a)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "404": { + "description": "Portal not found. (Code: 87d09a21-14d6-4da4-ab69-01e6c87f108c)
", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/portals/{id}/zip/{zipId}": { + "get": { + "tags": [ + "Public Portal Management" + ], + "description": "This endpoint gets the progress/status of the ZIP creation of a portal.", + "operationId": "HttpPortalGetStatusZipById", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the zip request collection.", + "required": true, + "type": "string" + }, + { + "in": "path", + "name": "zipId", + "description": "The ID of the requested zip.", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "Returns the zip request for a portal with the given ID.", + "schema": { + "$ref": "#/definitions/downloadZipStatus" + } + }, + "400": { + "description": "Not valid zip request id! (Code: 15331af9-82d6-41ba-a015-47c23f864eec)
Zip request is no longer available! (Code: 18b7b4aa-6b4a-4da4-b8b3-c7ab1381e28c)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/portals/{id}/assetids": { + "get": { + "tags": [ + "Public Portal Management" + ], + "description": "This endpoint gets all Asset IDs in portal scope.", + "operationId": "HttpPortalGetAllAssetIdsById", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the portal.", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "Returns all Asset IDs in scope of the portal.", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "400": { + "description": "Portal ID is mandatory and not valid. (Code: f2817cb8-8573-4205-b45d-1b9a7f3d8cbb)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "404": { + "description": "The requested item could not be found." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/ai/reverseassetsearch": { + "post": { + "tags": [ + "Public AI Operations" + ], + "description": "This endpoint allows to use one asset which is used for searching similar assets.", + "operationId": "HttpReverseAssetSearch", + "consumes": [ + "multipart/form-data" + ], + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "header", + "name": "Accept-Language", + "description": "The requested language of the response. If not matching it falls back to default language.", + "type": "string" + }, + { + "name": "name", + "description": "", + "type": "string", + "in": "formData" + }, + { + "name": "collectionid", + "description": "", + "type": "string", + "in": "formData" + }, + { + "name": "file", + "description": "", + "type": "file", + "in": "formData" + }, + { + "name": "filename", + "description": "", + "type": "string", + "in": "formData" + }, + { + "name": "previewof", + "description": "", + "type": "string", + "in": "formData" + } + ], + "responses": { + "200": { + "description": "Returns a list of similar Assets.", + "schema": { + "$ref": "#/definitions/searchResult" + } + }, + "400": { + "description": "Reverse Asset search failed. Query Asset Content length is insuffient (0 or too big). (Code: 76695187-7ace-4a2e-9fd2-7f0170a998d9)
Wrong content media type for Query Asset.Please upload file with multipart/form-data. (Code: 5ab68591-c21e-4cd7-8d00-01c13bfbb384)
Could not find file in multi-part data. (Code: cbdb4838-fab5-48b3-a8de-ac591316c904)
File type is not supported for reverse Asset search. (Code: 1dba4d87-6162-40b9-9076-2d56af6bcdbe)
", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "403": { + "description": "Not enough privileges to access item." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/assets/{id}/blobs": { + "get": { + "tags": [ + "Public Asset Operations" + ], + "description": "This endpoint checks, if an asset exists and returns the url for the requested blob.", + "operationId": "HttpGetAssetBlob", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the asset.", + "required": true, + "type": "string" + }, + { + "in": "query", + "name": "c", + "description": "\"t\" for thumbnail (default); \"op\" for optimized; \"os\" for original size; \"o\" for original.", + "required": true, + "type": "string" + }, + { + "in": "query", + "name": "portal_id", + "description": "If the request comes from portal this is the indicator. If used the \"key\" param becomes mandatory.", + "type": "string" + }, + { + "in": "query", + "name": "key", + "description": "The key is the MD5 hash of the original blob of the asset.", + "type": "string" + } + ], + "responses": { + "200": { + "description": "This function checks if asset exist on storage and returns the asset blob (incl. url).", + "schema": { + "$ref": "#/definitions/assetBlob" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "404": { + "description": "The requested item could not be found." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/assets/{id}/blob": { + "get": { + "tags": [ + "Public Asset Operations" + ], + "description": "This endpoint checks, if an asset exists, is an image, has original blob, is status active, is part of the shared collection and returns the requested asset blob.", + "operationId": "HttpGetSharedAssetBlob", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "query", + "name": "share_id", + "description": "This share ID is like an API key. Check on validy (format, expire, collection still availabe). Otherwise StatusCode 403 (Forbidden) is returned.", + "required": true, + "type": "string" + }, + { + "in": "header", + "name": "ay-password", + "description": "If shared collection has a password, this header is mandatory. Otherwise StatusCode 403 (Forbidden) is returned.", + "type": "string" + }, + { + "in": "path", + "name": "id", + "description": "The ID of the asset.", + "required": true, + "type": "string" + }, + { + "in": "query", + "name": "format", + "description": "Which download format the blob is requested.", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "Returns the asset blob (incl. URL) for the requested asset according to the input parameter(s)", + "schema": { + "$ref": "#/definitions/assetBlob" + } + }, + "400": { + "description": "Asset has to be image! Not allowed on type (Code: ec482f52-0ec8-4a8b-89fd-65b9d6b624cd)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "404": { + "description": "The requested item could not be found." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + } + } + }, + "/assets/{id}/collections": { + "get": { + "tags": [ + "Public Asset Operations" + ], + "description": "Returns all collections of a specific asset.", + "operationId": "HttpGetAssetCollectionsById", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the asset.", + "required": true, + "type": "string" + }, + { + "in": "query", + "name": "fields", + "description": "This limits the fields which are returned, separated by comma (',').", + "type": "string" + }, + { + "in": "query", + "name": "translations", + "description": "When default language should be returned and the translation dictionary is delivered. (Ignores the \"Accept-Language\" header)", + "type": "boolean" + }, + { + "in": "header", + "name": "Accept-Language", + "description": "The requested language of the response. If not matching it falls back to default language.", + "type": "string" + } + ], + "responses": { + "200": { + "description": "Returns all collections of a specific asset.", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/collection" + } + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "404": { + "description": "The requested item could not be found." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/assets/{id}/tocollection": { + "post": { + "tags": [ + "Public Asset Operations" + ], + "description": "This endpoint allows to move/assign from/to another collection with the given operation parameter.", + "operationId": "HttpAssetToCollection", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the asset.", + "required": true, + "type": "string" + }, + { + "in": "body", + "name": "body", + "description": "Contains information about this operation.", + "required": true, + "schema": { + "$ref": "#/definitions/moveCollectionBody" + } + } + ], + "responses": { + "400": { + "description": "Internal error. Request or Database client are null. (Code: 21814e91-379c-4c35-8ff9-974147ba6b76)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "204": { + "description": "Moves/assigns a single asset from/to collection with the given operation parameter." + }, + "404": { + "description": "The requested item could not be found." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/assets/{id}/download": { + "get": { + "tags": [ + "Public Asset Operations" + ], + "description": "This endpoint is similar to GetAssetBlob but with ContentDistribution and filename to let browser download the content.", + "operationId": "HttpGetAssetDownload", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the asset.", + "required": true, + "type": "string" + }, + { + "in": "query", + "name": "c", + "description": "\"t\" for thumbnail (default); \"op\" for optimized; \"os\" for original size; \"o\" for original.", + "type": "string" + }, + { + "in": "query", + "name": "f", + "description": "(optional) provide the id of any valid download format.", + "type": "string" + }, + { + "in": "query", + "name": "portal_id", + "description": "If the request comes from portal this is the indicator. It will be checked if the requested blob is valid for the portal.", + "type": "string" + }, + { + "in": "query", + "name": "key", + "description": "The key is the MD5 hash of the original blob of the asset.", + "type": "string" + } + ], + "responses": { + "200": { + "description": "This function checks if asset exist on storage and returns the asset blob (incl. url to download).", + "schema": { + "$ref": "#/definitions/assetBlob" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "404": { + "description": "The requested item could not be found." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/assets/{id}/resize": { + "get": { + "tags": [ + "Public Asset Operations" + ], + "description": "This endpoint lets you resize/modify the image asset according to the given parameter(s).", + "operationId": "HttpAssetResize", + "produces": [ + "image/xyz", + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the asset.", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "Returns the resized/modified image according to the input parameter(s)", + "schema": { + "format": "binary", + "type": "string" + } + }, + "400": { + "description": "Asset has to be image! Not allowed on type (Code: ec482f52-0ec8-4a8b-89fd-65b9d6b624cd)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "404": { + "description": "The requested item could not be found." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/assets/{id}/imageedit": { + "get": { + "tags": [ + "Public Asset Operations" + ], + "description": "This endpoint lets you resize/modify the image asset according to the given parameter(s).", + "operationId": "HttpAssetImageEdit", + "produces": [ + "image/xyz", + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the asset.", + "required": true, + "type": "string" + }, + { + "in": "query", + "name": "width", + "description": "The width of the final image.", + "type": "integer", + "format": "int32" + }, + { + "in": "query", + "name": "height", + "description": "The height of the final image.", + "type": "integer", + "format": "int32" + }, + { + "in": "query", + "name": "mode", + "description": "The supported modes: contain (default), cover, fill, crop, none", + "type": "string" + }, + { + "in": "query", + "name": "target", + "description": "The file type which the image should be (i.e. webp, png, jpg, gif)", + "type": "string" + }, + { + "in": "query", + "name": "bgcolor", + "description": "The color of the background color if background is visible (crop outside, png). RGB(A) in hex code (i.e. 00FFAA or with alpha channel: 44AABB77) and color names (i.e. lightgray) supported - default: transparent", + "type": "string" + }, + { + "in": "query", + "name": "dpi", + "description": "The density (counts for X and Y) of the target image.", + "type": "integer", + "format": "int32" + }, + { + "in": "query", + "name": "depth", + "description": "The bit depth of the target image.", + "type": "integer", + "format": "int32" + }, + { + "in": "query", + "name": "quality", + "description": "The quality of the target image (1-100).", + "type": "integer", + "format": "int32" + }, + { + "in": "query", + "name": "colorspace", + "description": "The color space of the image (Default: sRGB).", + "type": "string" + }, + { + "in": "query", + "name": "crop_x", + "description": "If mode is crop: The x coordinate of the point (if image is extended (outside) it is negative)", + "type": "integer", + "format": "int32" + }, + { + "in": "query", + "name": "crop_y", + "description": "If mode is crop: The y coordinate of the point (if image is extended (outside) it is negative)", + "type": "integer", + "format": "int32" + }, + { + "in": "query", + "name": "crop_width", + "description": "If mode=crop: The width of the cropping rectangle (from original pixel)", + "type": "integer", + "format": "int32" + }, + { + "in": "query", + "name": "crop_height", + "description": "If mode=crop: The height of the cropping rectangle (from original pixel)", + "type": "integer", + "format": "int32" + }, + { + "in": "query", + "name": "filter", + "description": "Which filter should be applied. To get all filters available use: /api/helper/imageeditfilters", + "type": "string" + }, + { + "in": "query", + "name": "original", + "description": "If set to true the internal image is used instead of the default original", + "type": "boolean" + } + ], + "responses": { + "200": { + "description": "Returns the resized/modified image according to the input parameter(s)", + "schema": { + "format": "binary", + "type": "string" + } + }, + "400": { + "description": "Asset has to be image! Not allowed on type (Code: ec482f52-0ec8-4a8b-89fd-65b9d6b624cd)
Asset does not have origsize or optimized blob reference. (Code: b6733be7 -8560-4b1a-8dfc-657ac668ffea)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "404": { + "description": "The requested item could not be found." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + }, + "post": { + "tags": [ + "Public Asset Operations" + ], + "description": "This endpoint lets you use the entire api of Imagemagick to edit the image.", + "operationId": "HttpImageDynamicEdit", + "consumes": [ + "application/json" + ], + "produces": [ + "image/xyz", + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the asset.", + "required": true, + "type": "string" + }, + { + "in": "query", + "name": "target_filename", + "description": "If the file should have a specific naming.", + "type": "string" + }, + { + "in": "body", + "name": "body", + "description": "Operations to be performed on the image directly mapped to c# imagemagick sdk", + "required": true, + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/dynamicImageOperation" + } + } + } + ], + "responses": { + "200": { + "description": "Returns the resized/modified image according to the input parameter(s)", + "schema": { + "format": "binary", + "type": "string" + } + }, + "400": { + "description": "Asset has to be image! Not allowed on type: {type} (Code: ec482f52-0ec8-4a8b-89fd-65b9d6b624cd)
Not a valid asset used. It has to be an asset, not deleted and from type {type} (Code: 320cda1c-7dd8-4b23-9b59-51ccee5e0a98)
", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "404": { + "description": "The requested item could not be found." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/assets/{id}/imageedit/{download_format_id}": { + "get": { + "tags": [ + "Public Asset Operations" + ], + "description": "This endpoint returns an image with the requested download format applied.", + "operationId": "HttpImageDynamicGetFromDownloadId", + "produces": [ + "image/xyz", + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the asset.", + "required": true, + "type": "string" + }, + { + "in": "path", + "name": "download_format_id", + "description": "The ID of the download format.", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "Returns the resized/modified image according to the input parameter(s)", + "schema": { + "format": "binary", + "type": "string" + } + }, + "400": { + "description": "Asset has to be image! Not allowed on type: {type} (Code: ec482f52-0ec8-4a8b-89fd-65b9d6b624cd)
The ID given is missing or not a valid download format ID. (Code: 7ec8d75d-3da4-4dce-8ab2-e52f0cf5f1f1)
Not a valid asset used. It has to be an asset, not deleted and from type {type} (Code: 320cda1c-7dd8-4b23-9b59-51ccee5e0a98)
Could not find requested download format. (Code: 05985771-df5e-4620-9b58-785177a1b223)
", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "404": { + "description": "The requested item could not be found." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/assets/{id}/availability": { + "put": { + "tags": [ + "Public Asset Operations" + ], + "description": "This endpoint sets the availability of the asset. All properties are put on the asset and replace previous values.To make an asset unavailable set the `availability` property to 'locked' or set the `available_from` property below the current date. To make it available set empty string to `availability` property or `available_to` property into past.", + "operationId": "HttpPutAssetAvailability", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the asset.", + "required": true, + "type": "string" + }, + { + "in": "body", + "name": "body", + "description": "The values are validated and put directly on the asset.", + "required": true, + "schema": { + "$ref": "#/definitions/assetAvailability" + } + } + ], + "responses": { + "200": { + "description": "The values are return which are put on the asset.", + "schema": { + "$ref": "#/definitions/assetAvailability" + } + }, + "400": { + "description": "Could not parse the asset availability object. (Code: 85ba8328-9181-4d74-a326-4073b17346d8)
Object is not a valid asset availability object. (Code: 5515ebe5-2751-4760-a864-47812126b9a1)
Asset availability has a confusing state: {updated.Availability}. (Code: 5515ebe5-2751-4760-a864-47812126b9a1)
Ambiguous information: Asset available_from can not be greater or equal as available_to when asset should be available.(Code: 16338bcd-614c-4322-a164-e3112d622392 )
Ambiguous information: Asset available_from can not be less or equal as available_to when asset should be locked and is not in the future. (Code: 092ddb50-2af8-49a1-b005-68c9d5c600d1)
Error on upsert asset availability in database - max retry count is reached. (Code: 98a80b23-bf8d-4cc1-ad6c-08cd69214dcd)
", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/assets/{id}/relations": { + "get": { + "tags": [ + "Public Asset Operations" + ], + "description": "This endpoint returns the asset relations", + "operationId": "HttpGetAssetRelationsById", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the asset.", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "Returns the asset relations for this specific asset.", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/assetRelation" + } + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "404": { + "description": "The requested item could not be found." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/assetrelations": { + "post": { + "tags": [ + "Public Asset Relation Management" + ], + "description": "This endpoint creates one asset relation entry in the database.", + "operationId": "HttpAssetRelationCreate", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "query", + "name": "translations", + "description": "When default language should be returned and the translation dictionary is delivered. (Ignores the \"Accept-Language\" header)", + "type": "boolean" + }, + { + "in": "header", + "name": "Accept-Language", + "description": "The requested language of the response. If not matching it falls back to default language.", + "type": "string" + }, + { + "in": "query", + "name": "assetrelationtypeid", + "description": "The ID of the asset relation type, where these asset relations should come from.", + "type": "string" + }, + { + "in": "body", + "name": "body", + "description": "This endpoint creates an asset relation in the database.", + "required": true, + "schema": { + "$ref": "#/definitions/assetRelation" + } + } + ], + "responses": { + "201": { + "description": "Returns the created asset relation.", + "schema": { + "$ref": "#/definitions/assetRelation" + } + }, + "400": { + "description": "Object is not a valid asset_relation. (Code: db336702-2654-4c87-8a17-38994ef5f812)
No input object given. (Code: 24897b5c-4322-4303-af28-578f374a17a0)
Not valid asset relation id! (Code: d5b66c4d-209a-4fe7-a4fc-2c36a86e8a6d)
Can not create asset relation with id {input.Id}. Asset Relation already exists. Delete first. (Code: 15964d55-b903-4120-8d83-bec54bd26e40)
Missing or invalid parameter \"assetrelationtypeid\" (Code: a0a5b486-972b-44c2-9378-96fc437c91ad)
Asset relation type not found. (Code: 33766cf4-d135-452b-9767-eb2171c5f258)
Asset relation must have at least two different assets. (Code: 5519ac52-aac3-49e4-9cde-925b1ac4e691)
Asset with ID {assetId} not found. (Code: 4fc224fb-6e5f-4ca0-b93d-f693a223a740)
The user does not have editor permission on all assets in the relation. (Code: 5179e72a-a72e-4731-a476-2de784703315)
For hierarchical relations, exactly one asset must be marked as parent. (Code: 1a9d8c7b-6e5f-3a2d-1b8c-7e6f5d4a3b2c)
Error on create asset relation in database - max retry count is reached. (Code: 7af65a99-32d8-4e98-b96b-00cd8649fc53)
The user does not have editor permission on the relation type. (Code: 63cad31c-ed36-4e1e-add4-349782019b68)
The asset relation contains assets that are already part of another relation of the same type. (Code: d3a34fc8-e658-487f-b224-5da2d0843ee1)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + }, + "get": { + "tags": [ + "Public Asset Relation Management" + ], + "description": "This endpoint lists all asset relations in database.", + "operationId": "HttpAssetRelationGetAll", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "query", + "name": "assetrelationtypeid", + "description": "The ID of the asset relation type, where these asset relations should come from.", + "type": "string" + }, + { + "in": "header", + "name": "Accept-Language", + "description": "The requested language of the response. If not matching it falls back to default language.", + "type": "string" + }, + { + "in": "query", + "name": "translations", + "description": "When default language should be returned and the translation dictionary is delivered. (Ignores the \"Accept-Language\" header)", + "type": "boolean" + } + ], + "responses": { + "200": { + "description": "Returns all asset relations in database.", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/assetRelation" + } + } + }, + "400": { + "description": "Invalid parameter \"assetrelationtypeid\". (Code: 16e4697f-5ba6-4dea-a51a-c2e08eff5faa)
Asset relation type not found. (Code: 33766cf4-d135-452b-9767-eb2171c5f258)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/assetrelations/{id}": { + "post": { + "tags": [ + "Public Asset Relation Management" + ], + "description": "This endpoint updates an asset relation entry in the database.", + "operationId": "HttpAssetRelationUpdateById", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the asset relation.", + "required": true, + "type": "string" + }, + { + "in": "query", + "name": "translations", + "description": "When default language should be returned and the translation dictionary is delivered. (Ignores the \"Accept-Language\" header)", + "type": "boolean" + }, + { + "in": "header", + "name": "Accept-Language", + "description": "The requested language of the response. If not matching it falls back to default language.", + "type": "string" + }, + { + "in": "body", + "name": "body", + "description": "This endpoint updates an asset relation with ID in the database.", + "required": true, + "schema": { + "$ref": "#/definitions/assetRelation" + } + } + ], + "responses": { + "200": { + "description": "Returns the updated asset relation.", + "schema": { + "$ref": "#/definitions/assetRelation" + } + }, + "400": { + "description": "Object is not a valid asset_relation. (Code: 6c5b4a9d-8e7f-3a2d-1b8c-7e6f5d4a3b2c)
No input object given. (Code: 5b4a9d8c-7e6f-3a2d-1b8c-7e6f5d4a3b2c)
Asset relation must have at least two different assets. (Code: 4a9d8c7b-6e5f-3a2d-1b8c-7e6f5d4a3b2c)
Asset with ID {assetId} not found. (Code: 3a9d8c7b-6e5f-3a2d-1b8c-7e6f5d4a3b2c)
The user does not have editor permission on all assets in the relation. (Code: 2a9d8c7b-6e5f-3a2d-1b8c-7e6f5d4a3b2c)
For hierarchical relations, exactly one asset must be marked as parent. (Code: 1a9d8c7b-6e5f-3a2d-1b8c-7e6f5d4a3b2c)
The user does not have editor permission on the relation type. (Code: 63cad31c-ed36-4e1e-add4-349782019b68)
The asset relation contains assets that are already part of another relation of the same type. (Code: b08c7606-ff7d-4b81-90ad-5d94f32cb7be)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "404": { + "description": "The requested item could not be found." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + }, + "get": { + "tags": [ + "Public Asset Relation Management" + ], + "description": "This endpoint gets a single asset relation.", + "operationId": "HttpAssetRelationGetById", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the asset relation.", + "required": true, + "type": "string" + }, + { + "in": "query", + "name": "translations", + "description": "When default language should be returned and the translation dictionary is delivered. (Ignores the \"Accept-Language\" header)", + "type": "boolean" + } + ], + "responses": { + "200": { + "description": "Returns the requested asset relation.", + "schema": { + "$ref": "#/definitions/assetRelation" + } + }, + "400": { + "description": "Asset relation type not found. (Code: 33766cf4-d135-452b-9767-eb2171c5f258)
The user does not have editor permission on the relation type. (Code: 63cad31c-ed36-4e1e-add4-349782019b68)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "404": { + "description": "The requested item could not be found." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + }, + "delete": { + "tags": [ + "Public Asset Relation Management" + ], + "description": "This endpoint deletes a single asset relation.", + "operationId": "HttpAssetRelationDeleteById", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the asset relation.", + "required": true, + "type": "string" + } + ], + "responses": { + "400": { + "description": "Error on deleting asset relation ({id}) database - max retry count is reached. (Code: 9d8c7b6a-5e4f-3a2d-1b8c-7e6f5d4a3b2c)
Asset relation type not found. (Code: 33766cf4-d135-452b-9767-eb2171c5f258)
The user does not have editor permission on the relation type. (Code: 3da4bd72-e810-46e5-a4ee-8fa2bd2dce32)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "204": { + "description": "The delete operation of the asset relation with the given ID was successful." + }, + "404": { + "description": "The requested item could not be found." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/assetrelationtypes": { + "get": { + "tags": [ + "Public Asset Relation Type Management" + ], + "description": "This endpoint lists all asset relation types in database.", + "operationId": "HttpAssetRelationTypeGetAll", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "query", + "name": "translations", + "description": "When default language should be returned and the translation dictionary is delivered. (Ignores the \"Accept-Language\" header)", + "type": "boolean" + }, + { + "in": "header", + "name": "Accept-Language", + "description": "The requested language of the response. If not matching it falls back to default language.", + "type": "string" + } + ], + "responses": { + "200": { + "description": "Returns all asset relation types in database.", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/assetRelationType" + } + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/assetrelationtypes/{id}": { + "get": { + "tags": [ + "Public Asset Relation Type Management" + ], + "description": "This endpoint gets a single asset relation type.", + "operationId": "HttpAssetRelationTypeGetById", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the asset relation type.", + "required": true, + "type": "string" + }, + { + "in": "query", + "name": "translations", + "description": "When default language should be returned and the translation dictionary is delivered. (Ignores the \"Accept-Language\" header)", + "type": "boolean" + }, + { + "in": "header", + "name": "Accept-Language", + "description": "The requested language of the response. If not matching it falls back to default language.", + "type": "string" + } + ], + "responses": { + "200": { + "description": "Returns the requested asset relation type.", + "schema": { + "$ref": "#/definitions/assetRelationType" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "404": { + "description": "If the asset relation type with the ID was not found." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/assets": { + "post": { + "tags": [ + "Public Asset Management" + ], + "description": "This endpoint creates one asset entry in the database.", + "operationId": "HttpAssetsCreate", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "query", + "name": "collectionid", + "description": "The ID of the collection where this assets should be assigned.", + "required": true, + "type": "string" + }, + { + "in": "query", + "name": "translations", + "description": "When default language should be returned and the translation dictionary is delivered. (Ignores the \"Accept-Language\" header)", + "type": "boolean" + }, + { + "in": "header", + "name": "Accept-Language", + "description": "The requested language of the response. If not matching it falls back to default language.", + "type": "string" + }, + { + "in": "body", + "name": "body", + "description": "This endpoint creates an unique asset ID and adds the information to the database.", + "required": true, + "schema": { + "$ref": "#/definitions/asset" + } + } + ], + "responses": { + "201": { + "description": "Returns the created simple asset.", + "schema": { + "$ref": "#/definitions/asset" + } + }, + "400": { + "description": "A parameter is null. (Code: 8f9036ff-037d-49a1-aab2-57899e5d30e6)
Given asset body is not valid. (Code: a51d1697-f56e-4fa3-bde8-3ab44e6cbb0a)
Asset availability has a confusing state: {updated.Availability}. (Code: 5515ebe5-2751-4760-a864-47812126b9a1)
Ambiguous information: Asset available_from can not be greater or equal as available_to when asset should be available.(Code: 16338bcd-614c-4322-a164-e3112d622392 )
Ambiguous information: Asset available_from can not be less or equal as available_to when asset should be locked and is not in the future. (Code: 092ddb50-2af8-49a1-b005-68c9d5c600d1)
Not valid asset id. (Code: b2409333-b6d4-4efc-b21e-56c1db9e9d25)
Can not create asset with id {input.Id}. Asset already exists. Delete first. (Code: ef721e67-6d4b-4e60-81cf-4be8f14581eb)
Error on creating custom items on asset. (Code: 4e780f21-17fc-4125-a9d8-2cf0c23d84d6)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + }, + "get": { + "tags": [ + "Public Asset Management" + ], + "description": "This endpoint lists all the assets, which are stored in the database and not deleted (status \"A\")", + "operationId": "HttpAssetsGet", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "query", + "name": "collectionid", + "description": "The ID of the collection where these assets should come from. (Is not required when 'collectiontypeid' is set.)", + "type": "string" + }, + { + "in": "query", + "name": "collectiontypeid", + "description": "The ID of the collection type where these assets should come from. (Is not required when 'collectionid' is set.) CAUTION: The assets returned are not distinct => Duplicates are possible if assets are in multiple collections in this collection type!", + "type": "string" + }, + { + "in": "query", + "name": "fields", + "description": "This limits the fields which are returned, separated by comma (','). Blobs can be limited with '.' on their container. (i.e. fields=blobs.thumbnails). Only if 'thumbnails' is set, the placeholder of this asset type are returned if no thumbnail blob is found.", + "type": "string" + }, + { + "in": "query", + "name": "expose", + "description": "This indicates if the given blobs should have URLs where these can be requested. (If not limited through 'fields' parameter it will expose all URLs of all blobs.)", + "type": "boolean" + }, + { + "in": "query", + "name": "continuation_token", + "description": "Each result returns the continous token if more results are available than requested. With this token, the next page could be fetched. (URL encoded!)", + "type": "string" + }, + { + "in": "query", + "name": "limit", + "description": "This number limits the page result of assets.", + "type": "integer", + "format": "int32" + }, + { + "in": "query", + "name": "orderby", + "description": "How the return assets are sorted. Default is property: modified_date (newest first).", + "type": "string" + }, + { + "in": "query", + "name": "filter", + "description": "This will limit the output on specific parameters which are separated by ':', '!:', '>', '>=', '<', '<='", + "type": "string" + }, + { + "in": "query", + "name": "items", + "description": "The items can be extended to fully filled items.", + "type": "boolean" + }, + { + "in": "query", + "name": "translations", + "description": "When default language should be returned and the translation dictionary is delivered. (Ignores the \"Accept-Language\" header)", + "type": "boolean" + }, + { + "in": "header", + "name": "Accept-Language", + "description": "The requested language of the response. If not matching it falls back to default language.", + "type": "string" + } + ], + "responses": { + "200": { + "description": "Returns the all assets (from given collection) as array.", + "schema": { + "$ref": "#/definitions/assetPageResult" + } + }, + "400": { + "description": "Could not query assets. Type: {type} (Code: 2744993d-fba5-4ae3-93df-ff95035c8af7)
Not allowed to query assets without valid collection id. (Code: 81515ce1-8e13-4a83-84e6-fe8057d55fc5)
Collection id {collectionId} not found. (Code: a3fe323c-6736-43e6-a9e9-49444f3f1406)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/assets/{id}": { + "get": { + "tags": [ + "Public Asset Management" + ], + "description": "This endpoint returns one single asset (from ID). If the returned asset is from a special asset type (e.g. \"AssetImage\") it returns the full entity.", + "operationId": "HttpAssetsGetById", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the asset.", + "required": true, + "type": "string" + }, + { + "in": "query", + "name": "fields", + "description": "Which fields are need to be filled out with comma separated. If one is set all non mandatory fields are left out. No validation if field exist.", + "type": "string" + }, + { + "in": "query", + "name": "expose", + "description": "This indicates if the given blobs should have URLs where these can be requested. It will expose placeholder blobs if no 'thumbnail' is found.", + "type": "boolean" + }, + { + "in": "query", + "name": "translations", + "description": "When default language should be returned and the translation dictionary is delivered. (Ignores the \"Accept-Language\" header)", + "type": "boolean" + }, + { + "in": "header", + "name": "Accept-Language", + "description": "The requested language of the response. If not matching it falls back to default language.", + "type": "string" + } + ], + "responses": { + "200": { + "description": "Returns the the asset with the given ID include type specific fields.", + "schema": { + "$ref": "#/definitions/asset" + } + }, + "404": { + "description": "If the asset with the ID was not found.", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + }, + "post": { + "tags": [ + "Public Asset Management" + ], + "description": "This endpoint updates one single asset (from ID)", + "operationId": "HttpPublicAssetsUpdateById", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the asset.", + "required": true, + "type": "string" + }, + { + "in": "query", + "name": "translations", + "description": "When default language should be returned and the translation dictionary is delivered. (Ignores the \"Accept-Language\" header)", + "type": "boolean" + }, + { + "in": "header", + "name": "Accept-Language", + "description": "The requested language of the response. If not matching it falls back to default language.", + "type": "string" + }, + { + "in": "body", + "name": "body", + "description": "The body has to contain one of the mentioned elements and a valid json. Not fitting properties are ignored.", + "required": true, + "schema": { + "$ref": "#/definitions/asset" + } + } + ], + "responses": { + "200": { + "description": "Returns the updated full (depending on asset type) asset including custom fields.", + "schema": { + "$ref": "#/definitions/asset" + } + }, + "400": { + "description": "A parameter is null. (Code: cea84d3b-ccb5-46c9-9768-11e1f81edf6c)
Object is not a valid asset. (Code: ea836a33-0d64-446f-8f67-2c3af564b18e)
Error on updating custom items. (Code: 9d044d04-53fb-4b6a-b629-554ad6ea19e2)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "404": { + "description": "If the asset with the ID was not found." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + }, + "delete": { + "tags": [ + "Public Asset Management" + ], + "operationId": "HttpAssetsDeleteById", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the asset.", + "required": true, + "type": "string" + } + ], + "responses": { + "400": { + "description": "A parameter is null. (Code: 355e5695-2dcb-4495-87ff-580540ad6274)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "204": { + "description": "The delete operation of the asset with the given ID was successful." + }, + "404": { + "description": "If the asset with the ID was not found." + }, + "403": { + "description": "Not enough privileges to access item." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/assetsupload": { + "post": { + "tags": [ + "Public Asset Management" + ], + "operationId": "HttpAssetUploadFile", + "consumes": [ + "multipart/form-data" + ], + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "header", + "name": "Accept-Language", + "description": "The requested language of the response. If not matching it falls back to default language.", + "type": "string" + }, + { + "name": "name", + "description": "", + "type": "string", + "in": "formData" + }, + { + "name": "collectionid", + "description": "", + "type": "string", + "in": "formData" + }, + { + "name": "file", + "description": "", + "type": "file", + "in": "formData" + }, + { + "name": "filename", + "description": "", + "type": "string", + "in": "formData" + }, + { + "name": "previewof", + "description": "", + "type": "string", + "in": "formData" + } + ], + "responses": { + "201": { + "description": "Returns the created uploaded asset.", + "schema": { + "$ref": "#/definitions/asset" + } + }, + "400": { + "description": "Request or Database client is null. (Code: feda1ab0-1477-4a76-abdd-3fa6fbdd0def)
Could not find file in multi-part data. (Code: b473c560-3ea1-4065-92e6-607973af9d9c)
This file is not supported. (Code: 12ac8746-349a-42c0-b73c-33257b73c728)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/assetsbulkupdate": { + "post": { + "tags": [ + "Public Asset Management" + ], + "operationId": "HttpAssetsBulkPostUpdate", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "header", + "name": "Accept-Language", + "description": "The requested language of the response. If not matching it falls back to default language.", + "type": "string" + }, + { + "in": "body", + "name": "body", + "description": "This endpoint updates multiple assets. The containing keywords (tags) will be distinctly added (no removal). Only custom values are added on assets which have those items.", + "required": true, + "schema": { + "$ref": "#/definitions/assetBulkUpdate" + } + } + ], + "responses": { + "200": { + "description": "Returns the info that the post update was successful. (Code: 9f12848f-573a-45bb-89ed-c44c44c1cc97)", + "schema": { + "$ref": "#/definitions/agravityInfoResponse" + } + }, + "400": { + "description": "A parameter is null. (Code: 22edc392-b73c-4d89-9710-6aad5edb0c1a)
Object is not a valid AssetBulkUpdate object. (Code: 0112ebf9-45cd-4284-b728-2c809faa4e4b)
Object is empty and not a valid AssetBulkUpdate object. (Code: f81bee0b-6e4e-4b6e-8f5c-019e498ca845)
Not sure what to update. asset_ids is not given. (Code: 93218cdf-4511-46a7-b336-46757d788d74)
Not all asset_ids are valid. (Code: 07e041bd-236c-4e48-bfca-89f9f5d340af)
Could not find all asset_ids in database. (Code: aa4e7de0-db79-431a-b684-76d157820775)
Could not find all asset_ids relations in database. (Code: 100b3432-1a26-4618-ba84-b1ac72ab1ec8)
Error on updating custom items on asset {asset.Id}. Reason see inner exception. (Code: 72faa784-ae94-49a9-a30e-1bad3674d432
Error on replacing custom items on asset {asset.Id}. Reason see inner exception. (Code: e83b9194-cbfe-43ec-bbfb-6d3fae5ad4d0)
The mandatory item '' can not be removed without having default value or is of type 'userdefinedlist'. (Code: 85b9c37d-6c66-46c4-9107-f7acf198e68a)
Property '' is mandatory but no default value was set! (Code: 16822359-3639-4610-b075-b39aa9e106a8)
Property '' is not of defined type: (Code: 1e9a1470-cfba-4a56-97b0-c44f77671880)
Property '' is mandatory but no value was given! (Code: c23f73ed-89cb-47c1-b653-3ec99c460707)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "404": { + "description": "If the asset with the ID was not found." + }, + "403": { + "description": "Not enough privileges to access item." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + }, + "put": { + "tags": [ + "Public Asset Management" + ], + "operationId": "HttpAssetsBulkPutUpdate", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "header", + "name": "Accept-Language", + "description": "The requested language of the response. If not matching it falls back to default language.", + "type": "string" + }, + { + "in": "body", + "name": "body", + "description": "This endpoint updates multiple assets. The containing keywords (tags) will replace existing. Only custom values are replaced on assets which have those items.", + "required": true, + "schema": { + "$ref": "#/definitions/assetBulkUpdate" + } + } + ], + "responses": { + "200": { + "description": "Returns the info that the post update was successful. (Code: de2972b8-d3e3-42ff-8c2c-5bd9b088dfef)", + "schema": { + "$ref": "#/definitions/agravityInfoResponse" + } + }, + "400": { + "description": "A parameter is null. (Code: 22edc392-b73c-4d89-9710-6aad5edb0c1a)
Object is not a valid AssetBulkUpdate object. (Code: 0112ebf9-45cd-4284-b728-2c809faa4e4b)
Object is empty and not a valid AssetBulkUpdate object. (Code: f81bee0b-6e4e-4b6e-8f5c-019e498ca845)
Not sure what to update. asset_ids is not given. (Code: 93218cdf-4511-46a7-b336-46757d788d74)
Not all asset_ids are valid. (Code: 07e041bd-236c-4e48-bfca-89f9f5d340af)
Could not find all asset_ids in database. (Code: aa4e7de0-db79-431a-b684-76d157820775)
Could not find all asset_ids relations in database. (Code: 100b3432-1a26-4618-ba84-b1ac72ab1ec8)
Error on updating custom items on asset {asset.Id}. Reason see inner exception. (Code: 72faa784-ae94-49a9-a30e-1bad3674d432
Error on replacing custom items on asset {asset.Id}. Reason see inner exception. (Code: e83b9194-cbfe-43ec-bbfb-6d3fae5ad4d0)
The mandatory item '' can not be removed without having default value or is of type 'userdefinedlist'. (Code: 85b9c37d-6c66-46c4-9107-f7acf198e68a)
Property '' is mandatory but no default value was set! (Code: 16822359-3639-4610-b075-b39aa9e106a8)
Property '' is not of defined type: (Code: 1e9a1470-cfba-4a56-97b0-c44f77671880)
Property '' is mandatory but no value was given! (Code: c23f73ed-89cb-47c1-b653-3ec99c460707)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "404": { + "description": "If the asset with the ID was not found." + }, + "403": { + "description": "Not enough privileges to access item." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + }, + "delete": { + "tags": [ + "Public Asset Management" + ], + "operationId": "HttpAssetsBulkDeleteUpdate", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "body", + "name": "body", + "description": "This endpoint updates multiple assets. The containing keywords (tags) will removed if existing. Only custom values are removed on assets which have those items.", + "required": true, + "schema": { + "$ref": "#/definitions/assetBulkUpdate" + } + } + ], + "responses": { + "200": { + "description": "Returns the info that remove update (delete) was successful. (Code: 35e4ad14-969e-4687-83ca-51c6828b5234)", + "schema": { + "$ref": "#/definitions/agravityInfoResponse" + } + }, + "400": { + "description": "A parameter is null. (Code: 22edc392-b73c-4d89-9710-6aad5edb0c1a)
Object is not a valid AssetBulkUpdate object. (Code: 0112ebf9-45cd-4284-b728-2c809faa4e4b)
Object is empty and not a valid AssetBulkUpdate object. (Code: f81bee0b-6e4e-4b6e-8f5c-019e498ca845)
Not sure what to update. asset_ids is not given. (Code: 93218cdf-4511-46a7-b336-46757d788d74)
Not all asset_ids are valid. (Code: 07e041bd-236c-4e48-bfca-89f9f5d340af)
Could not find all asset_ids in database. (Code: aa4e7de0-db79-431a-b684-76d157820775)
Could not find all asset_ids relations in database. (Code: 100b3432-1a26-4618-ba84-b1ac72ab1ec8)
Error on updating custom items on asset {asset.Id}. Reason see inner exception. (Code: 72faa784-ae94-49a9-a30e-1bad3674d432
Error on replacing custom items on asset {asset.Id}. Reason see inner exception. (Code: e83b9194-cbfe-43ec-bbfb-6d3fae5ad4d0)
The mandatory item '' can not be removed without having default value or is of type 'userdefinedlist'. (Code: 85b9c37d-6c66-46c4-9107-f7acf198e68a)
Property '' is mandatory but no default value was set! (Code: 16822359-3639-4610-b075-b39aa9e106a8)
Property '' is not of defined type: (Code: 1e9a1470-cfba-4a56-97b0-c44f77671880)
Property '' is mandatory but no value was given! (Code: c23f73ed-89cb-47c1-b653-3ec99c460707)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "404": { + "description": "If the asset with the ID was not found." + }, + "403": { + "description": "Not enough privileges to access item." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/assets/{id}/publish": { + "get": { + "tags": [ + "Public Asset Publishing" + ], + "description": "This endpoint lists all the published assets which are stored in the database if asset is still valid.", + "operationId": "HttpPublishedAssetsGet", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the asset.", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "Returns the all published assets as .", + "schema": { + "$ref": "#/definitions/publishEntity" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + }, + "post": { + "tags": [ + "Public Asset Publishing" + ], + "description": "This endpoint creates an additional published asset", + "operationId": "HttpPublishedAssetsCreate", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the asset.", + "required": true, + "type": "string" + }, + { + "in": "body", + "name": "body", + "description": "This creates / adds an unique published asset ID and adds the information to the asset (in DB).", + "required": true, + "schema": { + "$ref": "#/definitions/publishedAsset" + } + } + ], + "responses": { + "201": { + "description": "Returns the created published-asset entity.", + "schema": { + "$ref": "#/definitions/publishedAsset" + } + }, + "400": { + "description": "Could not publish asset because asset or original blob could not be found. (Code: 0da83425-da4e-4586-ae31-ba51e2c84f2c)
Could not publish an asset which is not active. (Code: be0b47c9-cf24-4cb8-a4ab-f17cdfe6dc4e)
Could not publish an asset which is locked. (Code: 16dbd27d-51f8-4556-a874-6cd7ddd7a1a8)
Could not resize asset for publishing. (Code: 2d9187ac-dc37-4365-a633-7ef90a326d0f)
Could not find optimized asset for publishing. (Code: e59e01cb-3f39-4c36-9c71-3d28bcabe486)
Tried to access not existion blob: does not exists.... (Code: a96e079b-61b3-492a-8adb-93b399287b46)
Publish to this target is not supported. (Code: 8136f041-60e4-40de-b534-71a7250095cc)
Publishing of asset failed. Blob could not be created. (Code: 43089864-d2a4-4a42-a2c2-1a9a2048bb58)
Could not update asset with ID (Code: 87429a31-01cd-4a62-9afb-81d0a56a59d2)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/assets/{id}/publish/{pid}": { + "get": { + "tags": [ + "Public Asset Publishing" + ], + "description": "This endpoint returns one single published asset (from ID). Not checked if assetId is not deleted!", + "operationId": "HttpPublishedAssetsGetById", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the asset.", + "required": true, + "type": "string" + }, + { + "in": "path", + "name": "pid", + "description": "The published asset ID.", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "Returns the published asset with the given ID.", + "schema": { + "$ref": "#/definitions/publishedAsset" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "404": { + "description": "If the asset or published asset with the IDs were not found." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/assets/{id}/versions": { + "post": { + "tags": [ + "Public Asset Versioning" + ], + "description": "This endpoint allows to create empty version or upload one asset which replaces the asset with given id and creates version.", + "operationId": "HttpAssetCreateVersion", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the asset.", + "required": true, + "type": "string" + }, + { + "in": "body", + "name": "body", + "description": "This VersionedAsset to create empty version (need to upload file with metadata to blob storage)", + "required": true, + "schema": { + "$ref": "#/definitions/versionedAsset" + } + } + ], + "responses": { + "201": { + "description": "Returns the created version of the asset.", + "schema": { + "$ref": "#/definitions/versionedAsset" + } + }, + "400": { + "description": "Asset is not active yet. Wait until process is finished. (Code: 2e1fbeb0-b405-4985-8bac-aa604d5cd125)
or AgravityProcessingException occured (see message). (Code: 37eb0897-6c1b-4147-9b6d-d0e756180623)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "404": { + "description": "Asset could not be found in database. (Code: 9a84addc-14b7-4a29-9f33-6f8f35e16bf3)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + }, + "get": { + "tags": [ + "Public Asset Versioning" + ], + "description": "This endpoint lists all the versioned assets which are stored in the database if asset is still valid.", + "operationId": "HttpVersionedAssetsGet", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the asset.", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "Returns the VersionEntity where all versioned assets are included.", + "schema": { + "$ref": "#/definitions/versionEntity" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "404": { + "description": "If the version of the asset is not found." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/assets/{id}/versionsupload": { + "post": { + "tags": [ + "Public Asset Versioning" + ], + "description": "This endpoint allows to upload one asset which replaces the asset with given id and creates a version which is returned.", + "operationId": "HttpAssetCreateUploadVersion", + "consumes": [ + "multipart/form-data" + ], + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the asset.", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "", + "type": "string", + "in": "formData" + }, + { + "name": "collectionid", + "description": "", + "type": "string", + "in": "formData" + }, + { + "name": "file", + "description": "", + "type": "file", + "in": "formData" + }, + { + "name": "filename", + "description": "", + "type": "string", + "in": "formData" + }, + { + "name": "previewof", + "description": "", + "type": "string", + "in": "formData" + } + ], + "responses": { + "201": { + "description": "Returns the created version of the asset.", + "schema": { + "$ref": "#/definitions/versionedAsset" + } + }, + "400": { + "description": "Asset is not active yet. Wait until process is finished. (Code: 2e1fbeb0-b405-4985-8bac-aa604d5cd125)
or asset upload failed. Content length is insuffient (0 or too big) (Code: b9fd835c-5456-4101-a643-ed5c1d5e5335)
or wrong content media type. Please upload file with multipart/form-data. (Code: 553ccca6-c06f-4a1d-9b1e-ff140fbcd389)
or could not find file in multi-part data. (Code: 0a66cf65-8926-44f3-9e7e-89de614828ad)
or this file is not supported. (Code: 214ef18f-0dca-4128-8543-e20339114e11)
or this file has to be from same file type when asset is published! (Code: 0bcf2586-ac2a-426f-b757-2352f50b53ef)
or AgravityProcessingException occured (see message). (Code: 37eb0897-6c1b-4147-9b6d-d0e756180623)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "404": { + "description": "Asset could not be found in database. (Code: 9a84addc-14b7-4a29-9f33-6f8f35e16bf3)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/assets/{id}/versions/{vNr}/restore": { + "post": { + "tags": [ + "Public Asset Versioning" + ], + "description": "This endpoint restores a version nr to be the current version and saves the current asset as version.", + "operationId": "HttpRestoreVersionedAssetsById", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the asset.", + "required": true, + "type": "string" + }, + { + "in": "path", + "name": "vNr", + "description": "The version number of the asset.", + "required": true, + "type": "string" + }, + { + "in": "body", + "name": "body", + "description": "Only the version_info is used and will be added to the current version which is archived (before the old version is restored).", + "required": true, + "schema": { + "$ref": "#/definitions/versionedAsset" + } + } + ], + "responses": { + "200": { + "description": "Returns the versioned asset.", + "schema": { + "$ref": "#/definitions/versionedAsset" + } + }, + "400": { + "description": "If the version is not a number.
If blobs or internal, thumbs or optimized are missing. Only assets can be restored which are complete processed.", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "404": { + "description": "If the asset or versioned asset with the IDs were not found." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/assets/{id}/versions/{vNr}": { + "delete": { + "tags": [ + "Public Asset Versioning" + ], + "description": "This endpoint deletes a version of an asset.", + "operationId": "HttpDeleteVersionedAssetsById", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the asset.", + "required": true, + "type": "string" + }, + { + "in": "path", + "name": "vNr", + "description": "The version number of the asset.", + "required": true, + "type": "string" + } + ], + "responses": { + "400": { + "description": "Given version of this asset is not a number (Code: 10fb9f76-1ee5-4b58-a642-bf37efa6c230)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "204": { + "description": "No description" + }, + "404": { + "description": "If the asset or versioned asset with the IDs were not found." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + }, + "post": { + "tags": [ + "Public Asset Versioning" + ], + "description": "This endpoint updates a version of an asset.", + "operationId": "HttpUpdateVersionedAssetsById", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the asset.", + "required": true, + "type": "string" + }, + { + "in": "path", + "name": "vNr", + "description": "The version number of the asset.", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "The updated asset version", + "schema": { + "$ref": "#/definitions/versionedAsset" + } + }, + "400": { + "description": "Given version of this asset is not a number (Code: 10fb9f76-1ee5-4b58-a642-bf37efa6c230)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "204": { + "description": "If nothing was updated." + }, + "404": { + "description": "If the asset or versioned asset with the IDs were not found." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/assets/{id}/versions/{vNr}/blobs": { + "get": { + "tags": [ + "Public Asset Versioning" + ], + "description": "This endpoint checks if assets and version exists and returns the url for the requested blob.", + "operationId": "HttpGetVersionedAssetBlobById", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the asset.", + "required": true, + "type": "string" + }, + { + "in": "path", + "name": "vNr", + "description": "The version number of the asset.", + "required": true, + "type": "integer", + "format": "int32" + }, + { + "in": "query", + "name": "c", + "description": "\"t\" for thumbnail (default); \"o\" for optimized", + "type": "string" + } + ], + "responses": { + "200": { + "description": "This function checks if asset exist on storage and returns the asset blob (incl. url).", + "schema": { + "$ref": "#/definitions/assetBlob" + } + }, + "400": { + "description": "Given version of this asset is not a number (Code: 7a60606d-764f-4e12-9bc1-ba8512de158a)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "404": { + "description": "The requested item could not be found." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/auth/containerwrite/{containerName}": { + "get": { + "tags": [ + "Public Authentication Management" + ], + "description": "This endpoint creates and returns a SAS-Token with write access for the requested container", + "operationId": "HttpAuthGetContainerWriteSasToken", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "containerName", + "description": "The name of the blob container", + "required": true, + "type": "string" + }, + { + "in": "query", + "name": "code", + "description": "The API key to access this endpoint. (Alternative using header x-function-keys with same value)", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "Returns SAS-Token for write access for the requested container.", + "schema": { + "$ref": "#/definitions/sasToken" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "400": { + "description": "A parameter is null. (Code: 0554451e-dcc9-4bef-a221-029bc3d77120)
Could not generate token for {containerName}. (Code: 3f19d7be-9d70-4268-93e6-de387daadd54)
No allowed to access containing {containerName}! (Code: fe2097fd-0370-4e30-8260-4a1d7f0e83e0)" + }, + "404": { + "description": "The requested item could not be found." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/auth/inbox": { + "get": { + "tags": [ + "Public Authentication Management" + ], + "description": "This endpoint creates and returns a SAS-Token with write access for the inbox container. Do not use this any longer. Use HttpAuthGetContainerWriteSasToken with inbox as container name.", + "operationId": "HttpAuthGetInboxContainerWriteSasToken", + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Returns SAS-Token for write access for the inbox.", + "schema": { + "$ref": "#/definitions/sasToken" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "400": { + "description": "A parameter is null. (Code: e30b767a-79e0-41f0-b3fd-dcb621fad0f1)
Could not generate token for inbox. (Code: 25b3843e-dbe2-4fc2-946f-3af17943c500)" + }, + "404": { + "description": "The requested item could not be found." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "deprecated": true, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/auth/users/{id}": { + "get": { + "tags": [ + "Public Authentication Management" + ], + "description": "This gets the user information about an Agravity User (incl. Online Status). Only full information if requester and userId are the same or it has role Admin.", + "operationId": "HttpAuthGetAgravityUserById", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the requested Agravity user.", + "required": true, + "type": "string" + }, + { + "in": "query", + "name": "limit", + "description": "(Optional): If the reponse should be limited to name and email.", + "type": "boolean" + } + ], + "responses": { + "200": { + "description": "Returns the Agravity user. Only if role agravity.admin or user itself get all roles, permissions, shares etc. ", + "schema": { + "$ref": "#/definitions/agravityUser" + } + }, + "400": { + "description": "The given ID is not a valid Agravity user ID. (Code: 6fdb9e67-d178-4038-b9c8-552fa9ef2a74)" + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "404": { + "description": "The requested item could not be found." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/collections": { + "get": { + "tags": [ + "Public Collection Management" + ], + "description": "This lists all the collections which are stored in the database and not deleted (status \"A\"). This will include all specific properties from collection type.", + "operationId": "HttpCollectionsGet", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "query", + "name": "collectiontypeid", + "description": "The ID of the collection type where these collections should come from.", + "required": true, + "type": "string" + }, + { + "in": "query", + "name": "level", + "description": "The hierarchy level of collections which should be returned.", + "type": "integer", + "format": "int32" + }, + { + "in": "query", + "name": "parentid", + "description": "The ID of the parent collection which should be queried. (No collectiontypeid is required)", + "type": "string" + }, + { + "in": "query", + "name": "fields", + "description": "This limits the fields which are returned, separated by comma (',').", + "type": "string" + }, + { + "in": "query", + "name": "items", + "description": "The items can be extended to fully filled items.", + "type": "boolean" + }, + { + "in": "query", + "name": "translations", + "description": "When default language should be returned and the translation dictionary is delivered. (Ignores the \"Accept-Language\" header)", + "type": "boolean" + }, + { + "in": "header", + "name": "Accept-Language", + "description": "The requested language of the response. If not matching it falls back to default language.", + "type": "string" + } + ], + "responses": { + "200": { + "description": "Returns the all collections as array.", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/collection" + } + } + }, + "400": { + "description": "Level not a positive number (Code: 757f7df3-3556-4c59-b5ac-9c7bfda6c3d4)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + }, + "post": { + "tags": [ + "Public Collection Management" + ], + "description": "This endpoint creates a unique collection ID and adds the information to the database.", + "operationId": "HttpCollectionsCreate", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "query", + "name": "collectiontypeid", + "description": "The ID of the collection type where this collections should be assigned.", + "required": true, + "type": "string" + }, + { + "in": "header", + "name": "Accept-Language", + "description": "The requested language of the response. If not matching it falls back to default language.", + "type": "string" + }, + { + "in": "body", + "name": "body", + "description": "This endpoint creates a unique collection ID and adds the information to the database.", + "required": true, + "schema": { + "$ref": "#/definitions/collection" + } + } + ], + "responses": { + "201": { + "description": "Returns the created collection.", + "schema": { + "$ref": "#/definitions/collection" + } + }, + "400": { + "description": "A parameter is null. (Code: 7dac18af-04ef-4da6-8b6e-e13dd8b027ae)
Missing or invalid parameter \"collectiontypeid\". (Code: 42a54d68-8a33-4a71-9545-7460f7a1339d)
The collection type \"collectiontypeid\" was not found. (Code: 203b1950-d942-4692-8e55-0ec5c137167f)
Property '' is not of defined type: (Code: 1e9a1470-cfba-4a56-97b0-c44f77671880)
Not valid collection id. (Code: 61a99ef3-c212-4171-8b37-290d8db4af3c)
Collection id does not match collection type! (Code: 6da1e562-a1e2-464a-a5e2-7d2621fe21bf)
Can not create collection with id {input.Id}. Collection already exists. Delete first. (Code: 321c4f48-7cc9-4ece-af88-89e95031dfde)
Object is not a valid collection. (Code: 67dd9a9f-b899-4607-bce8-0b0c4b4eec66)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/collections/{id}": { + "get": { + "tags": [ + "Public Collection Management" + ], + "description": "Returns one single collection (from ID). This will include all specific properties from collection type.", + "operationId": "HttpCollectionsGetById", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the collection.", + "required": true, + "type": "string" + }, + { + "in": "query", + "name": "fields", + "description": "This limits the fields which are returned, separated by comma (',').", + "type": "string" + }, + { + "in": "query", + "name": "items", + "description": "The items can be extended to fully filled items.", + "type": "boolean" + }, + { + "in": "query", + "name": "translations", + "description": "When default language should be returned and the translation dictionary is delivered. (Ignores the \"Accept-Language\" header)", + "type": "boolean" + }, + { + "in": "header", + "name": "Accept-Language", + "description": "The requested language of the response. If not matching it falls back to default language.", + "type": "string" + } + ], + "responses": { + "200": { + "description": "Returns the collection with the given ID.", + "schema": { + "$ref": "#/definitions/collection" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "404": { + "description": "If the collection with the ID was not found." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + }, + "post": { + "tags": [ + "Public Collection Management" + ], + "description": "This endpoint updates the collection. Specific properties could be updated.", + "operationId": "HttpPublicCollectionsUpdateById", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the collection.", + "required": true, + "type": "string" + }, + { + "in": "header", + "name": "Accept-Language", + "description": "The requested language of the response. If not matching it falls back to default language.", + "type": "string" + }, + { + "in": "body", + "name": "body", + "description": "The body has to be a valid collection json.Not fitting properties are ignored.", + "required": true, + "schema": { + "$ref": "#/definitions/collection" + } + } + ], + "responses": { + "200": { + "description": "Returns the updated collection and it includes all specific properties from collection type.", + "schema": { + "$ref": "#/definitions/collection" + } + }, + "400": { + "description": "Object is not a valid collection json. Parse error. (Code: 6910ae7e-6aea-4f15-8773-1c168a66d61d)
Can not update. Item value of \"{item.name}\" is not of the correct type \"{item.type}\". (Code: ec1aa2cd-65be-48b9-8972-002561bbe8ef)
Can not update. The item \"{item.name}\" is marked as mandatory but no value was given. (Code: 2955994d-010d-4b5c-88e0-af35da5f357f)
Validation error parent \"{collection.parent}\" not a collection GUID. (Code: d72d01f0-1809-41fe-85ea-0e423fc8e6f6)
Parent \"{collection.parent}\" is not allowed because it has different collection type. (Code: 7dadb5e1-6b2f-4649-bddc-e3bed033d79b)
Parent \"{collection.parent}\" for collection not found (Code: 7dadb5e1-6b2f-4649-bddc-e3bed033d79b)
Parent \"{collection.parent}\" must not be the same as the child. (Code: fb629d4f-4b1c-41e7-a589-f5da1e6fcaff)
", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "404": { + "description": "If the asset with the ID was not found." + }, + "403": { + "description": "Not enough privileges to access item." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + }, + "delete": { + "tags": [ + "Public Collection Management" + ], + "description": "This endpoint deletes the collection with the given ID (and their siblings).", + "operationId": "HttpPublicCollectionsDeleteById", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the collection.", + "required": true, + "type": "string" + }, + { + "in": "query", + "name": "deleteassets", + "description": "If this is true the assigned assets are set to delete as well.", + "type": "boolean" + } + ], + "responses": { + "400": { + "description": "Collection with ID {id} is null or not a well formated collection id! (Code: 6e59a8c1-564a-411b-ad3b-3b0b78d80644)Collection with ID {id} is set as default import collection. Change the DEFAULT_IMPORT_COLLECTION_ID to another collection or DV (Default Value). (Code: c0c98df2-6f3d-481b-ae1d-89f60a86be68)
", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "204": { + "description": "The delete operation of the collection with the given ID was successful." + }, + "404": { + "description": "If the collection with the ID was not found." + }, + "403": { + "description": "Not enough privileges to access item." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/collections/{id}/ancestors": { + "get": { + "tags": [ + "Public Collection Management" + ], + "description": "Get the complete tree of ancestors from a single collection.", + "operationId": "HttpCollectionsGetTreeAncestorsOfId", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the collection.", + "required": true, + "type": "string" + }, + { + "in": "query", + "name": "translations", + "description": "When default language should be returned and the translation dictionary is delivered. (Ignores the \"Accept-Language\" header)", + "type": "boolean" + }, + { + "in": "header", + "name": "Accept-Language", + "description": "The requested language of the response. If not matching it falls back to default language.", + "type": "string" + } + ], + "responses": { + "200": { + "description": "Returns the array of ancestors collections from the given collection in order by path.", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/collection" + } + } + }, + "400": { + "description": "Given collection id is not valid! (Code: 3f9fda3a-8911-45de-a4a0-34ea9e71e72d)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "404": { + "description": "If the collection with the ID was not found.", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/collections/{id}/descendants": { + "get": { + "tags": [ + "Public Collection Management" + ], + "description": "Get the complete tree of descendants from a single collection.", + "operationId": "HttpCollectionsGetDescendantsTreeOfId", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the collection.", + "required": true, + "type": "string" + }, + { + "in": "query", + "name": "translations", + "description": "When default language should be returned and the translation dictionary is delivered. (Ignores the \"Accept-Language\" header)", + "type": "boolean" + }, + { + "in": "header", + "name": "Accept-Language", + "description": "The requested language of the response. If not matching it falls back to default language.", + "type": "string" + } + ], + "responses": { + "200": { + "description": "Returns the array of descendants collections from the given collection in order by path.", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/collection" + } + } + }, + "400": { + "description": "Given collection id is not valid! (Code: 1f07346f-25a5-4338-9f83-cf96cc7af67d)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "404": { + "description": "If the collection with the ID was not found.", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/collections/{id}/previews": { + "get": { + "tags": [ + "Public Collection Management" + ], + "description": "This endpoint returns a generated thumbnail as a preview of the containing assets.", + "operationId": "HttpGetCollectionPreviewsById", + "produces": [ + "image/png", + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the collection.", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "Returns a generated png image as byte array.", + "schema": { + "type": "string" + } + }, + "404": { + "description": "If the collection with the ID was not found.", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/collectionsbynames": { + "post": { + "tags": [ + "Public Collection Management" + ], + "description": "This endpoint fetches all collections based on names which comes from an array inside the POST request body and return another list of EntityIdName objects and an array of strings with the names which could not be found.", + "operationId": "HttpPublicPostCollectionsGetByNames", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "body", + "name": "body", + "description": "An object with the array of strings with names of the collections to fetch.", + "required": true, + "schema": { + "$ref": "#/definitions/entityNamesRequest" + } + } + ], + "responses": { + "200": { + "description": "Returns an array of EntityIdName objects with the found collections and an array of strings with the names which could not be found.", + "schema": { + "$ref": "#/definitions/entityListResult" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "400": { + "description": "The request body is not a valid array of strings." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/secureupload/{id}": { + "get": { + "tags": [ + "Public Collection Secure Upload" + ], + "description": "Searchs for one single secure upload entity of an user and returns simple OK if found.", + "operationId": "HttpSecureUploadEntityCheckById", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the secure upload collection.", + "required": true, + "type": "string" + }, + { + "in": "query", + "name": "code", + "description": "The API key to access this endpoint. (Alternative using header x-function-keys with same value)", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "Returns 200 (OK) and returns the element - if this still exists, is valid and API Key is accepted.", + "schema": { + "$ref": "#/definitions/secureUploadEntity" + } + }, + "400": { + "description": "Not a valid secure upload id! (Code: f233ecb7-9f4e-43df-a6b6-172aa9ee66d0)
or No API key was provided. Please use 'code' param or 'x-functions-key' header property. (Code: a8843706-c481-4859-9555-2423dbdcc1a2)
or No matching API key or wrong password for this secure upload entity. (Code: e39a5c12-bbeb-4056-b717-2af89e21b319)
or Provided API key seems to be valid for authorization, but not to access this secure upload. (Code: ec38934a-43be-48ba-bf6f-b2e3b505812c)
or Secure upload entity date expired! (Code: c7ec0d4d-95e5-4211-b89e-c88a05d89571)}
or Provided API key seems to be valid for authentication, the ID does not match. (Code: d8e07922-173d-420c-a75c-539a5a182ad1)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "404": { + "description": "Secure upload entity not found for this user. (Code: 27ccd9e4-f5aa-4826-8384-b59451987bb9)
or Secure upload entity not found. (Code: 639ec439-2ec0-4c4e-9d5b-688be06e2234)
or Collection on which this secure upload is based, doesn't exist or is invalid! (Code: 3adffb93-800d-46a2-9bde-341216fc5f01)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/secureupload/{id}/upload": { + "post": { + "tags": [ + "Public Collection Secure Upload" + ], + "description": "This endpoint allows to securly upload one asset which is put onto the storage (INBOX). Object has to be FormData (Add file).", + "operationId": "HttpSecureUploadFileById", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the secure upload collection.", + "required": true, + "type": "string" + }, + { + "in": "query", + "name": "code", + "description": "The API key to access this endpoint. (Alternative using header x-function-keys with same value)", + "required": true, + "type": "string" + }, + { + "in": "body", + "name": "body", + "description": "This endpoint allows to upload one asset which is put onto the storage (INBOX). Object has to be FormData (Add file).", + "required": true, + "schema": { + "$ref": "#/definitions/file" + } + } + ], + "responses": { + "201": { + "description": "Returns the asset which was created.", + "schema": { + "$ref": "#/definitions/asset" + } + }, + "400": { + "description": "Secure upload failed. Content length is insuffient (0 or bigger than defined limit - default and maximum: 100 MB) (Code: bf2bdfc4-de75-42e4-add7-6cf7a546a3c0)
or Not a valid secure upload id! (Code: f233ecb7-9f4e-43df-a6b6-172aa9ee66d0)
or No API key was provided. Please use 'code' param or 'x-functions-key' header property. (Code: a8843706-c481-4859-9555-2423dbdcc1a2)
or No matching API key or wrong password for this secure upload entity. (Code: e39a5c12-bbeb-4056-b717-2af89e21b319)
or Provided API key seems to be valid for authorization, but not to access this secure upload. (Code: ec38934a-43be-48ba-bf6f-b2e3b505812c)
or Secure upload entity date expired! (Code: c7ec0d4d-95e5-4211-b89e-c88a05d89571)
or Provided API key seems to be valid for authentication, the ID does not match. (Code: d8e07922-173d-420c-a75c-539a5a182ad1)
or Wrong content media type. Please upload file with multipart/form-data. (Code: 4cdc8bde-e79f-4f52-a4cc-7b7c4d967b3c)
or Could not find file in multi-part data. (Code: 00440233-ef4a-48a1-ad7d-824232d7a17f)
or This file is not supported. (Code: 4b086d7e-dda3-4530-9d23-41a32a91b0fe)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "404": { + "description": "Secure upload entity not found for this user. (Code: 27ccd9e4-f5aa-4826-8384-b59451987bb9)
or Secure upload entity not found. (Code: 639ec439-2ec0-4c4e-9d5b-688be06e2234)
or Collection on which this secure upload is based, doesn't exist or is invalid! (Code: 3adffb93-800d-46a2-9bde-341216fc5f01)
or If the collection where this secure upload points to is not found.", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/collectiontypes": { + "get": { + "tags": [ + "Public Collection Type Management" + ], + "description": "This lists all available collection types which are stored in the database and not deleted (status \"A\").", + "operationId": "HttpCollectionTypesGet", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "query", + "name": "translations", + "description": "When default language should be returned and the translation dictionary is delivered. (Ignores the \"Accept-Language\" header)", + "type": "boolean" + }, + { + "in": "header", + "name": "Accept-Language", + "description": "The requested language of the response. If not matching it falls back to default language.", + "type": "string" + } + ], + "responses": { + "200": { + "description": "Returns the all collection types as array.", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/collectionType" + } + } + }, + "400": { + "description": "Could not create connection to CosmosDB (Code: e244cef3-2665-4757-ba34-0d4d0e71bb9d)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/collectiontypes/{id}": { + "get": { + "tags": [ + "Public Collection Type Management" + ], + "description": "Returns one single collection type (from ID).", + "operationId": "HttpCollectionTypesGetById", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the collection type.", + "required": true, + "type": "string" + }, + { + "in": "query", + "name": "translations", + "description": "When default language should be returned and the translation dictionary is delivered. (Ignores the \"Accept-Language\" header)", + "type": "boolean" + }, + { + "in": "header", + "name": "Accept-Language", + "description": "The requested language of the response. If not matching it falls back to default language.", + "type": "string" + } + ], + "responses": { + "200": { + "description": "Returns the collection type with the given ID.", + "schema": { + "$ref": "#/definitions/collectionType" + } + }, + "404": { + "description": "If the collection type with the ID was not found.", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/collectiontypesitems": { + "get": { + "tags": [ + "Public Collection Type Management" + ], + "description": "This method returns a list of collection types items. (Regardless of the permissions)", + "operationId": "HttpGetCollectionTypeItems", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "query", + "name": "includeblueprint", + "description": "True if the blueprint items should be included.", + "type": "boolean" + }, + { + "in": "query", + "name": "translations", + "description": "When default language should be returned and the translation dictionary is delivered. (Ignores the \"Accept-Language\" header)", + "type": "boolean" + }, + { + "in": "header", + "name": "Accept-Language", + "description": "The requested language of the response. If not matching it falls back to default language.", + "type": "string" + } + ], + "responses": { + "200": { + "description": "The collection types items for this item.", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/collTypeItem" + } + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "404": { + "description": "If the no collection type items were not found." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/config/frontend": { + "get": { + "tags": [ + "Public Configuration Management" + ], + "description": "Lists config value only for frontend stored in config table. Optional to filter for custom values only.", + "operationId": "HttpConfigGetFrontendAll", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "query", + "name": "customonly", + "description": "This returns only the custom created configurations.", + "type": "boolean" + } + ], + "responses": { + "200": { + "description": "Returns the frontend configations values in store", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/frontendAppConfig" + } + } + }, + "404": { + "description": "No config table could be found. (Code: 33d6286a-b7a4-428e-9f0b-cf7488d174ac)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "The config table could be be accessed. (Code: b9f176b8-cf22-4815-a90c-5a40611d2cfa)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + } + } + }, + "/downloadformats": { + "get": { + "tags": [ + "Public Download Format Management" + ], + "description": "This endpoint lists all download formats in database.", + "operationId": "HttpDownloadFormatsGetAll", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "header", + "name": "Accept-Language", + "description": "The requested language of the response. If not matching it falls back to default language.", + "type": "string" + } + ], + "responses": { + "200": { + "description": "Returns all download formats in database.", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/downloadFormat" + } + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/downloadformats-shared": { + "get": { + "tags": [ + "Public Download Format Management" + ], + "description": "This endpoint lists all download formats for a specific shared collections in database.Needs a valid shared collection ID to be authenticated.", + "operationId": "HttpDownloadFormatsGetAllFromShared", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "query", + "name": "share_id", + "description": "This share ID is like an API key. Check on validy (format, expire, collection still availabe). Otherwise StatusCode 403 (Forbidden) is returned.", + "required": true, + "type": "string" + }, + { + "in": "header", + "name": "ay-password", + "description": "If shared collection has a password, this header is mandatory. Otherwise StatusCode 403 (Forbidden) is returned.", + "type": "string" + }, + { + "in": "header", + "name": "Accept-Language", + "description": "The requested language of the response. If not matching it falls back to default language.", + "type": "string" + } + ], + "responses": { + "200": { + "description": "Returns download formats for the shared collection in database.", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/downloadFormat" + } + } + }, + "403": { + "description": "Not enough privileges to access item." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + } + } + }, + "/public/view": { + "get": { + "tags": [ + "Public Endpoints" + ], + "description": "This endpoint returns the content of an asset which is available in a specific portal (portal_id is \"key\") and returns the blob directly.", + "operationId": "HttpAssetGetViewForPortal", + "produces": [ + "application/octet-stream", + "application/json" + ], + "parameters": [ + { + "in": "query", + "name": "asset_id", + "description": "The ID of the asset.", + "required": true, + "type": "string" + }, + { + "in": "query", + "name": "portal_id", + "description": "If the request comes from portal this is the indicator.", + "required": true, + "type": "string" + }, + { + "in": "query", + "name": "format", + "description": "The name of the format (download format) or container.", + "required": true, + "type": "string" + }, + { + "in": "query", + "name": "download", + "description": "True if a direct download with file name should be started.", + "type": "string" + } + ], + "responses": { + "200": { + "description": "Returns the direct blob for download.", + "schema": { + "format": "binary", + "type": "string" + } + }, + "400": { + "description": "Portal ID is mandatory and not valid. {type} (Code: be59e94a-0f76-415f-a6b7-065e3abfc64e)
Downloadformat is not allowed on other asset type than image (Code: e77d141b-a2b4-4746-8910-5b97b2623cc4)
Downloadformat with id '{format}' not found. (Code: eb70a990-6a28-40b1-8631-63a085fd8ac3)
Tried to access not existion blob: {asset.Id} from container: {downloadFormat.OriginContainer}. (Code: 53683b61-67f4-47f9-9392-e7c651175854)
General error with message. (Code: 5cd6a8bd-2a53-4b6a-adef-efd898e8c248)
Blob with format '{format}' not found. (Code: 5a656869-4678-41dd-a311-af79e319d83f)
Get view from asset {asset?.Id} failed. Format '{format}' not found. (Code: 34473124-d3d4-4de0-8112-6798e4728e1f)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "404": { + "description": "The requested item could not be found." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + } + } + }, + "/version": { + "get": { + "tags": [ + "Public General Management" + ], + "description": "Get the current version of the backend. To see if backend was updated or not.", + "operationId": "HttpAgravityVersionInfo", + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "All information about backend.", + "schema": { + "$ref": "#/definitions/agravityVersion" + } + }, + "400": { + "description": "Only if any of the input variable are null (Code: 9a6fb6f2-4b7b-4253-a4f3-5a46b7ba0ca8)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "404": { + "description": "Only if assembly could not found (?)" + } + } + } + }, + "/deleted": { + "get": { + "tags": [ + "Public General Management" + ], + "description": "This endpoint checks all deleted entities in the database until a specific date and returns the elements which are deleted.", + "operationId": "HttpGetDeletedEntities", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "query", + "name": "entity_type", + "description": "The type of the entity (e.g. 'asset', 'collection_type', 'collection_type'", + "type": "string" + }, + { + "in": "query", + "name": "since", + "description": "The date in the past since the entities are marked as deleted in the database.", + "type": "string" + }, + { + "in": "query", + "name": "until", + "description": "The date in the past until the entities are marked as deleted in the database.", + "type": "string" + }, + { + "in": "query", + "name": "portal_id", + "description": "If the request comes from portal this is the indicator.", + "type": "string" + } + ], + "responses": { + "200": { + "description": "A list of entities which are deleted since the given date (last modified date = deleted date).", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/deletedEntities" + } + } + }, + "400": { + "description": "Since date could not be more in the future than until date. (Code: d362e2d4-b6b1-4547-a97c-058d2f46acfc)
Entity type '{entityType}' is not valid. (Code: 79abc89e-e072-4cf5-a63a-1573764975c6)
Entity type '{entityType}' is not allowed for this user. (Code: b00efbb5-faeb-4758-9ea3-44b5435a2311)
Error on getting deleted entities. (Code: 71fad553-4c82-423a-807e-ba272bfd3404)
", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "404": { + "description": "When the portal_id could not be found." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/durable/{instanceId}": { + "get": { + "tags": [ + "Public General Management" + ], + "description": "Trigger the durable execution to continue", + "operationId": "HttpTriggerDurableContinue", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "instanceId", + "description": "The instance ID of the durable function.", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "Operation successfull", + "schema": { + "$ref": "#/definitions/agravityInfoResponse" + } + }, + "400": { + "description": "Only if instaceId is null", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + } + } + } + }, + "/durable/scch/{instanceId}": { + "get": { + "tags": [ + "Public General Management" + ], + "description": "Trigger the durable execution to continue", + "operationId": "HttpTriggerDurableScchTrainingDone", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "instanceId", + "description": "The instance ID of the durable function.", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "Operation successfull", + "schema": { + "$ref": "#/definitions/agravityInfoResponse" + } + }, + "400": { + "description": "Only if instaceId is null", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + } + } + } + }, + "/helper/userdefinedlists": { + "get": { + "tags": [ + "Public Helper Tools" + ], + "description": "Returns all user defined lists of all collection types", + "operationId": "HttpGetAllUserDefinedLists", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "query", + "name": "translations", + "description": "When default language should be returned and the translation dictionary is delivered. (Ignores the \"Accept-Language\" header)", + "type": "boolean" + }, + { + "in": "header", + "name": "Accept-Language", + "description": "The requested language of the response. If not matching it falls back to default language.", + "type": "string" + } + ], + "responses": { + "200": { + "description": "A list of all user defined list entries.", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/collectionUDL" + } + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + }, + "patch": { + "tags": [ + "Public Helper Tools" + ], + "description": "This updates the cached user defined lists and store it in the system.", + "operationId": "HttpPatchUpdateCachedUserDefinedLists", + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "A full list of all UDLs and the collection types they are in and their permissions.", + "schema": { + "$ref": "#/definitions/collectionUDLListEntity" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "403": { + "description": "Not enough privileges to access item." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/helper/searchableitemnames": { + "get": { + "tags": [ + "Public Helper Tools" + ], + "description": "Returns all searchable items directly from the search index", + "operationId": "HttpGetAllowedSearchableItemNames", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "query", + "name": "portal_id", + "description": "If the search should be redirected to a specific portal.", + "type": "string" + } + ], + "responses": { + "400": { + "description": "Argument is null. (Code: 7e0e127f-d12d-441d-8405-25d91f2b32d6)
Argument exception: {message} (Code: 35c2fd8d-30ca-4c72-80fd-de91973b9c99)
Request failed: {message} (Code: fb5e9c1b-1206-4488-9240-3cc949c23646)
General error: {message} ({typeOfException}) (Code: e0289b2f-7a44-4cc6-a552-f025e5cdad3e)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "200": { + "description": "A string list of all searchable items.", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/helper/searchableitems": { + "get": { + "tags": [ + "Public Helper Tools" + ], + "description": "Returns all searchable items directly from the search index", + "operationId": "HttpGetAllowedSearchableItems", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "query", + "name": "portal_id", + "description": "If the search should be redirected to a specific portal.", + "type": "string" + } + ], + "responses": { + "200": { + "description": "A list of all searchable items.", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/searchableItem" + } + } + }, + "400": { + "description": "Argument is null. (Code: 5e87014c-7ac4-4487-b91d-ce03438d5d45)
Argument exception: {message} (Code: 1f7fb1e7-dbf4-41a8-b89c-9829067a1ca6)
Request failed: {message} (Code: b66c90a6-482e-40ee-b77d-06e001803ae0)
General error: {message} ({typeOfException}) (Code: 4ff25dc7-47dd-4bec-bcce-6ecdb11b01c8)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/helper/filterableitems": { + "get": { + "tags": [ + "Public Helper Tools" + ], + "description": "Returns all filterable items directly from the search index", + "operationId": "HttpGetAllowedFilterableItems", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "query", + "name": "portal_id", + "description": "If the search should be redirected to a specific portal.", + "type": "string" + } + ], + "responses": { + "200": { + "description": "A string list of all filterable items.", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "400": { + "description": "Argument is null. (Code: e12181d0-371e-47c4-88cc-1d2453a7d9a6)
Argument exception: {message} (Code: e109ada5-d770-43f3-a6e0-7d869b0bb8e1)
Request failed: {message} (Code: 2da00496-7e74-4c11-8bd0-1e92cbc8875a)
General error: {message} ({typeOfException}) (Code: 8c14ca12-da21-4a87-9bcd-9958407f102d)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/publish": { + "get": { + "tags": [ + "Public Publishing" + ], + "description": "This endpoint lists all the published assets which are stored in the database", + "operationId": "HttpPublishedAssetsGetAll", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "query", + "name": "cid", + "description": "Filter response for collection", + "type": "string" + }, + { + "in": "query", + "name": "incldescendants", + "description": "Include collections further down in hierarchy", + "type": "boolean" + } + ], + "responses": { + "200": { + "description": "Returns the all published assets as .", + "schema": { + "$ref": "#/definitions/publishEntity" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/savedsearches": { + "get": { + "tags": [ + "Public Saved Search" + ], + "description": "This endpoint lists all saved searches in database.", + "operationId": "HttpSavedSearchesGetAll", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "query", + "name": "external", + "description": "This parameter filters out all saved searches on basis this boolean. Only admins can request the external saved searches.", + "type": "boolean" + }, + { + "in": "query", + "name": "translations", + "description": "When default language should be returned and the translation dictionary is delivered. (Ignores the \"Accept-Language\" header)", + "type": "boolean" + }, + { + "in": "header", + "name": "Accept-Language", + "description": "The requested language of the response. If not matching it falls back to default language.", + "type": "string" + } + ], + "responses": { + "200": { + "description": "Returns all saved searches in database.", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/savedSearch" + } + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/search": { + "get": { + "tags": [ + "Public Search Management" + ], + "description": "This endpoint returns a configured max amount of results for search terms.", + "operationId": "HttpGlobalSearch", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "query", + "name": "s", + "description": "The search string which should be found.", + "required": true, + "type": "string" + }, + { + "in": "query", + "name": "limit", + "description": "How many results should be returend. 0 is backend configuration limit.", + "type": "integer", + "format": "int32" + }, + { + "in": "query", + "name": "skip", + "description": "(default: 0) - Used for paging - how many items should be skipped before next limit results will be fetched.", + "type": "integer", + "format": "int32" + }, + { + "in": "query", + "name": "collectiontypeid", + "description": "Limits the result on all collections from the given collectiontypeid parameter.", + "type": "string" + }, + { + "in": "query", + "name": "collectionid", + "description": "Limits the result on collection id (and siblings). Will be overwritten by collectiontypeid parameter.", + "type": "string" + }, + { + "in": "query", + "name": "mode", + "description": "Two modes supported: \"any\" or \"all\" search terms should be applied. (Only if Azure Search is enabled)", + "type": "string" + }, + { + "in": "query", + "name": "expose", + "description": "This will expose the thumbnail asset blob incl. URL with SAS Token.", + "type": "boolean" + }, + { + "in": "query", + "name": "filter", + "description": "Colon separated key value filter for filterable strings and string collections. For date or numbers \"<\", \"=\" and \">\" are possible. Mode influences AND (all) and OR (any) of all filters. Multiple filters are separated by semicolons. (Only if Azure Search is enabled)", + "type": "string" + }, + { + "in": "query", + "name": "broadness", + "description": "Search Broadness: Can be 0, 1 or 2. (0 is the most exact search, 2 is the broadest search) (1, 2 is with AI)", + "type": "integer", + "format": "int32" + }, + { + "in": "query", + "name": "rel_id", + "description": "The ID of the relation which this search is limited to. (Only the assets in this relation are returend)", + "type": "string" + }, + { + "in": "query", + "name": "scopefilter", + "description": "Colon separated key value filter for additional scopes. It applies the same conventions as for filter parameter.", + "type": "string" + }, + { + "in": "query", + "name": "orderby", + "description": "Sortable fields can be used. For descendant sorting use leading \"!\". (Only if Azure Search is enabled)", + "type": "string" + }, + { + "in": "query", + "name": "ids", + "description": "Comma separated values list with all ids which should be returned.", + "type": "string" + }, + { + "in": "query", + "name": "portal_id", + "description": "If the search should be redirected to a specific portal.", + "type": "string" + }, + { + "in": "query", + "name": "translations", + "description": "When default language should be returned and the translation dictionary is delivered. (Ignores the \"Accept-Language\" header)", + "type": "boolean" + }, + { + "in": "header", + "name": "Accept-Language", + "description": "The requested language of the response. If not matching it falls back to default language.", + "type": "string" + } + ], + "responses": { + "200": { + "description": "Returns the search result", + "schema": { + "$ref": "#/definitions/searchResult" + } + }, + "400": { + "description": "A required parameter is null. (Code: 870f62fe-827a-4ef3-98e7-7f309244ee00)
or provide at least parameter \"s=\" with search string (url encoded) (Code: de39bfb1-42e3-4edf-9651-5c4952524e69)
or limit is not a valid number! Can use 0 for defined limit. (Code: 7115dc96-99e3-47a4-827a-8cc63cc1ab68\nor skip is not a valid number! Can use 0 for defined skip. (Code: ad8237e0-236c-4404-8eaa-d81a9fa4e41c\nor parameter \"collectiontypeid=\" is not valid (not in correct format or not found in system). (Code: 330e6abb-e77e-4193-9aa0-9dfce168c674)
or parameter \"collectionid=\" is not valid (not in correct format or not found in system). (Code: c20f1dfb-0d19-419e-96eb-f5dee44576fe)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/search/facette": { + "get": { + "tags": [ + "Public Search Management" + ], + "description": "This endpoint returns one facette based on the search parameters.", + "operationId": "HttpGetSearchFacetteByName", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "query", + "name": "name", + "description": "The name of the facette.", + "required": true, + "type": "string" + }, + { + "in": "query", + "name": "s", + "description": "The search string which should be found.", + "required": true, + "type": "string" + }, + { + "in": "query", + "name": "collectiontypeid", + "description": "Limits the result on all collections from the given collectiontypeid parameter.", + "type": "string" + }, + { + "in": "query", + "name": "collectionid", + "description": "Limits the result on collection id (and siblings). Will be overwritten by collectiontypeid parameter.", + "type": "string" + }, + { + "in": "query", + "name": "mode", + "description": "Two modes supported: \"any\" or \"all\" search terms should be applied. (Only if Azure Search is enabled)", + "type": "string" + }, + { + "in": "query", + "name": "filter", + "description": "Key value filter for filterable strings and string collections separated by special ',,,'. For date or numbers \"<\", \"=\" and \">\" are possible. Mode influences AND (all) and OR (any) of all filters. Multiple filters are separated by semicolons. (Only if Azure Search is enabled)", + "type": "string" + }, + { + "in": "query", + "name": "scopefilter", + "description": "Colon separated key value filter for additional scopes. It applies the same conventions as for filter parameter.", + "type": "string" + }, + { + "in": "query", + "name": "ids", + "description": "Comma separated values list with all ids which should be returned.", + "type": "string" + }, + { + "in": "query", + "name": "portal_id", + "description": "If the search should be redirected to a specific portal.", + "type": "string" + } + ], + "responses": { + "200": { + "description": "Returns the search result", + "schema": { + "$ref": "#/definitions/searchFacet" + } + }, + "400": { + "description": "A required parameter is null. (Code: 870f62fe-827a-4ef3-98e7-7f309244ee00)
or provide at least parameter \"s=\" with search string (url encoded) (Code: 180db53c-9789-4588-ac4b-23d0c1eb1c06)
or limit is not a valid number! Can use 0 for defined limit. (Code: 7115dc96-99e3-47a4-827a-8cc63cc1ab68
or skip is not a valid number! Can use 0 for defined skip. (Code: ad8237e0-236c-4404-8eaa-d81a9fa4e41c
Parameter \"portal_id=\" is not valid.(Code: 2ef46a2f-07a5-4ee3-acef-5b421c3f493a)
Parameter \"portal_id=\" is not found in system. (Code: d0ed0426-9c08-4490-b43c-660093f63db9)
Azure Search is not enabled! (Code: ddeb49b9-9574-4682-a7bd-b2946033983f)
or parameter \"collectiontypeid=\" is not valid (not in correct format or not found in system). (Code: 330e6abb-e77e-4193-9aa0-9dfce168c674)
or parameter \"collectionid=\" is not valid (not in correct format or not found in system). (Code: c20f1dfb-0d19-419e-96eb-f5dee44576fe)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/searchadmin/status": { + "get": { + "tags": [ + "Public Search Management" + ], + "description": "This endpoint gives the status about the index and indexer.", + "operationId": "HttpSearchAdminGetStatus", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "query", + "name": "portal_id", + "description": "If the search should be redirected to a specific portal.", + "type": "string" + } + ], + "responses": { + "200": { + "description": "This gives status about the search.", + "schema": { + "$ref": "#/definitions/searchAdminStatus" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/shared/{id}": { + "get": { + "tags": [ + "Public Sharing Management" + ], + "description": "Returns one single shared collection (from ID)", + "operationId": "HttpSharedCollectionsGetById", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the shared collection.", + "required": true, + "type": "string" + }, + { + "in": "header", + "name": "ay-password", + "description": "If shared collection has a password, this header is mandatory. Otherwise StatusCode 403 (Forbidden) is returned.", + "type": "string" + }, + { + "in": "query", + "name": "continuation_token", + "description": "Each result returns the continous token if more results are available than requested. With this token, the next page could be fetched. (URL encoded!)", + "type": "string" + }, + { + "in": "query", + "name": "limit", + "description": "This number limits the page result of assets.", + "type": "integer", + "format": "int32" + }, + { + "in": "query", + "name": "orderby", + "description": "How the return assets are sorted. Default is property: created_date (newest first).", + "type": "string" + }, + { + "in": "header", + "name": "Accept-Language", + "description": "The requested language of the response. If not matching it falls back to default language.", + "type": "string" + } + ], + "responses": { + "200": { + "description": "Returns the shared collection with the given ID.", + "schema": { + "$ref": "#/definitions/sharedCollectionFull" + } + }, + "400": { + "description": "A parameter is null (Code: e61dfb16-e486-4c15-8b55-276bd85d291e)
or not valid shared id! (Code: e1eb7b29-e501-4727-bec3-26f5099b7418)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "404": { + "description": "Collection on which this share is based, doesn't exist. (Code: 79dde226-ae08-4f4b-b334-de0cad89c994)
or Shared collection date expired! (Code: 6758d66e-0ce6-4770-a497-01a578eac12c)
or Shared collection not found. (Code: 87d09a21-14d6-4da4-ab69-01e6c87f108c)
or User null or shared collection of user not found. (Code: 5a1ea520-377d-43f1-b2c3-506443056561)
", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "This share requires a password (Header: 'ay-password') to be accessed." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + } + } + }, + "/shared/{id}/zip": { + "post": { + "tags": [ + "Public Sharing Management" + ], + "description": "Initiates the ZIP creation of a shared collection.", + "operationId": "HttpSharedCollectionsRequestZipById", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the shared collection.", + "required": true, + "type": "string" + }, + { + "in": "header", + "name": "ay-password", + "description": "If shared collection has a password, this header is mandatory. Otherwise StatusCode 403 (Forbidden) is returned.", + "type": "string" + }, + { + "in": "body", + "name": "body", + "description": "The request of which assets or download formats should be used..", + "schema": { + "$ref": "#/definitions/downloadZipRequest" + } + } + ], + "responses": { + "201": { + "description": "Returns the requested download ZIP with created zip entity ID.", + "schema": { + "$ref": "#/definitions/downloadZipRequest" + } + }, + "400": { + "description": "Not valid shared id! (Code: e1eb7b29-e501-4727-bec3-26f5099b7418)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "404": { + "description": "Collection on which this share is based, doesn't exist. (Code: 79dde226-ae08-4f4b-b334-de0cad89c994)
or Shared collection date expired! (Code: 6758d66e-0ce6-4770-a497-01a578eac12c)
or Shared collection not found. (Code: 87d09a21-14d6-4da4-ab69-01e6c87f108c)
or User null or shared collection of user not found. (Code: 5a1ea520-377d-43f1-b2c3-506443056561)
", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "This share requires a password (Header: 'ay-password') to be accessed." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + } + } + }, + "/shared/{id}/zip/{zipId}": { + "get": { + "tags": [ + "Public Sharing Management" + ], + "description": "This endpoint gets the progress/status of the ZIP creation of a shared collection.", + "operationId": "HttpSharedCollectionsGetStatusZipById", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the zip request.", + "required": true, + "type": "string" + }, + { + "in": "path", + "name": "zipId", + "description": "The ID of the requested zip.", + "required": true, + "type": "string" + }, + { + "in": "header", + "name": "ay-password", + "description": "If shared collection has a password, this header is mandatory. Otherwise StatusCode 401 (Unauthorized) is returned.", + "type": "string" + } + ], + "responses": { + "200": { + "description": "Returns the status of the current zip request.", + "schema": { + "$ref": "#/definitions/downloadZipStatus" + } + }, + "400": { + "description": "Not valid shared id! (Code: e1eb7b29-e501-4727-bec3-26f5099b7418)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "404": { + "description": "Collection on which this share is based, doesn't exist. (Code: 79dde226-ae08-4f4b-b334-de0cad89c994)
or Shared collection date expired! (Code: 6758d66e-0ce6-4770-a497-01a578eac12c)
or Shared collection not found. (Code: 87d09a21-14d6-4da4-ab69-01e6c87f108c)
or User null or shared collection of user not found. (Code: 5a1ea520-377d-43f1-b2c3-506443056561)
", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "This share requires a password (Header: 'ay-password') to be accessed." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + } + } + }, + "/quickshares/{id}": { + "get": { + "tags": [ + "Public Sharing Management" + ], + "description": "Returns one single quick share (from ID)", + "operationId": "HttpQuickShareGetById", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the quick share.", + "required": true, + "type": "string" + }, + { + "in": "query", + "name": "continuation_token", + "description": "Each result returns the continous token if more results are available than requested. With this token, the next page could be fetched. (URL encoded!)", + "type": "string" + }, + { + "in": "query", + "name": "limit", + "description": "This number limits the page result of assets.", + "type": "integer", + "format": "int32" + }, + { + "in": "query", + "name": "orderby", + "description": "How the return assets are sorted. Default is property: created_date (newest first).", + "type": "string" + } + ], + "responses": { + "200": { + "description": "Returns the quick share with the given ID.", + "schema": { + "$ref": "#/definitions/quickShareFull" + } + }, + "400": { + "description": "Not valid quick share id! (Code: 02141b45-97dd-4474-aefb-a7774f8b538e)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "404": { + "description": "Quick share date expired! (Code: 6758d66e-0ce6-4770-a497-01a578eac12c)
or Quick share was not found. (Code: 412f11e3-5606-4075-a319-74ff1cee6a3e)
or Quick share date expired! (Code: da53b1d3-83eb-4fec-9f7c-56b571f117b2)
", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + } + } + }, + "/signalr/negotiate": { + "post": { + "tags": [ + "Public SignalR Connection Management" + ], + "description": "This endpoint delivers the connection data for a client.", + "operationId": "HttpSignalRNegotiate", + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "The signalr connection info for further processing.", + "schema": { + "$ref": "#/definitions/signalRConnectionInfo" + } + }, + "400": { + "description": "Could not negotiate with SignalR. (Code: 50e617b3-93e8-4b15-8072-0b3c12c26ec7)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/staticdefinedlists": { + "get": { + "tags": [ + "Public Static Defined List Management" + ], + "description": "This endpoint lists all static defined lists in database.", + "operationId": "HttpStaticDefinedListsGetAll", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "query", + "name": "translations", + "description": "When default language should be returned and the translation dictionary is delivered. (Ignores the \"Accept-Language\" header)", + "type": "boolean" + }, + { + "in": "header", + "name": "Accept-Language", + "description": "The requested language of the response. If not matching it falls back to default language.", + "type": "string" + } + ], + "responses": { + "200": { + "description": "Returns all static defined lists in database.", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/staticDefinedList" + } + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/staticdefinedlists/{id}": { + "get": { + "tags": [ + "Public Static Defined List Management" + ], + "description": "This endpoint gets a static defined list from database.", + "operationId": "HttpStaticDefinedListsGetById", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the static defined list.", + "required": true, + "type": "string" + }, + { + "in": "query", + "name": "translations", + "description": "When default language should be returned and the translation dictionary is delivered. (Ignores the \"Accept-Language\" header)", + "type": "boolean" + }, + { + "in": "header", + "name": "Accept-Language", + "description": "The requested language of the response. If not matching it falls back to default language.", + "type": "string" + } + ], + "responses": { + "200": { + "description": "Returns a static defined list with the given id.", + "schema": { + "$ref": "#/definitions/staticDefinedList" + } + }, + "404": { + "description": "The requested item could not be found." + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + }, + "post": { + "tags": [ + "Public Static Defined List Management" + ], + "description": "This endpoint update a static defined list in database (add, delete or replace values).", + "operationId": "HttpStaticDefinedListsUpdateById", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the static defined list.", + "required": true, + "type": "string" + }, + { + "in": "query", + "name": "translations", + "description": "When default language should be returned and the translation dictionary is delivered. (Ignores the \"Accept-Language\" header)", + "type": "boolean" + }, + { + "in": "header", + "name": "Accept-Language", + "description": "The requested language of the response. If not matching it falls back to default language.", + "type": "string" + }, + { + "in": "query", + "name": "updatemode", + "description": "The mode how the list should be updated. Available values are: add, delete and replace.", + "required": true, + "type": "string" + }, + { + "in": "body", + "name": "body", + "description": "The values which should be updated.", + "required": true, + "schema": { + "$ref": "#/definitions/staticDefinedList" + } + } + ], + "responses": { + "200": { + "description": "Returns the updated static defined list for values only the updated, deleted, added", + "schema": { + "$ref": "#/definitions/staticDefinedList" + } + }, + "400": { + "description": "Object is not a valid static_defined_list. (Code: 0970b102-0d79-4c1c-8144-2d6576234b5a)
No input object given. (Code: 4d2f5034-bf4f-4f19-8f3d-56e3d88b833a)Update mode: {given-update-mode} is not a valid update mode. Allowed modes are: add, delete, replace (Code: cb08ff14-4c6b-4d88-a1d7-7b39897d78e6)Error on create static defined list in database - max retry count is reached. (Code: a524c4cf-392e-4e37-9597-12cdce014757)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "404": { + "description": "If the static defined list with the ID was not found." + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/translations/{id}": { + "get": { + "tags": [ + "Public Translation Management" + ], + "description": "Get all the translations of a whole entity (Asset, Collection, Collection Type, Download Format)", + "operationId": "HttpTranslationsById", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of any translateable entity (Asset, Collection, Collection Type, Download Format).", + "required": true, + "type": "string" + }, + { + "in": "query", + "name": "items", + "description": "If the items should be included (only for entity type Collection and Asset).", + "type": "boolean" + } + ], + "responses": { + "200": { + "description": "Returns the dictionary of the dictionaries with all translations ", + "schema": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/dictionary_object" + } + } + }, + "400": { + "description": "Could not get all translations from {id}! (Code: fd86fae5-1eed-4770-b519-d403b85fa1d0)
Could not get entity {id} from database! (Code: eb42dc0d-78ee-4fc9-9a65-d5df472c7a03)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "404": { + "description": "If the entity with that ID was not found." + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/translations/{id}/{property}": { + "get": { + "tags": [ + "Public Translation Management" + ], + "description": "Get the translations of a specific field on the entity (Asset, Collection, Collection Type, Download Format)", + "operationId": "HttpTranslationsByIdFilterByProperty", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of any translateable entity (Asset, Collection, Collection Type, Download Format).", + "required": true, + "type": "string" + }, + { + "in": "query", + "name": "items", + "description": "If the items should be included (only for entity type Collection and Asset).", + "type": "boolean" + }, + { + "in": "path", + "name": "property", + "description": "Limit to one specific property (key)", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "Returns the dictionary of the dictionaries with all translations ", + "schema": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/dictionary_object" + } + } + }, + "400": { + "description": "Could not get all translations from {id}! (Code: fd86fae5-1eed-4770-b519-d403b85fa1d0)
Could not get entity {id} from database! (Code: eb42dc0d-78ee-4fc9-9a65-d5df472c7a03)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "404": { + "description": "If the entity with that ID was not found." + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/translations/{id}/custom/{customField}": { + "get": { + "tags": [ + "Public Translation Management" + ], + "description": "Get the translation of custom field on the entity (Asset, Collection)", + "operationId": "HttpTranslationsByIdFilterByCustomField", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of only translateable entities with custom fields (Asset, Collection).", + "required": true, + "type": "string" + }, + { + "in": "path", + "name": "customField", + "description": "Limit the output to a specific custom field key.", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "Returns the dictionary of the dictionaries with all translations ", + "schema": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/dictionary_object" + } + } + }, + "400": { + "description": "Could not get all translations from {id}! (Code: fd86fae5-1eed-4770-b519-d403b85fa1d0)
Could not get entity {id} from database! (Code: eb42dc0d-78ee-4fc9-9a65-d5df472c7a03)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "404": { + "description": "If the entity with that ID was not found." + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/webappdata/{id}": { + "get": { + "tags": [ + "Public Web App Data" + ], + "description": "This lists all elements of a given collection which can be used by the web frontend. It includes structure and all assets. All coming live from database.", + "operationId": "HttpGetWebAppData", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the collection for which this web data should be prepared.", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "This lists all elements which should be used by the web frontend.", + "schema": { + "$ref": "#/definitions/allWebAppData" + } + }, + "400": { + "description": "Update failed. (Code: e85183ec-6183-4329-a74f-6ceb963967a3)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "404": { + "description": "Collection not found - Never existed, not a collection or already deleted. (Code: 1d6325bf-7c1c-41ae-ba95-e41dd037a29f)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/data/collectiontype/{id}": { + "get": { + "tags": [ + "Public Web App Data" + ], + "description": "This returns all collections and assets from the given collection type.", + "operationId": "HttpGetDataCollectionType", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the collection type for which this web data should be prepared.", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "This returns all collections and assets from the given collection type.", + "schema": { + "$ref": "#/definitions/groupAllAppData" + } + }, + "400": { + "description": "Unknown request method (Code: 2e7570d3-7667-4bc9-89ea-f5d6f5aa84c0)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "404": { + "description": "Collection Type not found - Never existed, not a collection type or already deleted. (Code: 8f939f77-1ba9-40b7-905e-bef8ddc720a1)
or the web app data was never created (POST). (Code: 210910ed-68e8-4837-a58f-bfce0591cb49)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/workspaces": { + "get": { + "tags": [ + "Public Workspace Management" + ], + "description": "This lists all available workspaces which are stored in the database and not deleted (status \"A\").", + "operationId": "HttpWorkspacesGet", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "query", + "name": "translations", + "description": "When default language should be returned and the translation dictionary is delivered. (Ignores the \"Accept-Language\" header)", + "type": "boolean" + }, + { + "in": "header", + "name": "Accept-Language", + "description": "The requested language of the response. If not matching it falls back to default language.", + "type": "string" + } + ], + "responses": { + "200": { + "description": "Returns the all workspaces as array.", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/workspace" + } + } + }, + "400": { + "description": "Could not create connection to CosmosDB (Code: e244cef3-2665-4757-ba34-0d4d0e71bb9d)", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + }, + "/workspaces/{id}": { + "get": { + "tags": [ + "Public Workspace Management" + ], + "description": "Returns one single workspace (from ID).", + "operationId": "HttpWorkspacesGetById", + "produces": [ + "application/json" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the workspace.", + "required": true, + "type": "string" + }, + { + "in": "query", + "name": "translations", + "description": "When default language should be returned and the translation dictionary is delivered. (Ignores the \"Accept-Language\" header)", + "type": "boolean" + }, + { + "in": "header", + "name": "Accept-Language", + "description": "The requested language of the response. If not matching it falls back to default language.", + "type": "string" + } + ], + "responses": { + "200": { + "description": "Returns the workspace with the given ID.", + "schema": { + "$ref": "#/definitions/workspace" + } + }, + "404": { + "description": "If the workspace with the ID was not found.", + "schema": { + "$ref": "#/definitions/agravityErrorResponse" + } + }, + "401": { + "description": "Unauthorized. API Key not provided." + }, + "500": { + "description": "Internal server error. Please contact administrator." + } + }, + "security": [ + { + "function_key": [] + } + ] + } + } + }, + "definitions": { + "agravityErrorResponse": { + "type": "object", + "properties": { + "error_id": { + "type": "string" + }, + "error_message": { + "type": "string" + }, + "exception": { + "type": "string" + } + } + }, + "agravityInfoResponse": { + "type": "object", + "properties": { + "info_id": { + "type": "string" + }, + "info_message": { + "type": "string" + }, + "info_object": { + "type": "object" + } + } + }, + "agravityUser": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "entity_type": { + "type": "string" + }, + "name": { + "type": "string" + }, + "email": { + "type": "string" + }, + "impersonation": { + "type": "string" + }, + "apikey": { + "type": "string" + }, + "online_status": { + "$ref": "#/definitions/agravityUserOnlineStatus" + }, + "roles": { + "type": "array", + "items": { + "type": "string" + } + }, + "groups": { + "type": "array", + "items": { + "type": "string" + } + }, + "status": { + "type": "string" + }, + "created_date": { + "format": "date-time", + "type": "string" + }, + "created_by": { + "type": "string" + }, + "modified_date": { + "format": "date-time", + "type": "string" + }, + "modified_by": { + "type": "string" + }, + "pk": { + "type": "string" + }, + "_etag": { + "type": "string" + } + } + }, + "agravityUserOnlineStatus": { + "type": "object", + "properties": { + "status": { + "type": "string" + }, + "last_connection": { + "format": "date-time", + "type": "string" + } + } + }, + "agravityVersion": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "company": { + "type": "string" + }, + "customer": { + "type": "string" + }, + "contact": { + "type": "string" + }, + "updated": { + "format": "date-time", + "type": "string" + }, + "client_id": { + "type": "string" + }, + "tenant_id": { + "type": "string" + }, + "subscription_id": { + "type": "string" + }, + "base": { + "type": "string" + }, + "version": { + "type": "string" + }, + "enabled_features": { + "type": "array", + "items": { + "type": "string" + } + }, + "region": { + "type": "string" + } + } + }, + "allWebAppData": { + "type": "object", + "properties": { + "root_collection": { + "$ref": "#/definitions/collection" + }, + "subcollections": { + "type": "array", + "items": { + "$ref": "#/definitions/collection" + } + }, + "assets": { + "type": "array", + "items": { + "$ref": "#/definitions/asset" + } + }, + "pub_assets": { + "type": "array", + "items": { + "$ref": "#/definitions/publishedAsset" + } + }, + "created_date": { + "format": "date-time", + "type": "string" + } + } + }, + "asset": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "entity_type": { + "type": "string" + }, + "name": { + "type": "string" + }, + "asset_type": { + "type": "string" + }, + "duplicates": { + "type": "array", + "items": { + "type": "string" + } + }, + "keywords": { + "type": "array", + "items": { + "type": "string" + } + }, + "orig_blob": { + "$ref": "#/definitions/assetBlob" + }, + "blobs": { + "type": "array", + "items": { + "$ref": "#/definitions/assetBlob" + } + }, + "collections": { + "type": "array", + "items": { + "type": "string" + } + }, + "failed_reason": { + "type": "string" + }, + "quality_gate": { + "type": "array", + "items": { + "type": "string" + } + }, + "region_of_origin": { + "type": "string" + }, + "availability": { + "type": "string" + }, + "available_from": { + "format": "date-time", + "type": "string" + }, + "available_to": { + "format": "date-time", + "type": "string" + }, + "checkout": { + "$ref": "#/definitions/assetCheckout" + }, + "fs_synced": { + "type": "boolean" + }, + "custom": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/collTypeItem" + } + }, + "translations": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/dictionary_object" + } + }, + "role": { + "default": "NONE", + "enum": [ + "NONE", + "VIEWER", + "EDITOR" + ], + "type": "string" + }, + "description": { + "type": "string" + }, + "add_properties": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "status": { + "type": "string" + }, + "created_date": { + "format": "date-time", + "type": "string" + }, + "created_by": { + "type": "string" + }, + "modified_date": { + "format": "date-time", + "type": "string" + }, + "modified_by": { + "type": "string" + }, + "pk": { + "type": "string" + }, + "_etag": { + "type": "string" + } + } + }, + "assetAvailability": { + "type": "object", + "properties": { + "availability": { + "type": "string" + }, + "available_from": { + "format": "date-time", + "type": "string" + }, + "available_to": { + "format": "date-time", + "type": "string" + } + } + }, + "assetBlob": { + "type": "object", + "properties": { + "blob_type": { + "default": "UNKNOWN", + "enum": [ + "UNKNOWN", + "IMAGE", + "VIDEO", + "AUDIO", + "DOCUMENT", + "TEXT", + "OTHER" + ], + "type": "string" + }, + "name": { + "type": "string" + }, + "container": { + "type": "string" + }, + "size": { + "format": "int64", + "type": "integer" + }, + "extension": { + "type": "string" + }, + "content_type": { + "type": "string" + }, + "md5": { + "type": "string" + }, + "add_data": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "width": { + "format": "int32", + "type": "integer" + }, + "height": { + "format": "int32", + "type": "integer" + }, + "maxwidthheight": { + "format": "int32", + "type": "integer" + }, + "quality": { + "format": "double", + "type": "number" + }, + "orientation": { + "default": "PORTRAIT", + "enum": [ + "PORTRAIT", + "LANDSCAPE", + "SQUARE" + ], + "type": "string" + }, + "colorspace": { + "type": "string" + }, + "profile": { + "type": "string" + }, + "transparency": { + "type": "boolean" + }, + "mode": { + "type": "string" + }, + "target": { + "type": "string" + }, + "filter": { + "type": "string" + }, + "dpi_x": { + "format": "double", + "type": "number" + }, + "dpi_y": { + "format": "double", + "type": "number" + }, + "perhash": { + "type": "string" + }, + "dominantcolor": { + "type": "string" + }, + "depth": { + "format": "int32", + "type": "integer" + }, + "animated": { + "type": "boolean" + }, + "duration": { + "format": "int32", + "type": "integer" + }, + "videocodec": { + "type": "string" + }, + "videobitrate": { + "format": "int32", + "type": "integer" + }, + "fps": { + "format": "double", + "type": "number" + }, + "colormode": { + "type": "string" + }, + "audiocodec": { + "type": "string" + }, + "audiosamplerate": { + "type": "string" + }, + "audiochanneloutput": { + "type": "string" + }, + "audiobitrate": { + "format": "int32", + "type": "integer" + }, + "author": { + "type": "string" + }, + "title": { + "type": "string" + }, + "language": { + "type": "string" + }, + "wordcount": { + "format": "int32", + "type": "integer" + }, + "pages": { + "format": "int32", + "type": "integer" + }, + "encoding_name": { + "type": "string" + }, + "encoding_code": { + "type": "string" + }, + "url": { + "type": "string" + }, + "size_readable": { + "type": "string" + }, + "downloadable": { + "type": "boolean" + }, + "expires": { + "format": "date-time", + "type": "string" + }, + "uploaded_date": { + "format": "date-time", + "type": "string" + }, + "uploaded_by": { + "type": "string" + } + } + }, + "assetBulkUpdate": { + "type": "object", + "properties": { + "collection_id": { + "type": "string" + }, + "ref_asset": { + "$ref": "#/definitions/asset" + }, + "asset_ids": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "assetCheckout": { + "type": "object", + "properties": { + "user_id": { + "type": "string" + }, + "checkout_date": { + "format": "date-time", + "type": "string" + } + } + }, + "assetIconRule": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "entity_type": { + "type": "string" + }, + "type": { + "type": "string" + }, + "path": { + "type": "string" + }, + "color": { + "type": "string" + }, + "value": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "translations": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/dictionary_object" + } + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "add_properties": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "status": { + "type": "string" + }, + "created_date": { + "format": "date-time", + "type": "string" + }, + "created_by": { + "type": "string" + }, + "modified_date": { + "format": "date-time", + "type": "string" + }, + "modified_by": { + "type": "string" + }, + "pk": { + "type": "string" + }, + "_etag": { + "type": "string" + } + } + }, + "assetIdFormat": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "format": { + "type": "string" + } + } + }, + "assetMultiPartForm": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "collectionid": { + "type": "string" + }, + "file": { + "format": "binary", + "type": "string" + }, + "filename": { + "type": "string" + }, + "previewof": { + "type": "string" + } + } + }, + "assetPageResult": { + "type": "object", + "properties": { + "page": { + "type": "array", + "items": { + "$ref": "#/definitions/asset" + } + }, + "page_size": { + "format": "int32", + "type": "integer" + }, + "size": { + "format": "int32", + "type": "integer" + }, + "continuation_token": { + "type": "string" + }, + "filter": { + "type": "array", + "items": { + "$ref": "#/definitions/whereParam" + } + } + } + }, + "assetRelation": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "entity_type": { + "type": "string" + }, + "assets": { + "type": "array", + "items": { + "$ref": "#/definitions/relatedAsset" + } + }, + "status": { + "type": "string" + }, + "created_date": { + "format": "date-time", + "type": "string" + }, + "created_by": { + "type": "string" + }, + "modified_date": { + "format": "date-time", + "type": "string" + }, + "modified_by": { + "type": "string" + }, + "pk": { + "type": "string" + }, + "_etag": { + "type": "string" + } + } + }, + "assetRelationType": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "entity_type": { + "type": "string" + }, + "hierarchical": { + "type": "boolean" + }, + "sequential": { + "type": "boolean" + }, + "unique_per_asset": { + "type": "boolean" + }, + "translations": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/dictionary_object" + } + }, + "permissions": { + "type": "array", + "items": { + "$ref": "#/definitions/permissionEntity" + } + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "add_properties": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "status": { + "type": "string" + }, + "created_date": { + "format": "date-time", + "type": "string" + }, + "created_by": { + "type": "string" + }, + "modified_date": { + "format": "date-time", + "type": "string" + }, + "modified_by": { + "type": "string" + }, + "pk": { + "type": "string" + }, + "_etag": { + "type": "string" + } + } + }, + "azSearchOptions": { + "type": "object", + "properties": { + "searchString": { + "type": "string" + }, + "limit": { + "format": "int32", + "type": "integer" + }, + "skip": { + "format": "int32", + "type": "integer" + }, + "collectiontypeid": { + "type": "string" + }, + "collectionid": { + "type": "string" + }, + "filter": { + "type": "string" + }, + "orderby": { + "type": "string" + }, + "mode": { + "type": "string" + }, + "broadness": { + "format": "int32", + "type": "integer" + }, + "rel_id": { + "type": "string" + }, + "ids": { + "type": "string" + }, + "portal_id": { + "type": "string" + }, + "scopefilter": { + "type": "string" + } + } + }, + "collection": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "entity_type": { + "type": "string" + }, + "parent": { + "type": "string" + }, + "path": { + "type": "string" + }, + "level": { + "format": "int32", + "type": "integer" + }, + "custom": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/collTypeItem" + } + }, + "translations": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/dictionary_object" + } + }, + "role": { + "default": "NONE", + "enum": [ + "NONE", + "VIEWER", + "EDITOR" + ], + "type": "string" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "add_properties": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "status": { + "type": "string" + }, + "created_date": { + "format": "date-time", + "type": "string" + }, + "created_by": { + "type": "string" + }, + "modified_date": { + "format": "date-time", + "type": "string" + }, + "modified_by": { + "type": "string" + }, + "pk": { + "type": "string" + }, + "_etag": { + "type": "string" + } + } + }, + "collectionType": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "entity_type": { + "type": "string" + }, + "name": { + "type": "string" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/collTypeItem" + } + }, + "translations": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/dictionary_object" + } + }, + "order": { + "format": "int32", + "type": "integer" + }, + "permissions": { + "type": "array", + "items": { + "$ref": "#/definitions/permissionEntity" + } + }, + "permissionless": { + "type": "boolean" + }, + "role": { + "default": "NONE", + "enum": [ + "NONE", + "VIEWER", + "EDITOR" + ], + "type": "string" + }, + "description": { + "type": "string" + }, + "add_properties": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "status": { + "type": "string" + }, + "created_date": { + "format": "date-time", + "type": "string" + }, + "created_by": { + "type": "string" + }, + "modified_date": { + "format": "date-time", + "type": "string" + }, + "modified_by": { + "type": "string" + }, + "pk": { + "type": "string" + }, + "_etag": { + "type": "string" + } + } + }, + "collectionUDL": { + "type": "object", + "properties": { + "children": { + "type": "array", + "items": { + "$ref": "#/definitions/entityIdName" + } + }, + "name": { + "type": "string" + }, + "entity_type": { + "type": "string" + }, + "status": { + "type": "string" + }, + "translations": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/dictionary_object" + } + }, + "id": { + "type": "string" + }, + "pk": { + "type": "string" + } + } + }, + "collectionUDLListEntity": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "entity_type": { + "type": "string" + }, + "udl_refs": { + "type": "array", + "items": { + "$ref": "#/definitions/collectionUDLReference" + } + }, + "udl_entries": { + "type": "array", + "items": { + "$ref": "#/definitions/collectionUDL" + } + }, + "status": { + "type": "string" + }, + "created_date": { + "format": "date-time", + "type": "string" + }, + "created_by": { + "type": "string" + }, + "modified_date": { + "format": "date-time", + "type": "string" + }, + "modified_by": { + "type": "string" + }, + "pk": { + "type": "string" + }, + "_etag": { + "type": "string" + } + } + }, + "collectionUDLReference": { + "type": "object", + "properties": { + "parent": { + "type": "string" + }, + "coll_types": { + "type": "array", + "items": { + "type": "string" + } + }, + "permissions": { + "type": "array", + "items": { + "$ref": "#/definitions/permissionEntity" + } + } + } + }, + "collTypeItem": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "entity_type": { + "type": "string" + }, + "name": { + "type": "string" + }, + "item_type": { + "type": "string" + }, + "format": { + "type": "string" + }, + "label": { + "type": "string" + }, + "default_value": { + "type": "object" + }, + "mandatory": { + "type": "boolean" + }, + "searchable": { + "type": "boolean" + }, + "onlyasset": { + "type": "boolean" + }, + "multi": { + "type": "boolean" + }, + "md5": { + "type": "string" + }, + "group": { + "type": "string" + }, + "order": { + "format": "int32", + "type": "integer" + }, + "translations": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/dictionary_object" + } + }, + "status": { + "type": "string" + }, + "created_date": { + "format": "date-time", + "type": "string" + }, + "created_by": { + "type": "string" + }, + "modified_date": { + "format": "date-time", + "type": "string" + }, + "modified_by": { + "type": "string" + }, + "pk": { + "type": "string" + }, + "_etag": { + "type": "string" + } + } + }, + "createSftpUserResult": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "password": { + "type": "string" + } + } + }, + "customClaimsProviderResponseActionAttributeCollectionSubmit": { + "type": "object", + "properties": { + "@odata.type": { + "type": "string" + } + } + }, + "customClaimsProviderResponseActionTokenIssuanceStart": { + "type": "object", + "properties": { + "claims": { + "$ref": "#/definitions/customClaimsProviderResponseClaims" + }, + "@odata.type": { + "type": "string" + } + } + }, + "customClaimsProviderResponseClaims": { + "type": "object", + "properties": { + "userContext": { + "type": "array", + "items": { + "type": "string" + } + }, + "role": { + "type": "string" + } + } + }, + "customClaimsProviderResponseContentAttributeCollectionSubmit": { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/customClaimsProviderResponseDataAttributeCollectionSubmit" + } + } + }, + "customClaimsProviderResponseContentTokenIssuanceStart": { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/customClaimsProviderResponseDataTokenIssuanceStart" + } + } + }, + "customClaimsProviderResponseDataAttributeCollectionSubmit": { + "type": "object", + "properties": { + "actions": { + "type": "array", + "items": { + "$ref": "#/definitions/customClaimsProviderResponseActionAttributeCollectionSubmit" + } + }, + "@odata.type": { + "type": "string" + } + } + }, + "customClaimsProviderResponseDataTokenIssuanceStart": { + "type": "object", + "properties": { + "actions": { + "type": "array", + "items": { + "$ref": "#/definitions/customClaimsProviderResponseActionTokenIssuanceStart" + } + }, + "@odata.type": { + "type": "string" + } + } + }, + "dataResult": { + "type": "object", + "properties": { + "asset": { + "type": "array", + "items": { + "$ref": "#/definitions/asset" + } + }, + "sum_asset_results": { + "format": "int32", + "type": "integer" + }, + "collection": { + "type": "array", + "items": { + "$ref": "#/definitions/collection" + } + }, + "sum_collection_results": { + "format": "int32", + "type": "integer" + } + } + }, + "deletedEntities": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "deleted": { + "format": "date-time", + "type": "string" + }, + "entity_type": { + "type": "string" + } + } + }, + "dictionary_object": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "distZipResponse": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "modified_date": { + "format": "date-time", + "type": "string" + }, + "size": { + "format": "int64", + "type": "integer" + } + } + }, + "downloadFormat": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "entity_type": { + "type": "string" + }, + "operations": { + "type": "array", + "items": { + "$ref": "#/definitions/dynamicImageOperation" + } + }, + "extension": { + "type": "string" + }, + "asset_type": { + "type": "string" + }, + "origin": { + "type": "string" + }, + "fallback_thumb": { + "type": "boolean" + }, + "target_filename": { + "type": "string" + }, + "translations": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/dictionary_object" + } + }, + "permissions": { + "type": "array", + "items": { + "$ref": "#/definitions/permissionEntity" + } + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "add_properties": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "status": { + "type": "string" + }, + "created_date": { + "format": "date-time", + "type": "string" + }, + "created_by": { + "type": "string" + }, + "modified_date": { + "format": "date-time", + "type": "string" + }, + "modified_by": { + "type": "string" + }, + "pk": { + "type": "string" + }, + "_etag": { + "type": "string" + } + } + }, + "downloadZipRequest": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "zip_type": { + "default": "DOWNLOAD", + "enum": [ + "DOWNLOAD", + "SHARED", + "QUICKSHARE", + "PORTAL" + ], + "type": "string" + }, + "asset_ids": { + "type": "array", + "items": { + "type": "string" + } + }, + "allowed_formats": { + "type": "array", + "items": { + "$ref": "#/definitions/sharedAllowedFormat" + } + }, + "zipname": { + "type": "string" + }, + "email_to": { + "type": "array", + "items": { + "type": "string" + } + }, + "message": { + "type": "string" + }, + "valid_until": { + "format": "date-time", + "type": "string" + } + } + }, + "downloadZipStatus": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "user": { + "type": "string" + }, + "percent": { + "format": "double", + "type": "number" + }, + "part": { + "format": "double", + "type": "number" + }, + "count": { + "format": "int32", + "type": "integer" + }, + "message": { + "type": "string" + }, + "status": { + "type": "string" + }, + "zip_type": { + "default": "DOWNLOAD", + "enum": [ + "DOWNLOAD", + "SHARED", + "QUICKSHARE", + "PORTAL" + ], + "type": "string" + }, + "zipname": { + "type": "string" + }, + "size": { + "type": "string" + }, + "url": { + "type": "string" + } + } + }, + "dynamicImageOperation": { + "type": "object", + "properties": { + "operation": { + "type": "string" + }, + "params": { + "type": "array", + "items": { + "type": "object" + } + } + } + }, + "entityId": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "pk": { + "type": "string" + } + } + }, + "entityIdName": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "entity_type": { + "type": "string" + }, + "status": { + "type": "string" + }, + "translations": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/dictionary_object" + } + }, + "id": { + "type": "string" + }, + "pk": { + "type": "string" + } + } + }, + "entityListResult": { + "type": "object", + "properties": { + "entities": { + "type": "array", + "items": { + "$ref": "#/definitions/entityIdName" + } + }, + "notfounds": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "entityNamesRequest": { + "type": "object", + "properties": { + "names": { + "type": "array", + "items": { + "type": "string" + } + }, + "filter": { + "type": "string" + } + } + }, + "file": { + "type": "object" + }, + "frontendAppConfig": { + "type": "object", + "properties": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + }, + "description": { + "type": "string" + }, + "contentType": { + "type": "string" + }, + "sinceApiVersion": { + "type": "string" + } + } + }, + "groupAllAppData": { + "type": "object", + "properties": { + "collection_type": { + "$ref": "#/definitions/collectionType" + }, + "collections": { + "type": "array", + "items": { + "$ref": "#/definitions/collection" + } + }, + "assets": { + "type": "array", + "items": { + "$ref": "#/definitions/asset" + } + }, + "created_date": { + "format": "date-time", + "type": "string" + }, + "add_info": { + "type": "array", + "items": { + "$ref": "#/definitions/keyValuePair_object" + } + }, + "dist": { + "$ref": "#/definitions/distZipResponse" + } + } + }, + "keyValuePair_object": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "moveCollectionBody": { + "type": "object", + "properties": { + "from_collection_id": { + "type": "string" + }, + "to_collection_id": { + "type": "string" + }, + "operation": { + "type": "string" + } + } + }, + "permissionEntity": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "role": { + "default": "NONE", + "enum": [ + "NONE", + "VIEWER", + "EDITOR" + ], + "type": "string" + } + } + }, + "portal": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "entity_type": { + "type": "string" + }, + "authentication": { + "$ref": "#/definitions/portalAuthentication" + }, + "languages": { + "type": "string" + }, + "fields": { + "type": "array", + "items": { + "$ref": "#/definitions/portalFields" + } + }, + "filter": { + "type": "string" + }, + "limit_ids": { + "type": "array", + "items": { + "type": "string" + } + }, + "allowed_formats": { + "type": "array", + "items": { + "$ref": "#/definitions/sharedAllowedFormat" + } + }, + "asset_icon_rules": { + "type": "array", + "items": { + "$ref": "#/definitions/assetIconRule" + } + }, + "allowed_origins": { + "type": "array", + "items": { + "type": "string" + } + }, + "links": { + "$ref": "#/definitions/portalLinks" + }, + "theme": { + "$ref": "#/definitions/portalTheme" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "add_properties": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "status": { + "type": "string" + }, + "created_date": { + "format": "date-time", + "type": "string" + }, + "created_by": { + "type": "string" + }, + "modified_date": { + "format": "date-time", + "type": "string" + }, + "modified_by": { + "type": "string" + }, + "pk": { + "type": "string" + }, + "_etag": { + "type": "string" + } + } + }, + "portalAuthentication": { + "type": "object", + "properties": { + "method": { + "default": "UNDEFINED", + "enum": [ + "UNDEFINED", + "NONE", + "PASSWORD", + "EEID", + "AUTH0" + ], + "type": "string" + }, + "issuer": { + "type": "string" + }, + "client_id": { + "type": "string" + }, + "tenant_id": { + "type": "string" + }, + "password": { + "type": "string" + } + } + }, + "portalConfiguration": { + "type": "object", + "properties": { + "download_formats": { + "type": "array", + "items": { + "$ref": "#/definitions/downloadFormat" + } + }, + "sdls": { + "type": "array", + "items": { + "$ref": "#/definitions/staticDefinedList" + } + }, + "udls": { + "type": "array", + "items": { + "$ref": "#/definitions/collectionUDL" + } + }, + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/collTypeItem" + } + }, + "configs": { + "type": "array", + "items": { + "$ref": "#/definitions/frontendAppConfig" + } + }, + "id": { + "type": "string" + }, + "entity_type": { + "type": "string" + }, + "authentication": { + "$ref": "#/definitions/portalAuthentication" + }, + "languages": { + "type": "string" + }, + "fields": { + "type": "array", + "items": { + "$ref": "#/definitions/portalFields" + } + }, + "filter": { + "type": "string" + }, + "limit_ids": { + "type": "array", + "items": { + "type": "string" + } + }, + "allowed_formats": { + "type": "array", + "items": { + "$ref": "#/definitions/sharedAllowedFormat" + } + }, + "asset_icon_rules": { + "type": "array", + "items": { + "$ref": "#/definitions/assetIconRule" + } + }, + "allowed_origins": { + "type": "array", + "items": { + "type": "string" + } + }, + "links": { + "$ref": "#/definitions/portalLinks" + }, + "theme": { + "$ref": "#/definitions/portalTheme" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "add_properties": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "status": { + "type": "string" + }, + "created_date": { + "format": "date-time", + "type": "string" + }, + "created_by": { + "type": "string" + }, + "modified_date": { + "format": "date-time", + "type": "string" + }, + "modified_by": { + "type": "string" + }, + "pk": { + "type": "string" + }, + "_etag": { + "type": "string" + } + } + }, + "portalFields": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "detail_order": { + "format": "int32", + "type": "integer" + }, + "facet_order": { + "format": "int32", + "type": "integer" + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "user_context": { + "$ref": "#/definitions/portalUserContext" + }, + "format": { + "type": "string" + } + } + }, + "portalLinks": { + "type": "object", + "properties": { + "conditions": { + "type": "string" + }, + "privacy": { + "type": "string" + }, + "impressum": { + "type": "string" + } + } + }, + "portalTheme": { + "type": "object", + "properties": { + "logo_url": { + "type": "string" + }, + "topbar_color": { + "type": "string" + }, + "background_url": { + "type": "string" + }, + "fav_icon": { + "type": "string" + }, + "icon_empty": { + "type": "string" + }, + "icon_active": { + "type": "string" + }, + "colors": { + "type": "object", + "additionalProperties": { + "type": "object" + } + } + } + }, + "portalUserContext": { + "type": "object", + "properties": { + "key": { + "type": "string" + }, + "mandatory": { + "type": "boolean" + }, + "mapping": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "options": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "publishedAsset": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "target": { + "type": "string" + }, + "description": { + "type": "string" + }, + "usecases": { + "type": "array", + "items": { + "type": "string" + } + }, + "created_date": { + "format": "date-time", + "type": "string" + }, + "created_by": { + "type": "string" + }, + "url": { + "type": "string" + }, + "cdn": { + "type": "string" + }, + "status_table_id": { + "type": "string" + }, + "format": { + "type": "string" + }, + "properties": { + "type": "object", + "additionalProperties": { + "type": "object" + } + } + } + }, + "publishEntity": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "entity_type": { + "type": "string" + }, + "published": { + "type": "array", + "items": { + "$ref": "#/definitions/publishedAsset" + } + }, + "region_of_origin": { + "type": "string" + }, + "status": { + "type": "string" + }, + "created_date": { + "format": "date-time", + "type": "string" + }, + "created_by": { + "type": "string" + }, + "modified_date": { + "format": "date-time", + "type": "string" + }, + "modified_by": { + "type": "string" + }, + "pk": { + "type": "string" + }, + "_etag": { + "type": "string" + } + } + }, + "quickShareFull": { + "type": "object", + "properties": { + "page": { + "type": "array", + "items": { + "$ref": "#/definitions/sharedAsset" + } + }, + "page_size": { + "format": "int32", + "type": "integer" + }, + "size": { + "format": "int32", + "type": "integer" + }, + "continuation_token": { + "type": "string" + }, + "id": { + "type": "string" + }, + "entity_type": { + "type": "string" + }, + "name": { + "type": "string" + }, + "assets": { + "type": "array", + "items": { + "$ref": "#/definitions/assetIdFormat" + } + }, + "users": { + "type": "array", + "items": { + "$ref": "#/definitions/entityId" + } + }, + "expires": { + "format": "date-time", + "type": "string" + }, + "url": { + "type": "string" + }, + "zip_url": { + "type": "string" + }, + "status": { + "type": "string" + }, + "created_date": { + "format": "date-time", + "type": "string" + }, + "created_by": { + "type": "string" + }, + "modified_date": { + "format": "date-time", + "type": "string" + }, + "modified_by": { + "type": "string" + }, + "pk": { + "type": "string" + }, + "_etag": { + "type": "string" + } + } + }, + "relatedAsset": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "parent": { + "type": "boolean" + } + } + }, + "sasToken": { + "type": "object", + "properties": { + "token": { + "type": "string" + }, + "container": { + "type": "string" + }, + "blob": { + "type": "string" + }, + "url": { + "type": "string" + }, + "fulltoken": { + "type": "string" + }, + "expires": { + "format": "date-time", + "type": "string" + } + } + }, + "savedSearch": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "entity_type": { + "type": "string" + }, + "searchstring": { + "type": "string" + }, + "external": { + "type": "boolean" + }, + "translations": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/dictionary_object" + } + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "add_properties": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "status": { + "type": "string" + }, + "created_date": { + "format": "date-time", + "type": "string" + }, + "created_by": { + "type": "string" + }, + "modified_date": { + "format": "date-time", + "type": "string" + }, + "modified_by": { + "type": "string" + }, + "pk": { + "type": "string" + }, + "_etag": { + "type": "string" + } + } + }, + "searchableItem": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "is_key": { + "type": "boolean" + }, + "filterable": { + "type": "boolean" + }, + "hidden": { + "type": "boolean" + }, + "searchable": { + "type": "boolean" + }, + "facetable": { + "type": "boolean" + }, + "sortable": { + "type": "boolean" + }, + "is_collection": { + "type": "boolean" + }, + "searchtype": { + "type": "string" + }, + "fields": { + "type": "array", + "items": { + "$ref": "#/definitions/searchableItem" + } + } + } + }, + "searchAdminDataSourceStatus": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "status": { + "type": "string" + } + } + }, + "searchAdminIndexerLastRun": { + "type": "object", + "properties": { + "status": { + "type": "string" + }, + "starttime": { + "format": "date-time", + "type": "string" + }, + "endtime": { + "format": "date-time", + "type": "string" + }, + "itemcount": { + "format": "int64", + "type": "integer" + }, + "faileditemcount": { + "format": "int64", + "type": "integer" + } + } + }, + "searchAdminIndexerStatus": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "status": { + "type": "string" + }, + "error": { + "type": "string" + }, + "lastrun": { + "$ref": "#/definitions/searchAdminIndexerLastRun" + }, + "history": { + "type": "array", + "items": { + "$ref": "#/definitions/searchAdminIndexerLastRun" + } + } + } + }, + "searchAdminIndexStatus": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "status": { + "type": "string" + }, + "statistics": { + "$ref": "#/definitions/searchAdminStatistics" + } + } + }, + "searchAdminSkillStatus": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "skills": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "searchAdminStatistics": { + "type": "object", + "properties": { + "documentcount": { + "format": "int64", + "type": "integer" + }, + "storagesizebytes": { + "format": "int64", + "type": "integer" + } + } + }, + "searchAdminStatus": { + "type": "object", + "properties": { + "index": { + "$ref": "#/definitions/searchAdminIndexStatus" + }, + "indexer": { + "$ref": "#/definitions/searchAdminIndexerStatus" + }, + "datasource": { + "$ref": "#/definitions/searchAdminDataSourceStatus" + }, + "skillsets": { + "type": "array", + "items": { + "$ref": "#/definitions/searchAdminSkillStatus" + } + } + } + }, + "searchFacet": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "entities": { + "type": "array", + "items": { + "$ref": "#/definitions/searchFacetEntity" + } + } + } + }, + "searchFacetEntity": { + "type": "object", + "properties": { + "count": { + "format": "int64", + "type": "integer" + }, + "value": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "searchResult": { + "type": "object", + "properties": { + "data_result": { + "$ref": "#/definitions/dataResult" + }, + "options": { + "$ref": "#/definitions/azSearchOptions" + }, + "facets": { + "type": "array", + "items": { + "$ref": "#/definitions/searchFacet" + } + }, + "count": { + "format": "int64", + "type": "integer" + } + } + }, + "secureUploadEntity": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "entity_type": { + "type": "string" + }, + "collection_id": { + "type": "string" + }, + "url": { + "type": "string" + }, + "valid_until": { + "format": "date-time", + "type": "string" + }, + "password": { + "type": "string" + }, + "asset_tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "message": { + "type": "string" + }, + "sftp_connection": { + "$ref": "#/definitions/createSftpUserResult" + }, + "check_name_for_version": { + "type": "boolean" + }, + "status": { + "type": "string" + }, + "created_date": { + "format": "date-time", + "type": "string" + }, + "created_by": { + "type": "string" + }, + "modified_date": { + "format": "date-time", + "type": "string" + }, + "modified_by": { + "type": "string" + }, + "pk": { + "type": "string" + }, + "_etag": { + "type": "string" + } + } + }, + "sharedAllowedFormat": { + "type": "object", + "properties": { + "asset_type": { + "type": "string" + }, + "format": { + "type": "string" + } + } + }, + "sharedAsset": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "created_date": { + "format": "date-time", + "type": "string" + }, + "modified_date": { + "format": "date-time", + "type": "string" + }, + "asset_type": { + "type": "string" + }, + "orig_blob": { + "$ref": "#/definitions/assetBlob" + }, + "blobs": { + "type": "array", + "items": { + "$ref": "#/definitions/assetBlob" + } + } + } + }, + "sharedCollectionFull": { + "type": "object", + "properties": { + "page": { + "type": "array", + "items": { + "$ref": "#/definitions/sharedAsset" + } + }, + "page_size": { + "format": "int32", + "type": "integer" + }, + "size": { + "format": "int32", + "type": "integer" + }, + "continuation_token": { + "type": "string" + }, + "id": { + "type": "string" + }, + "entity_type": { + "type": "string" + }, + "collection_id": { + "type": "string" + }, + "url": { + "type": "string" + }, + "valid_until": { + "format": "date-time", + "type": "string" + }, + "valid_for": { + "type": "string" + }, + "message": { + "type": "string" + }, + "global": { + "type": "boolean" + }, + "allowed_formats": { + "type": "array", + "items": { + "$ref": "#/definitions/sharedAllowedFormat" + } + }, + "password": { + "type": "string" + }, + "status": { + "type": "string" + }, + "created_date": { + "format": "date-time", + "type": "string" + }, + "created_by": { + "type": "string" + }, + "modified_date": { + "format": "date-time", + "type": "string" + }, + "modified_by": { + "type": "string" + }, + "pk": { + "type": "string" + }, + "_etag": { + "type": "string" + } + } + }, + "signalRConnectionInfo": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "accessToken": { + "type": "string" + } + } + }, + "staticDefinedList": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "entity_type": { + "type": "string" + }, + "translations": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/dictionary_object" + } + }, + "values": { + "type": "array", + "items": { + "type": "string" + } + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "add_properties": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "status": { + "type": "string" + }, + "created_date": { + "format": "date-time", + "type": "string" + }, + "created_by": { + "type": "string" + }, + "modified_date": { + "format": "date-time", + "type": "string" + }, + "modified_by": { + "type": "string" + }, + "pk": { + "type": "string" + }, + "_etag": { + "type": "string" + } + } + }, + "versionedAsset": { + "type": "object", + "properties": { + "version_nr": { + "format": "int32", + "type": "integer" + }, + "until_date": { + "format": "date-time", + "type": "string" + }, + "version_info": { + "type": "string" + }, + "created_date": { + "format": "date-time", + "type": "string" + }, + "created_by": { + "type": "string" + }, + "blob_data": { + "$ref": "#/definitions/assetBlob" + }, + "blob_uploaded": { + "format": "date-time", + "type": "string" + }, + "mime_type": { + "type": "string" + } + } + }, + "versionEntity": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "entity_type": { + "type": "string" + }, + "versions": { + "type": "array", + "items": { + "$ref": "#/definitions/versionedAsset" + } + }, + "region_of_origin": { + "type": "string" + }, + "status": { + "type": "string" + }, + "created_date": { + "format": "date-time", + "type": "string" + }, + "created_by": { + "type": "string" + }, + "modified_date": { + "format": "date-time", + "type": "string" + }, + "modified_by": { + "type": "string" + }, + "pk": { + "type": "string" + }, + "_etag": { + "type": "string" + } + } + }, + "whereParam": { + "type": "object", + "properties": { + "operator": { + "default": "Equals", + "enum": [ + "Equals", + "NotEquals", + "GreaterThan", + "LessThan", + "GreaterThanOrEqual", + "LessThanOrEqual", + "Contains", + "StartsWith", + "ArrayContains", + "ArrayContainsPartial", + "IsDefined", + "IsNotDefined", + "IsEmpty", + "IsNotEmpty" + ], + "type": "string" + }, + "field": { + "type": "string" + }, + "value": { + "type": "object" + }, + "notPrefix": { + "type": "boolean" + }, + "valueType": { + "default": "String", + "enum": [ + "String", + "Bool", + "Number" + ], + "type": "string" + } + } + }, + "workspace": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "entity_type": { + "type": "string" + }, + "name": { + "type": "string" + }, + "collection_types": { + "type": "array", + "items": { + "$ref": "#/definitions/collectionType" + } + }, + "translations": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/dictionary_object" + } + }, + "order": { + "format": "int32", + "type": "integer" + }, + "permissions": { + "type": "array", + "items": { + "$ref": "#/definitions/permissionEntity" + } + }, + "description": { + "type": "string" + }, + "add_properties": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "status": { + "type": "string" + }, + "created_date": { + "format": "date-time", + "type": "string" + }, + "created_by": { + "type": "string" + }, + "modified_date": { + "format": "date-time", + "type": "string" + }, + "modified_by": { + "type": "string" + }, + "pk": { + "type": "string" + }, + "_etag": { + "type": "string" + } + } + } + }, + "securityDefinitions": { + "function_key": { + "type": "apiKey", + "name": "x-functions-key", + "in": "header" + } + } +} \ No newline at end of file diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..65140f2 --- /dev/null +++ b/tests/__init__.py @@ -0,0 +1 @@ +# tests package diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..bbec9da --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,31 @@ +"""Shared pytest fixtures for the agravity-client test suite.""" +from __future__ import annotations + +import pytest +import pytest_asyncio +import httpx + +from agravity_client.client import AgravityClient +from agravity_client.config import AgravityConfig + + +@pytest.fixture +def config() -> AgravityConfig: + """Return a test AgravityConfig with a dummy API key.""" + return AgravityConfig( + api_key="test-api-key", + base_url="https://api.example.local/api", + ) + + +@pytest_asyncio.fixture +async def client(config: AgravityConfig) -> AgravityClient: + """Return an AgravityClient backed by a real (but not-yet-connected) transport. + + Tests that need to mock HTTP responses should use ``pytest-httpx``'s + ``httpx_mock`` fixture and pass a transport via:: + + client._http = httpx.AsyncClient(transport=httpx_mock.get_async_handler()) + """ + async with AgravityClient(config) as c: + yield c diff --git a/tests/test_models.py b/tests/test_models.py new file mode 100644 index 0000000..881dd00 --- /dev/null +++ b/tests/test_models.py @@ -0,0 +1,72 @@ +"""Basic smoke tests for Pydantic model validation.""" +from __future__ import annotations + +import pytest +from agravity_client.models import ( + Asset, + AssetBlob, + AssetBlobType, + AssetPageResult, + Collection, + AgravityVersion, + SearchResult, + AzSearchOptions, +) + + +class TestAssetModel: + def test_minimal_asset(self): + asset = Asset.model_validate({"id": "abc123"}) + assert asset.id == "abc123" + + def test_asset_with_blob_type_enum(self): + asset = Asset.model_validate({ + "id": "abc", + "asset_type": "IMAGE", + }) + assert asset.asset_type == "IMAGE" + + def test_asset_page_result(self): + result = AssetPageResult.model_validate({ + "assets": [{"id": "a1"}, {"id": "a2"}], + "size": 2, + }) + assert len(result.assets) == 2 + assert result.assets[0].id == "a1" + + def test_extra_fields_allowed(self): + """Unknown API fields must not raise ValidationError.""" + asset = Asset.model_validate({"id": "x", "future_field": "value"}) + assert asset.id == "x" + + +class TestCollectionModel: + def test_minimal_collection(self): + coll = Collection.model_validate({"id": "c1", "name": "Root"}) + assert coll.id == "c1" + assert coll.name == "Root" + + +class TestVersionModel: + def test_agravity_version(self): + v = AgravityVersion.model_validate({ + "name": "Agravity", + "version": "10.3.0", + }) + assert v.version == "10.3.0" + + +class TestSearchModels: + def test_search_options_defaults(self): + opts = AzSearchOptions() + assert opts.limit is None + + def test_search_options_with_values(self): + opts = AzSearchOptions(searchterm="hello", limit=5) + dumped = opts.model_dump(exclude_none=True) + assert dumped["searchterm"] == "hello" + assert dumped["limit"] == 5 + + def test_search_result_minimal(self): + result = SearchResult.model_validate({}) + assert result.count is None