diff --git a/api/swagger.yml b/api/swagger.yml
index 47624672337..e6eb6e905ee 100644
--- a/api/swagger.yml
+++ b/api/swagger.yml
@@ -347,6 +347,15 @@ components:
items:
$ref: "#/components/schemas/ObjectStats"
+ UpdateObjectUserMetadata:
+ type: object
+ required:
+ - set
+ properties:
+ set:
+ description: Set this object user metadata
+ $ref: "#/components/schemas/ObjectUserMetadata"
+
ObjectCopyCreation:
type: object
required:
@@ -4993,6 +5002,51 @@ paths:
default:
$ref: "#/components/responses/ServerError"
+ /repositories/{repository}/branches/{branch}/objects/stat/user_metadata:
+ parameters:
+ - in: path
+ name: repository
+ required: true
+ schema:
+ type: string
+ - in: path
+ name: branch
+ required: true
+ schema:
+ type: string
+ description: branch to update
+ - in: query
+ name: path
+ description: path to object relative to the branch
+ required: true
+ schema:
+ type: string
+ put:
+ tags:
+ - objects
+ - experimental
+ operationId: updateObjectUserMetadata
+ summary: rewrite (all) object metadata
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/UpdateObjectUserMetadata"
+ responses:
+ 201:
+ description: User metadata updated
+ 401:
+ $ref: "#/components/responses/Unauthorized"
+ 404:
+ $ref: "#/components/responses/NotFound"
+ 400:
+ $ref: "#/components/responses/BadRequest"
+ 420:
+ description: too many requests
+ default:
+ $ref: "#/components/responses/ServerError"
+
/repositories/{repository}/refs/{ref}/objects/underlyingProperties:
parameters:
- in: path
diff --git a/clients/java-legacy/.openapi-generator/FILES b/clients/java-legacy/.openapi-generator/FILES
index c515d34c5bb..c6594ced75e 100644
--- a/clients/java-legacy/.openapi-generator/FILES
+++ b/clients/java-legacy/.openapi-generator/FILES
@@ -121,6 +121,7 @@ docs/TagCreation.md
docs/TagsApi.md
docs/TaskInfo.md
docs/UnderlyingObjectProperties.md
+docs/UpdateObjectUserMetadata.md
docs/UpdateToken.md
docs/UploadPart.md
docs/UsageReport.md
@@ -270,6 +271,7 @@ src/main/java/io/lakefs/clients/api/model/StsAuthRequest.java
src/main/java/io/lakefs/clients/api/model/TagCreation.java
src/main/java/io/lakefs/clients/api/model/TaskInfo.java
src/main/java/io/lakefs/clients/api/model/UnderlyingObjectProperties.java
+src/main/java/io/lakefs/clients/api/model/UpdateObjectUserMetadata.java
src/main/java/io/lakefs/clients/api/model/UpdateToken.java
src/main/java/io/lakefs/clients/api/model/UploadPart.java
src/main/java/io/lakefs/clients/api/model/UsageReport.java
@@ -393,6 +395,7 @@ src/test/java/io/lakefs/clients/api/model/StsAuthRequestTest.java
src/test/java/io/lakefs/clients/api/model/TagCreationTest.java
src/test/java/io/lakefs/clients/api/model/TaskInfoTest.java
src/test/java/io/lakefs/clients/api/model/UnderlyingObjectPropertiesTest.java
+src/test/java/io/lakefs/clients/api/model/UpdateObjectUserMetadataTest.java
src/test/java/io/lakefs/clients/api/model/UpdateTokenTest.java
src/test/java/io/lakefs/clients/api/model/UploadPartTest.java
src/test/java/io/lakefs/clients/api/model/UsageReportTest.java
diff --git a/clients/java-legacy/README.md b/clients/java-legacy/README.md
index 7d9369180f1..73fb7413eb6 100644
--- a/clients/java-legacy/README.md
+++ b/clients/java-legacy/README.md
@@ -200,6 +200,7 @@ Class | Method | HTTP request | Description
*ExperimentalApi* | [**listUserExternalPrincipals**](docs/ExperimentalApi.md#listUserExternalPrincipals) | **GET** /auth/users/{userId}/external/principals/ls | list user external policies attached to a user
*ExperimentalApi* | [**mergePullRequest**](docs/ExperimentalApi.md#mergePullRequest) | **PUT** /repositories/{repository}/pulls/{pull_request}/merge | merge pull request
*ExperimentalApi* | [**stsLogin**](docs/ExperimentalApi.md#stsLogin) | **POST** /sts/login | perform a login with STS
+*ExperimentalApi* | [**updateObjectUserMetadata**](docs/ExperimentalApi.md#updateObjectUserMetadata) | **PUT** /repositories/{repository}/branches/{branch}/objects/stat/user_metadata | rewrite (all) object metadata
*ExperimentalApi* | [**updatePullRequest**](docs/ExperimentalApi.md#updatePullRequest) | **PATCH** /repositories/{repository}/pulls/{pull_request} | update pull request
*ExternalApi* | [**createUserExternalPrincipal**](docs/ExternalApi.md#createUserExternalPrincipal) | **POST** /auth/users/{userId}/external/principals | attach external principal to user
*ExternalApi* | [**deleteUserExternalPrincipal**](docs/ExternalApi.md#deleteUserExternalPrincipal) | **DELETE** /auth/users/{userId}/external/principals | delete external principal from user
@@ -248,6 +249,7 @@ Class | Method | HTTP request | Description
*ObjectsApi* | [**headObject**](docs/ObjectsApi.md#headObject) | **HEAD** /repositories/{repository}/refs/{ref}/objects | check if object exists
*ObjectsApi* | [**listObjects**](docs/ObjectsApi.md#listObjects) | **GET** /repositories/{repository}/refs/{ref}/objects/ls | list objects under a given prefix
*ObjectsApi* | [**statObject**](docs/ObjectsApi.md#statObject) | **GET** /repositories/{repository}/refs/{ref}/objects/stat | get object metadata
+*ObjectsApi* | [**updateObjectUserMetadata**](docs/ObjectsApi.md#updateObjectUserMetadata) | **PUT** /repositories/{repository}/branches/{branch}/objects/stat/user_metadata | rewrite (all) object metadata
*ObjectsApi* | [**uploadObject**](docs/ObjectsApi.md#uploadObject) | **POST** /repositories/{repository}/branches/{branch}/objects |
*PullsApi* | [**createPullRequest**](docs/PullsApi.md#createPullRequest) | **POST** /repositories/{repository}/pulls | create pull request
*PullsApi* | [**getPullRequest**](docs/PullsApi.md#getPullRequest) | **GET** /repositories/{repository}/pulls/{pull_request} | get pull request
@@ -381,6 +383,7 @@ Class | Method | HTTP request | Description
- [TagCreation](docs/TagCreation.md)
- [TaskInfo](docs/TaskInfo.md)
- [UnderlyingObjectProperties](docs/UnderlyingObjectProperties.md)
+ - [UpdateObjectUserMetadata](docs/UpdateObjectUserMetadata.md)
- [UpdateToken](docs/UpdateToken.md)
- [UploadPart](docs/UploadPart.md)
- [UsageReport](docs/UsageReport.md)
diff --git a/clients/java-legacy/api/openapi.yaml b/clients/java-legacy/api/openapi.yaml
index d30b65ace2b..f1b26bc88b5 100644
--- a/clients/java-legacy/api/openapi.yaml
+++ b/clients/java-legacy/api/openapi.yaml
@@ -5648,6 +5648,74 @@ paths:
tags:
- objects
x-accepts: application/json
+ /repositories/{repository}/branches/{branch}/objects/stat/user_metadata:
+ put:
+ operationId: updateObjectUserMetadata
+ parameters:
+ - explode: false
+ in: path
+ name: repository
+ required: true
+ schema:
+ type: string
+ style: simple
+ - description: branch to update
+ explode: false
+ in: path
+ name: branch
+ required: true
+ schema:
+ type: string
+ style: simple
+ - description: path to object relative to the branch
+ explode: true
+ in: query
+ name: path
+ required: true
+ schema:
+ type: string
+ style: form
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/UpdateObjectUserMetadata'
+ required: true
+ responses:
+ "201":
+ description: User metadata updated
+ "401":
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Error'
+ description: Unauthorized
+ "404":
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Error'
+ description: Resource Not Found
+ "400":
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Error'
+ description: Bad Request
+ "420":
+ description: too many requests
+ default:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Error'
+ description: Internal Server Error
+ summary: rewrite (all) object metadata
+ tags:
+ - objects
+ - experimental
+ x-contentType: application/json
+ x-accepts: application/json
/repositories/{repository}/refs/{ref}/objects/underlyingProperties:
get:
operationId: getUnderlyingProperties
@@ -7694,6 +7762,18 @@ components:
- pagination
- results
type: object
+ UpdateObjectUserMetadata:
+ example:
+ set:
+ key: set
+ properties:
+ set:
+ additionalProperties:
+ type: string
+ type: object
+ required:
+ - set
+ type: object
ObjectCopyCreation:
example:
force: false
diff --git a/clients/java-legacy/docs/ExperimentalApi.md b/clients/java-legacy/docs/ExperimentalApi.md
index 4129c40395f..449bef8ca80 100644
--- a/clients/java-legacy/docs/ExperimentalApi.md
+++ b/clients/java-legacy/docs/ExperimentalApi.md
@@ -18,6 +18,7 @@ Method | HTTP request | Description
[**listUserExternalPrincipals**](ExperimentalApi.md#listUserExternalPrincipals) | **GET** /auth/users/{userId}/external/principals/ls | list user external policies attached to a user
[**mergePullRequest**](ExperimentalApi.md#mergePullRequest) | **PUT** /repositories/{repository}/pulls/{pull_request}/merge | merge pull request
[**stsLogin**](ExperimentalApi.md#stsLogin) | **POST** /sts/login | perform a login with STS
+[**updateObjectUserMetadata**](ExperimentalApi.md#updateObjectUserMetadata) | **PUT** /repositories/{repository}/branches/{branch}/objects/stat/user_metadata | rewrite (all) object metadata
[**updatePullRequest**](ExperimentalApi.md#updatePullRequest) | **PATCH** /repositories/{repository}/pulls/{pull_request} | update pull request
@@ -1327,6 +1328,104 @@ No authorization required
**420** | too many requests | - |
**0** | Internal Server Error | - |
+
+# **updateObjectUserMetadata**
+> updateObjectUserMetadata(repository, branch, path, updateObjectUserMetadata)
+
+rewrite (all) object metadata
+
+### Example
+```java
+// Import classes:
+import io.lakefs.clients.api.ApiClient;
+import io.lakefs.clients.api.ApiException;
+import io.lakefs.clients.api.Configuration;
+import io.lakefs.clients.api.auth.*;
+import io.lakefs.clients.api.models.*;
+import io.lakefs.clients.api.ExperimentalApi;
+
+public class Example {
+ public static void main(String[] args) {
+ ApiClient defaultClient = Configuration.getDefaultApiClient();
+ defaultClient.setBasePath("http://localhost/api/v1");
+
+ // Configure HTTP basic authorization: basic_auth
+ HttpBasicAuth basic_auth = (HttpBasicAuth) defaultClient.getAuthentication("basic_auth");
+ basic_auth.setUsername("YOUR USERNAME");
+ basic_auth.setPassword("YOUR PASSWORD");
+
+ // Configure API key authorization: cookie_auth
+ ApiKeyAuth cookie_auth = (ApiKeyAuth) defaultClient.getAuthentication("cookie_auth");
+ cookie_auth.setApiKey("YOUR API KEY");
+ // Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
+ //cookie_auth.setApiKeyPrefix("Token");
+
+ // Configure HTTP bearer authorization: jwt_token
+ HttpBearerAuth jwt_token = (HttpBearerAuth) defaultClient.getAuthentication("jwt_token");
+ jwt_token.setBearerToken("BEARER TOKEN");
+
+ // Configure API key authorization: oidc_auth
+ ApiKeyAuth oidc_auth = (ApiKeyAuth) defaultClient.getAuthentication("oidc_auth");
+ oidc_auth.setApiKey("YOUR API KEY");
+ // Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
+ //oidc_auth.setApiKeyPrefix("Token");
+
+ // Configure API key authorization: saml_auth
+ ApiKeyAuth saml_auth = (ApiKeyAuth) defaultClient.getAuthentication("saml_auth");
+ saml_auth.setApiKey("YOUR API KEY");
+ // Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
+ //saml_auth.setApiKeyPrefix("Token");
+
+ ExperimentalApi apiInstance = new ExperimentalApi(defaultClient);
+ String repository = "repository_example"; // String |
+ String branch = "branch_example"; // String | branch to update
+ String path = "path_example"; // String | path to object relative to the branch
+ UpdateObjectUserMetadata updateObjectUserMetadata = new UpdateObjectUserMetadata(); // UpdateObjectUserMetadata |
+ try {
+ apiInstance.updateObjectUserMetadata(repository, branch, path, updateObjectUserMetadata);
+ } catch (ApiException e) {
+ System.err.println("Exception when calling ExperimentalApi#updateObjectUserMetadata");
+ System.err.println("Status code: " + e.getCode());
+ System.err.println("Reason: " + e.getResponseBody());
+ System.err.println("Response headers: " + e.getResponseHeaders());
+ e.printStackTrace();
+ }
+ }
+}
+```
+
+### Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **repository** | **String**| |
+ **branch** | **String**| branch to update |
+ **path** | **String**| path to object relative to the branch |
+ **updateObjectUserMetadata** | [**UpdateObjectUserMetadata**](UpdateObjectUserMetadata.md)| |
+
+### Return type
+
+null (empty response body)
+
+### Authorization
+
+[basic_auth](../README.md#basic_auth), [cookie_auth](../README.md#cookie_auth), [jwt_token](../README.md#jwt_token), [oidc_auth](../README.md#oidc_auth), [saml_auth](../README.md#saml_auth)
+
+### HTTP request headers
+
+ - **Content-Type**: application/json
+ - **Accept**: application/json
+
+### HTTP response details
+| Status code | Description | Response headers |
+|-------------|-------------|------------------|
+**201** | User metadata updated | - |
+**401** | Unauthorized | - |
+**404** | Resource Not Found | - |
+**400** | Bad Request | - |
+**420** | too many requests | - |
+**0** | Internal Server Error | - |
+
# **updatePullRequest**
> updatePullRequest(repository, pullRequest, pullRequestBasic)
diff --git a/clients/java-legacy/docs/ObjectsApi.md b/clients/java-legacy/docs/ObjectsApi.md
index 763634236bc..c5a3390a130 100644
--- a/clients/java-legacy/docs/ObjectsApi.md
+++ b/clients/java-legacy/docs/ObjectsApi.md
@@ -12,6 +12,7 @@ Method | HTTP request | Description
[**headObject**](ObjectsApi.md#headObject) | **HEAD** /repositories/{repository}/refs/{ref}/objects | check if object exists
[**listObjects**](ObjectsApi.md#listObjects) | **GET** /repositories/{repository}/refs/{ref}/objects/ls | list objects under a given prefix
[**statObject**](ObjectsApi.md#statObject) | **GET** /repositories/{repository}/refs/{ref}/objects/stat | get object metadata
+[**updateObjectUserMetadata**](ObjectsApi.md#updateObjectUserMetadata) | **PUT** /repositories/{repository}/branches/{branch}/objects/stat/user_metadata | rewrite (all) object metadata
[**uploadObject**](ObjectsApi.md#uploadObject) | **POST** /repositories/{repository}/branches/{branch}/objects |
@@ -823,6 +824,104 @@ Name | Type | Description | Notes
**420** | too many requests | - |
**0** | Internal Server Error | - |
+
+# **updateObjectUserMetadata**
+> updateObjectUserMetadata(repository, branch, path, updateObjectUserMetadata)
+
+rewrite (all) object metadata
+
+### Example
+```java
+// Import classes:
+import io.lakefs.clients.api.ApiClient;
+import io.lakefs.clients.api.ApiException;
+import io.lakefs.clients.api.Configuration;
+import io.lakefs.clients.api.auth.*;
+import io.lakefs.clients.api.models.*;
+import io.lakefs.clients.api.ObjectsApi;
+
+public class Example {
+ public static void main(String[] args) {
+ ApiClient defaultClient = Configuration.getDefaultApiClient();
+ defaultClient.setBasePath("http://localhost/api/v1");
+
+ // Configure HTTP basic authorization: basic_auth
+ HttpBasicAuth basic_auth = (HttpBasicAuth) defaultClient.getAuthentication("basic_auth");
+ basic_auth.setUsername("YOUR USERNAME");
+ basic_auth.setPassword("YOUR PASSWORD");
+
+ // Configure API key authorization: cookie_auth
+ ApiKeyAuth cookie_auth = (ApiKeyAuth) defaultClient.getAuthentication("cookie_auth");
+ cookie_auth.setApiKey("YOUR API KEY");
+ // Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
+ //cookie_auth.setApiKeyPrefix("Token");
+
+ // Configure HTTP bearer authorization: jwt_token
+ HttpBearerAuth jwt_token = (HttpBearerAuth) defaultClient.getAuthentication("jwt_token");
+ jwt_token.setBearerToken("BEARER TOKEN");
+
+ // Configure API key authorization: oidc_auth
+ ApiKeyAuth oidc_auth = (ApiKeyAuth) defaultClient.getAuthentication("oidc_auth");
+ oidc_auth.setApiKey("YOUR API KEY");
+ // Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
+ //oidc_auth.setApiKeyPrefix("Token");
+
+ // Configure API key authorization: saml_auth
+ ApiKeyAuth saml_auth = (ApiKeyAuth) defaultClient.getAuthentication("saml_auth");
+ saml_auth.setApiKey("YOUR API KEY");
+ // Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
+ //saml_auth.setApiKeyPrefix("Token");
+
+ ObjectsApi apiInstance = new ObjectsApi(defaultClient);
+ String repository = "repository_example"; // String |
+ String branch = "branch_example"; // String | branch to update
+ String path = "path_example"; // String | path to object relative to the branch
+ UpdateObjectUserMetadata updateObjectUserMetadata = new UpdateObjectUserMetadata(); // UpdateObjectUserMetadata |
+ try {
+ apiInstance.updateObjectUserMetadata(repository, branch, path, updateObjectUserMetadata);
+ } catch (ApiException e) {
+ System.err.println("Exception when calling ObjectsApi#updateObjectUserMetadata");
+ System.err.println("Status code: " + e.getCode());
+ System.err.println("Reason: " + e.getResponseBody());
+ System.err.println("Response headers: " + e.getResponseHeaders());
+ e.printStackTrace();
+ }
+ }
+}
+```
+
+### Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **repository** | **String**| |
+ **branch** | **String**| branch to update |
+ **path** | **String**| path to object relative to the branch |
+ **updateObjectUserMetadata** | [**UpdateObjectUserMetadata**](UpdateObjectUserMetadata.md)| |
+
+### Return type
+
+null (empty response body)
+
+### Authorization
+
+[basic_auth](../README.md#basic_auth), [cookie_auth](../README.md#cookie_auth), [jwt_token](../README.md#jwt_token), [oidc_auth](../README.md#oidc_auth), [saml_auth](../README.md#saml_auth)
+
+### HTTP request headers
+
+ - **Content-Type**: application/json
+ - **Accept**: application/json
+
+### HTTP response details
+| Status code | Description | Response headers |
+|-------------|-------------|------------------|
+**201** | User metadata updated | - |
+**401** | Unauthorized | - |
+**404** | Resource Not Found | - |
+**400** | Bad Request | - |
+**420** | too many requests | - |
+**0** | Internal Server Error | - |
+
# **uploadObject**
> ObjectStats uploadObject(repository, branch, path, ifNoneMatch, storageClass, force, content)
diff --git a/clients/java-legacy/docs/UpdateObjectUserMetadata.md b/clients/java-legacy/docs/UpdateObjectUserMetadata.md
new file mode 100644
index 00000000000..da76849885b
--- /dev/null
+++ b/clients/java-legacy/docs/UpdateObjectUserMetadata.md
@@ -0,0 +1,13 @@
+
+
+# UpdateObjectUserMetadata
+
+
+## Properties
+
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**set** | **Map<String, String>** | |
+
+
+
diff --git a/clients/java-legacy/src/main/java/io/lakefs/clients/api/ExperimentalApi.java b/clients/java-legacy/src/main/java/io/lakefs/clients/api/ExperimentalApi.java
index 1dae057d590..face87332b9 100644
--- a/clients/java-legacy/src/main/java/io/lakefs/clients/api/ExperimentalApi.java
+++ b/clients/java-legacy/src/main/java/io/lakefs/clients/api/ExperimentalApi.java
@@ -45,6 +45,7 @@
import io.lakefs.clients.api.model.PullRequestsList;
import io.lakefs.clients.api.model.StagingLocation;
import io.lakefs.clients.api.model.StsAuthRequest;
+import io.lakefs.clients.api.model.UpdateObjectUserMetadata;
import java.lang.reflect.Type;
import java.util.ArrayList;
@@ -2158,6 +2159,166 @@ public okhttp3.Call stsLoginAsync(StsAuthRequest stsAuthRequest, final ApiCallba
localVarApiClient.executeAsync(localVarCall, localVarReturnType, _callback);
return localVarCall;
}
+ /**
+ * Build call for updateObjectUserMetadata
+ * @param repository (required)
+ * @param branch branch to update (required)
+ * @param path path to object relative to the branch (required)
+ * @param updateObjectUserMetadata (required)
+ * @param _callback Callback for upload/download progress
+ * @return Call to execute
+ * @throws ApiException If fail to serialize the request body object
+ * @http.response.details
+
+ Status Code | Description | Response Headers |
+ 201 | User metadata updated | - |
+ 401 | Unauthorized | - |
+ 404 | Resource Not Found | - |
+ 400 | Bad Request | - |
+ 420 | too many requests | - |
+ 0 | Internal Server Error | - |
+
+ */
+ public okhttp3.Call updateObjectUserMetadataCall(String repository, String branch, String path, UpdateObjectUserMetadata updateObjectUserMetadata, final ApiCallback _callback) throws ApiException {
+ Object localVarPostBody = updateObjectUserMetadata;
+
+ // create path and map variables
+ String localVarPath = "/repositories/{repository}/branches/{branch}/objects/stat/user_metadata"
+ .replaceAll("\\{" + "repository" + "\\}", localVarApiClient.escapeString(repository.toString()))
+ .replaceAll("\\{" + "branch" + "\\}", localVarApiClient.escapeString(branch.toString()));
+
+ List localVarQueryParams = new ArrayList();
+ List localVarCollectionQueryParams = new ArrayList();
+ Map localVarHeaderParams = new HashMap();
+ Map localVarCookieParams = new HashMap();
+ Map localVarFormParams = new HashMap();
+
+ if (path != null) {
+ localVarQueryParams.addAll(localVarApiClient.parameterToPair("path", path));
+ }
+
+ final String[] localVarAccepts = {
+ "application/json"
+ };
+ final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts);
+ if (localVarAccept != null) {
+ localVarHeaderParams.put("Accept", localVarAccept);
+ }
+
+ final String[] localVarContentTypes = {
+ "application/json"
+ };
+ final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes);
+ localVarHeaderParams.put("Content-Type", localVarContentType);
+
+ String[] localVarAuthNames = new String[] { "basic_auth", "cookie_auth", "jwt_token", "oidc_auth", "saml_auth" };
+ return localVarApiClient.buildCall(localVarPath, "PUT", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback);
+ }
+
+ @SuppressWarnings("rawtypes")
+ private okhttp3.Call updateObjectUserMetadataValidateBeforeCall(String repository, String branch, String path, UpdateObjectUserMetadata updateObjectUserMetadata, final ApiCallback _callback) throws ApiException {
+
+ // verify the required parameter 'repository' is set
+ if (repository == null) {
+ throw new ApiException("Missing the required parameter 'repository' when calling updateObjectUserMetadata(Async)");
+ }
+
+ // verify the required parameter 'branch' is set
+ if (branch == null) {
+ throw new ApiException("Missing the required parameter 'branch' when calling updateObjectUserMetadata(Async)");
+ }
+
+ // verify the required parameter 'path' is set
+ if (path == null) {
+ throw new ApiException("Missing the required parameter 'path' when calling updateObjectUserMetadata(Async)");
+ }
+
+ // verify the required parameter 'updateObjectUserMetadata' is set
+ if (updateObjectUserMetadata == null) {
+ throw new ApiException("Missing the required parameter 'updateObjectUserMetadata' when calling updateObjectUserMetadata(Async)");
+ }
+
+
+ okhttp3.Call localVarCall = updateObjectUserMetadataCall(repository, branch, path, updateObjectUserMetadata, _callback);
+ return localVarCall;
+
+ }
+
+ /**
+ * rewrite (all) object metadata
+ *
+ * @param repository (required)
+ * @param branch branch to update (required)
+ * @param path path to object relative to the branch (required)
+ * @param updateObjectUserMetadata (required)
+ * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
+ * @http.response.details
+
+ Status Code | Description | Response Headers |
+ 201 | User metadata updated | - |
+ 401 | Unauthorized | - |
+ 404 | Resource Not Found | - |
+ 400 | Bad Request | - |
+ 420 | too many requests | - |
+ 0 | Internal Server Error | - |
+
+ */
+ public void updateObjectUserMetadata(String repository, String branch, String path, UpdateObjectUserMetadata updateObjectUserMetadata) throws ApiException {
+ updateObjectUserMetadataWithHttpInfo(repository, branch, path, updateObjectUserMetadata);
+ }
+
+ /**
+ * rewrite (all) object metadata
+ *
+ * @param repository (required)
+ * @param branch branch to update (required)
+ * @param path path to object relative to the branch (required)
+ * @param updateObjectUserMetadata (required)
+ * @return ApiResponse<Void>
+ * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
+ * @http.response.details
+
+ Status Code | Description | Response Headers |
+ 201 | User metadata updated | - |
+ 401 | Unauthorized | - |
+ 404 | Resource Not Found | - |
+ 400 | Bad Request | - |
+ 420 | too many requests | - |
+ 0 | Internal Server Error | - |
+
+ */
+ public ApiResponse updateObjectUserMetadataWithHttpInfo(String repository, String branch, String path, UpdateObjectUserMetadata updateObjectUserMetadata) throws ApiException {
+ okhttp3.Call localVarCall = updateObjectUserMetadataValidateBeforeCall(repository, branch, path, updateObjectUserMetadata, null);
+ return localVarApiClient.execute(localVarCall);
+ }
+
+ /**
+ * rewrite (all) object metadata (asynchronously)
+ *
+ * @param repository (required)
+ * @param branch branch to update (required)
+ * @param path path to object relative to the branch (required)
+ * @param updateObjectUserMetadata (required)
+ * @param _callback The callback to be executed when the API call finishes
+ * @return The request call
+ * @throws ApiException If fail to process the API call, e.g. serializing the request body object
+ * @http.response.details
+
+ Status Code | Description | Response Headers |
+ 201 | User metadata updated | - |
+ 401 | Unauthorized | - |
+ 404 | Resource Not Found | - |
+ 400 | Bad Request | - |
+ 420 | too many requests | - |
+ 0 | Internal Server Error | - |
+
+ */
+ public okhttp3.Call updateObjectUserMetadataAsync(String repository, String branch, String path, UpdateObjectUserMetadata updateObjectUserMetadata, final ApiCallback _callback) throws ApiException {
+
+ okhttp3.Call localVarCall = updateObjectUserMetadataValidateBeforeCall(repository, branch, path, updateObjectUserMetadata, _callback);
+ localVarApiClient.executeAsync(localVarCall, _callback);
+ return localVarCall;
+ }
/**
* Build call for updatePullRequest
* @param repository (required)
diff --git a/clients/java-legacy/src/main/java/io/lakefs/clients/api/ObjectsApi.java b/clients/java-legacy/src/main/java/io/lakefs/clients/api/ObjectsApi.java
index 1c3ae1d2a52..c16b19878cc 100644
--- a/clients/java-legacy/src/main/java/io/lakefs/clients/api/ObjectsApi.java
+++ b/clients/java-legacy/src/main/java/io/lakefs/clients/api/ObjectsApi.java
@@ -35,6 +35,7 @@
import io.lakefs.clients.api.model.ObjectStatsList;
import io.lakefs.clients.api.model.PathList;
import io.lakefs.clients.api.model.UnderlyingObjectProperties;
+import io.lakefs.clients.api.model.UpdateObjectUserMetadata;
import java.lang.reflect.Type;
import java.util.ArrayList;
@@ -1421,6 +1422,166 @@ public okhttp3.Call statObjectAsync(String repository, String ref, String path,
localVarApiClient.executeAsync(localVarCall, localVarReturnType, _callback);
return localVarCall;
}
+ /**
+ * Build call for updateObjectUserMetadata
+ * @param repository (required)
+ * @param branch branch to update (required)
+ * @param path path to object relative to the branch (required)
+ * @param updateObjectUserMetadata (required)
+ * @param _callback Callback for upload/download progress
+ * @return Call to execute
+ * @throws ApiException If fail to serialize the request body object
+ * @http.response.details
+
+ Status Code | Description | Response Headers |
+ 201 | User metadata updated | - |
+ 401 | Unauthorized | - |
+ 404 | Resource Not Found | - |
+ 400 | Bad Request | - |
+ 420 | too many requests | - |
+ 0 | Internal Server Error | - |
+
+ */
+ public okhttp3.Call updateObjectUserMetadataCall(String repository, String branch, String path, UpdateObjectUserMetadata updateObjectUserMetadata, final ApiCallback _callback) throws ApiException {
+ Object localVarPostBody = updateObjectUserMetadata;
+
+ // create path and map variables
+ String localVarPath = "/repositories/{repository}/branches/{branch}/objects/stat/user_metadata"
+ .replaceAll("\\{" + "repository" + "\\}", localVarApiClient.escapeString(repository.toString()))
+ .replaceAll("\\{" + "branch" + "\\}", localVarApiClient.escapeString(branch.toString()));
+
+ List localVarQueryParams = new ArrayList();
+ List localVarCollectionQueryParams = new ArrayList();
+ Map localVarHeaderParams = new HashMap();
+ Map localVarCookieParams = new HashMap();
+ Map localVarFormParams = new HashMap();
+
+ if (path != null) {
+ localVarQueryParams.addAll(localVarApiClient.parameterToPair("path", path));
+ }
+
+ final String[] localVarAccepts = {
+ "application/json"
+ };
+ final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts);
+ if (localVarAccept != null) {
+ localVarHeaderParams.put("Accept", localVarAccept);
+ }
+
+ final String[] localVarContentTypes = {
+ "application/json"
+ };
+ final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes);
+ localVarHeaderParams.put("Content-Type", localVarContentType);
+
+ String[] localVarAuthNames = new String[] { "basic_auth", "cookie_auth", "jwt_token", "oidc_auth", "saml_auth" };
+ return localVarApiClient.buildCall(localVarPath, "PUT", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback);
+ }
+
+ @SuppressWarnings("rawtypes")
+ private okhttp3.Call updateObjectUserMetadataValidateBeforeCall(String repository, String branch, String path, UpdateObjectUserMetadata updateObjectUserMetadata, final ApiCallback _callback) throws ApiException {
+
+ // verify the required parameter 'repository' is set
+ if (repository == null) {
+ throw new ApiException("Missing the required parameter 'repository' when calling updateObjectUserMetadata(Async)");
+ }
+
+ // verify the required parameter 'branch' is set
+ if (branch == null) {
+ throw new ApiException("Missing the required parameter 'branch' when calling updateObjectUserMetadata(Async)");
+ }
+
+ // verify the required parameter 'path' is set
+ if (path == null) {
+ throw new ApiException("Missing the required parameter 'path' when calling updateObjectUserMetadata(Async)");
+ }
+
+ // verify the required parameter 'updateObjectUserMetadata' is set
+ if (updateObjectUserMetadata == null) {
+ throw new ApiException("Missing the required parameter 'updateObjectUserMetadata' when calling updateObjectUserMetadata(Async)");
+ }
+
+
+ okhttp3.Call localVarCall = updateObjectUserMetadataCall(repository, branch, path, updateObjectUserMetadata, _callback);
+ return localVarCall;
+
+ }
+
+ /**
+ * rewrite (all) object metadata
+ *
+ * @param repository (required)
+ * @param branch branch to update (required)
+ * @param path path to object relative to the branch (required)
+ * @param updateObjectUserMetadata (required)
+ * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
+ * @http.response.details
+
+ Status Code | Description | Response Headers |
+ 201 | User metadata updated | - |
+ 401 | Unauthorized | - |
+ 404 | Resource Not Found | - |
+ 400 | Bad Request | - |
+ 420 | too many requests | - |
+ 0 | Internal Server Error | - |
+
+ */
+ public void updateObjectUserMetadata(String repository, String branch, String path, UpdateObjectUserMetadata updateObjectUserMetadata) throws ApiException {
+ updateObjectUserMetadataWithHttpInfo(repository, branch, path, updateObjectUserMetadata);
+ }
+
+ /**
+ * rewrite (all) object metadata
+ *
+ * @param repository (required)
+ * @param branch branch to update (required)
+ * @param path path to object relative to the branch (required)
+ * @param updateObjectUserMetadata (required)
+ * @return ApiResponse<Void>
+ * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
+ * @http.response.details
+
+ Status Code | Description | Response Headers |
+ 201 | User metadata updated | - |
+ 401 | Unauthorized | - |
+ 404 | Resource Not Found | - |
+ 400 | Bad Request | - |
+ 420 | too many requests | - |
+ 0 | Internal Server Error | - |
+
+ */
+ public ApiResponse updateObjectUserMetadataWithHttpInfo(String repository, String branch, String path, UpdateObjectUserMetadata updateObjectUserMetadata) throws ApiException {
+ okhttp3.Call localVarCall = updateObjectUserMetadataValidateBeforeCall(repository, branch, path, updateObjectUserMetadata, null);
+ return localVarApiClient.execute(localVarCall);
+ }
+
+ /**
+ * rewrite (all) object metadata (asynchronously)
+ *
+ * @param repository (required)
+ * @param branch branch to update (required)
+ * @param path path to object relative to the branch (required)
+ * @param updateObjectUserMetadata (required)
+ * @param _callback The callback to be executed when the API call finishes
+ * @return The request call
+ * @throws ApiException If fail to process the API call, e.g. serializing the request body object
+ * @http.response.details
+
+ Status Code | Description | Response Headers |
+ 201 | User metadata updated | - |
+ 401 | Unauthorized | - |
+ 404 | Resource Not Found | - |
+ 400 | Bad Request | - |
+ 420 | too many requests | - |
+ 0 | Internal Server Error | - |
+
+ */
+ public okhttp3.Call updateObjectUserMetadataAsync(String repository, String branch, String path, UpdateObjectUserMetadata updateObjectUserMetadata, final ApiCallback _callback) throws ApiException {
+
+ okhttp3.Call localVarCall = updateObjectUserMetadataValidateBeforeCall(repository, branch, path, updateObjectUserMetadata, _callback);
+ localVarApiClient.executeAsync(localVarCall, _callback);
+ return localVarCall;
+ }
/**
* Build call for uploadObject
* @param repository (required)
diff --git a/clients/java-legacy/src/main/java/io/lakefs/clients/api/model/UpdateObjectUserMetadata.java b/clients/java-legacy/src/main/java/io/lakefs/clients/api/model/UpdateObjectUserMetadata.java
new file mode 100644
index 00000000000..3e7c5391389
--- /dev/null
+++ b/clients/java-legacy/src/main/java/io/lakefs/clients/api/model/UpdateObjectUserMetadata.java
@@ -0,0 +1,106 @@
+/*
+ * lakeFS API
+ * lakeFS HTTP API
+ *
+ * The version of the OpenAPI document: 1.0.0
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+
+package io.lakefs.clients.api.model;
+
+import java.util.Objects;
+import java.util.Arrays;
+import com.google.gson.TypeAdapter;
+import com.google.gson.annotations.JsonAdapter;
+import com.google.gson.annotations.SerializedName;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * UpdateObjectUserMetadata
+ */
+@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen")
+public class UpdateObjectUserMetadata {
+ public static final String SERIALIZED_NAME_SET = "set";
+ @SerializedName(SERIALIZED_NAME_SET)
+ private Map set = new HashMap();
+
+
+ public UpdateObjectUserMetadata set(Map set) {
+
+ this.set = set;
+ return this;
+ }
+
+ public UpdateObjectUserMetadata putSetItem(String key, String setItem) {
+ this.set.put(key, setItem);
+ return this;
+ }
+
+ /**
+ * Get set
+ * @return set
+ **/
+ @javax.annotation.Nonnull
+ @ApiModelProperty(required = true, value = "")
+
+ public Map getSet() {
+ return set;
+ }
+
+
+ public void setSet(Map set) {
+ this.set = set;
+ }
+
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ UpdateObjectUserMetadata updateObjectUserMetadata = (UpdateObjectUserMetadata) o;
+ return Objects.equals(this.set, updateObjectUserMetadata.set);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(set);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("class UpdateObjectUserMetadata {\n");
+ sb.append(" set: ").append(toIndentedString(set)).append("\n");
+ sb.append("}");
+ return sb.toString();
+ }
+
+ /**
+ * Convert the given object to string with each line indented by 4 spaces
+ * (except the first line).
+ */
+ private String toIndentedString(Object o) {
+ if (o == null) {
+ return "null";
+ }
+ return o.toString().replace("\n", "\n ");
+ }
+
+}
+
diff --git a/clients/java-legacy/src/test/java/io/lakefs/clients/api/ExperimentalApiTest.java b/clients/java-legacy/src/test/java/io/lakefs/clients/api/ExperimentalApiTest.java
index 8293db196ad..c9f32010645 100644
--- a/clients/java-legacy/src/test/java/io/lakefs/clients/api/ExperimentalApiTest.java
+++ b/clients/java-legacy/src/test/java/io/lakefs/clients/api/ExperimentalApiTest.java
@@ -32,6 +32,7 @@
import io.lakefs.clients.api.model.PullRequestsList;
import io.lakefs.clients.api.model.StagingLocation;
import io.lakefs.clients.api.model.StsAuthRequest;
+import io.lakefs.clients.api.model.UpdateObjectUserMetadata;
import org.junit.Test;
import org.junit.Ignore;
@@ -286,6 +287,24 @@ public void stsLoginTest() throws ApiException {
// TODO: test validations
}
+ /**
+ * rewrite (all) object metadata
+ *
+ *
+ *
+ * @throws ApiException
+ * if the Api call fails
+ */
+ @Test
+ public void updateObjectUserMetadataTest() throws ApiException {
+ String repository = null;
+ String branch = null;
+ String path = null;
+ UpdateObjectUserMetadata updateObjectUserMetadata = null;
+ api.updateObjectUserMetadata(repository, branch, path, updateObjectUserMetadata);
+ // TODO: test validations
+ }
+
/**
* update pull request
*
diff --git a/clients/java-legacy/src/test/java/io/lakefs/clients/api/ObjectsApiTest.java b/clients/java-legacy/src/test/java/io/lakefs/clients/api/ObjectsApiTest.java
index 750fb22f5e4..524a42b9609 100644
--- a/clients/java-legacy/src/test/java/io/lakefs/clients/api/ObjectsApiTest.java
+++ b/clients/java-legacy/src/test/java/io/lakefs/clients/api/ObjectsApiTest.java
@@ -22,6 +22,7 @@
import io.lakefs.clients.api.model.ObjectStatsList;
import io.lakefs.clients.api.model.PathList;
import io.lakefs.clients.api.model.UnderlyingObjectProperties;
+import io.lakefs.clients.api.model.UpdateObjectUserMetadata;
import org.junit.Test;
import org.junit.Ignore;
@@ -189,6 +190,24 @@ public void statObjectTest() throws ApiException {
// TODO: test validations
}
+ /**
+ * rewrite (all) object metadata
+ *
+ *
+ *
+ * @throws ApiException
+ * if the Api call fails
+ */
+ @Test
+ public void updateObjectUserMetadataTest() throws ApiException {
+ String repository = null;
+ String branch = null;
+ String path = null;
+ UpdateObjectUserMetadata updateObjectUserMetadata = null;
+ api.updateObjectUserMetadata(repository, branch, path, updateObjectUserMetadata);
+ // TODO: test validations
+ }
+
/**
*
*
diff --git a/clients/java-legacy/src/test/java/io/lakefs/clients/api/model/UpdateObjectUserMetadataTest.java b/clients/java-legacy/src/test/java/io/lakefs/clients/api/model/UpdateObjectUserMetadataTest.java
new file mode 100644
index 00000000000..6f38dbe4ec2
--- /dev/null
+++ b/clients/java-legacy/src/test/java/io/lakefs/clients/api/model/UpdateObjectUserMetadataTest.java
@@ -0,0 +1,54 @@
+/*
+ * lakeFS API
+ * lakeFS HTTP API
+ *
+ * The version of the OpenAPI document: 1.0.0
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+
+package io.lakefs.clients.api.model;
+
+import com.google.gson.TypeAdapter;
+import com.google.gson.annotations.JsonAdapter;
+import com.google.gson.annotations.SerializedName;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.junit.Assert;
+import org.junit.Ignore;
+import org.junit.Test;
+
+
+/**
+ * Model tests for UpdateObjectUserMetadata
+ */
+public class UpdateObjectUserMetadataTest {
+ private final UpdateObjectUserMetadata model = new UpdateObjectUserMetadata();
+
+ /**
+ * Model tests for UpdateObjectUserMetadata
+ */
+ @Test
+ public void testUpdateObjectUserMetadata() {
+ // TODO: test UpdateObjectUserMetadata
+ }
+
+ /**
+ * Test the property 'set'
+ */
+ @Test
+ public void setTest() {
+ // TODO: test set
+ }
+
+}
diff --git a/clients/java/README.md b/clients/java/README.md
index 0f85d4d3384..fe71fb372b3 100644
--- a/clients/java/README.md
+++ b/clients/java/README.md
@@ -208,6 +208,7 @@ Class | Method | HTTP request | Description
*ExperimentalApi* | [**listUserExternalPrincipals**](docs/ExperimentalApi.md#listUserExternalPrincipals) | **GET** /auth/users/{userId}/external/principals/ls | list user external policies attached to a user
*ExperimentalApi* | [**mergePullRequest**](docs/ExperimentalApi.md#mergePullRequest) | **PUT** /repositories/{repository}/pulls/{pull_request}/merge | merge pull request
*ExperimentalApi* | [**stsLogin**](docs/ExperimentalApi.md#stsLogin) | **POST** /sts/login | perform a login with STS
+*ExperimentalApi* | [**updateObjectUserMetadata**](docs/ExperimentalApi.md#updateObjectUserMetadata) | **PUT** /repositories/{repository}/branches/{branch}/objects/stat/user_metadata | rewrite (all) object metadata
*ExperimentalApi* | [**updatePullRequest**](docs/ExperimentalApi.md#updatePullRequest) | **PATCH** /repositories/{repository}/pulls/{pull_request} | update pull request
*ExternalApi* | [**createUserExternalPrincipal**](docs/ExternalApi.md#createUserExternalPrincipal) | **POST** /auth/users/{userId}/external/principals | attach external principal to user
*ExternalApi* | [**deleteUserExternalPrincipal**](docs/ExternalApi.md#deleteUserExternalPrincipal) | **DELETE** /auth/users/{userId}/external/principals | delete external principal from user
@@ -256,6 +257,7 @@ Class | Method | HTTP request | Description
*ObjectsApi* | [**headObject**](docs/ObjectsApi.md#headObject) | **HEAD** /repositories/{repository}/refs/{ref}/objects | check if object exists
*ObjectsApi* | [**listObjects**](docs/ObjectsApi.md#listObjects) | **GET** /repositories/{repository}/refs/{ref}/objects/ls | list objects under a given prefix
*ObjectsApi* | [**statObject**](docs/ObjectsApi.md#statObject) | **GET** /repositories/{repository}/refs/{ref}/objects/stat | get object metadata
+*ObjectsApi* | [**updateObjectUserMetadata**](docs/ObjectsApi.md#updateObjectUserMetadata) | **PUT** /repositories/{repository}/branches/{branch}/objects/stat/user_metadata | rewrite (all) object metadata
*ObjectsApi* | [**uploadObject**](docs/ObjectsApi.md#uploadObject) | **POST** /repositories/{repository}/branches/{branch}/objects |
*PullsApi* | [**createPullRequest**](docs/PullsApi.md#createPullRequest) | **POST** /repositories/{repository}/pulls | create pull request
*PullsApi* | [**getPullRequest**](docs/PullsApi.md#getPullRequest) | **GET** /repositories/{repository}/pulls/{pull_request} | get pull request
@@ -387,6 +389,7 @@ Class | Method | HTTP request | Description
- [TagCreation](docs/TagCreation.md)
- [TaskInfo](docs/TaskInfo.md)
- [UnderlyingObjectProperties](docs/UnderlyingObjectProperties.md)
+ - [UpdateObjectUserMetadata](docs/UpdateObjectUserMetadata.md)
- [UpdateToken](docs/UpdateToken.md)
- [UploadPart](docs/UploadPart.md)
- [UsageReport](docs/UsageReport.md)
diff --git a/clients/java/api/openapi.yaml b/clients/java/api/openapi.yaml
index df33158a06a..90b4e5a569d 100644
--- a/clients/java/api/openapi.yaml
+++ b/clients/java/api/openapi.yaml
@@ -5643,6 +5643,74 @@ paths:
tags:
- objects
x-accepts: application/json
+ /repositories/{repository}/branches/{branch}/objects/stat/user_metadata:
+ put:
+ operationId: updateObjectUserMetadata
+ parameters:
+ - explode: false
+ in: path
+ name: repository
+ required: true
+ schema:
+ type: string
+ style: simple
+ - description: branch to update
+ explode: false
+ in: path
+ name: branch
+ required: true
+ schema:
+ type: string
+ style: simple
+ - description: path to object relative to the branch
+ explode: true
+ in: query
+ name: path
+ required: true
+ schema:
+ type: string
+ style: form
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/UpdateObjectUserMetadata'
+ required: true
+ responses:
+ "201":
+ description: User metadata updated
+ "401":
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Error'
+ description: Unauthorized
+ "404":
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Error'
+ description: Resource Not Found
+ "400":
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Error'
+ description: Bad Request
+ "420":
+ description: too many requests
+ default:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Error'
+ description: Internal Server Error
+ summary: rewrite (all) object metadata
+ tags:
+ - objects
+ - experimental
+ x-content-type: application/json
+ x-accepts: application/json
/repositories/{repository}/refs/{ref}/objects/underlyingProperties:
get:
operationId: getUnderlyingProperties
@@ -7668,6 +7736,18 @@ components:
- pagination
- results
type: object
+ UpdateObjectUserMetadata:
+ example:
+ set:
+ key: set
+ properties:
+ set:
+ additionalProperties:
+ type: string
+ type: object
+ required:
+ - set
+ type: object
ObjectCopyCreation:
example:
force: false
diff --git a/clients/java/docs/ExperimentalApi.md b/clients/java/docs/ExperimentalApi.md
index c0ba459f098..26a453d4dcd 100644
--- a/clients/java/docs/ExperimentalApi.md
+++ b/clients/java/docs/ExperimentalApi.md
@@ -18,6 +18,7 @@ All URIs are relative to */api/v1*
| [**listUserExternalPrincipals**](ExperimentalApi.md#listUserExternalPrincipals) | **GET** /auth/users/{userId}/external/principals/ls | list user external policies attached to a user |
| [**mergePullRequest**](ExperimentalApi.md#mergePullRequest) | **PUT** /repositories/{repository}/pulls/{pull_request}/merge | merge pull request |
| [**stsLogin**](ExperimentalApi.md#stsLogin) | **POST** /sts/login | perform a login with STS |
+| [**updateObjectUserMetadata**](ExperimentalApi.md#updateObjectUserMetadata) | **PUT** /repositories/{repository}/branches/{branch}/objects/stat/user_metadata | rewrite (all) object metadata |
| [**updatePullRequest**](ExperimentalApi.md#updatePullRequest) | **PATCH** /repositories/{repository}/pulls/{pull_request} | update pull request |
@@ -1354,6 +1355,105 @@ No authorization required
| **420** | too many requests | - |
| **0** | Internal Server Error | - |
+
+# **updateObjectUserMetadata**
+> updateObjectUserMetadata(repository, branch, path, updateObjectUserMetadata).execute();
+
+rewrite (all) object metadata
+
+### Example
+```java
+// Import classes:
+import io.lakefs.clients.sdk.ApiClient;
+import io.lakefs.clients.sdk.ApiException;
+import io.lakefs.clients.sdk.Configuration;
+import io.lakefs.clients.sdk.auth.*;
+import io.lakefs.clients.sdk.models.*;
+import io.lakefs.clients.sdk.ExperimentalApi;
+
+public class Example {
+ public static void main(String[] args) {
+ ApiClient defaultClient = Configuration.getDefaultApiClient();
+ defaultClient.setBasePath("/api/v1");
+
+ // Configure HTTP basic authorization: basic_auth
+ HttpBasicAuth basic_auth = (HttpBasicAuth) defaultClient.getAuthentication("basic_auth");
+ basic_auth.setUsername("YOUR USERNAME");
+ basic_auth.setPassword("YOUR PASSWORD");
+
+ // Configure API key authorization: cookie_auth
+ ApiKeyAuth cookie_auth = (ApiKeyAuth) defaultClient.getAuthentication("cookie_auth");
+ cookie_auth.setApiKey("YOUR API KEY");
+ // Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
+ //cookie_auth.setApiKeyPrefix("Token");
+
+ // Configure API key authorization: oidc_auth
+ ApiKeyAuth oidc_auth = (ApiKeyAuth) defaultClient.getAuthentication("oidc_auth");
+ oidc_auth.setApiKey("YOUR API KEY");
+ // Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
+ //oidc_auth.setApiKeyPrefix("Token");
+
+ // Configure API key authorization: saml_auth
+ ApiKeyAuth saml_auth = (ApiKeyAuth) defaultClient.getAuthentication("saml_auth");
+ saml_auth.setApiKey("YOUR API KEY");
+ // Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
+ //saml_auth.setApiKeyPrefix("Token");
+
+ // Configure HTTP bearer authorization: jwt_token
+ HttpBearerAuth jwt_token = (HttpBearerAuth) defaultClient.getAuthentication("jwt_token");
+ jwt_token.setBearerToken("BEARER TOKEN");
+
+ ExperimentalApi apiInstance = new ExperimentalApi(defaultClient);
+ String repository = "repository_example"; // String |
+ String branch = "branch_example"; // String | branch to update
+ String path = "path_example"; // String | path to object relative to the branch
+ UpdateObjectUserMetadata updateObjectUserMetadata = new UpdateObjectUserMetadata(); // UpdateObjectUserMetadata |
+ try {
+ apiInstance.updateObjectUserMetadata(repository, branch, path, updateObjectUserMetadata)
+ .execute();
+ } catch (ApiException e) {
+ System.err.println("Exception when calling ExperimentalApi#updateObjectUserMetadata");
+ System.err.println("Status code: " + e.getCode());
+ System.err.println("Reason: " + e.getResponseBody());
+ System.err.println("Response headers: " + e.getResponseHeaders());
+ e.printStackTrace();
+ }
+ }
+}
+```
+
+### Parameters
+
+| Name | Type | Description | Notes |
+|------------- | ------------- | ------------- | -------------|
+| **repository** | **String**| | |
+| **branch** | **String**| branch to update | |
+| **path** | **String**| path to object relative to the branch | |
+| **updateObjectUserMetadata** | [**UpdateObjectUserMetadata**](UpdateObjectUserMetadata.md)| | |
+
+### Return type
+
+null (empty response body)
+
+### Authorization
+
+[basic_auth](../README.md#basic_auth), [cookie_auth](../README.md#cookie_auth), [oidc_auth](../README.md#oidc_auth), [saml_auth](../README.md#saml_auth), [jwt_token](../README.md#jwt_token)
+
+### HTTP request headers
+
+ - **Content-Type**: application/json
+ - **Accept**: application/json
+
+### HTTP response details
+| Status code | Description | Response headers |
+|-------------|-------------|------------------|
+| **201** | User metadata updated | - |
+| **401** | Unauthorized | - |
+| **404** | Resource Not Found | - |
+| **400** | Bad Request | - |
+| **420** | too many requests | - |
+| **0** | Internal Server Error | - |
+
# **updatePullRequest**
> updatePullRequest(repository, pullRequest, pullRequestBasic).execute();
diff --git a/clients/java/docs/ObjectsApi.md b/clients/java/docs/ObjectsApi.md
index d441235e74e..986a3e9d2dd 100644
--- a/clients/java/docs/ObjectsApi.md
+++ b/clients/java/docs/ObjectsApi.md
@@ -12,6 +12,7 @@ All URIs are relative to */api/v1*
| [**headObject**](ObjectsApi.md#headObject) | **HEAD** /repositories/{repository}/refs/{ref}/objects | check if object exists |
| [**listObjects**](ObjectsApi.md#listObjects) | **GET** /repositories/{repository}/refs/{ref}/objects/ls | list objects under a given prefix |
| [**statObject**](ObjectsApi.md#statObject) | **GET** /repositories/{repository}/refs/{ref}/objects/stat | get object metadata |
+| [**updateObjectUserMetadata**](ObjectsApi.md#updateObjectUserMetadata) | **PUT** /repositories/{repository}/branches/{branch}/objects/stat/user_metadata | rewrite (all) object metadata |
| [**uploadObject**](ObjectsApi.md#uploadObject) | **POST** /repositories/{repository}/branches/{branch}/objects | |
@@ -845,6 +846,105 @@ public class Example {
| **420** | too many requests | - |
| **0** | Internal Server Error | - |
+
+# **updateObjectUserMetadata**
+> updateObjectUserMetadata(repository, branch, path, updateObjectUserMetadata).execute();
+
+rewrite (all) object metadata
+
+### Example
+```java
+// Import classes:
+import io.lakefs.clients.sdk.ApiClient;
+import io.lakefs.clients.sdk.ApiException;
+import io.lakefs.clients.sdk.Configuration;
+import io.lakefs.clients.sdk.auth.*;
+import io.lakefs.clients.sdk.models.*;
+import io.lakefs.clients.sdk.ObjectsApi;
+
+public class Example {
+ public static void main(String[] args) {
+ ApiClient defaultClient = Configuration.getDefaultApiClient();
+ defaultClient.setBasePath("/api/v1");
+
+ // Configure HTTP basic authorization: basic_auth
+ HttpBasicAuth basic_auth = (HttpBasicAuth) defaultClient.getAuthentication("basic_auth");
+ basic_auth.setUsername("YOUR USERNAME");
+ basic_auth.setPassword("YOUR PASSWORD");
+
+ // Configure API key authorization: cookie_auth
+ ApiKeyAuth cookie_auth = (ApiKeyAuth) defaultClient.getAuthentication("cookie_auth");
+ cookie_auth.setApiKey("YOUR API KEY");
+ // Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
+ //cookie_auth.setApiKeyPrefix("Token");
+
+ // Configure API key authorization: oidc_auth
+ ApiKeyAuth oidc_auth = (ApiKeyAuth) defaultClient.getAuthentication("oidc_auth");
+ oidc_auth.setApiKey("YOUR API KEY");
+ // Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
+ //oidc_auth.setApiKeyPrefix("Token");
+
+ // Configure API key authorization: saml_auth
+ ApiKeyAuth saml_auth = (ApiKeyAuth) defaultClient.getAuthentication("saml_auth");
+ saml_auth.setApiKey("YOUR API KEY");
+ // Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
+ //saml_auth.setApiKeyPrefix("Token");
+
+ // Configure HTTP bearer authorization: jwt_token
+ HttpBearerAuth jwt_token = (HttpBearerAuth) defaultClient.getAuthentication("jwt_token");
+ jwt_token.setBearerToken("BEARER TOKEN");
+
+ ObjectsApi apiInstance = new ObjectsApi(defaultClient);
+ String repository = "repository_example"; // String |
+ String branch = "branch_example"; // String | branch to update
+ String path = "path_example"; // String | path to object relative to the branch
+ UpdateObjectUserMetadata updateObjectUserMetadata = new UpdateObjectUserMetadata(); // UpdateObjectUserMetadata |
+ try {
+ apiInstance.updateObjectUserMetadata(repository, branch, path, updateObjectUserMetadata)
+ .execute();
+ } catch (ApiException e) {
+ System.err.println("Exception when calling ObjectsApi#updateObjectUserMetadata");
+ System.err.println("Status code: " + e.getCode());
+ System.err.println("Reason: " + e.getResponseBody());
+ System.err.println("Response headers: " + e.getResponseHeaders());
+ e.printStackTrace();
+ }
+ }
+}
+```
+
+### Parameters
+
+| Name | Type | Description | Notes |
+|------------- | ------------- | ------------- | -------------|
+| **repository** | **String**| | |
+| **branch** | **String**| branch to update | |
+| **path** | **String**| path to object relative to the branch | |
+| **updateObjectUserMetadata** | [**UpdateObjectUserMetadata**](UpdateObjectUserMetadata.md)| | |
+
+### Return type
+
+null (empty response body)
+
+### Authorization
+
+[basic_auth](../README.md#basic_auth), [cookie_auth](../README.md#cookie_auth), [oidc_auth](../README.md#oidc_auth), [saml_auth](../README.md#saml_auth), [jwt_token](../README.md#jwt_token)
+
+### HTTP request headers
+
+ - **Content-Type**: application/json
+ - **Accept**: application/json
+
+### HTTP response details
+| Status code | Description | Response headers |
+|-------------|-------------|------------------|
+| **201** | User metadata updated | - |
+| **401** | Unauthorized | - |
+| **404** | Resource Not Found | - |
+| **400** | Bad Request | - |
+| **420** | too many requests | - |
+| **0** | Internal Server Error | - |
+
# **uploadObject**
> ObjectStats uploadObject(repository, branch, path).ifNoneMatch(ifNoneMatch).storageClass(storageClass).force(force).content(content).execute();
diff --git a/clients/java/docs/UpdateObjectUserMetadata.md b/clients/java/docs/UpdateObjectUserMetadata.md
new file mode 100644
index 00000000000..01806918b68
--- /dev/null
+++ b/clients/java/docs/UpdateObjectUserMetadata.md
@@ -0,0 +1,13 @@
+
+
+# UpdateObjectUserMetadata
+
+
+## Properties
+
+| Name | Type | Description | Notes |
+|------------ | ------------- | ------------- | -------------|
+|**set** | **Map<String, String>** | | |
+
+
+
diff --git a/clients/java/src/main/java/io/lakefs/clients/sdk/ExperimentalApi.java b/clients/java/src/main/java/io/lakefs/clients/sdk/ExperimentalApi.java
index 019de8a6b10..c47c8f0f7f6 100644
--- a/clients/java/src/main/java/io/lakefs/clients/sdk/ExperimentalApi.java
+++ b/clients/java/src/main/java/io/lakefs/clients/sdk/ExperimentalApi.java
@@ -45,6 +45,7 @@
import io.lakefs.clients.sdk.model.PullRequestsList;
import io.lakefs.clients.sdk.model.StagingLocation;
import io.lakefs.clients.sdk.model.StsAuthRequest;
+import io.lakefs.clients.sdk.model.UpdateObjectUserMetadata;
import java.lang.reflect.Type;
import java.util.ArrayList;
@@ -2891,6 +2892,209 @@ public okhttp3.Call executeAsync(final ApiCallback _callbac
public APIstsLoginRequest stsLogin(StsAuthRequest stsAuthRequest) {
return new APIstsLoginRequest(stsAuthRequest);
}
+ private okhttp3.Call updateObjectUserMetadataCall(String repository, String branch, String path, UpdateObjectUserMetadata updateObjectUserMetadata, final ApiCallback _callback) throws ApiException {
+ String basePath = null;
+ // Operation Servers
+ String[] localBasePaths = new String[] { };
+
+ // Determine Base Path to Use
+ if (localCustomBaseUrl != null){
+ basePath = localCustomBaseUrl;
+ } else if ( localBasePaths.length > 0 ) {
+ basePath = localBasePaths[localHostIndex];
+ } else {
+ basePath = null;
+ }
+
+ Object localVarPostBody = updateObjectUserMetadata;
+
+ // create path and map variables
+ String localVarPath = "/repositories/{repository}/branches/{branch}/objects/stat/user_metadata"
+ .replace("{" + "repository" + "}", localVarApiClient.escapeString(repository.toString()))
+ .replace("{" + "branch" + "}", localVarApiClient.escapeString(branch.toString()));
+
+ List localVarQueryParams = new ArrayList();
+ List localVarCollectionQueryParams = new ArrayList();
+ Map localVarHeaderParams = new HashMap();
+ Map localVarCookieParams = new HashMap();
+ Map localVarFormParams = new HashMap();
+
+ if (path != null) {
+ localVarQueryParams.addAll(localVarApiClient.parameterToPair("path", path));
+ }
+
+ final String[] localVarAccepts = {
+ "application/json"
+ };
+ final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts);
+ if (localVarAccept != null) {
+ localVarHeaderParams.put("Accept", localVarAccept);
+ }
+
+ final String[] localVarContentTypes = {
+ "application/json"
+ };
+ final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes);
+ if (localVarContentType != null) {
+ localVarHeaderParams.put("Content-Type", localVarContentType);
+ }
+
+ String[] localVarAuthNames = new String[] { "basic_auth", "cookie_auth", "oidc_auth", "saml_auth", "jwt_token" };
+ return localVarApiClient.buildCall(basePath, localVarPath, "PUT", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback);
+ }
+
+ @SuppressWarnings("rawtypes")
+ private okhttp3.Call updateObjectUserMetadataValidateBeforeCall(String repository, String branch, String path, UpdateObjectUserMetadata updateObjectUserMetadata, final ApiCallback _callback) throws ApiException {
+ // verify the required parameter 'repository' is set
+ if (repository == null) {
+ throw new ApiException("Missing the required parameter 'repository' when calling updateObjectUserMetadata(Async)");
+ }
+
+ // verify the required parameter 'branch' is set
+ if (branch == null) {
+ throw new ApiException("Missing the required parameter 'branch' when calling updateObjectUserMetadata(Async)");
+ }
+
+ // verify the required parameter 'path' is set
+ if (path == null) {
+ throw new ApiException("Missing the required parameter 'path' when calling updateObjectUserMetadata(Async)");
+ }
+
+ // verify the required parameter 'updateObjectUserMetadata' is set
+ if (updateObjectUserMetadata == null) {
+ throw new ApiException("Missing the required parameter 'updateObjectUserMetadata' when calling updateObjectUserMetadata(Async)");
+ }
+
+ return updateObjectUserMetadataCall(repository, branch, path, updateObjectUserMetadata, _callback);
+
+ }
+
+
+ private ApiResponse updateObjectUserMetadataWithHttpInfo(String repository, String branch, String path, UpdateObjectUserMetadata updateObjectUserMetadata) throws ApiException {
+ okhttp3.Call localVarCall = updateObjectUserMetadataValidateBeforeCall(repository, branch, path, updateObjectUserMetadata, null);
+ return localVarApiClient.execute(localVarCall);
+ }
+
+ private okhttp3.Call updateObjectUserMetadataAsync(String repository, String branch, String path, UpdateObjectUserMetadata updateObjectUserMetadata, final ApiCallback _callback) throws ApiException {
+
+ okhttp3.Call localVarCall = updateObjectUserMetadataValidateBeforeCall(repository, branch, path, updateObjectUserMetadata, _callback);
+ localVarApiClient.executeAsync(localVarCall, _callback);
+ return localVarCall;
+ }
+
+ public class APIupdateObjectUserMetadataRequest {
+ private final String repository;
+ private final String branch;
+ private final String path;
+ private final UpdateObjectUserMetadata updateObjectUserMetadata;
+
+ private APIupdateObjectUserMetadataRequest(String repository, String branch, String path, UpdateObjectUserMetadata updateObjectUserMetadata) {
+ this.repository = repository;
+ this.branch = branch;
+ this.path = path;
+ this.updateObjectUserMetadata = updateObjectUserMetadata;
+ }
+
+ /**
+ * Build call for updateObjectUserMetadata
+ * @param _callback ApiCallback API callback
+ * @return Call to execute
+ * @throws ApiException If fail to serialize the request body object
+ * @http.response.details
+
+ Status Code | Description | Response Headers |
+ 201 | User metadata updated | - |
+ 401 | Unauthorized | - |
+ 404 | Resource Not Found | - |
+ 400 | Bad Request | - |
+ 420 | too many requests | - |
+ 0 | Internal Server Error | - |
+
+ */
+ public okhttp3.Call buildCall(final ApiCallback _callback) throws ApiException {
+ return updateObjectUserMetadataCall(repository, branch, path, updateObjectUserMetadata, _callback);
+ }
+
+ /**
+ * Execute updateObjectUserMetadata request
+ * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
+ * @http.response.details
+
+ Status Code | Description | Response Headers |
+ 201 | User metadata updated | - |
+ 401 | Unauthorized | - |
+ 404 | Resource Not Found | - |
+ 400 | Bad Request | - |
+ 420 | too many requests | - |
+ 0 | Internal Server Error | - |
+
+ */
+ public void execute() throws ApiException {
+ updateObjectUserMetadataWithHttpInfo(repository, branch, path, updateObjectUserMetadata);
+ }
+
+ /**
+ * Execute updateObjectUserMetadata request with HTTP info returned
+ * @return ApiResponse<Void>
+ * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
+ * @http.response.details
+
+ Status Code | Description | Response Headers |
+ 201 | User metadata updated | - |
+ 401 | Unauthorized | - |
+ 404 | Resource Not Found | - |
+ 400 | Bad Request | - |
+ 420 | too many requests | - |
+ 0 | Internal Server Error | - |
+
+ */
+ public ApiResponse executeWithHttpInfo() throws ApiException {
+ return updateObjectUserMetadataWithHttpInfo(repository, branch, path, updateObjectUserMetadata);
+ }
+
+ /**
+ * Execute updateObjectUserMetadata request (asynchronously)
+ * @param _callback The callback to be executed when the API call finishes
+ * @return The request call
+ * @throws ApiException If fail to process the API call, e.g. serializing the request body object
+ * @http.response.details
+
+ Status Code | Description | Response Headers |
+ 201 | User metadata updated | - |
+ 401 | Unauthorized | - |
+ 404 | Resource Not Found | - |
+ 400 | Bad Request | - |
+ 420 | too many requests | - |
+ 0 | Internal Server Error | - |
+
+ */
+ public okhttp3.Call executeAsync(final ApiCallback _callback) throws ApiException {
+ return updateObjectUserMetadataAsync(repository, branch, path, updateObjectUserMetadata, _callback);
+ }
+ }
+
+ /**
+ * rewrite (all) object metadata
+ *
+ * @param repository (required)
+ * @param branch branch to update (required)
+ * @param path path to object relative to the branch (required)
+ * @param updateObjectUserMetadata (required)
+ * @return APIupdateObjectUserMetadataRequest
+ * @http.response.details
+
+ Status Code | Description | Response Headers |
+ 201 | User metadata updated | - |
+ 401 | Unauthorized | - |
+ 404 | Resource Not Found | - |
+ 400 | Bad Request | - |
+ 420 | too many requests | - |
+ 0 | Internal Server Error | - |
+
+ */
+ public APIupdateObjectUserMetadataRequest updateObjectUserMetadata(String repository, String branch, String path, UpdateObjectUserMetadata updateObjectUserMetadata) {
+ return new APIupdateObjectUserMetadataRequest(repository, branch, path, updateObjectUserMetadata);
+ }
private okhttp3.Call updatePullRequestCall(String repository, String pullRequest, PullRequestBasic pullRequestBasic, final ApiCallback _callback) throws ApiException {
String basePath = null;
// Operation Servers
diff --git a/clients/java/src/main/java/io/lakefs/clients/sdk/JSON.java b/clients/java/src/main/java/io/lakefs/clients/sdk/JSON.java
index 1d03e373f03..d75185f772c 100644
--- a/clients/java/src/main/java/io/lakefs/clients/sdk/JSON.java
+++ b/clients/java/src/main/java/io/lakefs/clients/sdk/JSON.java
@@ -190,6 +190,7 @@ private static Class getClassByDiscriminator(Map classByDiscriminatorValue, Stri
gsonBuilder.registerTypeAdapterFactory(new io.lakefs.clients.sdk.model.TagCreation.CustomTypeAdapterFactory());
gsonBuilder.registerTypeAdapterFactory(new io.lakefs.clients.sdk.model.TaskInfo.CustomTypeAdapterFactory());
gsonBuilder.registerTypeAdapterFactory(new io.lakefs.clients.sdk.model.UnderlyingObjectProperties.CustomTypeAdapterFactory());
+ gsonBuilder.registerTypeAdapterFactory(new io.lakefs.clients.sdk.model.UpdateObjectUserMetadata.CustomTypeAdapterFactory());
gsonBuilder.registerTypeAdapterFactory(new io.lakefs.clients.sdk.model.UpdateToken.CustomTypeAdapterFactory());
gsonBuilder.registerTypeAdapterFactory(new io.lakefs.clients.sdk.model.UploadPart.CustomTypeAdapterFactory());
gsonBuilder.registerTypeAdapterFactory(new io.lakefs.clients.sdk.model.UsageReport.CustomTypeAdapterFactory());
diff --git a/clients/java/src/main/java/io/lakefs/clients/sdk/ObjectsApi.java b/clients/java/src/main/java/io/lakefs/clients/sdk/ObjectsApi.java
index 8f2ea7cc92d..3c0c2c2dcb8 100644
--- a/clients/java/src/main/java/io/lakefs/clients/sdk/ObjectsApi.java
+++ b/clients/java/src/main/java/io/lakefs/clients/sdk/ObjectsApi.java
@@ -35,6 +35,7 @@
import io.lakefs.clients.sdk.model.ObjectStatsList;
import io.lakefs.clients.sdk.model.PathList;
import io.lakefs.clients.sdk.model.UnderlyingObjectProperties;
+import io.lakefs.clients.sdk.model.UpdateObjectUserMetadata;
import java.lang.reflect.Type;
import java.util.ArrayList;
@@ -1889,6 +1890,209 @@ public okhttp3.Call executeAsync(final ApiCallback _callback) throw
public APIstatObjectRequest statObject(String repository, String ref, String path) {
return new APIstatObjectRequest(repository, ref, path);
}
+ private okhttp3.Call updateObjectUserMetadataCall(String repository, String branch, String path, UpdateObjectUserMetadata updateObjectUserMetadata, final ApiCallback _callback) throws ApiException {
+ String basePath = null;
+ // Operation Servers
+ String[] localBasePaths = new String[] { };
+
+ // Determine Base Path to Use
+ if (localCustomBaseUrl != null){
+ basePath = localCustomBaseUrl;
+ } else if ( localBasePaths.length > 0 ) {
+ basePath = localBasePaths[localHostIndex];
+ } else {
+ basePath = null;
+ }
+
+ Object localVarPostBody = updateObjectUserMetadata;
+
+ // create path and map variables
+ String localVarPath = "/repositories/{repository}/branches/{branch}/objects/stat/user_metadata"
+ .replace("{" + "repository" + "}", localVarApiClient.escapeString(repository.toString()))
+ .replace("{" + "branch" + "}", localVarApiClient.escapeString(branch.toString()));
+
+ List localVarQueryParams = new ArrayList();
+ List localVarCollectionQueryParams = new ArrayList();
+ Map localVarHeaderParams = new HashMap();
+ Map localVarCookieParams = new HashMap();
+ Map localVarFormParams = new HashMap();
+
+ if (path != null) {
+ localVarQueryParams.addAll(localVarApiClient.parameterToPair("path", path));
+ }
+
+ final String[] localVarAccepts = {
+ "application/json"
+ };
+ final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts);
+ if (localVarAccept != null) {
+ localVarHeaderParams.put("Accept", localVarAccept);
+ }
+
+ final String[] localVarContentTypes = {
+ "application/json"
+ };
+ final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes);
+ if (localVarContentType != null) {
+ localVarHeaderParams.put("Content-Type", localVarContentType);
+ }
+
+ String[] localVarAuthNames = new String[] { "basic_auth", "cookie_auth", "oidc_auth", "saml_auth", "jwt_token" };
+ return localVarApiClient.buildCall(basePath, localVarPath, "PUT", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback);
+ }
+
+ @SuppressWarnings("rawtypes")
+ private okhttp3.Call updateObjectUserMetadataValidateBeforeCall(String repository, String branch, String path, UpdateObjectUserMetadata updateObjectUserMetadata, final ApiCallback _callback) throws ApiException {
+ // verify the required parameter 'repository' is set
+ if (repository == null) {
+ throw new ApiException("Missing the required parameter 'repository' when calling updateObjectUserMetadata(Async)");
+ }
+
+ // verify the required parameter 'branch' is set
+ if (branch == null) {
+ throw new ApiException("Missing the required parameter 'branch' when calling updateObjectUserMetadata(Async)");
+ }
+
+ // verify the required parameter 'path' is set
+ if (path == null) {
+ throw new ApiException("Missing the required parameter 'path' when calling updateObjectUserMetadata(Async)");
+ }
+
+ // verify the required parameter 'updateObjectUserMetadata' is set
+ if (updateObjectUserMetadata == null) {
+ throw new ApiException("Missing the required parameter 'updateObjectUserMetadata' when calling updateObjectUserMetadata(Async)");
+ }
+
+ return updateObjectUserMetadataCall(repository, branch, path, updateObjectUserMetadata, _callback);
+
+ }
+
+
+ private ApiResponse updateObjectUserMetadataWithHttpInfo(String repository, String branch, String path, UpdateObjectUserMetadata updateObjectUserMetadata) throws ApiException {
+ okhttp3.Call localVarCall = updateObjectUserMetadataValidateBeforeCall(repository, branch, path, updateObjectUserMetadata, null);
+ return localVarApiClient.execute(localVarCall);
+ }
+
+ private okhttp3.Call updateObjectUserMetadataAsync(String repository, String branch, String path, UpdateObjectUserMetadata updateObjectUserMetadata, final ApiCallback _callback) throws ApiException {
+
+ okhttp3.Call localVarCall = updateObjectUserMetadataValidateBeforeCall(repository, branch, path, updateObjectUserMetadata, _callback);
+ localVarApiClient.executeAsync(localVarCall, _callback);
+ return localVarCall;
+ }
+
+ public class APIupdateObjectUserMetadataRequest {
+ private final String repository;
+ private final String branch;
+ private final String path;
+ private final UpdateObjectUserMetadata updateObjectUserMetadata;
+
+ private APIupdateObjectUserMetadataRequest(String repository, String branch, String path, UpdateObjectUserMetadata updateObjectUserMetadata) {
+ this.repository = repository;
+ this.branch = branch;
+ this.path = path;
+ this.updateObjectUserMetadata = updateObjectUserMetadata;
+ }
+
+ /**
+ * Build call for updateObjectUserMetadata
+ * @param _callback ApiCallback API callback
+ * @return Call to execute
+ * @throws ApiException If fail to serialize the request body object
+ * @http.response.details
+
+ Status Code | Description | Response Headers |
+ 201 | User metadata updated | - |
+ 401 | Unauthorized | - |
+ 404 | Resource Not Found | - |
+ 400 | Bad Request | - |
+ 420 | too many requests | - |
+ 0 | Internal Server Error | - |
+
+ */
+ public okhttp3.Call buildCall(final ApiCallback _callback) throws ApiException {
+ return updateObjectUserMetadataCall(repository, branch, path, updateObjectUserMetadata, _callback);
+ }
+
+ /**
+ * Execute updateObjectUserMetadata request
+ * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
+ * @http.response.details
+
+ Status Code | Description | Response Headers |
+ 201 | User metadata updated | - |
+ 401 | Unauthorized | - |
+ 404 | Resource Not Found | - |
+ 400 | Bad Request | - |
+ 420 | too many requests | - |
+ 0 | Internal Server Error | - |
+
+ */
+ public void execute() throws ApiException {
+ updateObjectUserMetadataWithHttpInfo(repository, branch, path, updateObjectUserMetadata);
+ }
+
+ /**
+ * Execute updateObjectUserMetadata request with HTTP info returned
+ * @return ApiResponse<Void>
+ * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
+ * @http.response.details
+
+ Status Code | Description | Response Headers |
+ 201 | User metadata updated | - |
+ 401 | Unauthorized | - |
+ 404 | Resource Not Found | - |
+ 400 | Bad Request | - |
+ 420 | too many requests | - |
+ 0 | Internal Server Error | - |
+
+ */
+ public ApiResponse executeWithHttpInfo() throws ApiException {
+ return updateObjectUserMetadataWithHttpInfo(repository, branch, path, updateObjectUserMetadata);
+ }
+
+ /**
+ * Execute updateObjectUserMetadata request (asynchronously)
+ * @param _callback The callback to be executed when the API call finishes
+ * @return The request call
+ * @throws ApiException If fail to process the API call, e.g. serializing the request body object
+ * @http.response.details
+
+ Status Code | Description | Response Headers |
+ 201 | User metadata updated | - |
+ 401 | Unauthorized | - |
+ 404 | Resource Not Found | - |
+ 400 | Bad Request | - |
+ 420 | too many requests | - |
+ 0 | Internal Server Error | - |
+
+ */
+ public okhttp3.Call executeAsync(final ApiCallback _callback) throws ApiException {
+ return updateObjectUserMetadataAsync(repository, branch, path, updateObjectUserMetadata, _callback);
+ }
+ }
+
+ /**
+ * rewrite (all) object metadata
+ *
+ * @param repository (required)
+ * @param branch branch to update (required)
+ * @param path path to object relative to the branch (required)
+ * @param updateObjectUserMetadata (required)
+ * @return APIupdateObjectUserMetadataRequest
+ * @http.response.details
+
+ Status Code | Description | Response Headers |
+ 201 | User metadata updated | - |
+ 401 | Unauthorized | - |
+ 404 | Resource Not Found | - |
+ 400 | Bad Request | - |
+ 420 | too many requests | - |
+ 0 | Internal Server Error | - |
+
+ */
+ public APIupdateObjectUserMetadataRequest updateObjectUserMetadata(String repository, String branch, String path, UpdateObjectUserMetadata updateObjectUserMetadata) {
+ return new APIupdateObjectUserMetadataRequest(repository, branch, path, updateObjectUserMetadata);
+ }
private okhttp3.Call uploadObjectCall(String repository, String branch, String path, String ifNoneMatch, String storageClass, Boolean force, File content, final ApiCallback _callback) throws ApiException {
String basePath = null;
// Operation Servers
diff --git a/clients/java/src/main/java/io/lakefs/clients/sdk/model/UpdateObjectUserMetadata.java b/clients/java/src/main/java/io/lakefs/clients/sdk/model/UpdateObjectUserMetadata.java
new file mode 100644
index 00000000000..55adc0c22df
--- /dev/null
+++ b/clients/java/src/main/java/io/lakefs/clients/sdk/model/UpdateObjectUserMetadata.java
@@ -0,0 +1,300 @@
+/*
+ * lakeFS API
+ * lakeFS HTTP API
+ *
+ * The version of the OpenAPI document: 1.0.0
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+
+package io.lakefs.clients.sdk.model;
+
+import java.util.Objects;
+import com.google.gson.TypeAdapter;
+import com.google.gson.annotations.JsonAdapter;
+import com.google.gson.annotations.SerializedName;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonDeserializationContext;
+import com.google.gson.JsonDeserializer;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParseException;
+import com.google.gson.TypeAdapterFactory;
+import com.google.gson.reflect.TypeToken;
+import com.google.gson.TypeAdapter;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+import java.io.IOException;
+
+import java.lang.reflect.Type;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import io.lakefs.clients.sdk.JSON;
+
+/**
+ * UpdateObjectUserMetadata
+ */
+@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen")
+public class UpdateObjectUserMetadata {
+ public static final String SERIALIZED_NAME_SET = "set";
+ @SerializedName(SERIALIZED_NAME_SET)
+ private Map set = new HashMap<>();
+
+ public UpdateObjectUserMetadata() {
+ }
+
+ public UpdateObjectUserMetadata set(Map set) {
+
+ this.set = set;
+ return this;
+ }
+
+ public UpdateObjectUserMetadata putSetItem(String key, String setItem) {
+ if (this.set == null) {
+ this.set = new HashMap<>();
+ }
+ this.set.put(key, setItem);
+ return this;
+ }
+
+ /**
+ * Get set
+ * @return set
+ **/
+ @javax.annotation.Nonnull
+ public Map getSet() {
+ return set;
+ }
+
+
+ public void setSet(Map set) {
+ this.set = set;
+ }
+
+ /**
+ * A container for additional, undeclared properties.
+ * This is a holder for any undeclared properties as specified with
+ * the 'additionalProperties' keyword in the OAS document.
+ */
+ private Map additionalProperties;
+
+ /**
+ * Set the additional (undeclared) property with the specified name and value.
+ * If the property does not already exist, create it otherwise replace it.
+ *
+ * @param key name of the property
+ * @param value value of the property
+ * @return the UpdateObjectUserMetadata instance itself
+ */
+ public UpdateObjectUserMetadata putAdditionalProperty(String key, Object value) {
+ if (this.additionalProperties == null) {
+ this.additionalProperties = new HashMap();
+ }
+ this.additionalProperties.put(key, value);
+ return this;
+ }
+
+ /**
+ * Return the additional (undeclared) property.
+ *
+ * @return a map of objects
+ */
+ public Map getAdditionalProperties() {
+ return additionalProperties;
+ }
+
+ /**
+ * Return the additional (undeclared) property with the specified name.
+ *
+ * @param key name of the property
+ * @return an object
+ */
+ public Object getAdditionalProperty(String key) {
+ if (this.additionalProperties == null) {
+ return null;
+ }
+ return this.additionalProperties.get(key);
+ }
+
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ UpdateObjectUserMetadata updateObjectUserMetadata = (UpdateObjectUserMetadata) o;
+ return Objects.equals(this.set, updateObjectUserMetadata.set)&&
+ Objects.equals(this.additionalProperties, updateObjectUserMetadata.additionalProperties);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(set, additionalProperties);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("class UpdateObjectUserMetadata {\n");
+ sb.append(" set: ").append(toIndentedString(set)).append("\n");
+ sb.append(" additionalProperties: ").append(toIndentedString(additionalProperties)).append("\n");
+ sb.append("}");
+ return sb.toString();
+ }
+
+ /**
+ * Convert the given object to string with each line indented by 4 spaces
+ * (except the first line).
+ */
+ private String toIndentedString(Object o) {
+ if (o == null) {
+ return "null";
+ }
+ return o.toString().replace("\n", "\n ");
+ }
+
+
+ public static HashSet openapiFields;
+ public static HashSet openapiRequiredFields;
+
+ static {
+ // a set of all properties/fields (JSON key names)
+ openapiFields = new HashSet();
+ openapiFields.add("set");
+
+ // a set of required properties/fields (JSON key names)
+ openapiRequiredFields = new HashSet();
+ openapiRequiredFields.add("set");
+ }
+
+ /**
+ * Validates the JSON Element and throws an exception if issues found
+ *
+ * @param jsonElement JSON Element
+ * @throws IOException if the JSON Element is invalid with respect to UpdateObjectUserMetadata
+ */
+ public static void validateJsonElement(JsonElement jsonElement) throws IOException {
+ if (jsonElement == null) {
+ if (!UpdateObjectUserMetadata.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null
+ throw new IllegalArgumentException(String.format("The required field(s) %s in UpdateObjectUserMetadata is not found in the empty JSON string", UpdateObjectUserMetadata.openapiRequiredFields.toString()));
+ }
+ }
+
+ // check to make sure all required properties/fields are present in the JSON string
+ for (String requiredField : UpdateObjectUserMetadata.openapiRequiredFields) {
+ if (jsonElement.getAsJsonObject().get(requiredField) == null) {
+ throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString()));
+ }
+ }
+ JsonObject jsonObj = jsonElement.getAsJsonObject();
+ }
+
+ public static class CustomTypeAdapterFactory implements TypeAdapterFactory {
+ @SuppressWarnings("unchecked")
+ @Override
+ public TypeAdapter create(Gson gson, TypeToken type) {
+ if (!UpdateObjectUserMetadata.class.isAssignableFrom(type.getRawType())) {
+ return null; // this class only serializes 'UpdateObjectUserMetadata' and its subtypes
+ }
+ final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class);
+ final TypeAdapter thisAdapter
+ = gson.getDelegateAdapter(this, TypeToken.get(UpdateObjectUserMetadata.class));
+
+ return (TypeAdapter) new TypeAdapter() {
+ @Override
+ public void write(JsonWriter out, UpdateObjectUserMetadata value) throws IOException {
+ JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject();
+ obj.remove("additionalProperties");
+ // serialize additional properties
+ if (value.getAdditionalProperties() != null) {
+ for (Map.Entry entry : value.getAdditionalProperties().entrySet()) {
+ if (entry.getValue() instanceof String)
+ obj.addProperty(entry.getKey(), (String) entry.getValue());
+ else if (entry.getValue() instanceof Number)
+ obj.addProperty(entry.getKey(), (Number) entry.getValue());
+ else if (entry.getValue() instanceof Boolean)
+ obj.addProperty(entry.getKey(), (Boolean) entry.getValue());
+ else if (entry.getValue() instanceof Character)
+ obj.addProperty(entry.getKey(), (Character) entry.getValue());
+ else {
+ obj.add(entry.getKey(), gson.toJsonTree(entry.getValue()).getAsJsonObject());
+ }
+ }
+ }
+ elementAdapter.write(out, obj);
+ }
+
+ @Override
+ public UpdateObjectUserMetadata read(JsonReader in) throws IOException {
+ JsonElement jsonElement = elementAdapter.read(in);
+ validateJsonElement(jsonElement);
+ JsonObject jsonObj = jsonElement.getAsJsonObject();
+ // store additional fields in the deserialized instance
+ UpdateObjectUserMetadata instance = thisAdapter.fromJsonTree(jsonObj);
+ for (Map.Entry entry : jsonObj.entrySet()) {
+ if (!openapiFields.contains(entry.getKey())) {
+ if (entry.getValue().isJsonPrimitive()) { // primitive type
+ if (entry.getValue().getAsJsonPrimitive().isString())
+ instance.putAdditionalProperty(entry.getKey(), entry.getValue().getAsString());
+ else if (entry.getValue().getAsJsonPrimitive().isNumber())
+ instance.putAdditionalProperty(entry.getKey(), entry.getValue().getAsNumber());
+ else if (entry.getValue().getAsJsonPrimitive().isBoolean())
+ instance.putAdditionalProperty(entry.getKey(), entry.getValue().getAsBoolean());
+ else
+ throw new IllegalArgumentException(String.format("The field `%s` has unknown primitive type. Value: %s", entry.getKey(), entry.getValue().toString()));
+ } else if (entry.getValue().isJsonArray()) {
+ instance.putAdditionalProperty(entry.getKey(), gson.fromJson(entry.getValue(), List.class));
+ } else { // JSON object
+ instance.putAdditionalProperty(entry.getKey(), gson.fromJson(entry.getValue(), HashMap.class));
+ }
+ }
+ }
+ return instance;
+ }
+
+ }.nullSafe();
+ }
+ }
+
+ /**
+ * Create an instance of UpdateObjectUserMetadata given an JSON string
+ *
+ * @param jsonString JSON string
+ * @return An instance of UpdateObjectUserMetadata
+ * @throws IOException if the JSON string is invalid with respect to UpdateObjectUserMetadata
+ */
+ public static UpdateObjectUserMetadata fromJson(String jsonString) throws IOException {
+ return JSON.getGson().fromJson(jsonString, UpdateObjectUserMetadata.class);
+ }
+
+ /**
+ * Convert an instance of UpdateObjectUserMetadata to an JSON string
+ *
+ * @return JSON string
+ */
+ public String toJson() {
+ return JSON.getGson().toJson(this);
+ }
+}
+
diff --git a/clients/java/src/test/java/io/lakefs/clients/sdk/ExperimentalApiTest.java b/clients/java/src/test/java/io/lakefs/clients/sdk/ExperimentalApiTest.java
index 694e5a28edd..ac3e1f54000 100644
--- a/clients/java/src/test/java/io/lakefs/clients/sdk/ExperimentalApiTest.java
+++ b/clients/java/src/test/java/io/lakefs/clients/sdk/ExperimentalApiTest.java
@@ -32,6 +32,7 @@
import io.lakefs.clients.sdk.model.PullRequestsList;
import io.lakefs.clients.sdk.model.StagingLocation;
import io.lakefs.clients.sdk.model.StsAuthRequest;
+import io.lakefs.clients.sdk.model.UpdateObjectUserMetadata;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
@@ -278,6 +279,22 @@ public void stsLoginTest() throws ApiException {
// TODO: test validations
}
+ /**
+ * rewrite (all) object metadata
+ *
+ * @throws ApiException if the Api call fails
+ */
+ @Test
+ public void updateObjectUserMetadataTest() throws ApiException {
+ String repository = null;
+ String branch = null;
+ String path = null;
+ UpdateObjectUserMetadata updateObjectUserMetadata = null;
+ api.updateObjectUserMetadata(repository, branch, path, updateObjectUserMetadata)
+ .execute();
+ // TODO: test validations
+ }
+
/**
* update pull request
*
diff --git a/clients/java/src/test/java/io/lakefs/clients/sdk/ObjectsApiTest.java b/clients/java/src/test/java/io/lakefs/clients/sdk/ObjectsApiTest.java
index 4580efc6547..4dfe4591a17 100644
--- a/clients/java/src/test/java/io/lakefs/clients/sdk/ObjectsApiTest.java
+++ b/clients/java/src/test/java/io/lakefs/clients/sdk/ObjectsApiTest.java
@@ -22,6 +22,7 @@
import io.lakefs.clients.sdk.model.ObjectStatsList;
import io.lakefs.clients.sdk.model.PathList;
import io.lakefs.clients.sdk.model.UnderlyingObjectProperties;
+import io.lakefs.clients.sdk.model.UpdateObjectUserMetadata;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
@@ -186,6 +187,22 @@ public void statObjectTest() throws ApiException {
// TODO: test validations
}
+ /**
+ * rewrite (all) object metadata
+ *
+ * @throws ApiException if the Api call fails
+ */
+ @Test
+ public void updateObjectUserMetadataTest() throws ApiException {
+ String repository = null;
+ String branch = null;
+ String path = null;
+ UpdateObjectUserMetadata updateObjectUserMetadata = null;
+ api.updateObjectUserMetadata(repository, branch, path, updateObjectUserMetadata)
+ .execute();
+ // TODO: test validations
+ }
+
/**
* @throws ApiException if the Api call fails
*/
diff --git a/clients/java/src/test/java/io/lakefs/clients/sdk/model/UpdateObjectUserMetadataTest.java b/clients/java/src/test/java/io/lakefs/clients/sdk/model/UpdateObjectUserMetadataTest.java
new file mode 100644
index 00000000000..c31e86167da
--- /dev/null
+++ b/clients/java/src/test/java/io/lakefs/clients/sdk/model/UpdateObjectUserMetadataTest.java
@@ -0,0 +1,50 @@
+/*
+ * lakeFS API
+ * lakeFS HTTP API
+ *
+ * The version of the OpenAPI document: 1.0.0
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+
+package io.lakefs.clients.sdk.model;
+
+import com.google.gson.TypeAdapter;
+import com.google.gson.annotations.JsonAdapter;
+import com.google.gson.annotations.SerializedName;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Model tests for UpdateObjectUserMetadata
+ */
+public class UpdateObjectUserMetadataTest {
+ private final UpdateObjectUserMetadata model = new UpdateObjectUserMetadata();
+
+ /**
+ * Model tests for UpdateObjectUserMetadata
+ */
+ @Test
+ public void testUpdateObjectUserMetadata() {
+ // TODO: test UpdateObjectUserMetadata
+ }
+
+ /**
+ * Test the property 'set'
+ */
+ @Test
+ public void setTest() {
+ // TODO: test set
+ }
+
+}
diff --git a/clients/python-legacy/.openapi-generator/FILES b/clients/python-legacy/.openapi-generator/FILES
index c79003efcf6..f2ac2ec3636 100644
--- a/clients/python-legacy/.openapi-generator/FILES
+++ b/clients/python-legacy/.openapi-generator/FILES
@@ -121,6 +121,7 @@ docs/TagCreation.md
docs/TagsApi.md
docs/TaskInfo.md
docs/UnderlyingObjectProperties.md
+docs/UpdateObjectUserMetadata.md
docs/UpdateToken.md
docs/UploadPart.md
docs/UsageReport.md
@@ -256,6 +257,7 @@ lakefs_client/model/sts_auth_request.py
lakefs_client/model/tag_creation.py
lakefs_client/model/task_info.py
lakefs_client/model/underlying_object_properties.py
+lakefs_client/model/update_object_user_metadata.py
lakefs_client/model/update_token.py
lakefs_client/model/upload_part.py
lakefs_client/model/usage_report.py
@@ -390,6 +392,7 @@ test/test_tag_creation.py
test/test_tags_api.py
test/test_task_info.py
test/test_underlying_object_properties.py
+test/test_update_object_user_metadata.py
test/test_update_token.py
test/test_upload_part.py
test/test_usage_report.py
diff --git a/clients/python-legacy/README.md b/clients/python-legacy/README.md
index 344b0e4eaa1..7d3c4d19611 100644
--- a/clients/python-legacy/README.md
+++ b/clients/python-legacy/README.md
@@ -181,6 +181,7 @@ Class | Method | HTTP request | Description
*ExperimentalApi* | [**list_user_external_principals**](docs/ExperimentalApi.md#list_user_external_principals) | **GET** /auth/users/{userId}/external/principals/ls | list user external policies attached to a user
*ExperimentalApi* | [**merge_pull_request**](docs/ExperimentalApi.md#merge_pull_request) | **PUT** /repositories/{repository}/pulls/{pull_request}/merge | merge pull request
*ExperimentalApi* | [**sts_login**](docs/ExperimentalApi.md#sts_login) | **POST** /sts/login | perform a login with STS
+*ExperimentalApi* | [**update_object_user_metadata**](docs/ExperimentalApi.md#update_object_user_metadata) | **PUT** /repositories/{repository}/branches/{branch}/objects/stat/user_metadata | rewrite (all) object metadata
*ExperimentalApi* | [**update_pull_request**](docs/ExperimentalApi.md#update_pull_request) | **PATCH** /repositories/{repository}/pulls/{pull_request} | update pull request
*ExternalApi* | [**create_user_external_principal**](docs/ExternalApi.md#create_user_external_principal) | **POST** /auth/users/{userId}/external/principals | attach external principal to user
*ExternalApi* | [**delete_user_external_principal**](docs/ExternalApi.md#delete_user_external_principal) | **DELETE** /auth/users/{userId}/external/principals | delete external principal from user
@@ -229,6 +230,7 @@ Class | Method | HTTP request | Description
*ObjectsApi* | [**head_object**](docs/ObjectsApi.md#head_object) | **HEAD** /repositories/{repository}/refs/{ref}/objects | check if object exists
*ObjectsApi* | [**list_objects**](docs/ObjectsApi.md#list_objects) | **GET** /repositories/{repository}/refs/{ref}/objects/ls | list objects under a given prefix
*ObjectsApi* | [**stat_object**](docs/ObjectsApi.md#stat_object) | **GET** /repositories/{repository}/refs/{ref}/objects/stat | get object metadata
+*ObjectsApi* | [**update_object_user_metadata**](docs/ObjectsApi.md#update_object_user_metadata) | **PUT** /repositories/{repository}/branches/{branch}/objects/stat/user_metadata | rewrite (all) object metadata
*ObjectsApi* | [**upload_object**](docs/ObjectsApi.md#upload_object) | **POST** /repositories/{repository}/branches/{branch}/objects |
*PullsApi* | [**create_pull_request**](docs/PullsApi.md#create_pull_request) | **POST** /repositories/{repository}/pulls | create pull request
*PullsApi* | [**get_pull_request**](docs/PullsApi.md#get_pull_request) | **GET** /repositories/{repository}/pulls/{pull_request} | get pull request
@@ -365,6 +367,7 @@ Class | Method | HTTP request | Description
- [TagCreation](docs/TagCreation.md)
- [TaskInfo](docs/TaskInfo.md)
- [UnderlyingObjectProperties](docs/UnderlyingObjectProperties.md)
+ - [UpdateObjectUserMetadata](docs/UpdateObjectUserMetadata.md)
- [UpdateToken](docs/UpdateToken.md)
- [UploadPart](docs/UploadPart.md)
- [UsageReport](docs/UsageReport.md)
diff --git a/clients/python-legacy/docs/ExperimentalApi.md b/clients/python-legacy/docs/ExperimentalApi.md
index 2b93c41b9d3..1745f3bd9b2 100644
--- a/clients/python-legacy/docs/ExperimentalApi.md
+++ b/clients/python-legacy/docs/ExperimentalApi.md
@@ -18,6 +18,7 @@ Method | HTTP request | Description
[**list_user_external_principals**](ExperimentalApi.md#list_user_external_principals) | **GET** /auth/users/{userId}/external/principals/ls | list user external policies attached to a user
[**merge_pull_request**](ExperimentalApi.md#merge_pull_request) | **PUT** /repositories/{repository}/pulls/{pull_request}/merge | merge pull request
[**sts_login**](ExperimentalApi.md#sts_login) | **POST** /sts/login | perform a login with STS
+[**update_object_user_metadata**](ExperimentalApi.md#update_object_user_metadata) | **PUT** /repositories/{repository}/branches/{branch}/objects/stat/user_metadata | rewrite (all) object metadata
[**update_pull_request**](ExperimentalApi.md#update_pull_request) | **PATCH** /repositories/{repository}/pulls/{pull_request} | update pull request
@@ -1628,6 +1629,124 @@ No authorization required
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+# **update_object_user_metadata**
+> update_object_user_metadata(repository, branch, path, update_object_user_metadata)
+
+rewrite (all) object metadata
+
+### Example
+
+* Basic Authentication (basic_auth):
+* Api Key Authentication (cookie_auth):
+* Bearer (JWT) Authentication (jwt_token):
+* Api Key Authentication (oidc_auth):
+* Api Key Authentication (saml_auth):
+
+```python
+import time
+import lakefs_client
+from lakefs_client.api import experimental_api
+from lakefs_client.model.error import Error
+from lakefs_client.model.update_object_user_metadata import UpdateObjectUserMetadata
+from pprint import pprint
+# Defining the host is optional and defaults to http://localhost/api/v1
+# See configuration.py for a list of all supported configuration parameters.
+configuration = lakefs_client.Configuration(
+ host = "http://localhost/api/v1"
+)
+
+# The client must configure the authentication and authorization parameters
+# in accordance with the API server security policy.
+# Examples for each auth method are provided below, use the example that
+# satisfies your auth use case.
+
+# Configure HTTP basic authorization: basic_auth
+configuration = lakefs_client.Configuration(
+ username = 'YOUR_USERNAME',
+ password = 'YOUR_PASSWORD'
+)
+
+# Configure API key authorization: cookie_auth
+configuration.api_key['cookie_auth'] = 'YOUR_API_KEY'
+
+# Uncomment below to setup prefix (e.g. Bearer) for API key, if needed
+# configuration.api_key_prefix['cookie_auth'] = 'Bearer'
+
+# Configure Bearer authorization (JWT): jwt_token
+configuration = lakefs_client.Configuration(
+ access_token = 'YOUR_BEARER_TOKEN'
+)
+
+# Configure API key authorization: oidc_auth
+configuration.api_key['oidc_auth'] = 'YOUR_API_KEY'
+
+# Uncomment below to setup prefix (e.g. Bearer) for API key, if needed
+# configuration.api_key_prefix['oidc_auth'] = 'Bearer'
+
+# Configure API key authorization: saml_auth
+configuration.api_key['saml_auth'] = 'YOUR_API_KEY'
+
+# Uncomment below to setup prefix (e.g. Bearer) for API key, if needed
+# configuration.api_key_prefix['saml_auth'] = 'Bearer'
+
+# Enter a context with an instance of the API client
+with lakefs_client.ApiClient(configuration) as api_client:
+ # Create an instance of the API class
+ api_instance = experimental_api.ExperimentalApi(api_client)
+ repository = "repository_example" # str |
+ branch = "branch_example" # str | branch to update
+ path = "path_example" # str | path to object relative to the branch
+ update_object_user_metadata = UpdateObjectUserMetadata(
+ set=ObjectUserMetadata(
+ key="key_example",
+ ),
+ ) # UpdateObjectUserMetadata |
+
+ # example passing only required values which don't have defaults set
+ try:
+ # rewrite (all) object metadata
+ api_instance.update_object_user_metadata(repository, branch, path, update_object_user_metadata)
+ except lakefs_client.ApiException as e:
+ print("Exception when calling ExperimentalApi->update_object_user_metadata: %s\n" % e)
+```
+
+
+### Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **repository** | **str**| |
+ **branch** | **str**| branch to update |
+ **path** | **str**| path to object relative to the branch |
+ **update_object_user_metadata** | [**UpdateObjectUserMetadata**](UpdateObjectUserMetadata.md)| |
+
+### Return type
+
+void (empty response body)
+
+### Authorization
+
+[basic_auth](../README.md#basic_auth), [cookie_auth](../README.md#cookie_auth), [jwt_token](../README.md#jwt_token), [oidc_auth](../README.md#oidc_auth), [saml_auth](../README.md#saml_auth)
+
+### HTTP request headers
+
+ - **Content-Type**: application/json
+ - **Accept**: application/json
+
+
+### HTTP response details
+
+| Status code | Description | Response headers |
+|-------------|-------------|------------------|
+**201** | User metadata updated | - |
+**401** | Unauthorized | - |
+**404** | Resource Not Found | - |
+**400** | Bad Request | - |
+**420** | too many requests | - |
+**0** | Internal Server Error | - |
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
# **update_pull_request**
> update_pull_request(repository, pull_request, pull_request_basic)
diff --git a/clients/python-legacy/docs/ObjectsApi.md b/clients/python-legacy/docs/ObjectsApi.md
index e84269d94c9..359fc089674 100644
--- a/clients/python-legacy/docs/ObjectsApi.md
+++ b/clients/python-legacy/docs/ObjectsApi.md
@@ -12,6 +12,7 @@ Method | HTTP request | Description
[**head_object**](ObjectsApi.md#head_object) | **HEAD** /repositories/{repository}/refs/{ref}/objects | check if object exists
[**list_objects**](ObjectsApi.md#list_objects) | **GET** /repositories/{repository}/refs/{ref}/objects/ls | list objects under a given prefix
[**stat_object**](ObjectsApi.md#stat_object) | **GET** /repositories/{repository}/refs/{ref}/objects/stat | get object metadata
+[**update_object_user_metadata**](ObjectsApi.md#update_object_user_metadata) | **PUT** /repositories/{repository}/branches/{branch}/objects/stat/user_metadata | rewrite (all) object metadata
[**upload_object**](ObjectsApi.md#upload_object) | **POST** /repositories/{repository}/branches/{branch}/objects |
@@ -1009,6 +1010,124 @@ Name | Type | Description | Notes
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+# **update_object_user_metadata**
+> update_object_user_metadata(repository, branch, path, update_object_user_metadata)
+
+rewrite (all) object metadata
+
+### Example
+
+* Basic Authentication (basic_auth):
+* Api Key Authentication (cookie_auth):
+* Bearer (JWT) Authentication (jwt_token):
+* Api Key Authentication (oidc_auth):
+* Api Key Authentication (saml_auth):
+
+```python
+import time
+import lakefs_client
+from lakefs_client.api import objects_api
+from lakefs_client.model.error import Error
+from lakefs_client.model.update_object_user_metadata import UpdateObjectUserMetadata
+from pprint import pprint
+# Defining the host is optional and defaults to http://localhost/api/v1
+# See configuration.py for a list of all supported configuration parameters.
+configuration = lakefs_client.Configuration(
+ host = "http://localhost/api/v1"
+)
+
+# The client must configure the authentication and authorization parameters
+# in accordance with the API server security policy.
+# Examples for each auth method are provided below, use the example that
+# satisfies your auth use case.
+
+# Configure HTTP basic authorization: basic_auth
+configuration = lakefs_client.Configuration(
+ username = 'YOUR_USERNAME',
+ password = 'YOUR_PASSWORD'
+)
+
+# Configure API key authorization: cookie_auth
+configuration.api_key['cookie_auth'] = 'YOUR_API_KEY'
+
+# Uncomment below to setup prefix (e.g. Bearer) for API key, if needed
+# configuration.api_key_prefix['cookie_auth'] = 'Bearer'
+
+# Configure Bearer authorization (JWT): jwt_token
+configuration = lakefs_client.Configuration(
+ access_token = 'YOUR_BEARER_TOKEN'
+)
+
+# Configure API key authorization: oidc_auth
+configuration.api_key['oidc_auth'] = 'YOUR_API_KEY'
+
+# Uncomment below to setup prefix (e.g. Bearer) for API key, if needed
+# configuration.api_key_prefix['oidc_auth'] = 'Bearer'
+
+# Configure API key authorization: saml_auth
+configuration.api_key['saml_auth'] = 'YOUR_API_KEY'
+
+# Uncomment below to setup prefix (e.g. Bearer) for API key, if needed
+# configuration.api_key_prefix['saml_auth'] = 'Bearer'
+
+# Enter a context with an instance of the API client
+with lakefs_client.ApiClient(configuration) as api_client:
+ # Create an instance of the API class
+ api_instance = objects_api.ObjectsApi(api_client)
+ repository = "repository_example" # str |
+ branch = "branch_example" # str | branch to update
+ path = "path_example" # str | path to object relative to the branch
+ update_object_user_metadata = UpdateObjectUserMetadata(
+ set=ObjectUserMetadata(
+ key="key_example",
+ ),
+ ) # UpdateObjectUserMetadata |
+
+ # example passing only required values which don't have defaults set
+ try:
+ # rewrite (all) object metadata
+ api_instance.update_object_user_metadata(repository, branch, path, update_object_user_metadata)
+ except lakefs_client.ApiException as e:
+ print("Exception when calling ObjectsApi->update_object_user_metadata: %s\n" % e)
+```
+
+
+### Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **repository** | **str**| |
+ **branch** | **str**| branch to update |
+ **path** | **str**| path to object relative to the branch |
+ **update_object_user_metadata** | [**UpdateObjectUserMetadata**](UpdateObjectUserMetadata.md)| |
+
+### Return type
+
+void (empty response body)
+
+### Authorization
+
+[basic_auth](../README.md#basic_auth), [cookie_auth](../README.md#cookie_auth), [jwt_token](../README.md#jwt_token), [oidc_auth](../README.md#oidc_auth), [saml_auth](../README.md#saml_auth)
+
+### HTTP request headers
+
+ - **Content-Type**: application/json
+ - **Accept**: application/json
+
+
+### HTTP response details
+
+| Status code | Description | Response headers |
+|-------------|-------------|------------------|
+**201** | User metadata updated | - |
+**401** | Unauthorized | - |
+**404** | Resource Not Found | - |
+**400** | Bad Request | - |
+**420** | too many requests | - |
+**0** | Internal Server Error | - |
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
# **upload_object**
> ObjectStats upload_object(repository, branch, path)
diff --git a/clients/python-legacy/docs/UpdateObjectUserMetadata.md b/clients/python-legacy/docs/UpdateObjectUserMetadata.md
new file mode 100644
index 00000000000..9c8964f7541
--- /dev/null
+++ b/clients/python-legacy/docs/UpdateObjectUserMetadata.md
@@ -0,0 +1,12 @@
+# UpdateObjectUserMetadata
+
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**set** | [**ObjectUserMetadata**](ObjectUserMetadata.md) | |
+**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/clients/python-legacy/lakefs_client/api/experimental_api.py b/clients/python-legacy/lakefs_client/api/experimental_api.py
index e410de0ea55..30d3d94f30c 100644
--- a/clients/python-legacy/lakefs_client/api/experimental_api.py
+++ b/clients/python-legacy/lakefs_client/api/experimental_api.py
@@ -40,6 +40,7 @@
from lakefs_client.model.pull_requests_list import PullRequestsList
from lakefs_client.model.staging_location import StagingLocation
from lakefs_client.model.sts_auth_request import StsAuthRequest
+from lakefs_client.model.update_object_user_metadata import UpdateObjectUserMetadata
class ExperimentalApi(object):
@@ -984,6 +985,80 @@ def __init__(self, api_client=None):
},
api_client=api_client
)
+ self.update_object_user_metadata_endpoint = _Endpoint(
+ settings={
+ 'response_type': None,
+ 'auth': [
+ 'basic_auth',
+ 'cookie_auth',
+ 'jwt_token',
+ 'oidc_auth',
+ 'saml_auth'
+ ],
+ 'endpoint_path': '/repositories/{repository}/branches/{branch}/objects/stat/user_metadata',
+ 'operation_id': 'update_object_user_metadata',
+ 'http_method': 'PUT',
+ 'servers': None,
+ },
+ params_map={
+ 'all': [
+ 'repository',
+ 'branch',
+ 'path',
+ 'update_object_user_metadata',
+ ],
+ 'required': [
+ 'repository',
+ 'branch',
+ 'path',
+ 'update_object_user_metadata',
+ ],
+ 'nullable': [
+ ],
+ 'enum': [
+ ],
+ 'validation': [
+ ]
+ },
+ root_map={
+ 'validations': {
+ },
+ 'allowed_values': {
+ },
+ 'openapi_types': {
+ 'repository':
+ (str,),
+ 'branch':
+ (str,),
+ 'path':
+ (str,),
+ 'update_object_user_metadata':
+ (UpdateObjectUserMetadata,),
+ },
+ 'attribute_map': {
+ 'repository': 'repository',
+ 'branch': 'branch',
+ 'path': 'path',
+ },
+ 'location_map': {
+ 'repository': 'path',
+ 'branch': 'path',
+ 'path': 'query',
+ 'update_object_user_metadata': 'body',
+ },
+ 'collection_format_map': {
+ }
+ },
+ headers_map={
+ 'accept': [
+ 'application/json'
+ ],
+ 'content_type': [
+ 'application/json'
+ ]
+ },
+ api_client=api_client
+ )
self.update_pull_request_endpoint = _Endpoint(
settings={
'response_type': None,
@@ -2035,6 +2110,83 @@ def sts_login(
sts_auth_request
return self.sts_login_endpoint.call_with_http_info(**kwargs)
+ def update_object_user_metadata(
+ self,
+ repository,
+ branch,
+ path,
+ update_object_user_metadata,
+ **kwargs
+ ):
+ """rewrite (all) object metadata # noqa: E501
+
+ This method makes a synchronous HTTP request by default. To make an
+ asynchronous HTTP request, please pass async_req=True
+
+ >>> thread = api.update_object_user_metadata(repository, branch, path, update_object_user_metadata, async_req=True)
+ >>> result = thread.get()
+
+ Args:
+ repository (str):
+ branch (str): branch to update
+ path (str): path to object relative to the branch
+ update_object_user_metadata (UpdateObjectUserMetadata):
+
+ Keyword Args:
+ _return_http_data_only (bool): response data without head status
+ code and headers. Default is True.
+ _preload_content (bool): if False, the urllib3.HTTPResponse object
+ will be returned without reading/decoding response data.
+ Default is True.
+ _request_timeout (int/float/tuple): timeout setting for this request. If
+ one number provided, it will be total request timeout. It can also
+ be a pair (tuple) of (connection, read) timeouts.
+ Default is None.
+ _check_input_type (bool): specifies if type checking
+ should be done one the data sent to the server.
+ Default is True.
+ _check_return_type (bool): specifies if type checking
+ should be done one the data received from the server.
+ Default is True.
+ _host_index (int/None): specifies the index of the server
+ that we want to use.
+ Default is read from the configuration.
+ async_req (bool): execute request asynchronously
+
+ Returns:
+ None
+ If the method is called asynchronously, returns the request
+ thread.
+ """
+ kwargs['async_req'] = kwargs.get(
+ 'async_req', False
+ )
+ kwargs['_return_http_data_only'] = kwargs.get(
+ '_return_http_data_only', True
+ )
+ kwargs['_preload_content'] = kwargs.get(
+ '_preload_content', True
+ )
+ kwargs['_request_timeout'] = kwargs.get(
+ '_request_timeout', None
+ )
+ kwargs['_check_input_type'] = kwargs.get(
+ '_check_input_type', True
+ )
+ kwargs['_check_return_type'] = kwargs.get(
+ '_check_return_type', True
+ )
+ kwargs['_host_index'] = kwargs.get('_host_index')
+ kwargs['repository'] = \
+ repository
+ kwargs['branch'] = \
+ branch
+ kwargs['path'] = \
+ path
+ kwargs['update_object_user_metadata'] = \
+ update_object_user_metadata
+ return self.update_object_user_metadata_endpoint.call_with_http_info(**kwargs)
+
def update_pull_request(
self,
repository,
diff --git a/clients/python-legacy/lakefs_client/api/objects_api.py b/clients/python-legacy/lakefs_client/api/objects_api.py
index 5941b74039c..18b36f6f287 100644
--- a/clients/python-legacy/lakefs_client/api/objects_api.py
+++ b/clients/python-legacy/lakefs_client/api/objects_api.py
@@ -29,6 +29,7 @@
from lakefs_client.model.object_stats_list import ObjectStatsList
from lakefs_client.model.path_list import PathList
from lakefs_client.model.underlying_object_properties import UnderlyingObjectProperties
+from lakefs_client.model.update_object_user_metadata import UpdateObjectUserMetadata
class ObjectsApi(object):
@@ -669,6 +670,80 @@ def __init__(self, api_client=None):
},
api_client=api_client
)
+ self.update_object_user_metadata_endpoint = _Endpoint(
+ settings={
+ 'response_type': None,
+ 'auth': [
+ 'basic_auth',
+ 'cookie_auth',
+ 'jwt_token',
+ 'oidc_auth',
+ 'saml_auth'
+ ],
+ 'endpoint_path': '/repositories/{repository}/branches/{branch}/objects/stat/user_metadata',
+ 'operation_id': 'update_object_user_metadata',
+ 'http_method': 'PUT',
+ 'servers': None,
+ },
+ params_map={
+ 'all': [
+ 'repository',
+ 'branch',
+ 'path',
+ 'update_object_user_metadata',
+ ],
+ 'required': [
+ 'repository',
+ 'branch',
+ 'path',
+ 'update_object_user_metadata',
+ ],
+ 'nullable': [
+ ],
+ 'enum': [
+ ],
+ 'validation': [
+ ]
+ },
+ root_map={
+ 'validations': {
+ },
+ 'allowed_values': {
+ },
+ 'openapi_types': {
+ 'repository':
+ (str,),
+ 'branch':
+ (str,),
+ 'path':
+ (str,),
+ 'update_object_user_metadata':
+ (UpdateObjectUserMetadata,),
+ },
+ 'attribute_map': {
+ 'repository': 'repository',
+ 'branch': 'branch',
+ 'path': 'path',
+ },
+ 'location_map': {
+ 'repository': 'path',
+ 'branch': 'path',
+ 'path': 'query',
+ 'update_object_user_metadata': 'body',
+ },
+ 'collection_format_map': {
+ }
+ },
+ headers_map={
+ 'accept': [
+ 'application/json'
+ ],
+ 'content_type': [
+ 'application/json'
+ ]
+ },
+ api_client=api_client
+ )
self.upload_object_endpoint = _Endpoint(
settings={
'response_type': (ObjectStats,),
@@ -1358,6 +1433,83 @@ def stat_object(
path
return self.stat_object_endpoint.call_with_http_info(**kwargs)
+ def update_object_user_metadata(
+ self,
+ repository,
+ branch,
+ path,
+ update_object_user_metadata,
+ **kwargs
+ ):
+ """rewrite (all) object metadata # noqa: E501
+
+ This method makes a synchronous HTTP request by default. To make an
+ asynchronous HTTP request, please pass async_req=True
+
+ >>> thread = api.update_object_user_metadata(repository, branch, path, update_object_user_metadata, async_req=True)
+ >>> result = thread.get()
+
+ Args:
+ repository (str):
+ branch (str): branch to update
+ path (str): path to object relative to the branch
+ update_object_user_metadata (UpdateObjectUserMetadata):
+
+ Keyword Args:
+ _return_http_data_only (bool): response data without head status
+ code and headers. Default is True.
+ _preload_content (bool): if False, the urllib3.HTTPResponse object
+ will be returned without reading/decoding response data.
+ Default is True.
+ _request_timeout (int/float/tuple): timeout setting for this request. If
+ one number provided, it will be total request timeout. It can also
+ be a pair (tuple) of (connection, read) timeouts.
+ Default is None.
+ _check_input_type (bool): specifies if type checking
+ should be done one the data sent to the server.
+ Default is True.
+ _check_return_type (bool): specifies if type checking
+ should be done one the data received from the server.
+ Default is True.
+ _host_index (int/None): specifies the index of the server
+ that we want to use.
+ Default is read from the configuration.
+ async_req (bool): execute request asynchronously
+
+ Returns:
+ None
+ If the method is called asynchronously, returns the request
+ thread.
+ """
+ kwargs['async_req'] = kwargs.get(
+ 'async_req', False
+ )
+ kwargs['_return_http_data_only'] = kwargs.get(
+ '_return_http_data_only', True
+ )
+ kwargs['_preload_content'] = kwargs.get(
+ '_preload_content', True
+ )
+ kwargs['_request_timeout'] = kwargs.get(
+ '_request_timeout', None
+ )
+ kwargs['_check_input_type'] = kwargs.get(
+ '_check_input_type', True
+ )
+ kwargs['_check_return_type'] = kwargs.get(
+ '_check_return_type', True
+ )
+ kwargs['_host_index'] = kwargs.get('_host_index')
+ kwargs['repository'] = \
+ repository
+ kwargs['branch'] = \
+ branch
+ kwargs['path'] = \
+ path
+ kwargs['update_object_user_metadata'] = \
+ update_object_user_metadata
+ return self.update_object_user_metadata_endpoint.call_with_http_info(**kwargs)
+
def upload_object(
self,
repository,
diff --git a/clients/python-legacy/lakefs_client/model/update_object_user_metadata.py b/clients/python-legacy/lakefs_client/model/update_object_user_metadata.py
new file mode 100644
index 00000000000..5232ee45c22
--- /dev/null
+++ b/clients/python-legacy/lakefs_client/model/update_object_user_metadata.py
@@ -0,0 +1,268 @@
+"""
+ lakeFS API
+
+ lakeFS HTTP API # noqa: E501
+
+ The version of the OpenAPI document: 1.0.0
+ Contact: services@treeverse.io
+ Generated by: https://openapi-generator.tech
+"""
+
+
+import re # noqa: F401
+import sys # noqa: F401
+
+from lakefs_client.model_utils import ( # noqa: F401
+ ApiTypeError,
+ ModelComposed,
+ ModelNormal,
+ ModelSimple,
+ cached_property,
+ change_keys_js_to_python,
+ convert_js_args_to_python_args,
+ date,
+ datetime,
+ file_type,
+ none_type,
+ validate_get_composed_info,
+)
+from ..model_utils import OpenApiModel
+from lakefs_client.exceptions import ApiAttributeError
+
+
+def lazy_import():
+ from lakefs_client.model.object_user_metadata import ObjectUserMetadata
+ globals()['ObjectUserMetadata'] = ObjectUserMetadata
+
+
+class UpdateObjectUserMetadata(ModelNormal):
+ """NOTE: This class is auto generated by OpenAPI Generator.
+ Ref: https://openapi-generator.tech
+
+ Do not edit the class manually.
+
+ Attributes:
+ allowed_values (dict): The key is the tuple path to the attribute
+ and the for var_name this is (var_name,). The value is a dict
+ with a capitalized key describing the allowed value and an allowed
+ value. These dicts store the allowed enum values.
+ attribute_map (dict): The key is attribute name
+ and the value is json key in definition.
+ discriminator_value_class_map (dict): A dict to go from the discriminator
+ variable value to the discriminator class name.
+ validations (dict): The key is the tuple path to the attribute
+ and the for var_name this is (var_name,). The value is a dict
+ that stores validations for max_length, min_length, max_items,
+ min_items, exclusive_maximum, inclusive_maximum, exclusive_minimum,
+ inclusive_minimum, and regex.
+ additional_properties_type (tuple): A tuple of classes accepted
+ as additional properties values.
+ """
+
+ allowed_values = {
+ }
+
+ validations = {
+ }
+
+ @cached_property
+ def additional_properties_type():
+ """
+ This must be a method because a model may have properties that are
+ of type self, this must run after the class is loaded
+ """
+ lazy_import()
+ return (bool, date, datetime, dict, float, int, list, str, none_type,) # noqa: E501
+
+ _nullable = False
+
+ @cached_property
+ def openapi_types():
+ """
+ This must be a method because a model may have properties that are
+ of type self, this must run after the class is loaded
+
+ Returns
+ openapi_types (dict): The key is attribute name
+ and the value is attribute type.
+ """
+ lazy_import()
+ return {
+ 'set': (ObjectUserMetadata,), # noqa: E501
+ }
+
+ @cached_property
+ def discriminator():
+ return None
+
+
+ attribute_map = {
+ 'set': 'set', # noqa: E501
+ }
+
+ read_only_vars = {
+ }
+
+ _composed_schemas = {}
+
+ @classmethod
+ @convert_js_args_to_python_args
+ def _from_openapi_data(cls, set, *args, **kwargs): # noqa: E501
+ """UpdateObjectUserMetadata - a model defined in OpenAPI
+
+ Args:
+ set (ObjectUserMetadata):
+
+ Keyword Args:
+ _check_type (bool): if True, values for parameters in openapi_types
+ will be type checked and a TypeError will be
+ raised if the wrong type is input.
+ Defaults to True
+ _path_to_item (tuple/list): This is a list of keys or values to
+ drill down to the model in received_data
+ when deserializing a response
+ _spec_property_naming (bool): True if the variable names in the input data
+ are serialized names, as specified in the OpenAPI document.
+ False if the variable names in the input data
+ are pythonic names, e.g. snake case (default)
+ _configuration (Configuration): the instance to use when
+ deserializing a file_type parameter.
+ If passed, type conversion is attempted
+ If omitted no type conversion is done.
+ _visited_composed_classes (tuple): This stores a tuple of
+ classes that we have traveled through so that
+ if we see that class again we will not use its
+ discriminator again.
+ When traveling through a discriminator, the
+ composed schema that is
+ is traveled through is added to this set.
+ For example if Animal has a discriminator
+ petType and we pass in "Dog", and the class Dog
+ allOf includes Animal, we move through Animal
+ once using the discriminator, and pick Dog.
+ Then in Dog, we will make an instance of the
+ Animal class but this time we won't travel
+ through its discriminator because we passed in
+ _visited_composed_classes = (Animal,)
+ """
+
+ _check_type = kwargs.pop('_check_type', True)
+ _spec_property_naming = kwargs.pop('_spec_property_naming', False)
+ _path_to_item = kwargs.pop('_path_to_item', ())
+ _configuration = kwargs.pop('_configuration', None)
+ _visited_composed_classes = kwargs.pop('_visited_composed_classes', ())
+
+ self = super(OpenApiModel, cls).__new__(cls)
+
+ if args:
+ raise ApiTypeError(
+ "Invalid positional arguments=%s passed to %s. Remove those invalid positional arguments." % (
+ args,
+ self.__class__.__name__,
+ ),
+ path_to_item=_path_to_item,
+ valid_classes=(self.__class__,),
+ )
+
+ self._data_store = {}
+ self._check_type = _check_type
+ self._spec_property_naming = _spec_property_naming
+ self._path_to_item = _path_to_item
+ self._configuration = _configuration
+ self._visited_composed_classes = _visited_composed_classes + (self.__class__,)
+
+ self.set = set
+ for var_name, var_value in kwargs.items():
+ if var_name not in self.attribute_map and \
+ self._configuration is not None and \
+ self._configuration.discard_unknown_keys and \
+ self.additional_properties_type is None:
+ # discard variable.
+ continue
+ setattr(self, var_name, var_value)
+ return self
+
+ required_properties = set([
+ '_data_store',
+ '_check_type',
+ '_spec_property_naming',
+ '_path_to_item',
+ '_configuration',
+ '_visited_composed_classes',
+ ])
+
+ @convert_js_args_to_python_args
+ def __init__(self, set, *args, **kwargs): # noqa: E501
+ """UpdateObjectUserMetadata - a model defined in OpenAPI
+
+ Args:
+ set (ObjectUserMetadata):
+
+ Keyword Args:
+ _check_type (bool): if True, values for parameters in openapi_types
+ will be type checked and a TypeError will be
+ raised if the wrong type is input.
+ Defaults to True
+ _path_to_item (tuple/list): This is a list of keys or values to
+ drill down to the model in received_data
+ when deserializing a response
+ _spec_property_naming (bool): True if the variable names in the input data
+ are serialized names, as specified in the OpenAPI document.
+ False if the variable names in the input data
+ are pythonic names, e.g. snake case (default)
+ _configuration (Configuration): the instance to use when
+ deserializing a file_type parameter.
+ If passed, type conversion is attempted
+ If omitted no type conversion is done.
+ _visited_composed_classes (tuple): This stores a tuple of
+ classes that we have traveled through so that
+ if we see that class again we will not use its
+ discriminator again.
+ When traveling through a discriminator, the
+ composed schema that is
+ is traveled through is added to this set.
+ For example if Animal has a discriminator
+ petType and we pass in "Dog", and the class Dog
+ allOf includes Animal, we move through Animal
+ once using the discriminator, and pick Dog.
+ Then in Dog, we will make an instance of the
+ Animal class but this time we won't travel
+ through its discriminator because we passed in
+ _visited_composed_classes = (Animal,)
+ """
+
+ _check_type = kwargs.pop('_check_type', True)
+ _spec_property_naming = kwargs.pop('_spec_property_naming', False)
+ _path_to_item = kwargs.pop('_path_to_item', ())
+ _configuration = kwargs.pop('_configuration', None)
+ _visited_composed_classes = kwargs.pop('_visited_composed_classes', ())
+
+ if args:
+ raise ApiTypeError(
+ "Invalid positional arguments=%s passed to %s. Remove those invalid positional arguments." % (
+ args,
+ self.__class__.__name__,
+ ),
+ path_to_item=_path_to_item,
+ valid_classes=(self.__class__,),
+ )
+
+ self._data_store = {}
+ self._check_type = _check_type
+ self._spec_property_naming = _spec_property_naming
+ self._path_to_item = _path_to_item
+ self._configuration = _configuration
+ self._visited_composed_classes = _visited_composed_classes + (self.__class__,)
+
+ self.set = set
+ for var_name, var_value in kwargs.items():
+ if var_name not in self.attribute_map and \
+ self._configuration is not None and \
+ self._configuration.discard_unknown_keys and \
+ self.additional_properties_type is None:
+ # discard variable.
+ continue
+ setattr(self, var_name, var_value)
+ if var_name in self.read_only_vars:
+ raise ApiAttributeError(f"`{var_name}` is a read-only attribute. Use `from_openapi_data` to instantiate "
+ f"class with read only attributes.")
diff --git a/clients/python-legacy/lakefs_client/models/__init__.py b/clients/python-legacy/lakefs_client/models/__init__.py
index 36869513ca3..56ef69f7b1b 100644
--- a/clients/python-legacy/lakefs_client/models/__init__.py
+++ b/clients/python-legacy/lakefs_client/models/__init__.py
@@ -111,6 +111,7 @@
from lakefs_client.model.tag_creation import TagCreation
from lakefs_client.model.task_info import TaskInfo
from lakefs_client.model.underlying_object_properties import UnderlyingObjectProperties
+from lakefs_client.model.update_object_user_metadata import UpdateObjectUserMetadata
from lakefs_client.model.update_token import UpdateToken
from lakefs_client.model.upload_part import UploadPart
from lakefs_client.model.usage_report import UsageReport
diff --git a/clients/python-legacy/test/test_experimental_api.py b/clients/python-legacy/test/test_experimental_api.py
index 9eb6f001e74..822d3fad4d0 100644
--- a/clients/python-legacy/test/test_experimental_api.py
+++ b/clients/python-legacy/test/test_experimental_api.py
@@ -122,6 +122,13 @@ def test_sts_login(self):
"""
pass
+ def test_update_object_user_metadata(self):
+ """Test case for update_object_user_metadata
+
+ rewrite (all) object metadata # noqa: E501
+ """
+ pass
+
def test_update_pull_request(self):
"""Test case for update_pull_request
diff --git a/clients/python-legacy/test/test_objects_api.py b/clients/python-legacy/test/test_objects_api.py
index 6f11f90d999..a1572dac1db 100644
--- a/clients/python-legacy/test/test_objects_api.py
+++ b/clients/python-legacy/test/test_objects_api.py
@@ -80,6 +80,13 @@ def test_stat_object(self):
"""
pass
+ def test_update_object_user_metadata(self):
+ """Test case for update_object_user_metadata
+
+ rewrite (all) object metadata # noqa: E501
+ """
+ pass
+
def test_upload_object(self):
"""Test case for upload_object
diff --git a/clients/python-legacy/test/test_update_object_user_metadata.py b/clients/python-legacy/test/test_update_object_user_metadata.py
new file mode 100644
index 00000000000..d35359e6ce6
--- /dev/null
+++ b/clients/python-legacy/test/test_update_object_user_metadata.py
@@ -0,0 +1,38 @@
+"""
+ lakeFS API
+
+ lakeFS HTTP API # noqa: E501
+
+ The version of the OpenAPI document: 1.0.0
+ Contact: services@treeverse.io
+ Generated by: https://openapi-generator.tech
+"""
+
+
+import sys
+import unittest
+
+import lakefs_client
+from lakefs_client.model.object_user_metadata import ObjectUserMetadata
+globals()['ObjectUserMetadata'] = ObjectUserMetadata
+from lakefs_client.model.update_object_user_metadata import UpdateObjectUserMetadata
+
+
+class TestUpdateObjectUserMetadata(unittest.TestCase):
+ """UpdateObjectUserMetadata unit test stubs"""
+
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ def testUpdateObjectUserMetadata(self):
+ """Test UpdateObjectUserMetadata"""
+ # FIXME: construct object with mandatory attributes with example values
+ # model = UpdateObjectUserMetadata() # noqa: E501
+ pass
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/clients/python/.openapi-generator/FILES b/clients/python/.openapi-generator/FILES
index 23a8aefb953..b35b2eb7fd6 100644
--- a/clients/python/.openapi-generator/FILES
+++ b/clients/python/.openapi-generator/FILES
@@ -114,6 +114,7 @@ docs/TagCreation.md
docs/TagsApi.md
docs/TaskInfo.md
docs/UnderlyingObjectProperties.md
+docs/UpdateObjectUserMetadata.md
docs/UpdateToken.md
docs/UploadPart.md
docs/UsageReport.md
@@ -243,6 +244,7 @@ lakefs_sdk/models/sts_auth_request.py
lakefs_sdk/models/tag_creation.py
lakefs_sdk/models/task_info.py
lakefs_sdk/models/underlying_object_properties.py
+lakefs_sdk/models/update_object_user_metadata.py
lakefs_sdk/models/update_token.py
lakefs_sdk/models/upload_part.py
lakefs_sdk/models/usage_report.py
@@ -372,6 +374,7 @@ test/test_tag_creation.py
test/test_tags_api.py
test/test_task_info.py
test/test_underlying_object_properties.py
+test/test_update_object_user_metadata.py
test/test_update_token.py
test/test_upload_part.py
test/test_usage_report.py
diff --git a/clients/python/README.md b/clients/python/README.md
index c1171e034bc..78eec3fe76c 100644
--- a/clients/python/README.md
+++ b/clients/python/README.md
@@ -184,6 +184,7 @@ Class | Method | HTTP request | Description
*ExperimentalApi* | [**list_user_external_principals**](docs/ExperimentalApi.md#list_user_external_principals) | **GET** /auth/users/{userId}/external/principals/ls | list user external policies attached to a user
*ExperimentalApi* | [**merge_pull_request**](docs/ExperimentalApi.md#merge_pull_request) | **PUT** /repositories/{repository}/pulls/{pull_request}/merge | merge pull request
*ExperimentalApi* | [**sts_login**](docs/ExperimentalApi.md#sts_login) | **POST** /sts/login | perform a login with STS
+*ExperimentalApi* | [**update_object_user_metadata**](docs/ExperimentalApi.md#update_object_user_metadata) | **PUT** /repositories/{repository}/branches/{branch}/objects/stat/user_metadata | rewrite (all) object metadata
*ExperimentalApi* | [**update_pull_request**](docs/ExperimentalApi.md#update_pull_request) | **PATCH** /repositories/{repository}/pulls/{pull_request} | update pull request
*ExternalApi* | [**create_user_external_principal**](docs/ExternalApi.md#create_user_external_principal) | **POST** /auth/users/{userId}/external/principals | attach external principal to user
*ExternalApi* | [**delete_user_external_principal**](docs/ExternalApi.md#delete_user_external_principal) | **DELETE** /auth/users/{userId}/external/principals | delete external principal from user
@@ -232,6 +233,7 @@ Class | Method | HTTP request | Description
*ObjectsApi* | [**head_object**](docs/ObjectsApi.md#head_object) | **HEAD** /repositories/{repository}/refs/{ref}/objects | check if object exists
*ObjectsApi* | [**list_objects**](docs/ObjectsApi.md#list_objects) | **GET** /repositories/{repository}/refs/{ref}/objects/ls | list objects under a given prefix
*ObjectsApi* | [**stat_object**](docs/ObjectsApi.md#stat_object) | **GET** /repositories/{repository}/refs/{ref}/objects/stat | get object metadata
+*ObjectsApi* | [**update_object_user_metadata**](docs/ObjectsApi.md#update_object_user_metadata) | **PUT** /repositories/{repository}/branches/{branch}/objects/stat/user_metadata | rewrite (all) object metadata
*ObjectsApi* | [**upload_object**](docs/ObjectsApi.md#upload_object) | **POST** /repositories/{repository}/branches/{branch}/objects |
*PullsApi* | [**create_pull_request**](docs/PullsApi.md#create_pull_request) | **POST** /repositories/{repository}/pulls | create pull request
*PullsApi* | [**get_pull_request**](docs/PullsApi.md#get_pull_request) | **GET** /repositories/{repository}/pulls/{pull_request} | get pull request
@@ -363,6 +365,7 @@ Class | Method | HTTP request | Description
- [TagCreation](docs/TagCreation.md)
- [TaskInfo](docs/TaskInfo.md)
- [UnderlyingObjectProperties](docs/UnderlyingObjectProperties.md)
+ - [UpdateObjectUserMetadata](docs/UpdateObjectUserMetadata.md)
- [UpdateToken](docs/UpdateToken.md)
- [UploadPart](docs/UploadPart.md)
- [UsageReport](docs/UsageReport.md)
diff --git a/clients/python/docs/ExperimentalApi.md b/clients/python/docs/ExperimentalApi.md
index 2dc45b9a02c..1ecf62850a9 100644
--- a/clients/python/docs/ExperimentalApi.md
+++ b/clients/python/docs/ExperimentalApi.md
@@ -18,6 +18,7 @@ Method | HTTP request | Description
[**list_user_external_principals**](ExperimentalApi.md#list_user_external_principals) | **GET** /auth/users/{userId}/external/principals/ls | list user external policies attached to a user
[**merge_pull_request**](ExperimentalApi.md#merge_pull_request) | **PUT** /repositories/{repository}/pulls/{pull_request}/merge | merge pull request
[**sts_login**](ExperimentalApi.md#sts_login) | **POST** /sts/login | perform a login with STS
+[**update_object_user_metadata**](ExperimentalApi.md#update_object_user_metadata) | **PUT** /repositories/{repository}/branches/{branch}/objects/stat/user_metadata | rewrite (all) object metadata
[**update_pull_request**](ExperimentalApi.md#update_pull_request) | **PATCH** /repositories/{repository}/pulls/{pull_request} | update pull request
@@ -1557,6 +1558,121 @@ No authorization required
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+# **update_object_user_metadata**
+> update_object_user_metadata(repository, branch, path, update_object_user_metadata)
+
+rewrite (all) object metadata
+
+### Example
+
+* Basic Authentication (basic_auth):
+* Api Key Authentication (cookie_auth):
+* Api Key Authentication (oidc_auth):
+* Api Key Authentication (saml_auth):
+* Bearer (JWT) Authentication (jwt_token):
+
+```python
+import time
+import os
+import lakefs_sdk
+from lakefs_sdk.models.update_object_user_metadata import UpdateObjectUserMetadata
+from lakefs_sdk.rest import ApiException
+from pprint import pprint
+
+# Defining the host is optional and defaults to /api/v1
+# See configuration.py for a list of all supported configuration parameters.
+configuration = lakefs_sdk.Configuration(
+ host = "/api/v1"
+)
+
+# The client must configure the authentication and authorization parameters
+# in accordance with the API server security policy.
+# Examples for each auth method are provided below, use the example that
+# satisfies your auth use case.
+
+# Configure HTTP basic authorization: basic_auth
+configuration = lakefs_sdk.Configuration(
+ username = os.environ["USERNAME"],
+ password = os.environ["PASSWORD"]
+)
+
+# Configure API key authorization: cookie_auth
+configuration.api_key['cookie_auth'] = os.environ["API_KEY"]
+
+# Uncomment below to setup prefix (e.g. Bearer) for API key, if needed
+# configuration.api_key_prefix['cookie_auth'] = 'Bearer'
+
+# Configure API key authorization: oidc_auth
+configuration.api_key['oidc_auth'] = os.environ["API_KEY"]
+
+# Uncomment below to setup prefix (e.g. Bearer) for API key, if needed
+# configuration.api_key_prefix['oidc_auth'] = 'Bearer'
+
+# Configure API key authorization: saml_auth
+configuration.api_key['saml_auth'] = os.environ["API_KEY"]
+
+# Uncomment below to setup prefix (e.g. Bearer) for API key, if needed
+# configuration.api_key_prefix['saml_auth'] = 'Bearer'
+
+# Configure Bearer authorization (JWT): jwt_token
+configuration = lakefs_sdk.Configuration(
+ access_token = os.environ["BEARER_TOKEN"]
+)
+
+# Enter a context with an instance of the API client
+with lakefs_sdk.ApiClient(configuration) as api_client:
+ # Create an instance of the API class
+ api_instance = lakefs_sdk.ExperimentalApi(api_client)
+ repository = 'repository_example' # str |
+ branch = 'branch_example' # str | branch to update
+ path = 'path_example' # str | path to object relative to the branch
+ update_object_user_metadata = lakefs_sdk.UpdateObjectUserMetadata() # UpdateObjectUserMetadata |
+
+ try:
+ # rewrite (all) object metadata
+ api_instance.update_object_user_metadata(repository, branch, path, update_object_user_metadata)
+ except Exception as e:
+ print("Exception when calling ExperimentalApi->update_object_user_metadata: %s\n" % e)
+```
+
+
+
+### Parameters
+
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **repository** | **str**| |
+ **branch** | **str**| branch to update |
+ **path** | **str**| path to object relative to the branch |
+ **update_object_user_metadata** | [**UpdateObjectUserMetadata**](UpdateObjectUserMetadata.md)| |
+
+### Return type
+
+void (empty response body)
+
+### Authorization
+
+[basic_auth](../README.md#basic_auth), [cookie_auth](../README.md#cookie_auth), [oidc_auth](../README.md#oidc_auth), [saml_auth](../README.md#saml_auth), [jwt_token](../README.md#jwt_token)
+
+### HTTP request headers
+
+ - **Content-Type**: application/json
+ - **Accept**: application/json
+
+### HTTP response details
+
+| Status code | Description | Response headers |
+|-------------|-------------|------------------|
+**201** | User metadata updated | - |
+**401** | Unauthorized | - |
+**404** | Resource Not Found | - |
+**400** | Bad Request | - |
+**420** | too many requests | - |
+**0** | Internal Server Error | - |
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
# **update_pull_request**
> update_pull_request(repository, pull_request, pull_request_basic)
diff --git a/clients/python/docs/ObjectsApi.md b/clients/python/docs/ObjectsApi.md
index a9ab5b4e74a..505b4739d38 100644
--- a/clients/python/docs/ObjectsApi.md
+++ b/clients/python/docs/ObjectsApi.md
@@ -12,6 +12,7 @@ Method | HTTP request | Description
[**head_object**](ObjectsApi.md#head_object) | **HEAD** /repositories/{repository}/refs/{ref}/objects | check if object exists
[**list_objects**](ObjectsApi.md#list_objects) | **GET** /repositories/{repository}/refs/{ref}/objects/ls | list objects under a given prefix
[**stat_object**](ObjectsApi.md#stat_object) | **GET** /repositories/{repository}/refs/{ref}/objects/stat | get object metadata
+[**update_object_user_metadata**](ObjectsApi.md#update_object_user_metadata) | **PUT** /repositories/{repository}/branches/{branch}/objects/stat/user_metadata | rewrite (all) object metadata
[**upload_object**](ObjectsApi.md#upload_object) | **POST** /repositories/{repository}/branches/{branch}/objects |
@@ -964,6 +965,121 @@ Name | Type | Description | Notes
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+# **update_object_user_metadata**
+> update_object_user_metadata(repository, branch, path, update_object_user_metadata)
+
+rewrite (all) object metadata
+
+### Example
+
+* Basic Authentication (basic_auth):
+* Api Key Authentication (cookie_auth):
+* Api Key Authentication (oidc_auth):
+* Api Key Authentication (saml_auth):
+* Bearer (JWT) Authentication (jwt_token):
+
+```python
+import time
+import os
+import lakefs_sdk
+from lakefs_sdk.models.update_object_user_metadata import UpdateObjectUserMetadata
+from lakefs_sdk.rest import ApiException
+from pprint import pprint
+
+# Defining the host is optional and defaults to /api/v1
+# See configuration.py for a list of all supported configuration parameters.
+configuration = lakefs_sdk.Configuration(
+ host = "/api/v1"
+)
+
+# The client must configure the authentication and authorization parameters
+# in accordance with the API server security policy.
+# Examples for each auth method are provided below, use the example that
+# satisfies your auth use case.
+
+# Configure HTTP basic authorization: basic_auth
+configuration = lakefs_sdk.Configuration(
+ username = os.environ["USERNAME"],
+ password = os.environ["PASSWORD"]
+)
+
+# Configure API key authorization: cookie_auth
+configuration.api_key['cookie_auth'] = os.environ["API_KEY"]
+
+# Uncomment below to setup prefix (e.g. Bearer) for API key, if needed
+# configuration.api_key_prefix['cookie_auth'] = 'Bearer'
+
+# Configure API key authorization: oidc_auth
+configuration.api_key['oidc_auth'] = os.environ["API_KEY"]
+
+# Uncomment below to setup prefix (e.g. Bearer) for API key, if needed
+# configuration.api_key_prefix['oidc_auth'] = 'Bearer'
+
+# Configure API key authorization: saml_auth
+configuration.api_key['saml_auth'] = os.environ["API_KEY"]
+
+# Uncomment below to setup prefix (e.g. Bearer) for API key, if needed
+# configuration.api_key_prefix['saml_auth'] = 'Bearer'
+
+# Configure Bearer authorization (JWT): jwt_token
+configuration = lakefs_sdk.Configuration(
+ access_token = os.environ["BEARER_TOKEN"]
+)
+
+# Enter a context with an instance of the API client
+with lakefs_sdk.ApiClient(configuration) as api_client:
+ # Create an instance of the API class
+ api_instance = lakefs_sdk.ObjectsApi(api_client)
+ repository = 'repository_example' # str |
+ branch = 'branch_example' # str | branch to update
+ path = 'path_example' # str | path to object relative to the branch
+ update_object_user_metadata = lakefs_sdk.UpdateObjectUserMetadata() # UpdateObjectUserMetadata |
+
+ try:
+ # rewrite (all) object metadata
+ api_instance.update_object_user_metadata(repository, branch, path, update_object_user_metadata)
+ except Exception as e:
+ print("Exception when calling ObjectsApi->update_object_user_metadata: %s\n" % e)
+```
+
+
+
+### Parameters
+
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **repository** | **str**| |
+ **branch** | **str**| branch to update |
+ **path** | **str**| path to object relative to the branch |
+ **update_object_user_metadata** | [**UpdateObjectUserMetadata**](UpdateObjectUserMetadata.md)| |
+
+### Return type
+
+void (empty response body)
+
+### Authorization
+
+[basic_auth](../README.md#basic_auth), [cookie_auth](../README.md#cookie_auth), [oidc_auth](../README.md#oidc_auth), [saml_auth](../README.md#saml_auth), [jwt_token](../README.md#jwt_token)
+
+### HTTP request headers
+
+ - **Content-Type**: application/json
+ - **Accept**: application/json
+
+### HTTP response details
+
+| Status code | Description | Response headers |
+|-------------|-------------|------------------|
+**201** | User metadata updated | - |
+**401** | Unauthorized | - |
+**404** | Resource Not Found | - |
+**400** | Bad Request | - |
+**420** | too many requests | - |
+**0** | Internal Server Error | - |
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
# **upload_object**
> ObjectStats upload_object(repository, branch, path, if_none_match=if_none_match, storage_class=storage_class, force=force, content=content)
diff --git a/clients/python/docs/UpdateObjectUserMetadata.md b/clients/python/docs/UpdateObjectUserMetadata.md
new file mode 100644
index 00000000000..bc6eb8d2b7e
--- /dev/null
+++ b/clients/python/docs/UpdateObjectUserMetadata.md
@@ -0,0 +1,29 @@
+# UpdateObjectUserMetadata
+
+
+## Properties
+
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**set** | **Dict[str, str]** | |
+
+## Example
+
+```python
+from lakefs_sdk.models.update_object_user_metadata import UpdateObjectUserMetadata
+
+# TODO update the JSON string below
+json = "{}"
+# create an instance of UpdateObjectUserMetadata from a JSON string
+update_object_user_metadata_instance = UpdateObjectUserMetadata.from_json(json)
+# print the JSON string representation of the object
+print UpdateObjectUserMetadata.to_json()
+
+# convert the object into a dict
+update_object_user_metadata_dict = update_object_user_metadata_instance.to_dict()
+# create an instance of UpdateObjectUserMetadata from a dict
+update_object_user_metadata_form_dict = update_object_user_metadata.from_dict(update_object_user_metadata_dict)
+```
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/clients/python/lakefs_sdk/__init__.py b/clients/python/lakefs_sdk/__init__.py
index 19d61431752..58a0428be1c 100644
--- a/clients/python/lakefs_sdk/__init__.py
+++ b/clients/python/lakefs_sdk/__init__.py
@@ -145,6 +145,7 @@
from lakefs_sdk.models.tag_creation import TagCreation
from lakefs_sdk.models.task_info import TaskInfo
from lakefs_sdk.models.underlying_object_properties import UnderlyingObjectProperties
+from lakefs_sdk.models.update_object_user_metadata import UpdateObjectUserMetadata
from lakefs_sdk.models.update_token import UpdateToken
from lakefs_sdk.models.upload_part import UploadPart
from lakefs_sdk.models.usage_report import UsageReport
diff --git a/clients/python/lakefs_sdk/api/experimental_api.py b/clients/python/lakefs_sdk/api/experimental_api.py
index d6f91203d05..d672206ac17 100644
--- a/clients/python/lakefs_sdk/api/experimental_api.py
+++ b/clients/python/lakefs_sdk/api/experimental_api.py
@@ -46,6 +46,7 @@
from lakefs_sdk.models.pull_request_creation_response import PullRequestCreationResponse
from lakefs_sdk.models.pull_requests_list import PullRequestsList
from lakefs_sdk.models.sts_auth_request import StsAuthRequest
+from lakefs_sdk.models.update_object_user_metadata import UpdateObjectUserMetadata
from lakefs_sdk.api_client import ApiClient
from lakefs_sdk.api_response import ApiResponse
@@ -2285,6 +2286,172 @@ def sts_login_with_http_info(self, sts_auth_request : StsAuthRequest, **kwargs)
collection_formats=_collection_formats,
_request_auth=_params.get('_request_auth'))
+ @validate_arguments
+ def update_object_user_metadata(self, repository : StrictStr, branch : Annotated[StrictStr, Field(..., description="branch to update")], path : Annotated[StrictStr, Field(..., description="path to object relative to the branch")], update_object_user_metadata : UpdateObjectUserMetadata, **kwargs) -> None: # noqa: E501
+ """rewrite (all) object metadata # noqa: E501
+
+ This method makes a synchronous HTTP request by default. To make an
+ asynchronous HTTP request, please pass async_req=True
+
+ >>> thread = api.update_object_user_metadata(repository, branch, path, update_object_user_metadata, async_req=True)
+ >>> result = thread.get()
+
+ :param repository: (required)
+ :type repository: str
+ :param branch: branch to update (required)
+ :type branch: str
+ :param path: path to object relative to the branch (required)
+ :type path: str
+ :param update_object_user_metadata: (required)
+ :type update_object_user_metadata: UpdateObjectUserMetadata
+ :param async_req: Whether to execute the request asynchronously.
+ :type async_req: bool, optional
+ :param _request_timeout: timeout setting for this request. If one
+ number provided, it will be total request
+ timeout. It can also be a pair (tuple) of
+ (connection, read) timeouts.
+ :return: Returns the result object.
+ If the method is called asynchronously,
+ returns the request thread.
+ :rtype: None
+ """
+ kwargs['_return_http_data_only'] = True
+ if '_preload_content' in kwargs:
+ raise ValueError("Error! Please call the update_object_user_metadata_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data")
+ return self.update_object_user_metadata_with_http_info(repository, branch, path, update_object_user_metadata, **kwargs) # noqa: E501
+
+ @validate_arguments
+ def update_object_user_metadata_with_http_info(self, repository : StrictStr, branch : Annotated[StrictStr, Field(..., description="branch to update")], path : Annotated[StrictStr, Field(..., description="path to object relative to the branch")], update_object_user_metadata : UpdateObjectUserMetadata, **kwargs) -> ApiResponse: # noqa: E501
+ """rewrite (all) object metadata # noqa: E501
+
+ This method makes a synchronous HTTP request by default. To make an
+ asynchronous HTTP request, please pass async_req=True
+
+ >>> thread = api.update_object_user_metadata_with_http_info(repository, branch, path, update_object_user_metadata, async_req=True)
+ >>> result = thread.get()
+
+ :param repository: (required)
+ :type repository: str
+ :param branch: branch to update (required)
+ :type branch: str
+ :param path: path to object relative to the branch (required)
+ :type path: str
+ :param update_object_user_metadata: (required)
+ :type update_object_user_metadata: UpdateObjectUserMetadata
+ :param async_req: Whether to execute the request asynchronously.
+ :type async_req: bool, optional
+ :param _preload_content: if False, the ApiResponse.data will
+ be set to none and raw_data will store the
+ HTTP response body without reading/decoding.
+ Default is True.
+ :type _preload_content: bool, optional
+ :param _return_http_data_only: response data instead of ApiResponse
+ object with status code, headers, etc
+ :type _return_http_data_only: bool, optional
+ :param _request_timeout: timeout setting for this request. If one
+ number provided, it will be total request
+ timeout. It can also be a pair (tuple) of
+ (connection, read) timeouts.
+ :param _request_auth: set to override the auth_settings for an a single
+ request; this effectively ignores the authentication
+ in the spec for a single request.
+ :type _request_auth: dict, optional
+ :type _content_type: string, optional: force content-type for the request
+ :return: Returns the result object.
+ If the method is called asynchronously,
+ returns the request thread.
+ :rtype: None
+ """
+
+ _params = locals()
+
+ _all_params = [
+ 'repository',
+ 'branch',
+ 'path',
+ 'update_object_user_metadata'
+ ]
+ _all_params.extend(
+ [
+ 'async_req',
+ '_return_http_data_only',
+ '_preload_content',
+ '_request_timeout',
+ '_request_auth',
+ '_content_type',
+ '_headers'
+ ]
+ )
+
+ # validate the arguments
+ for _key, _val in _params['kwargs'].items():
+ if _key not in _all_params:
+ raise ApiTypeError(
+ "Got an unexpected keyword argument '%s'"
+ " to method update_object_user_metadata" % _key
+ )
+ _params[_key] = _val
+ del _params['kwargs']
+
+ _collection_formats = {}
+
+ # process the path parameters
+ _path_params = {}
+ if _params['repository']:
+ _path_params['repository'] = _params['repository']
+
+ if _params['branch']:
+ _path_params['branch'] = _params['branch']
+
+
+ # process the query parameters
+ _query_params = []
+ if _params.get('path') is not None: # noqa: E501
+ _query_params.append(('path', _params['path']))
+
+ # process the header parameters
+ _header_params = dict(_params.get('_headers', {}))
+ # process the form parameters
+ _form_params = []
+ _files = {}
+ # process the body parameter
+ _body_params = None
+ if _params['update_object_user_metadata'] is not None:
+ _body_params = _params['update_object_user_metadata']
+
+ # set the HTTP header `Accept`
+ _header_params['Accept'] = self.api_client.select_header_accept(
+ ['application/json']) # noqa: E501
+
+ # set the HTTP header `Content-Type`
+ _content_types_list = _params.get('_content_type',
+ self.api_client.select_header_content_type(
+ ['application/json']))
+ if _content_types_list:
+ _header_params['Content-Type'] = _content_types_list
+
+ # authentication setting
+ _auth_settings = ['basic_auth', 'cookie_auth', 'oidc_auth', 'saml_auth', 'jwt_token'] # noqa: E501
+
+ _response_types_map = {}
+
+ return self.api_client.call_api(
+ '/repositories/{repository}/branches/{branch}/objects/stat/user_metadata', 'PUT',
+ _path_params,
+ _query_params,
+ _header_params,
+ body=_body_params,
+ post_params=_form_params,
+ files=_files,
+ response_types_map=_response_types_map,
+ auth_settings=_auth_settings,
+ async_req=_params.get('async_req'),
+ _return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501
+ _preload_content=_params.get('_preload_content', True),
+ _request_timeout=_params.get('_request_timeout'),
+ collection_formats=_collection_formats,
+ _request_auth=_params.get('_request_auth'))
+
@validate_arguments
def update_pull_request(self, repository : StrictStr, pull_request : Annotated[StrictStr, Field(..., description="pull request id")], pull_request_basic : PullRequestBasic, **kwargs) -> None: # noqa: E501
"""update pull request # noqa: E501
diff --git a/clients/python/lakefs_sdk/api/objects_api.py b/clients/python/lakefs_sdk/api/objects_api.py
index 50c43248b80..91bd2323171 100644
--- a/clients/python/lakefs_sdk/api/objects_api.py
+++ b/clients/python/lakefs_sdk/api/objects_api.py
@@ -36,6 +36,7 @@
from lakefs_sdk.models.object_stats_list import ObjectStatsList
from lakefs_sdk.models.path_list import PathList
from lakefs_sdk.models.underlying_object_properties import UnderlyingObjectProperties
+from lakefs_sdk.models.update_object_user_metadata import UpdateObjectUserMetadata
from lakefs_sdk.api_client import ApiClient
from lakefs_sdk.api_response import ApiResponse
@@ -1427,6 +1428,172 @@ def stat_object_with_http_info(self, repository : StrictStr, ref : Annotated[Str
collection_formats=_collection_formats,
_request_auth=_params.get('_request_auth'))
+ @validate_arguments
+ def update_object_user_metadata(self, repository : StrictStr, branch : Annotated[StrictStr, Field(..., description="branch to update")], path : Annotated[StrictStr, Field(..., description="path to object relative to the branch")], update_object_user_metadata : UpdateObjectUserMetadata, **kwargs) -> None: # noqa: E501
+ """rewrite (all) object metadata # noqa: E501
+
+ This method makes a synchronous HTTP request by default. To make an
+ asynchronous HTTP request, please pass async_req=True
+
+ >>> thread = api.update_object_user_metadata(repository, branch, path, update_object_user_metadata, async_req=True)
+ >>> result = thread.get()
+
+ :param repository: (required)
+ :type repository: str
+ :param branch: branch to update (required)
+ :type branch: str
+ :param path: path to object relative to the branch (required)
+ :type path: str
+ :param update_object_user_metadata: (required)
+ :type update_object_user_metadata: UpdateObjectUserMetadata
+ :param async_req: Whether to execute the request asynchronously.
+ :type async_req: bool, optional
+ :param _request_timeout: timeout setting for this request. If one
+ number provided, it will be total request
+ timeout. It can also be a pair (tuple) of
+ (connection, read) timeouts.
+ :return: Returns the result object.
+ If the method is called asynchronously,
+ returns the request thread.
+ :rtype: None
+ """
+ kwargs['_return_http_data_only'] = True
+ if '_preload_content' in kwargs:
+ raise ValueError("Error! Please call the update_object_user_metadata_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data")
+ return self.update_object_user_metadata_with_http_info(repository, branch, path, update_object_user_metadata, **kwargs) # noqa: E501
+
+ @validate_arguments
+ def update_object_user_metadata_with_http_info(self, repository : StrictStr, branch : Annotated[StrictStr, Field(..., description="branch to update")], path : Annotated[StrictStr, Field(..., description="path to object relative to the branch")], update_object_user_metadata : UpdateObjectUserMetadata, **kwargs) -> ApiResponse: # noqa: E501
+ """rewrite (all) object metadata # noqa: E501
+
+ This method makes a synchronous HTTP request by default. To make an
+ asynchronous HTTP request, please pass async_req=True
+
+ >>> thread = api.update_object_user_metadata_with_http_info(repository, branch, path, update_object_user_metadata, async_req=True)
+ >>> result = thread.get()
+
+ :param repository: (required)
+ :type repository: str
+ :param branch: branch to update (required)
+ :type branch: str
+ :param path: path to object relative to the branch (required)
+ :type path: str
+ :param update_object_user_metadata: (required)
+ :type update_object_user_metadata: UpdateObjectUserMetadata
+ :param async_req: Whether to execute the request asynchronously.
+ :type async_req: bool, optional
+ :param _preload_content: if False, the ApiResponse.data will
+ be set to none and raw_data will store the
+ HTTP response body without reading/decoding.
+ Default is True.
+ :type _preload_content: bool, optional
+ :param _return_http_data_only: response data instead of ApiResponse
+ object with status code, headers, etc
+ :type _return_http_data_only: bool, optional
+ :param _request_timeout: timeout setting for this request. If one
+ number provided, it will be total request
+ timeout. It can also be a pair (tuple) of
+ (connection, read) timeouts.
+ :param _request_auth: set to override the auth_settings for an a single
+ request; this effectively ignores the authentication
+ in the spec for a single request.
+ :type _request_auth: dict, optional
+ :type _content_type: string, optional: force content-type for the request
+ :return: Returns the result object.
+ If the method is called asynchronously,
+ returns the request thread.
+ :rtype: None
+ """
+
+ _params = locals()
+
+ _all_params = [
+ 'repository',
+ 'branch',
+ 'path',
+ 'update_object_user_metadata'
+ ]
+ _all_params.extend(
+ [
+ 'async_req',
+ '_return_http_data_only',
+ '_preload_content',
+ '_request_timeout',
+ '_request_auth',
+ '_content_type',
+ '_headers'
+ ]
+ )
+
+ # validate the arguments
+ for _key, _val in _params['kwargs'].items():
+ if _key not in _all_params:
+ raise ApiTypeError(
+ "Got an unexpected keyword argument '%s'"
+ " to method update_object_user_metadata" % _key
+ )
+ _params[_key] = _val
+ del _params['kwargs']
+
+ _collection_formats = {}
+
+ # process the path parameters
+ _path_params = {}
+ if _params['repository']:
+ _path_params['repository'] = _params['repository']
+
+ if _params['branch']:
+ _path_params['branch'] = _params['branch']
+
+
+ # process the query parameters
+ _query_params = []
+ if _params.get('path') is not None: # noqa: E501
+ _query_params.append(('path', _params['path']))
+
+ # process the header parameters
+ _header_params = dict(_params.get('_headers', {}))
+ # process the form parameters
+ _form_params = []
+ _files = {}
+ # process the body parameter
+ _body_params = None
+ if _params['update_object_user_metadata'] is not None:
+ _body_params = _params['update_object_user_metadata']
+
+ # set the HTTP header `Accept`
+ _header_params['Accept'] = self.api_client.select_header_accept(
+ ['application/json']) # noqa: E501
+
+ # set the HTTP header `Content-Type`
+ _content_types_list = _params.get('_content_type',
+ self.api_client.select_header_content_type(
+ ['application/json']))
+ if _content_types_list:
+ _header_params['Content-Type'] = _content_types_list
+
+ # authentication setting
+ _auth_settings = ['basic_auth', 'cookie_auth', 'oidc_auth', 'saml_auth', 'jwt_token'] # noqa: E501
+
+ _response_types_map = {}
+
+ return self.api_client.call_api(
+ '/repositories/{repository}/branches/{branch}/objects/stat/user_metadata', 'PUT',
+ _path_params,
+ _query_params,
+ _header_params,
+ body=_body_params,
+ post_params=_form_params,
+ files=_files,
+ response_types_map=_response_types_map,
+ auth_settings=_auth_settings,
+ async_req=_params.get('async_req'),
+ _return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501
+ _preload_content=_params.get('_preload_content', True),
+ _request_timeout=_params.get('_request_timeout'),
+ collection_formats=_collection_formats,
+ _request_auth=_params.get('_request_auth'))
+
@validate_arguments
def upload_object(self, repository : StrictStr, branch : StrictStr, path : Annotated[StrictStr, Field(..., description="relative to the branch")], if_none_match : Annotated[Optional[StrictStr], Field(description="Set to \"*\" to atomically allow the upload only if the key has no object yet. Other values are not supported.")] = None, storage_class : Annotated[Optional[StrictStr], Field(description="Deprecated, this capability will not be supported in future releases.")] = None, force : Optional[StrictBool] = None, content : Annotated[Optional[Union[StrictBytes, StrictStr]], Field(description="Only a single file per upload which must be named \\\"content\\\".")] = None, **kwargs) -> ObjectStats: # noqa: E501
"""upload_object # noqa: E501
diff --git a/clients/python/lakefs_sdk/models/__init__.py b/clients/python/lakefs_sdk/models/__init__.py
index 319059c9435..49b9091bbaf 100644
--- a/clients/python/lakefs_sdk/models/__init__.py
+++ b/clients/python/lakefs_sdk/models/__init__.py
@@ -112,6 +112,7 @@
from lakefs_sdk.models.tag_creation import TagCreation
from lakefs_sdk.models.task_info import TaskInfo
from lakefs_sdk.models.underlying_object_properties import UnderlyingObjectProperties
+from lakefs_sdk.models.update_object_user_metadata import UpdateObjectUserMetadata
from lakefs_sdk.models.update_token import UpdateToken
from lakefs_sdk.models.upload_part import UploadPart
from lakefs_sdk.models.usage_report import UsageReport
diff --git a/clients/python/lakefs_sdk/models/update_object_user_metadata.py b/clients/python/lakefs_sdk/models/update_object_user_metadata.py
new file mode 100644
index 00000000000..a95ce70a541
--- /dev/null
+++ b/clients/python/lakefs_sdk/models/update_object_user_metadata.py
@@ -0,0 +1,75 @@
+# coding: utf-8
+
+"""
+ lakeFS API
+
+ lakeFS HTTP API
+
+ The version of the OpenAPI document: 1.0.0
+ Contact: services@treeverse.io
+ Generated by OpenAPI Generator (https://openapi-generator.tech)
+
+ Do not edit the class manually.
+""" # noqa: E501
+
+
+from __future__ import annotations
+import pprint
+import re # noqa: F401
+import json
+
+
+from typing import Dict
+try:
+ from pydantic.v1 import BaseModel, Field, StrictStr
+except ImportError:
+ from pydantic import BaseModel, Field, StrictStr
+
+class UpdateObjectUserMetadata(BaseModel):
+ """
+ UpdateObjectUserMetadata
+ """
+ set: Dict[str, StrictStr] = Field(...)
+ __properties = ["set"]
+
+ class Config:
+ """Pydantic configuration"""
+ allow_population_by_field_name = True
+ validate_assignment = True
+
+ def to_str(self) -> str:
+ """Returns the string representation of the model using alias"""
+ return pprint.pformat(self.dict(by_alias=True))
+
+ def to_json(self) -> str:
+ """Returns the JSON representation of the model using alias"""
+ return json.dumps(self.to_dict())
+
+ @classmethod
+ def from_json(cls, json_str: str) -> UpdateObjectUserMetadata:
+ """Create an instance of UpdateObjectUserMetadata from a JSON string"""
+ return cls.from_dict(json.loads(json_str))
+
+ def to_dict(self):
+ """Returns the dictionary representation of the model using alias"""
+ _dict = self.dict(by_alias=True,
+ exclude={
+ },
+ exclude_none=True)
+ return _dict
+
+ @classmethod
+ def from_dict(cls, obj: dict) -> UpdateObjectUserMetadata:
+ """Create an instance of UpdateObjectUserMetadata from a dict"""
+ if obj is None:
+ return None
+
+ if not isinstance(obj, dict):
+ return UpdateObjectUserMetadata.parse_obj(obj)
+
+ _obj = UpdateObjectUserMetadata.parse_obj({
+ "set": obj.get("set")
+ })
+ return _obj
+
+
diff --git a/clients/python/test/test_experimental_api.py b/clients/python/test/test_experimental_api.py
index ce066b2cccc..e30b75d6166 100644
--- a/clients/python/test/test_experimental_api.py
+++ b/clients/python/test/test_experimental_api.py
@@ -127,6 +127,13 @@ def test_sts_login(self):
"""
pass
+ def test_update_object_user_metadata(self):
+ """Test case for update_object_user_metadata
+
+ rewrite (all) object metadata # noqa: E501
+ """
+ pass
+
def test_update_pull_request(self):
"""Test case for update_pull_request
diff --git a/clients/python/test/test_objects_api.py b/clients/python/test/test_objects_api.py
index 334c3b05171..4db012969cb 100644
--- a/clients/python/test/test_objects_api.py
+++ b/clients/python/test/test_objects_api.py
@@ -85,6 +85,13 @@ def test_stat_object(self):
"""
pass
+ def test_update_object_user_metadata(self):
+ """Test case for update_object_user_metadata
+
+ rewrite (all) object metadata # noqa: E501
+ """
+ pass
+
def test_upload_object(self):
"""Test case for upload_object
diff --git a/clients/python/test/test_update_object_user_metadata.py b/clients/python/test/test_update_object_user_metadata.py
new file mode 100644
index 00000000000..e219d9a4a8a
--- /dev/null
+++ b/clients/python/test/test_update_object_user_metadata.py
@@ -0,0 +1,60 @@
+# coding: utf-8
+
+"""
+ lakeFS API
+
+ lakeFS HTTP API
+
+ The version of the OpenAPI document: 1.0.0
+ Contact: services@treeverse.io
+ Generated by OpenAPI Generator (https://openapi-generator.tech)
+
+ Do not edit the class manually.
+""" # noqa: E501
+
+
+import unittest
+import datetime
+
+import lakefs_sdk
+from lakefs_sdk.models.update_object_user_metadata import UpdateObjectUserMetadata # noqa: E501
+from lakefs_sdk.rest import ApiException
+
+class TestUpdateObjectUserMetadata(unittest.TestCase):
+ """UpdateObjectUserMetadata unit test stubs"""
+
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ def make_instance(self, include_optional):
+ """Test UpdateObjectUserMetadata
+ include_option is a boolean, when False only required
+ params are included, when True both required and
+ optional params are included """
+ # uncomment below to create an instance of `UpdateObjectUserMetadata`
+ """
+ model = lakefs_sdk.models.update_object_user_metadata.UpdateObjectUserMetadata() # noqa: E501
+ if include_optional :
+ return UpdateObjectUserMetadata(
+ set = {
+ 'key' : ''
+ }
+ )
+ else :
+ return UpdateObjectUserMetadata(
+ set = {
+ 'key' : ''
+ },
+ )
+ """
+
+ def testUpdateObjectUserMetadata(self):
+ """Test UpdateObjectUserMetadata"""
+ # inst_req_only = self.make_instance(include_optional=False)
+ # inst_req_and_optional = self.make_instance(include_optional=True)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/clients/rust/.openapi-generator/FILES b/clients/rust/.openapi-generator/FILES
index 38ff7f89a6c..c3b70eed96c 100644
--- a/clients/rust/.openapi-generator/FILES
+++ b/clients/rust/.openapi-generator/FILES
@@ -117,6 +117,7 @@ docs/TagCreation.md
docs/TagsApi.md
docs/TaskInfo.md
docs/UnderlyingObjectProperties.md
+docs/UpdateObjectUserMetadata.md
docs/UpdateToken.md
docs/UploadPart.md
docs/UsageReport.md
@@ -243,6 +244,7 @@ src/models/sts_auth_request.rs
src/models/tag_creation.rs
src/models/task_info.rs
src/models/underlying_object_properties.rs
+src/models/update_object_user_metadata.rs
src/models/update_token.rs
src/models/upload_part.rs
src/models/usage_report.rs
diff --git a/clients/rust/README.md b/clients/rust/README.md
index 8bbba4c565a..fdae09f4752 100644
--- a/clients/rust/README.md
+++ b/clients/rust/README.md
@@ -91,6 +91,7 @@ Class | Method | HTTP request | Description
*ExperimentalApi* | [**list_user_external_principals**](docs/ExperimentalApi.md#list_user_external_principals) | **GET** /auth/users/{userId}/external/principals/ls | list user external policies attached to a user
*ExperimentalApi* | [**merge_pull_request**](docs/ExperimentalApi.md#merge_pull_request) | **PUT** /repositories/{repository}/pulls/{pull_request}/merge | merge pull request
*ExperimentalApi* | [**sts_login**](docs/ExperimentalApi.md#sts_login) | **POST** /sts/login | perform a login with STS
+*ExperimentalApi* | [**update_object_user_metadata**](docs/ExperimentalApi.md#update_object_user_metadata) | **PUT** /repositories/{repository}/branches/{branch}/objects/stat/user_metadata | rewrite (all) object metadata
*ExperimentalApi* | [**update_pull_request**](docs/ExperimentalApi.md#update_pull_request) | **PATCH** /repositories/{repository}/pulls/{pull_request} | update pull request
*ExternalApi* | [**create_user_external_principal**](docs/ExternalApi.md#create_user_external_principal) | **POST** /auth/users/{userId}/external/principals | attach external principal to user
*ExternalApi* | [**delete_user_external_principal**](docs/ExternalApi.md#delete_user_external_principal) | **DELETE** /auth/users/{userId}/external/principals | delete external principal from user
@@ -139,6 +140,7 @@ Class | Method | HTTP request | Description
*ObjectsApi* | [**head_object**](docs/ObjectsApi.md#head_object) | **HEAD** /repositories/{repository}/refs/{ref}/objects | check if object exists
*ObjectsApi* | [**list_objects**](docs/ObjectsApi.md#list_objects) | **GET** /repositories/{repository}/refs/{ref}/objects/ls | list objects under a given prefix
*ObjectsApi* | [**stat_object**](docs/ObjectsApi.md#stat_object) | **GET** /repositories/{repository}/refs/{ref}/objects/stat | get object metadata
+*ObjectsApi* | [**update_object_user_metadata**](docs/ObjectsApi.md#update_object_user_metadata) | **PUT** /repositories/{repository}/branches/{branch}/objects/stat/user_metadata | rewrite (all) object metadata
*ObjectsApi* | [**upload_object**](docs/ObjectsApi.md#upload_object) | **POST** /repositories/{repository}/branches/{branch}/objects |
*PullsApi* | [**create_pull_request**](docs/PullsApi.md#create_pull_request) | **POST** /repositories/{repository}/pulls | create pull request
*PullsApi* | [**get_pull_request**](docs/PullsApi.md#get_pull_request) | **GET** /repositories/{repository}/pulls/{pull_request} | get pull request
@@ -270,6 +272,7 @@ Class | Method | HTTP request | Description
- [TagCreation](docs/TagCreation.md)
- [TaskInfo](docs/TaskInfo.md)
- [UnderlyingObjectProperties](docs/UnderlyingObjectProperties.md)
+ - [UpdateObjectUserMetadata](docs/UpdateObjectUserMetadata.md)
- [UpdateToken](docs/UpdateToken.md)
- [UploadPart](docs/UploadPart.md)
- [UsageReport](docs/UsageReport.md)
diff --git a/clients/rust/docs/ExperimentalApi.md b/clients/rust/docs/ExperimentalApi.md
index 009a9a377a6..143a5921012 100644
--- a/clients/rust/docs/ExperimentalApi.md
+++ b/clients/rust/docs/ExperimentalApi.md
@@ -18,6 +18,7 @@ Method | HTTP request | Description
[**list_user_external_principals**](ExperimentalApi.md#list_user_external_principals) | **GET** /auth/users/{userId}/external/principals/ls | list user external policies attached to a user
[**merge_pull_request**](ExperimentalApi.md#merge_pull_request) | **PUT** /repositories/{repository}/pulls/{pull_request}/merge | merge pull request
[**sts_login**](ExperimentalApi.md#sts_login) | **POST** /sts/login | perform a login with STS
+[**update_object_user_metadata**](ExperimentalApi.md#update_object_user_metadata) | **PUT** /repositories/{repository}/branches/{branch}/objects/stat/user_metadata | rewrite (all) object metadata
[**update_pull_request**](ExperimentalApi.md#update_pull_request) | **PATCH** /repositories/{repository}/pulls/{pull_request} | update pull request
@@ -449,6 +450,37 @@ No authorization required
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+## update_object_user_metadata
+
+> update_object_user_metadata(repository, branch, path, update_object_user_metadata)
+rewrite (all) object metadata
+
+### Parameters
+
+
+Name | Type | Description | Required | Notes
+------------- | ------------- | ------------- | ------------- | -------------
+**repository** | **String** | | [required] |
+**branch** | **String** | branch to update | [required] |
+**path** | **String** | path to object relative to the branch | [required] |
+**update_object_user_metadata** | [**UpdateObjectUserMetadata**](UpdateObjectUserMetadata.md) | | [required] |
+
+### Return type
+
+ (empty response body)
+
+### Authorization
+
+[basic_auth](../README.md#basic_auth), [cookie_auth](../README.md#cookie_auth), [oidc_auth](../README.md#oidc_auth), [saml_auth](../README.md#saml_auth), [jwt_token](../README.md#jwt_token)
+
+### HTTP request headers
+
+- **Content-Type**: application/json
+- **Accept**: application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+
## update_pull_request
> update_pull_request(repository, pull_request, pull_request_basic)
diff --git a/clients/rust/docs/ObjectsApi.md b/clients/rust/docs/ObjectsApi.md
index 92cecae6644..af4029304b6 100644
--- a/clients/rust/docs/ObjectsApi.md
+++ b/clients/rust/docs/ObjectsApi.md
@@ -12,6 +12,7 @@ Method | HTTP request | Description
[**head_object**](ObjectsApi.md#head_object) | **HEAD** /repositories/{repository}/refs/{ref}/objects | check if object exists
[**list_objects**](ObjectsApi.md#list_objects) | **GET** /repositories/{repository}/refs/{ref}/objects/ls | list objects under a given prefix
[**stat_object**](ObjectsApi.md#stat_object) | **GET** /repositories/{repository}/refs/{ref}/objects/stat | get object metadata
+[**update_object_user_metadata**](ObjectsApi.md#update_object_user_metadata) | **PUT** /repositories/{repository}/branches/{branch}/objects/stat/user_metadata | rewrite (all) object metadata
[**upload_object**](ObjectsApi.md#upload_object) | **POST** /repositories/{repository}/branches/{branch}/objects |
@@ -270,6 +271,37 @@ Name | Type | Description | Required | Notes
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+## update_object_user_metadata
+
+> update_object_user_metadata(repository, branch, path, update_object_user_metadata)
+rewrite (all) object metadata
+
+### Parameters
+
+
+Name | Type | Description | Required | Notes
+------------- | ------------- | ------------- | ------------- | -------------
+**repository** | **String** | | [required] |
+**branch** | **String** | branch to update | [required] |
+**path** | **String** | path to object relative to the branch | [required] |
+**update_object_user_metadata** | [**UpdateObjectUserMetadata**](UpdateObjectUserMetadata.md) | | [required] |
+
+### Return type
+
+ (empty response body)
+
+### Authorization
+
+[basic_auth](../README.md#basic_auth), [cookie_auth](../README.md#cookie_auth), [oidc_auth](../README.md#oidc_auth), [saml_auth](../README.md#saml_auth), [jwt_token](../README.md#jwt_token)
+
+### HTTP request headers
+
+- **Content-Type**: application/json
+- **Accept**: application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+
## upload_object
> models::ObjectStats upload_object(repository, branch, path, if_none_match, storage_class, force, content)
diff --git a/clients/rust/docs/UpdateObjectUserMetadata.md b/clients/rust/docs/UpdateObjectUserMetadata.md
new file mode 100644
index 00000000000..2e6abf0a2ec
--- /dev/null
+++ b/clients/rust/docs/UpdateObjectUserMetadata.md
@@ -0,0 +1,11 @@
+# UpdateObjectUserMetadata
+
+## Properties
+
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**set** | **std::collections::HashMap** | |
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/clients/rust/src/apis/experimental_api.rs b/clients/rust/src/apis/experimental_api.rs
index 2792272d0e6..0aeaec125ad 100644
--- a/clients/rust/src/apis/experimental_api.rs
+++ b/clients/rust/src/apis/experimental_api.rs
@@ -185,6 +185,18 @@ pub enum StsLoginError {
UnknownValue(serde_json::Value),
}
+/// struct for typed errors of method [`update_object_user_metadata`]
+#[derive(Debug, Clone, Serialize, Deserialize)]
+#[serde(untagged)]
+pub enum UpdateObjectUserMetadataError {
+ Status401(models::Error),
+ Status404(models::Error),
+ Status400(models::Error),
+ Status420(),
+ DefaultResponse(models::Error),
+ UnknownValue(serde_json::Value),
+}
+
/// struct for typed errors of method [`update_pull_request`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
@@ -693,6 +705,41 @@ pub async fn sts_login(configuration: &configuration::Configuration, sts_auth_re
}
}
+pub async fn update_object_user_metadata(configuration: &configuration::Configuration, repository: &str, branch: &str, path: &str, update_object_user_metadata: models::UpdateObjectUserMetadata) -> Result<(), Error> {
+ let local_var_configuration = configuration;
+
+ let local_var_client = &local_var_configuration.client;
+
+ let local_var_uri_str = format!("{}/repositories/{repository}/branches/{branch}/objects/stat/user_metadata", local_var_configuration.base_path, repository=crate::apis::urlencode(repository), branch=crate::apis::urlencode(branch));
+ let mut local_var_req_builder = local_var_client.request(reqwest::Method::PUT, local_var_uri_str.as_str());
+
+ local_var_req_builder = local_var_req_builder.query(&[("path", &path.to_string())]);
+ if let Some(ref local_var_user_agent) = local_var_configuration.user_agent {
+ local_var_req_builder = local_var_req_builder.header(reqwest::header::USER_AGENT, local_var_user_agent.clone());
+ }
+ if let Some(ref local_var_auth_conf) = local_var_configuration.basic_auth {
+ local_var_req_builder = local_var_req_builder.basic_auth(local_var_auth_conf.0.to_owned(), local_var_auth_conf.1.to_owned());
+ };
+ if let Some(ref local_var_token) = local_var_configuration.bearer_access_token {
+ local_var_req_builder = local_var_req_builder.bearer_auth(local_var_token.to_owned());
+ };
+ local_var_req_builder = local_var_req_builder.json(&update_object_user_metadata);
+
+ let local_var_req = local_var_req_builder.build()?;
+ let local_var_resp = local_var_client.execute(local_var_req).await?;
+
+ let local_var_status = local_var_resp.status();
+ let local_var_content = local_var_resp.text().await?;
+
+ if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
+ Ok(())
+ } else {
+ let local_var_entity: Option = serde_json::from_str(&local_var_content).ok();
+ let local_var_error = ResponseContent { status: local_var_status, content: local_var_content, entity: local_var_entity };
+ Err(Error::ResponseError(local_var_error))
+ }
+}
+
pub async fn update_pull_request(configuration: &configuration::Configuration, repository: &str, pull_request: &str, pull_request_basic: models::PullRequestBasic) -> Result<(), Error> {
let local_var_configuration = configuration;
diff --git a/clients/rust/src/apis/objects_api.rs b/clients/rust/src/apis/objects_api.rs
index 2e63c3c18f3..b43a7d7c06e 100644
--- a/clients/rust/src/apis/objects_api.rs
+++ b/clients/rust/src/apis/objects_api.rs
@@ -113,6 +113,18 @@ pub enum StatObjectError {
UnknownValue(serde_json::Value),
}
+/// struct for typed errors of method [`update_object_user_metadata`]
+#[derive(Debug, Clone, Serialize, Deserialize)]
+#[serde(untagged)]
+pub enum UpdateObjectUserMetadataError {
+ Status401(models::Error),
+ Status404(models::Error),
+ Status400(models::Error),
+ Status420(),
+ DefaultResponse(models::Error),
+ UnknownValue(serde_json::Value),
+}
+
/// struct for typed errors of method [`upload_object`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
@@ -442,6 +454,41 @@ pub async fn stat_object(configuration: &configuration::Configuration, repositor
}
}
+pub async fn update_object_user_metadata(configuration: &configuration::Configuration, repository: &str, branch: &str, path: &str, update_object_user_metadata: models::UpdateObjectUserMetadata) -> Result<(), Error> {
+ let local_var_configuration = configuration;
+
+ let local_var_client = &local_var_configuration.client;
+
+ let local_var_uri_str = format!("{}/repositories/{repository}/branches/{branch}/objects/stat/user_metadata", local_var_configuration.base_path, repository=crate::apis::urlencode(repository), branch=crate::apis::urlencode(branch));
+ let mut local_var_req_builder = local_var_client.request(reqwest::Method::PUT, local_var_uri_str.as_str());
+
+ local_var_req_builder = local_var_req_builder.query(&[("path", &path.to_string())]);
+ if let Some(ref local_var_user_agent) = local_var_configuration.user_agent {
+ local_var_req_builder = local_var_req_builder.header(reqwest::header::USER_AGENT, local_var_user_agent.clone());
+ }
+ if let Some(ref local_var_auth_conf) = local_var_configuration.basic_auth {
+ local_var_req_builder = local_var_req_builder.basic_auth(local_var_auth_conf.0.to_owned(), local_var_auth_conf.1.to_owned());
+ };
+ if let Some(ref local_var_token) = local_var_configuration.bearer_access_token {
+ local_var_req_builder = local_var_req_builder.bearer_auth(local_var_token.to_owned());
+ };
+ local_var_req_builder = local_var_req_builder.json(&update_object_user_metadata);
+
+ let local_var_req = local_var_req_builder.build()?;
+ let local_var_resp = local_var_client.execute(local_var_req).await?;
+
+ let local_var_status = local_var_resp.status();
+ let local_var_content = local_var_resp.text().await?;
+
+ if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
+ Ok(())
+ } else {
+ let local_var_entity: Option = serde_json::from_str(&local_var_content).ok();
+ let local_var_error = ResponseContent { status: local_var_status, content: local_var_content, entity: local_var_entity };
+ Err(Error::ResponseError(local_var_error))
+ }
+}
+
pub async fn upload_object(configuration: &configuration::Configuration, repository: &str, branch: &str, path: &str, if_none_match: Option<&str>, storage_class: Option<&str>, force: Option, content: Option) -> Result> {
let local_var_configuration = configuration;
diff --git a/clients/rust/src/models/mod.rs b/clients/rust/src/models/mod.rs
index 8a0474bb81e..c1eb1195a9b 100644
--- a/clients/rust/src/models/mod.rs
+++ b/clients/rust/src/models/mod.rs
@@ -192,6 +192,8 @@ pub mod task_info;
pub use self::task_info::TaskInfo;
pub mod underlying_object_properties;
pub use self::underlying_object_properties::UnderlyingObjectProperties;
+pub mod update_object_user_metadata;
+pub use self::update_object_user_metadata::UpdateObjectUserMetadata;
pub mod update_token;
pub use self::update_token::UpdateToken;
pub mod upload_part;
diff --git a/clients/rust/src/models/update_object_user_metadata.rs b/clients/rust/src/models/update_object_user_metadata.rs
new file mode 100644
index 00000000000..3c4f2066851
--- /dev/null
+++ b/clients/rust/src/models/update_object_user_metadata.rs
@@ -0,0 +1,26 @@
+/*
+ * lakeFS API
+ *
+ * lakeFS HTTP API
+ *
+ * The version of the OpenAPI document: 1.0.0
+ * Contact: services@treeverse.io
+ * Generated by: https://openapi-generator.tech
+ */
+
+use crate::models;
+
+#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
+pub struct UpdateObjectUserMetadata {
+ #[serde(rename = "set")]
+ pub set: std::collections::HashMap,
+}
+
+impl UpdateObjectUserMetadata {
+ pub fn new(set: std::collections::HashMap) -> UpdateObjectUserMetadata {
+ UpdateObjectUserMetadata {
+ set,
+ }
+ }
+}
+
diff --git a/cmd/lakectl/cmd/fs_update_metadata.go b/cmd/lakectl/cmd/fs_update_metadata.go
new file mode 100644
index 00000000000..dcf71dce3a7
--- /dev/null
+++ b/cmd/lakectl/cmd/fs_update_metadata.go
@@ -0,0 +1,71 @@
+package cmd
+
+import (
+ "errors"
+ "fmt"
+ "net/http"
+ "strings"
+
+ "github.com/spf13/cobra"
+ "github.com/treeverse/lakefs/pkg/api/apigen"
+)
+
+var errExpectedKV = errors.New("expected =")
+
+var fsUpdateUserMetadataCmd = &cobra.Command{
+ Use: "update-metadata ",
+ Short: "Update user metadata on the specified URI",
+ Hidden: true,
+ Args: cobra.ExactArgs(1),
+ ValidArgsFunction: ValidArgsRepository,
+ Run: func(cmd *cobra.Command, args []string) {
+ pathURI := MustParsePathURI("path URI", args[0])
+ userMetadataKVs, err := cmd.Flags().GetStringSlice("metadata")
+ if err != nil {
+ DieErr(err)
+ }
+ userMetadata, err := makeMap(userMetadataKVs)
+ if err != nil {
+ DieErr(err)
+ }
+
+ body := apigen.UpdateObjectUserMetadataJSONRequestBody{
+ Set: apigen.ObjectUserMetadata{
+ AdditionalProperties: userMetadata,
+ },
+ }
+
+ client := getClient()
+
+ ctx := cmd.Context()
+ resp, err := client.UpdateObjectUserMetadata(
+ ctx, pathURI.Repository, pathURI.Ref,
+ &apigen.UpdateObjectUserMetadataParams{Path: *pathURI.Path},
+ body,
+ )
+ DieOnErrorOrUnexpectedStatusCode(resp, err, http.StatusNoContent)
+ },
+}
+
+// makeMap converts a slice of strings of the form KEY=VALUE into a map.
+//
+//nolint:mnd
+func makeMap(kvs []string) (map[string]string, error) {
+ ret := make(map[string]string, len(kvs))
+ for _, kv := range kvs {
+ s := strings.SplitN(kv, "=", 2)
+ if len(s) < 2 {
+ return nil, fmt.Errorf("%w, got %s", errExpectedKV, kv)
+ }
+ k := s[0]
+ v := s[1]
+ ret[k] = v
+ }
+ return ret, nil
+}
+
+//nolint:gochecknoinits
+func init() {
+ fsUpdateUserMetadataCmd.Flags().StringSliceP("metadata", "", nil, "Metadata to set, in the form key1=value1,key2=value2")
+ fsCmd.AddCommand(fsUpdateUserMetadataCmd)
+}
diff --git a/docs/assets/js/swagger.yml b/docs/assets/js/swagger.yml
index 47624672337..e6eb6e905ee 100644
--- a/docs/assets/js/swagger.yml
+++ b/docs/assets/js/swagger.yml
@@ -347,6 +347,15 @@ components:
items:
$ref: "#/components/schemas/ObjectStats"
+ UpdateObjectUserMetadata:
+ type: object
+ required:
+ - set
+ properties:
+ set:
+ description: Set this object user metadata
+ $ref: "#/components/schemas/ObjectUserMetadata"
+
ObjectCopyCreation:
type: object
required:
@@ -4993,6 +5002,51 @@ paths:
default:
$ref: "#/components/responses/ServerError"
+ /repositories/{repository}/branches/{branch}/objects/stat/user_metadata:
+ parameters:
+ - in: path
+ name: repository
+ required: true
+ schema:
+ type: string
+ - in: path
+ name: branch
+ required: true
+ schema:
+ type: string
+ description: branch to update
+ - in: query
+ name: path
+ description: path to object relative to the branch
+ required: true
+ schema:
+ type: string
+ put:
+ tags:
+ - objects
+ - experimental
+ operationId: updateObjectUserMetadata
+ summary: rewrite (all) object metadata
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/UpdateObjectUserMetadata"
+ responses:
+ 201:
+ description: User metadata updated
+ 401:
+ $ref: "#/components/responses/Unauthorized"
+ 404:
+ $ref: "#/components/responses/NotFound"
+ 400:
+ $ref: "#/components/responses/BadRequest"
+ 420:
+ description: too many requests
+ default:
+ $ref: "#/components/responses/ServerError"
+
/repositories/{repository}/refs/{ref}/objects/underlyingProperties:
parameters:
- in: path
diff --git a/docs/reference/cli.md b/docs/reference/cli.md
index fd31e6b916b..b5cfcae51fa 100644
--- a/docs/reference/cli.md
+++ b/docs/reference/cli.md
@@ -2293,6 +2293,27 @@ lakectl fs stat [flags]
+### lakectl fs update-metadata
+
+**note:** This command is a lakeFS plumbing command. Don't use it unless you're really sure you know what you're doing.
+{: .note .note-warning }
+
+Update user metadata on the specified URI
+
+```
+lakectl fs update-metadata [flags]
+```
+
+#### Options
+{:.no_toc}
+
+```
+ -h, --help help for update-metadata
+ --metadata strings Metadata to set, in the form key1=value1,key2=value2
+```
+
+
+
### lakectl fs upload
Upload a local file to the specified URI
diff --git a/pkg/api/controller.go b/pkg/api/controller.go
index 0c6ca2606d9..9972cad616e 100644
--- a/pkg/api/controller.go
+++ b/pkg/api/controller.go
@@ -4689,6 +4689,35 @@ func (c *Controller) StatObject(w http.ResponseWriter, r *http.Request, reposito
writeResponse(w, r, code, objStat)
}
+func (c *Controller) UpdateObjectUserMetadata(w http.ResponseWriter, r *http.Request, body apigen.UpdateObjectUserMetadataJSONRequestBody, repository, branch string, params apigen.UpdateObjectUserMetadataParams) {
+ if !c.authorize(w, r, permissions.Node{
+ Permission: permissions.Permission{
+ Action: permissions.WriteObjectAction,
+ Resource: permissions.ObjectArn(repository, params.Path),
+ },
+ }) {
+ return
+ }
+ ctx := r.Context()
+ c.LogAction(ctx, "update_object_user_metadata", r, repository, branch, "")
+
+ // read all the _other_ metadata. Does not require checking read
+ // permissions, as the caller will never see this.
+ entry, err := c.Catalog.GetEntry(ctx, repository, branch, params.Path, catalog.GetEntryParams{})
+ if c.handleAPIError(ctx, w, r, err) {
+ return
+ }
+
+ entry.Metadata = catalog.Metadata(body.Set.AdditionalProperties)
+
+ err = c.Catalog.CreateEntry(ctx, repository, branch, *entry)
+ if c.handleAPIError(ctx, w, r, err) {
+ return
+ }
+
+ writeResponse(w, r, http.StatusNoContent, nil)
+}
+
func (c *Controller) GetUnderlyingProperties(w http.ResponseWriter, r *http.Request, repository, ref string, params apigen.GetUnderlyingPropertiesParams) {
if !c.authorize(w, r, permissions.Node{
Permission: permissions.Permission{
diff --git a/pkg/api/controller_test.go b/pkg/api/controller_test.go
index 4212400ffb0..bd9aefaaf9a 100644
--- a/pkg/api/controller_test.go
+++ b/pkg/api/controller_test.go
@@ -2289,6 +2289,83 @@ func TestController_ObjectsStatObjectHandler(t *testing.T) {
})
}
+func TestController_UpdateObjectUserMetadataHander(t *testing.T) {
+ clt, deps := setupClientWithAdmin(t)
+ ctx := context.Background()
+
+ repo := testUniqueRepoName()
+ _, err := deps.catalog.CreateRepository(ctx, repo, onBlock(deps, "some-bucket"), "main", false)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ t.Run("update metadata", func(t *testing.T) {
+ const objPath = "foo/bar"
+ entry := catalog.DBEntry{
+ Path: objPath,
+ PhysicalAddress: "this_is_bars_address",
+ CreationDate: time.Now(),
+ Size: 666,
+ Checksum: "this_is_a_checksum",
+ }
+ testutil.Must(t, deps.catalog.CreateEntry(ctx, repo, "main", entry))
+
+ userMetadataMap := map[string]string{
+ "foo": "bar",
+ "baz": "quux",
+ }
+
+ body := apigen.UpdateObjectUserMetadataJSONRequestBody{
+ Set: apigen.ObjectUserMetadata{
+ AdditionalProperties: userMetadataMap,
+ },
+ }
+
+ resp, err := clt.UpdateObjectUserMetadataWithResponse(ctx, repo, "main",
+ &apigen.UpdateObjectUserMetadataParams{Path: objPath},
+ body,
+ )
+ verifyResponseOK(t, resp, err)
+
+ // Verify that it was set
+ statResp, err := clt.StatObjectWithResponse(ctx, repo, "main",
+ &apigen.StatObjectParams{
+ Path: objPath,
+ UserMetadata: swag.Bool(true),
+ },
+ )
+ verifyResponseOK(t, statResp, err)
+ objectStats := statResp.JSON200
+ if diffs := deep.Equal(objectStats.Metadata.AdditionalProperties, userMetadataMap); diffs != nil {
+ t.Errorf("did not get expected metadata, diffs %s", diffs)
+ }
+ })
+
+ t.Run("update metadata not found", func(t *testing.T) {
+ const objPath = "foo/not/found/bar"
+
+ userMetadata := map[string]string{
+ "foo": "bar",
+ "baz": "quux",
+ }
+
+ body := apigen.UpdateObjectUserMetadataJSONRequestBody{
+ Set: apigen.ObjectUserMetadata{
+ AdditionalProperties: userMetadata,
+ },
+ }
+
+ resp, err := clt.UpdateObjectUserMetadataWithResponse(ctx, repo, "main",
+ &apigen.UpdateObjectUserMetadataParams{Path: objPath},
+ body,
+ )
+ testutil.Must(t, err)
+ if resp.JSON404 == nil {
+ t.Errorf("Expected 404, got %+v", resp)
+ }
+ })
+}
+
func TestController_ObjectsListObjectsHandler(t *testing.T) {
clt, deps := setupClientWithAdmin(t)
ctx := context.Background()