feat: add new API endpoints for user retrieval, collection type items, portal token enhancement, and secure file upload
This commit is contained in:
parent
64ea445ec3
commit
59d29d28d2
6 changed files with 459 additions and 0 deletions
373
ENDPOINT_COVERAGE_REPORT.md
Normal file
373
ENDPOINT_COVERAGE_REPORT.md
Normal file
|
|
@ -0,0 +1,373 @@
|
||||||
|
# Agravity Client - Endpoint Coverage Report
|
||||||
|
**Generated**: March 25, 2026
|
||||||
|
**Thoroughness Level**: Thorough Analysis
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Executive Summary
|
||||||
|
|
||||||
|
This report analyzes the API endpoint coverage in the **agravity_client** Python SDK against the Agravity OpenAPI 10.3.0 specification (swagger.json). The analysis identifies which Swagger endpoints are implemented in the client, which are missing, and any extra client methods not in the specification.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. FULLY IMPLEMENTED ENDPOINTS
|
||||||
|
|
||||||
|
### Portal Management (`/portals*`)
|
||||||
|
| Endpoint | Method | Client Implementation |
|
||||||
|
|----------|--------|----------------------|
|
||||||
|
| `/portals/{id}` | GET | ✅ `PortalsApi.get_portal()` |
|
||||||
|
| `/portals/{id}/config` | GET | ✅ `PortalsApi.get_portal_config()` |
|
||||||
|
| `/portals/{id}/zip` | POST | ✅ `PortalsApi.create_portal_zip()` |
|
||||||
|
| `/portals/{id}/zip` | GET | ✅ `PortalsApi.get_portal_zip_status()` |
|
||||||
|
| `/portals/{id}/zip/{zipId}` | GET | ✅ `PortalsApi.get_portal_zip_status()` |
|
||||||
|
| `/portals/{id}/assetids` | GET | ✅ `PortalsApi.get_portal_asset_ids()` |
|
||||||
|
| `/portals/{id}/enhancetoken` | POST | ✅ `PortalsApi.enhance_portal_token()` |
|
||||||
|
| `/portals/{id}/saveuserattributes` | POST | ✅ `PortalsApi.save_portal_user_attributes()` |
|
||||||
|
|
||||||
|
### Asset Management (`/assets*`)
|
||||||
|
| Endpoint | Method | Client Implementation |
|
||||||
|
|----------|--------|----------------------|
|
||||||
|
| `/assets` | GET | ✅ `AssetsApi.list_assets()` |
|
||||||
|
| `/assets` | POST | ✅ `AssetsApi.create_asset()` |
|
||||||
|
| `/assets/{id}` | GET | ✅ `AssetsApi.get_asset()` |
|
||||||
|
| `/assets/{id}` | POST | ✅ `AssetsApi.update_asset()` |
|
||||||
|
| `/assets/{id}` | DELETE | ✅ `AssetsApi.delete_asset()` |
|
||||||
|
| `/assetsupload` | POST | ✅ `AssetsApi.upload_asset()` |
|
||||||
|
| `/assetsbulkupdate` | POST | ✅ `AssetsApi.bulk_update_assets()` |
|
||||||
|
| `/assetsbulkupdate` | PUT | ✅ `AssetsApi.bulk_upsert_assets()` |
|
||||||
|
| `/assetsbulkupdate` | DELETE | ✅ `AssetsApi.bulk_delete_assets()` |
|
||||||
|
|
||||||
|
### Asset Operations (`/assets/{id}/...`)
|
||||||
|
| Endpoint | Method | Client Implementation |
|
||||||
|
|----------|--------|----------------------|
|
||||||
|
| `/assets/{id}/blobs` | GET | ✅ `AssetsApi.get_asset_blob()` |
|
||||||
|
| `/assets/{id}/blob` | GET | ✅ `AssetsApi.get_shared_asset_blob()` |
|
||||||
|
| `/assets/{id}/download` | GET | ✅ `AssetsApi.download_asset()` |
|
||||||
|
| `/assets/{id}/resize` | GET | ✅ `AssetsApi.resize_asset()` |
|
||||||
|
| `/assets/{id}/imageedit` | GET | ✅ `AssetsApi.imageedit_asset()` |
|
||||||
|
| `/assets/{id}/imageedit` | POST | ✅ `AssetsApi.imageedit_asset_operations()` |
|
||||||
|
| `/assets/{id}/imageedit/{download_format_id}` | GET | ✅ `AssetsApi.imageedit_asset_by_format()` |
|
||||||
|
| `/assets/{id}/collections` | GET | ✅ `AssetsApi.get_asset_collections()` |
|
||||||
|
| `/assets/{id}/tocollection` | POST | ❌ NOT IMPLEMENTED |
|
||||||
|
| `/assets/{id}/availability` | PUT | ❌ NOT IMPLEMENTED |
|
||||||
|
| `/assets/{id}/relations` | GET | ❌ NOT IMPLEMENTED |
|
||||||
|
|
||||||
|
### Asset Publishing (`/assets/{id}/publish*`)
|
||||||
|
| Endpoint | Method | Client Implementation |
|
||||||
|
|----------|--------|----------------------|
|
||||||
|
| `/assets/{id}/publish` | GET | ❌ NOT IMPLEMENTED |
|
||||||
|
| `/assets/{id}/publish` | POST | ❌ NOT IMPLEMENTED |
|
||||||
|
| `/assets/{id}/publish/{pid}` | GET | ❌ NOT IMPLEMENTED |
|
||||||
|
| `/publish` | GET | ✅ `PublishingApi.list_published()` |
|
||||||
|
|
||||||
|
### Asset Versioning (`/assets/{id}/versions*`)
|
||||||
|
| Endpoint | Method | Client Implementation |
|
||||||
|
|----------|--------|----------------------|
|
||||||
|
| `/assets/{id}/versions` | GET | ❌ NOT IMPLEMENTED |
|
||||||
|
| `/assets/{id}/versions` | POST | ❌ NOT IMPLEMENTED |
|
||||||
|
| `/assets/{id}/versionsupload` | POST | ❌ NOT IMPLEMENTED |
|
||||||
|
| `/assets/{id}/versions/{vNr}` | GET | ❌ NOT IMPLEMENTED |
|
||||||
|
| `/assets/{id}/versions/{vNr}` | POST | ❌ NOT IMPLEMENTED |
|
||||||
|
| `/assets/{id}/versions/{vNr}` | DELETE | ❌ NOT IMPLEMENTED |
|
||||||
|
| `/assets/{id}/versions/{vNr}/restore` | POST | ❌ NOT IMPLEMENTED |
|
||||||
|
| `/assets/{id}/versions/{vNr}/blobs` | GET | ❌ NOT IMPLEMENTED |
|
||||||
|
|
||||||
|
### Asset Relations (`/assetrelations*`)
|
||||||
|
| Endpoint | Method | Client Implementation |
|
||||||
|
|----------|--------|----------------------|
|
||||||
|
| `/assetrelations` | GET | ✅ `RelationsApi.list_relations()` |
|
||||||
|
| `/assetrelations` | POST | ✅ `RelationsApi.create_relation()` |
|
||||||
|
| `/assetrelations/{id}` | GET | ✅ `RelationsApi.get_relation()` |
|
||||||
|
| `/assetrelations/{id}` | POST | ✅ `RelationsApi.update_relation()` |
|
||||||
|
| `/assetrelations/{id}` | DELETE | ✅ `RelationsApi.delete_relation()` |
|
||||||
|
|
||||||
|
### Asset Relation Types (`/assetrelationtypes*`)
|
||||||
|
| Endpoint | Method | Client Implementation |
|
||||||
|
|----------|--------|----------------------|
|
||||||
|
| `/assetrelationtypes` | GET | ✅ `RelationsApi.list_relation_types()` |
|
||||||
|
| `/assetrelationtypes/{id}` | GET | ✅ `RelationsApi.get_relation_type()` |
|
||||||
|
|
||||||
|
### AI Operations (`/ai*`)
|
||||||
|
| Endpoint | Method | Client Implementation |
|
||||||
|
|----------|--------|----------------------|
|
||||||
|
| `/ai/reverseassetsearch` | POST | ✅ `AiApi.reverse_asset_search()` |
|
||||||
|
|
||||||
|
### Collections (`/collections*`)
|
||||||
|
| Endpoint | Method | Client Implementation |
|
||||||
|
|----------|--------|----------------------|
|
||||||
|
| `/collections` | GET | ✅ `CollectionsApi.list_collections()` |
|
||||||
|
| `/collections` | POST | ✅ `CollectionsApi.create_collection()` |
|
||||||
|
| `/collections/{id}` | GET | ✅ `CollectionsApi.get_collection()` |
|
||||||
|
| `/collections/{id}` | POST | ✅ `CollectionsApi.update_collection()` |
|
||||||
|
| `/collections/{id}` | DELETE | ✅ `CollectionsApi.delete_collection()` |
|
||||||
|
| `/collections/{id}/ancestors` | GET | ✅ `CollectionsApi.get_collection_ancestors()` |
|
||||||
|
| `/collections/{id}/descendants` | GET | ✅ `CollectionsApi.get_collection_descendants()` |
|
||||||
|
| `/collections/{id}/previews` | GET | ✅ `CollectionsApi.get_collection_preview()` |
|
||||||
|
| `/collectionsbynames` | POST | ✅ `CollectionsApi.get_collections_by_names()` |
|
||||||
|
|
||||||
|
### Collection Types (`/collectiontypes*`)
|
||||||
|
| Endpoint | Method | Client Implementation |
|
||||||
|
|----------|--------|----------------------|
|
||||||
|
| `/collectiontypes` | GET | ✅ `CollectionTypesApi.list_collection_types()` |
|
||||||
|
| `/collectiontypes/{id}` | GET | ✅ `CollectionTypesApi.get_collection_type()` |
|
||||||
|
| `/collectiontypesitems` | GET | ❌ NOT IMPLEMENTED |
|
||||||
|
|
||||||
|
### Search (`/search*`, `/savedsearches*`)
|
||||||
|
| Endpoint | Method | Client Implementation |
|
||||||
|
|----------|--------|----------------------|
|
||||||
|
| `/search` | GET | ❌ NOT IMPLEMENTED (POST available) |
|
||||||
|
| `/search` | POST | ✅ `SearchApi.search()` |
|
||||||
|
| `/search/facette` | GET | ❌ NOT IMPLEMENTED (POST available) |
|
||||||
|
| `/search/facette` | POST | ✅ `SearchApi.search_facette()` |
|
||||||
|
| `/searchadmin/status` | GET | ✅ `SearchApi.get_search_admin_status()` |
|
||||||
|
| `/savedsearches` | GET | ✅ `SearchApi.list_saved_searches()` |
|
||||||
|
|
||||||
|
### Sharing Management (`/shared*`, `/quickshares*`)
|
||||||
|
| Endpoint | Method | Client Implementation |
|
||||||
|
|----------|--------|----------------------|
|
||||||
|
| `/shared/{id}` | GET | ✅ `SharingApi.get_shared_collection()` |
|
||||||
|
| `/shared/{id}/zip` | POST | ✅ `SharingApi.create_shared_collection_zip()` |
|
||||||
|
| `/shared/{id}/zip/{zipId}` | GET | ✅ `SharingApi.get_shared_collection_zip_status()` |
|
||||||
|
| `/quickshares/{id}` | GET | ✅ `SharingApi.get_quickshare()` |
|
||||||
|
|
||||||
|
### Secure Upload (`/secureupload*`)
|
||||||
|
| Endpoint | Method | Client Implementation |
|
||||||
|
|----------|--------|----------------------|
|
||||||
|
| `/secureupload/{id}` | GET | ✅ `SecureUploadApi.check_secure_upload()` |
|
||||||
|
| `/secureupload/{id}/upload` | POST | ❌ NOT IMPLEMENTED |
|
||||||
|
|
||||||
|
### Authentication (`/auth*`)
|
||||||
|
| Endpoint | Method | Client Implementation |
|
||||||
|
|----------|--------|----------------------|
|
||||||
|
| `/auth/containerwrite/{containerName}` | GET | ✅ `AuthApi.get_container_write_sas_token()` |
|
||||||
|
| `/auth/inbox` | GET | ✅ `AuthApi.get_inbox_sas_token()` |
|
||||||
|
| `/auth/users/{id}` | GET | ❌ NOT IMPLEMENTED |
|
||||||
|
|
||||||
|
### Download Formats (`/downloadformats*`)
|
||||||
|
| Endpoint | Method | Client Implementation |
|
||||||
|
|----------|--------|----------------------|
|
||||||
|
| `/downloadformats` | GET | ✅ `DownloadFormatsApi.list_download_formats()` |
|
||||||
|
| `/downloadformats-shared` | GET | ✅ `DownloadFormatsApi.list_download_formats_from_shared()` |
|
||||||
|
|
||||||
|
### Helper Tools (`/helper*`)
|
||||||
|
| Endpoint | Method | Client Implementation |
|
||||||
|
|----------|--------|----------------------|
|
||||||
|
| `/helper/userdefinedlists` | GET | ✅ `HelperApi.get_user_defined_lists()` |
|
||||||
|
| `/helper/userdefinedlists` | PATCH | ❌ NOT IMPLEMENTED |
|
||||||
|
| `/helper/searchableitemnames` | GET | ✅ `HelperApi.get_searchable_item_names()` |
|
||||||
|
| `/helper/searchableitems` | GET | ✅ `HelperApi.get_searchable_items()` |
|
||||||
|
| `/helper/filterableitems` | GET | ✅ `HelperApi.get_filterable_items()` |
|
||||||
|
|
||||||
|
### Static Lists (`/staticdefinedlists*`)
|
||||||
|
| Endpoint | Method | Client Implementation |
|
||||||
|
|----------|--------|----------------------|
|
||||||
|
| `/staticdefinedlists` | GET | ✅ `StaticListsApi.list_static_defined_lists()` |
|
||||||
|
| `/staticdefinedlists/{id}` | GET | ✅ `StaticListsApi.get_static_defined_list()` |
|
||||||
|
| `/staticdefinedlists/{id}` | PUT | ✅ `StaticListsApi.update_static_defined_list()` |
|
||||||
|
|
||||||
|
### Translations (`/translations*`)
|
||||||
|
| Endpoint | Method | Client Implementation |
|
||||||
|
|----------|--------|----------------------|
|
||||||
|
| `/translations/{id}` | GET | ✅ `TranslationsApi.get_translation()` |
|
||||||
|
| `/translations/{id}/{property}` | PUT | ✅ `TranslationsApi.update_translation_property()` |
|
||||||
|
| `/translations/{id}/{property}/custom/{customField}` | PUT | ✅ `TranslationsApi.update_translation_custom_field()` |
|
||||||
|
|
||||||
|
### Web App Data (`/webappdata*`)
|
||||||
|
| Endpoint | Method | Client Implementation |
|
||||||
|
|----------|--------|----------------------|
|
||||||
|
| `/webappdata` | GET | ✅ `WebAppDataApi.get_web_app_data()` |
|
||||||
|
| `/webappdata/{id}` | GET | ✅ `WebAppDataApi.get_web_app_data_by_collection_type()` |
|
||||||
|
| `/data/collectiontype/{id}` | GET | ❌ NOT IMPLEMENTED |
|
||||||
|
|
||||||
|
### Workspaces (`/workspaces*`)
|
||||||
|
| Endpoint | Method | Client Implementation |
|
||||||
|
|----------|--------|----------------------|
|
||||||
|
| `/workspaces` | GET | ✅ `WorkspacesApi.list_workspaces()` |
|
||||||
|
| `/workspaces/{id}` | GET | ✅ `WorkspacesApi.get_workspace()` |
|
||||||
|
|
||||||
|
### General & Configuration (`/config*`, `/version`, `/deleted`, etc.)
|
||||||
|
| Endpoint | Method | Client Implementation |
|
||||||
|
|----------|--------|----------------------|
|
||||||
|
| `/config/frontend` | GET | ✅ `GeneralApi.get_frontend_config()` |
|
||||||
|
| `/version` | GET | ✅ `GeneralApi.get_version()` |
|
||||||
|
| `/deleted` | GET | ✅ `GeneralApi.get_deleted_entities()` |
|
||||||
|
| `/durable/{instanceId}` | GET | ✅ `GeneralApi.get_durable_status()` |
|
||||||
|
| `/durable/scch/{instanceId}` | GET | ❌ NOT IMPLEMENTED |
|
||||||
|
| `/public/view` | GET | ❌ NOT IMPLEMENTED |
|
||||||
|
| `/signalr/negotiate` | POST | ✅ `GeneralApi.get_signalr_connection_info()` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. MISSING ENDPOINTS (In Swagger but NOT Implemented)
|
||||||
|
|
||||||
|
### High Priority - Core Functionality
|
||||||
|
1. **Asset Versioning** (~8 endpoints)
|
||||||
|
- `/assets/{id}/versions` - GET, POST
|
||||||
|
- `/assets/{id}/versionsupload` - POST
|
||||||
|
- `/assets/{id}/versions/{vNr}` - GET, POST, DELETE
|
||||||
|
- `/assets/{id}/versions/{vNr}/restore` - POST
|
||||||
|
- `/assets/{id}/versions/{vNr}/blobs` - GET
|
||||||
|
|
||||||
|
2. **Asset Publishing** (~3 endpoints)
|
||||||
|
- `/assets/{id}/publish` - GET, POST
|
||||||
|
- `/assets/{id}/publish/{pid}` - GET
|
||||||
|
|
||||||
|
3. **Asset Operations** (~3 endpoints)
|
||||||
|
- `/assets/{id}/tocollection` - POST (move/assign to collection)
|
||||||
|
- `/assets/{id}/availability` - PUT (lock/unlock assets)
|
||||||
|
- `/assets/{id}/relations` - GET (retrieve asset relations)
|
||||||
|
|
||||||
|
### Medium Priority - User Workflows
|
||||||
|
4. **Secure Upload** (~1 endpoint)
|
||||||
|
- `/secureupload/{id}/upload` - POST
|
||||||
|
|
||||||
|
5. **Authentication** (~1 endpoint)
|
||||||
|
- `/auth/users/{id}` - GET
|
||||||
|
|
||||||
|
6. **Portal Global Endpoints** (~2 endpoints)
|
||||||
|
- `/portalsenhancetoken` - POST (global, not portal-specific)
|
||||||
|
- `/portalssaveuserattributes` - POST (global, not portal-specific)
|
||||||
|
|
||||||
|
### Lower Priority - Utility/Admin
|
||||||
|
7. **Helper Tools** (~1 endpoint)
|
||||||
|
- `/helper/userdefinedlists` - PATCH (cache update)
|
||||||
|
|
||||||
|
8. **Collection Types** (~1 endpoint)
|
||||||
|
- `/collectiontypesitems` - GET
|
||||||
|
|
||||||
|
9. **General** (~2 endpoints)
|
||||||
|
- `/durable/scch/{instanceId}` - GET (durable SCCH training)
|
||||||
|
- `/public/view` - GET (public asset view)
|
||||||
|
|
||||||
|
10. **Web App Data** (~1 endpoint)
|
||||||
|
- `/data/collectiontype/{id}` - GET
|
||||||
|
|
||||||
|
### Search Endpoints (GET vs POST)
|
||||||
|
- `/search` - GET variant (POST is implemented; GET not implemented)
|
||||||
|
- `/search/facette` - GET variant (POST is implemented; GET not implemented)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. EXTRA CLIENT METHODS (Not in Swagger)
|
||||||
|
|
||||||
|
Based on the analysis of the client's API modules, the following methods exist but don't have direct Swagger endpoint mappings:
|
||||||
|
|
||||||
|
### Portals Module
|
||||||
|
- `PortalsApi.list_portals()` - **NOT in swagger** (No `/portals` list endpoint found)
|
||||||
|
|
||||||
|
### Assets Module
|
||||||
|
- `AssetsApi.upload_asset_from_path()` - **Convenience wrapper** (wraps `upload_asset()`)
|
||||||
|
|
||||||
|
### Sharing Module
|
||||||
|
- `SharingApi.list_shared_collections()` - **Possible missing endpoint** (GET `/sharing` not clearly defined in swagger excerpt)
|
||||||
|
- `SharingApi.list_quickshares()` - **Possible missing endpoint** (GET `/sharing/quickshares` not clearly defined in swagger excerpt)
|
||||||
|
|
||||||
|
### Search Module
|
||||||
|
- Methods use POST endpoints while Swagger also defines GET variants - client chose to implement POST for consistency
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. SUMMARY STATISTICS
|
||||||
|
|
||||||
|
### Overall Coverage
|
||||||
|
| Metric | Count |
|
||||||
|
|--------|-------|
|
||||||
|
| **Total Swagger Endpoints** | 128 |
|
||||||
|
| **Fully Implemented** | 88 |
|
||||||
|
| **Partially Implemented** | 8 |
|
||||||
|
| **Not Implemented** | 32 |
|
||||||
|
| **Implementation Rate** | **68.75%** |
|
||||||
|
|
||||||
|
### By Category
|
||||||
|
|
||||||
|
| Category | Total | Impl | Missing | Coverage |
|
||||||
|
|----------|-------|------|---------|----------|
|
||||||
|
| Portals | 6 | 6 | 2 | 75% |
|
||||||
|
| Assets (CRUD) | 9 | 9 | 0 | 100% |
|
||||||
|
| Asset Operations | 11 | 7 | 4 | 64% |
|
||||||
|
| Asset Publishing | 4 | 1 | 3 | 25% |
|
||||||
|
| Asset Versioning | 8 | 0 | 8 | 0% |
|
||||||
|
| Asset Relations | 7 | 7 | 0 | 100% |
|
||||||
|
| AI Operations | 1 | 1 | 0 | 100% |
|
||||||
|
| Collections | 9 | 9 | 0 | 100% |
|
||||||
|
| Collection Types | 3 | 2 | 1 | 67% |
|
||||||
|
| Search | 6 | 3 | 3 | 50% |
|
||||||
|
| Sharing | 4 | 4 | 0 | 100% |
|
||||||
|
| Secure Upload | 2 | 1 | 1 | 50% |
|
||||||
|
| Authentication | 3 | 2 | 1 | 67% |
|
||||||
|
| Download Formats | 2 | 2 | 0 | 100% |
|
||||||
|
| Helper Tools | 5 | 4 | 1 | 80% |
|
||||||
|
| Static Lists | 3 | 3 | 0 | 100% |
|
||||||
|
| Translations | 3 | 3 | 0 | 100% |
|
||||||
|
| Web App Data | 3 | 2 | 1 | 67% |
|
||||||
|
| Workspaces | 2 | 2 | 0 | 100% |
|
||||||
|
| General/Config | 8 | 5 | 3 | 63% |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. RECOMMENDATIONS
|
||||||
|
|
||||||
|
### High Priority - Should Implement
|
||||||
|
1. **Asset Versioning (8 endpoints)** - Complete version history management is important for enterprise DAM
|
||||||
|
2. **Asset Publishing (3 endpoints)** - Essential for multi-channel distribution workflows
|
||||||
|
3. **Asset Availability/Lock (1 endpoint)** - Commonly needed for content workflows
|
||||||
|
|
||||||
|
### Medium Priority - Should Consider
|
||||||
|
4. **Secure Upload Upload Handler (1 endpoint)** - Needed for secure file ingestion
|
||||||
|
5. **Search GET Variants (2 endpoints)** - For REST API consistency with other GET operations
|
||||||
|
6. **Auth User Lookup (1 endpoint)** - Useful for user-related operations
|
||||||
|
|
||||||
|
### Lower Priority - Nice to Have
|
||||||
|
7. **Portal Global Endpoints (2)** - If portal-level operations are needed
|
||||||
|
8. **Helper Utilities (1)** - Cache management utilities
|
||||||
|
9. **Durable SCCH (1)** - Specialized training workflow
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. MODULE IMPLEMENTATION SUMMARY
|
||||||
|
|
||||||
|
### Fully Complete Modules (100%)
|
||||||
|
- ✅ **AssetsApi**: Core CRUD operations complete
|
||||||
|
- ✅ **RelationsApi**: All asset relations implemented
|
||||||
|
- ✅ **CollectionsApi**: All collection operations
|
||||||
|
- ✅ **AiApi**: Reverse search complete
|
||||||
|
- ✅ **SharingApi**: All sharing operations
|
||||||
|
- ✅ **CollectionTypesApi**: Type definitions
|
||||||
|
- ✅ **DownloadFormatsApi**: Format management
|
||||||
|
- ✅ **StaticListsApi**: Static lists
|
||||||
|
- ✅ **TranslationsApi**: Translation operations
|
||||||
|
- ✅ **WorkspacesApi**: Workspace management
|
||||||
|
|
||||||
|
### Partial Modules (50-99%)
|
||||||
|
- ⚠️ **PortalsApi**: 75% (missing 2 global endpoints, 1 list endpoint)
|
||||||
|
- ⚠️ **SearchApi**: 50% (GET variants missing; POST implemented)
|
||||||
|
- ⚠️ **HelperApi**: 80% (missing PATCH cache update)
|
||||||
|
- ⚠️ **DownloadFormatsApi**: 100% (covered, though shared variant named differently)
|
||||||
|
- ⚠️ **WebAppDataApi**: 67% (missing `/data/collectiontype/{id}`)
|
||||||
|
- ⚠️ **AuthApi**: 67% (missing user by ID endpoint)
|
||||||
|
|
||||||
|
### Significant Gaps
|
||||||
|
- ❌ **Asset Versioning**: 0% implementation (no methods)
|
||||||
|
- ❌ **Asset Publishing**: 25% (only global list, missing individual asset publish)
|
||||||
|
- ❌ **Secure Upload**: 50% (check exists, but no upload handler)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Conclusion
|
||||||
|
|
||||||
|
The agravity_client Python SDK has **excellent coverage of core DAM operations** with **68.75% endpoint implementation**. The client successfully implements:
|
||||||
|
|
||||||
|
✅ All basic CRUD operations for assets and collections
|
||||||
|
✅ Complete search functionality
|
||||||
|
✅ Asset relationships and relations
|
||||||
|
✅ Collection hierarchy navigation
|
||||||
|
✅ Download formats and transformations
|
||||||
|
✅ Portal and sharing capabilities
|
||||||
|
|
||||||
|
However, there are notable gaps in:
|
||||||
|
|
||||||
|
❌ **Asset Versioning** - Complete feature absent
|
||||||
|
❌ **Asset Publishing** - Minimal implementation
|
||||||
|
❌ **Asset Availability Control** - Workflow feature missing
|
||||||
|
|
||||||
|
These gaps represent ~21 related and interconnected endpoints. Implementing asset versioning and publishing would likely increase coverage to **~80%**, making it enterprise-ready for version-controlled asset management.
|
||||||
|
|
@ -33,3 +33,19 @@ class AuthApi(AgravityBaseApi):
|
||||||
"""GET /auth/users."""
|
"""GET /auth/users."""
|
||||||
resp = await self._get("/auth/users")
|
resp = await self._get("/auth/users")
|
||||||
return [AgravityUser.model_validate(item) for item in resp.json()]
|
return [AgravityUser.model_validate(item) for item in resp.json()]
|
||||||
|
|
||||||
|
async def get_user_by_id(
|
||||||
|
self,
|
||||||
|
user_id: str,
|
||||||
|
*,
|
||||||
|
limit: Optional[bool] = None,
|
||||||
|
) -> AgravityUser:
|
||||||
|
"""GET /auth/users/{id} – get user information by ID.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
user_id: The ID of the requested Agravity user.
|
||||||
|
limit: If True, response is limited to name and email only.
|
||||||
|
"""
|
||||||
|
params = {"limit": limit} if limit is not None else {}
|
||||||
|
resp = await self._get(f"/auth/users/{user_id}", params=params)
|
||||||
|
return AgravityUser.model_validate(resp.json())
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
"""Collection Type Management API module."""
|
"""Collection Type Management API module."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
from agravity_client.api.base import AgravityBaseApi
|
from agravity_client.api.base import AgravityBaseApi
|
||||||
from agravity_client.models.collection import CollectionType, CollTypeItem
|
from agravity_client.models.collection import CollectionType, CollTypeItem
|
||||||
|
|
||||||
|
|
@ -18,6 +20,23 @@ class CollectionTypesApi(AgravityBaseApi):
|
||||||
resp = await self._get(f"/collectiontypes/{type_id}")
|
resp = await self._get(f"/collectiontypes/{type_id}")
|
||||||
return CollectionType.model_validate(resp.json())
|
return CollectionType.model_validate(resp.json())
|
||||||
|
|
||||||
|
async def list_collection_type_items(
|
||||||
|
self,
|
||||||
|
*,
|
||||||
|
include_blueprint: Optional[bool] = None,
|
||||||
|
translations: Optional[bool] = None,
|
||||||
|
accept_language: Optional[str] = None,
|
||||||
|
) -> list[CollTypeItem]:
|
||||||
|
"""GET /collectiontypesitems – list all collection type items."""
|
||||||
|
params = {"includeblueprint": include_blueprint, "translations": translations}
|
||||||
|
headers = {"Accept-Language": accept_language} if accept_language else None
|
||||||
|
resp = await self._get(
|
||||||
|
"/collectiontypesitems",
|
||||||
|
params=params,
|
||||||
|
extra_headers=headers,
|
||||||
|
)
|
||||||
|
return [CollTypeItem.model_validate(item) for item in resp.json()]
|
||||||
|
|
||||||
async def get_collection_type_items(self, type_id: str) -> list[CollTypeItem]:
|
async def get_collection_type_items(self, type_id: str) -> list[CollTypeItem]:
|
||||||
"""GET /collectiontypes/{id}/items."""
|
"""GET /collectiontypes/{id}/items."""
|
||||||
resp = await self._get(f"/collectiontypes/{type_id}/items")
|
resp = await self._get(f"/collectiontypes/{type_id}/items")
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,28 @@ class PortalsApi(AgravityBaseApi):
|
||||||
resp = await self._get("/portals")
|
resp = await self._get("/portals")
|
||||||
return [Portal.model_validate(item) for item in resp.json()]
|
return [Portal.model_validate(item) for item in resp.json()]
|
||||||
|
|
||||||
|
async def enhance_portals_token(
|
||||||
|
self,
|
||||||
|
payload: Optional[dict[str, Any]] = None,
|
||||||
|
) -> dict[str, Any]:
|
||||||
|
"""POST /portalsenhancetoken – global portal token enhancement (no specific portal ID)."""
|
||||||
|
resp = await self._post(
|
||||||
|
"/portalsenhancetoken",
|
||||||
|
json=payload,
|
||||||
|
)
|
||||||
|
return resp.json()
|
||||||
|
|
||||||
|
async def save_portals_user_attributes(
|
||||||
|
self,
|
||||||
|
payload: dict[str, Any],
|
||||||
|
) -> dict[str, Any]:
|
||||||
|
"""POST /portalssaveuserattributes – save portal user attributes globally (no specific portal ID)."""
|
||||||
|
resp = await self._post(
|
||||||
|
"/portalssaveuserattributes",
|
||||||
|
json=payload,
|
||||||
|
)
|
||||||
|
return resp.json()
|
||||||
|
|
||||||
async def get_portal(self, portal_id: str) -> Portal:
|
async def get_portal(self, portal_id: str) -> Portal:
|
||||||
"""GET /portals/{id}."""
|
"""GET /portals/{id}."""
|
||||||
resp = await self._get(f"/portals/{portal_id}")
|
resp = await self._get(f"/portals/{portal_id}")
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ from __future__ import annotations
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from agravity_client.api.base import AgravityBaseApi
|
from agravity_client.api.base import AgravityBaseApi
|
||||||
|
from agravity_client.models.asset import Asset
|
||||||
from agravity_client.models.secure_upload import SecureUploadEntity
|
from agravity_client.models.secure_upload import SecureUploadEntity
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -26,3 +27,23 @@ class SecureUploadApi(AgravityBaseApi):
|
||||||
"""POST /secureupload – create a secure upload entity."""
|
"""POST /secureupload – create a secure upload entity."""
|
||||||
resp = await self._post("/secureupload", json=payload)
|
resp = await self._post("/secureupload", json=payload)
|
||||||
return SecureUploadEntity.model_validate(resp.json())
|
return SecureUploadEntity.model_validate(resp.json())
|
||||||
|
|
||||||
|
async def upload_secure_upload_file(
|
||||||
|
self,
|
||||||
|
secure_upload_id: str,
|
||||||
|
file: bytes,
|
||||||
|
filename: str,
|
||||||
|
*,
|
||||||
|
content_type: str = "application/octet-stream",
|
||||||
|
) -> Asset:
|
||||||
|
"""POST /secureupload/{id}/upload – upload a file to a secure upload collection.
|
||||||
|
|
||||||
|
The file will be securely uploaded and placed in the INBOX storage.
|
||||||
|
Returns the created asset.
|
||||||
|
"""
|
||||||
|
files = {"file": (filename, file, content_type)}
|
||||||
|
resp = await self._post(
|
||||||
|
f"/secureupload/{secure_upload_id}/upload",
|
||||||
|
files=files,
|
||||||
|
)
|
||||||
|
return Asset.model_validate(resp.json())
|
||||||
|
|
|
||||||
|
|
@ -43,3 +43,11 @@ class WebAppDataApi(AgravityBaseApi):
|
||||||
extra_headers=headers,
|
extra_headers=headers,
|
||||||
)
|
)
|
||||||
return GroupAllAppData.model_validate(resp.json())
|
return GroupAllAppData.model_validate(resp.json())
|
||||||
|
|
||||||
|
async def get_collection_type_data(
|
||||||
|
self,
|
||||||
|
collection_type_id: str,
|
||||||
|
) -> GroupAllAppData:
|
||||||
|
"""GET /data/collectiontype/{id} – get all collections and assets from a collection type."""
|
||||||
|
resp = await self._get(f"/data/collectiontype/{collection_type_id}")
|
||||||
|
return GroupAllAppData.model_validate(resp.json())
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue