use of ml.comet.experiment.artifact.Artifact in project comet-java-sdk by comet-ml.
the class BaseExperiment method upsertArtifact.
/**
* Synchronously upsert provided Comet artifact into Comet backend.
*
* @param artifact the {@link ArtifactImpl} instance.
* @return the {@link ArtifactEntry} describing saved artifact.
* @throws ArtifactException if operation failed.
*/
ArtifactEntry upsertArtifact(@NonNull final Artifact artifact) throws ArtifactException {
try {
ArtifactImpl artifactImpl = (ArtifactImpl) artifact;
ArtifactRequest request = createArtifactUpsertRequest(artifactImpl);
ArtifactEntry response = validateAndGetExperimentKey().concatMap(experimentKey -> getRestApiClient().upsertArtifact(request, experimentKey)).blockingGet();
if (StringUtils.isBlank(response.getPreviousVersion())) {
getLogger().info(getString(ARTIFACT_VERSION_CREATED_WITHOUT_PREVIOUS, artifactImpl.getName(), response.getCurrentVersion()));
} else {
getLogger().info(getString(ARTIFACT_VERSION_CREATED_WITH_PREVIOUS, artifactImpl.getName(), response.getCurrentVersion(), response.getPreviousVersion()));
}
return response;
} catch (Throwable e) {
throw new ArtifactException(getString(FAILED_TO_UPSERT_ARTIFACT, artifact), e);
}
}
use of ml.comet.experiment.artifact.Artifact in project comet-java-sdk by comet-ml.
the class ArtifactSupportTest method testLogAndGetArtifact.
@Test
public void testLogAndGetArtifact() {
try (OnlineExperimentImpl experiment = (OnlineExperimentImpl) createOnlineExperiment()) {
ArtifactImpl artifact = createArtifact();
// add remote assets
//
URI firstAssetLink = new URI("s3://bucket/folder/firstAssetFile.extension");
String firstAssetFileName = "firstAssetFileName";
artifact.addRemoteAsset(firstAssetLink, firstAssetFileName);
String secondAssetExpectedFileName = "secondAssetFile.extension";
URI secondAssetLink = new URI("s3://bucket/folder/" + secondAssetExpectedFileName);
artifact.addRemoteAsset(secondAssetLink, secondAssetExpectedFileName);
// add local assets
//
artifact.addAsset(Objects.requireNonNull(TestUtils.getFile(IMAGE_FILE_NAME)), IMAGE_FILE_NAME, false, SOME_METADATA);
artifact.addAsset(Objects.requireNonNull(TestUtils.getFile(CODE_FILE_NAME)), CODE_FILE_NAME, false);
byte[] someData = "some data".getBytes(StandardCharsets.UTF_8);
String someDataName = "someDataName";
artifact.addAsset(someData, someDataName);
// add assets folder
//
artifact.addAssetFolder(assetsFolder.toFile(), true, true);
// the logged artifact validator
Function4<LoggedArtifact, ArtifactImpl, String, List<String>, Void> loggedArtifactValidator = (actual, original, experimentKey, expectedAliases) -> {
assertNotNull(actual, "logged artifact expected");
assertEquals(original.getType(), actual.getArtifactType(), "wrong artifact type");
assertEquals(new HashSet<>(expectedAliases), actual.getAliases(), "wrong aliases");
assertEquals(SOME_METADATA, actual.getMetadata(), "wrong metadata");
assertEquals(new HashSet<>(original.getVersionTags()), actual.getVersionTags(), "wrong version tags");
assertEquals(WORKSPACE_NAME, actual.getWorkspace(), "wrong workspace");
assertEquals(experimentKey, actual.getSourceExperimentKey(), "wrong experiment key");
assertEquals(original.getName(), actual.getName(), "wrong artifact name");
return null;
};
// check artifacts-in-progress counter before
assertEquals(0, experiment.getArtifactsInProgress().get(), "artifacts-in-progress counter must be zero at start");
// log artifact and check results
//
CompletableFuture<LoggedArtifact> futureArtifact = experiment.logArtifact(artifact);
// check artifacts-in-progress counter while in progress
assertEquals(1, experiment.getArtifactsInProgress().get(), "artifacts-in-progress counter has wrong value while still in progress");
LoggedArtifact loggedArtifact = futureArtifact.get(60, SECONDS);
// check artifacts-in-progress counter after
Awaitility.await("artifacts-in-progress counter must be decreased").pollInterval(10, TimeUnit.MILLISECONDS).atMost(1, TimeUnit.SECONDS).until(() -> experiment.getArtifactsInProgress().get() == 0);
assertEquals(0, experiment.getArtifactsInProgress().get(), "artifacts-in-progress counter must be zero after log operation completed");
List<String> expectedAliases = new ArrayList<>(artifact.getAliases());
loggedArtifactValidator.apply(loggedArtifact, artifact, experiment.getExperimentKey(), expectedAliases);
// get artifact details from server and check its correctness
//
LoggedArtifact loggedArtifactFromServer = experiment.getArtifact(loggedArtifact.getName(), loggedArtifact.getWorkspace(), loggedArtifact.getVersion());
// added by the backend automatically
expectedAliases.add(ALIAS_LATEST);
loggedArtifactValidator.apply(loggedArtifactFromServer, artifact, experiment.getExperimentKey(), expectedAliases);
// check that correct assets was logged
//
Collection<LoggedArtifactAsset> loggedAssets = loggedArtifactFromServer.getAssets();
Collection<ArtifactAsset> assets = artifact.getAssets();
assertEquals(assets.size(), loggedAssets.size(), "wrong size");
loggedAssets.forEach(loggedArtifactAsset -> validateArtifactAsset(new ArtifactAssetImpl((LoggedArtifactAssetImpl) loggedArtifactAsset), assets));
} catch (Throwable t) {
fail(t);
}
}
use of ml.comet.experiment.artifact.Artifact in project comet-java-sdk by comet-ml.
the class BaseExperiment method getArtifactVersionDetail.
/**
* Synchronously retrieves all data about a specific Artifact Version.
*
* @param options the {@link GetArtifactOptions} defining query options.
* @return the {@link LoggedArtifact} instance holding all data about a specific Artifact Version.
* @throws ArtifactNotFoundException if artifact is not found or no artifact data returned.
* @throws InvalidArtifactStateException if artifact was not closed or has empty artifact data returned.
* @throws ArtifactException if failed to get artifact due to the unexpected error.
*/
LoggedArtifact getArtifactVersionDetail(@NonNull GetArtifactOptions options) throws ArtifactNotFoundException, InvalidArtifactStateException, ArtifactException {
try {
ArtifactVersionDetail detail = validateAndGetExperimentKey().concatMap(experimentKey -> getRestApiClient().getArtifactVersionDetail(options, experimentKey)).blockingGet();
ArtifactDto artifactDto = detail.getArtifact();
if (artifactDto == null) {
throw new InvalidArtifactStateException(getString(ARTIFACT_HAS_NO_DETAILS, options));
}
return detail.copyToLoggedArtifact(new LoggedArtifactImpl(artifactDto.getArtifactName(), artifactDto.getArtifactType(), this));
} catch (CometApiException apiException) {
switch(apiException.getSdkErrorCode()) {
case noArtifactFound:
throw new ArtifactNotFoundException(getString(ARTIFACT_NOT_FOUND, options), apiException);
case artifactVersionStateNotClosed:
case artifactVersionStateNotClosedErrorOccurred:
throw new InvalidArtifactStateException(getString(ARTIFACT_NOT_READY, options), apiException);
default:
throw new ArtifactException(getString(GET_ARTIFACT_FAILED_UNEXPECTEDLY, options), apiException);
}
} catch (Throwable e) {
throw new ArtifactException(getString(GET_ARTIFACT_FAILED_UNEXPECTEDLY, options), e);
}
}
use of ml.comet.experiment.artifact.Artifact in project comet-java-sdk by comet-ml.
the class BaseExperimentAsync method sendArtifactAssetAsync.
/**
* Attempts to send given {@link ArtifactAsset} or its subclass asynchronously.
*
* @param asset the artifact asset.
* @param <T> the type of the artifact asset.
* @return the {@link Single} which can be used to subscribe for operation results.
*/
private <T extends ArtifactAsset> Single<RestApiResponse> sendArtifactAssetAsync(@NonNull final T asset) {
Single<RestApiResponse> single;
Scheduler scheduler = Schedulers.io();
if (asset.isRemote()) {
// remote asset
single = validateAndGetExperimentKey().subscribeOn(scheduler).concatMap(experimentKey -> getRestApiClient().logRemoteAsset((RemoteAsset) asset, experimentKey));
} else {
// local asset
single = validateAndGetExperimentKey().subscribeOn(scheduler).concatMap(experimentKey -> getRestApiClient().logAsset(asset, experimentKey));
}
return single.doOnSuccess(restApiResponse -> checkAndLogAssetResponse(restApiResponse, getLogger(), asset)).doOnError(throwable -> getLogger().error(getString(FAILED_TO_SEND_LOG_ARTIFACT_ASSET_REQUEST, asset), throwable));
}
use of ml.comet.experiment.artifact.Artifact in project comet-java-sdk by comet-ml.
the class ArtifactExample method run.
private static void run(OnlineExperiment experiment) throws Exception {
experiment.setExperimentName("Artifact Example");
Map<String, Object> metadata = BaseExample.createMetaData();
List<String> aliases = Arrays.asList("alias1", "alias2");
List<String> tags = Arrays.asList("tag1", "tag2");
String artifactName = "someArtifact";
String artifactType = "someType";
Artifact artifact = Artifact.newArtifact(artifactName, artifactType).withAliases(aliases).withVersionTags(tags).withMetadata(metadata).build();
// add remote assets
//
URI firstAssetLink = new URI("s3://bucket/folder/firstAssetFile.extension");
String firstAssetFileName = "firstAssetFileName";
artifact.addRemoteAsset(firstAssetLink, firstAssetFileName);
String secondAssetExpectedFileName = "secondAssetFile.extension";
URI secondAssetLink = new URI("s3://bucket/folder/" + secondAssetExpectedFileName);
artifact.addRemoteAsset(secondAssetLink, secondAssetExpectedFileName);
// add local assets
//
artifact.addAsset(getResourceFile(CHART_IMAGE_FILE), AMAZING_CHART_NAME, false, metadata);
artifact.addAsset(getResourceFile(MODEL_FILE), false);
byte[] someData = "some data".getBytes(StandardCharsets.UTF_8);
String someDataName = "someDataName";
artifact.addAsset(someData, someDataName);
// add assets folder
//
Path assetDir = BaseExample.copyResourcesToTmpDir();
artifact.addAssetFolder(assetDir.toFile(), true, true);
// log artifact
//
CompletableFuture<LoggedArtifact> futureArtifact = experiment.logArtifact(artifact);
LoggedArtifact loggedArtifact = futureArtifact.get(60, SECONDS);
System.out.printf("\nArtifact upload complete: %s\n\n", loggedArtifact.getFullName());
// get logged assets
//
Collection<LoggedArtifactAsset> loggedAssets = loggedArtifact.getAssets();
System.out.printf("Received %d logged artifact assets from the Comet server. Downloading asset files...\n", loggedAssets.size());
// download artifact assets to the local directory one by one
//
final Path assetsTmpDir = Files.createTempDirectory("ArtifactExampleAssets");
loggedAssets.forEach(loggedArtifactAsset -> {
if (!loggedArtifactAsset.isRemote()) {
ArtifactAsset asset = loggedArtifactAsset.download(assetsTmpDir);
System.out.printf("Downloaded asset '%s' of size %d bytes to '%s'\n", asset.getLogicalPath(), asset.getSize().orElse(0L), asset.getFile());
} else {
URI uri = loggedArtifactAsset.getLink().orElse(null);
System.out.printf("Skipping download of the remote asset %s. It must be downloaded using its URI '%s'\n", loggedArtifactAsset.getLogicalPath(), uri);
}
});
System.out.printf("Assets of the artifact's '%s' successfully downloaded to the folder: %s\n\n", loggedArtifact.getFullName(), assetsTmpDir);
// load content of the artifact asset into the memory
//
LoggedArtifactAsset asset = loggedAssets.stream().filter(loggedArtifactAsset -> {
Long size = loggedArtifactAsset.getSize().orElse(0L);
return !loggedArtifactAsset.isRemote() && size > 0;
}).findFirst().orElse(null);
if (asset != null) {
System.out.printf("Loading content of the artifact asset '%s' into memory\n", asset.getAssetId());
int buffSize = 512;
try (InputStream in = new BufferedInputStream(asset.openStream(), buffSize)) {
// work with input stream
byte[] buff = IOUtils.byteArray(buffSize);
ByteArrayOutputStream out = new ByteArrayOutputStream();
for (int count; (count = in.read(buff)) > 0; ) {
out.write(buff, 0, count);
}
System.out.printf("Content of the asset '%s' successfully loaded into memory, data size: %d.\n\n", asset.getLogicalPath(), out.size());
} catch (Throwable t) {
System.err.printf("Failed to read asset data, reason: %s\n\n", t);
throw t;
}
}
// download artifact to the local directory
//
final Path artifactTmpDir = Files.createTempDirectory("ArtifactExampleArtifact");
System.out.printf("Downloading artifact to the folder: %s\n", artifactTmpDir.toFile().getAbsoluteFile());
DownloadedArtifact downloadedArtifact = loggedArtifact.download(artifactTmpDir, AssetOverwriteStrategy.FAIL_IF_DIFFERENT);
Collection<ArtifactAsset> assets = downloadedArtifact.getAssets();
System.out.printf("Artifact '%s' successfully downloaded. Received %d artifact assets from the Comet server.\n\n", downloadedArtifact.getFullName(), assets.size());
// update downloaded artifact
//
System.out.printf("Starting update of the artifact: %s\n", downloadedArtifact.getFullName());
downloadedArtifact.getAliases().add("downloaded");
downloadedArtifact.getMetadata().put("updated", "someUpdatedValue");
downloadedArtifact.addAsset(getResourceFile(GRAPH_JSON_FILE), "updated_graph.json", false, metadata);
downloadedArtifact.incrementMinorVersion();
CompletableFuture<LoggedArtifact> futureUpdatedArtifact = experiment.logArtifact(downloadedArtifact);
loggedArtifact = futureUpdatedArtifact.get(60, SECONDS);
System.out.printf("\nArtifact update completed, new artifact version created: %s\n\n", loggedArtifact.getFullName());
// get artifact asset by logical path
//
System.out.printf("Finding asset '%s' of the artifact: %s\n", AMAZING_CHART_NAME, loggedArtifact.getFullName());
asset = loggedArtifact.getAsset(AMAZING_CHART_NAME);
System.out.printf("Successfully found asset '%s' of the artifact: %s\n\n", asset, loggedArtifact.getFullName());
System.out.println("===== Experiment completed ====");
}
Aggregations