Search in sources :

Example 6 with ArtifactAsset

use of ml.comet.experiment.artifact.ArtifactAsset in project comet-java-sdk by comet-ml.

the class ArtifactSupportTest method testLogAndUpdateArtifact.

@Test
@Timeout(value = 300, unit = SECONDS)
void testLogAndUpdateArtifact() throws IOException {
    Path tmpDir = Files.createTempDirectory("testLogAndUpdateArtifact");
    try (OnlineExperimentImpl experiment = (OnlineExperimentImpl) createOnlineExperiment()) {
        ArtifactImpl artifact = createArtifact();
        // add local assets
        // 
        File imageFile = TestUtils.getFile(IMAGE_FILE_NAME);
        assertNotNull(imageFile);
        artifact.addAsset(imageFile, IMAGE_FILE_NAME, false, SOME_METADATA);
        File textFile = TestUtils.getFile(SOME_TEXT_FILE_NAME);
        assertNotNull(textFile);
        artifact.addAsset(textFile, SOME_TEXT_FILE_NAME, false, SOME_METADATA);
        // log artifact and check results
        // 
        CompletableFuture<LoggedArtifact> futureArtifact = experiment.logArtifact(artifact);
        LoggedArtifact loggedArtifact = futureArtifact.get(60, SECONDS);
        // download artifact and check that file was preserved
        // 
        DownloadedArtifact downloadedArtifact = loggedArtifact.download(tmpDir, AssetOverwriteStrategy.PRESERVE);
        assertNotNull(downloadedArtifact, "downloaded artifact expected");
        int originalAssetsCount = 2;
        assertEquals(originalAssetsCount, downloadedArtifact.getAssets().size(), "downloaded artifact has wrong assets size");
        // update artifact
        // 
        Set<String> newTags = new HashSet<>(Collections.singletonList("downloaded tag"));
        downloadedArtifact.setVersionTags(newTags);
        String extraAlias = "downloaded alias";
        assertTrue(downloadedArtifact.getAliases().add(extraAlias), "failed to add alias");
        String extraKey = "downloaded key";
        String extraMetaValue = "some value";
        downloadedArtifact.getMetadata().put(extraKey, extraMetaValue);
        downloadedArtifact.addAsset(Objects.requireNonNull(TestUtils.getFile(CODE_FILE_NAME)), CODE_FILE_NAME, false);
        downloadedArtifact.incrementMinorVersion();
        String newArtifactVersion = downloadedArtifact.getVersion();
        Collection<ArtifactAsset> assets = downloadedArtifact.getAssets();
        assertEquals(originalAssetsCount + 1, assets.size(), "wrong number of assets after update");
        // log downloaded artifact
        // 
        CompletableFuture<LoggedArtifact> futureUpdatedArtifact = experiment.logArtifact(downloadedArtifact);
        loggedArtifact = futureUpdatedArtifact.get(60, SECONDS);
        // read artifact from server and check that it was actually updated
        LoggedArtifact loggedArtifactFromServer = experiment.getArtifact(loggedArtifact.getName(), loggedArtifact.getWorkspace(), loggedArtifact.getVersion());
        assertEquals(newArtifactVersion, loggedArtifactFromServer.getVersion(), "wrong version");
        assertEquals(newTags, loggedArtifactFromServer.getVersionTags(), "wrong version tags");
        Set<String> expectedAliases = new HashSet<>(artifact.getAliases());
        expectedAliases.add(extraAlias);
        expectedAliases.add(ALIAS_LATEST);
        assertEquals(expectedAliases, loggedArtifactFromServer.getAliases(), "wrong aliases");
        Map<String, Object> expectedMetadata = new HashMap<>(artifact.getMetadata());
        expectedMetadata.put(extraKey, extraMetaValue);
        assertEquals(expectedMetadata, loggedArtifactFromServer.getMetadata(), "wrong metadata");
        // get assets from server and check that all assets are correct including new one
        Collection<LoggedArtifactAsset> loggedAssets = loggedArtifactFromServer.getAssets();
        assertNotNull(loggedAssets, "assets expected");
        assertEquals(assets.size(), loggedAssets.size(), "wrong assets size");
        loggedAssets.forEach(loggedArtifactAsset -> validateArtifactAsset(new ArtifactAssetImpl((LoggedArtifactAssetImpl) loggedArtifactAsset), assets));
    } catch (Throwable t) {
        fail(t);
    } finally {
        PathUtils.delete(tmpDir);
    }
}
Also used : Path(java.nio.file.Path) LoggedArtifact(ml.comet.experiment.artifact.LoggedArtifact) LoggedArtifactAsset(ml.comet.experiment.artifact.LoggedArtifactAsset) ArtifactAsset(ml.comet.experiment.artifact.ArtifactAsset) HashMap(java.util.HashMap) LogMessages.getString(ml.comet.experiment.impl.resources.LogMessages.getString) DownloadedArtifact(ml.comet.experiment.artifact.DownloadedArtifact) LoggedArtifactAsset(ml.comet.experiment.artifact.LoggedArtifactAsset) ArtifactAssetImpl(ml.comet.experiment.impl.asset.ArtifactAssetImpl) File(java.io.File) HashSet(java.util.HashSet) Test(org.junit.jupiter.api.Test) Timeout(org.junit.jupiter.api.Timeout)

Example 7 with ArtifactAsset

use of ml.comet.experiment.artifact.ArtifactAsset in project comet-java-sdk by comet-ml.

the class ArtifactImpl method appendAsset.

<T extends ArtifactAsset> void appendAsset(@NonNull final T asset) throws ConflictingArtifactAssetNameException {
    String key = asset.getLogicalPath();
    ArtifactAsset a = this.assetsMap.get(key);
    if (a != null) {
        throw new ConflictingArtifactAssetNameException(getString(CONFLICTING_ARTIFACT_ASSET_NAME, asset, key, a));
    }
    this.assetsMap.put(key, asset);
}
Also used : ArtifactAsset(ml.comet.experiment.artifact.ArtifactAsset) ConflictingArtifactAssetNameException(ml.comet.experiment.artifact.ConflictingArtifactAssetNameException) LogMessages.getString(ml.comet.experiment.impl.resources.LogMessages.getString)

Example 8 with ArtifactAsset

use of ml.comet.experiment.artifact.ArtifactAsset in project comet-java-sdk by comet-ml.

the class BaseExperiment method downloadArtifactAsset.

/**
 * Allows to synchronously download specific {@link LoggedArtifactAsset} to the local file system.
 *
 * @param asset             the asset to be downloaded.
 * @param dir               the parent directory where asset file should be stored.
 * @param file              the relative path to the asset file.
 * @param overwriteStrategy the overwrite strategy to be applied if file already exists.
 * @return the {@link ArtifactAsset} instance with details about downloaded asset file.
 * @throws ArtifactDownloadException if failed to download asset.
 */
ArtifactAssetImpl downloadArtifactAsset(@NonNull LoggedArtifactAssetImpl asset, @NonNull Path dir, @NonNull Path file, @NonNull AssetOverwriteStrategy overwriteStrategy) throws ArtifactDownloadException {
    if (asset.isRemote()) {
        throw new ArtifactDownloadException(getString(REMOTE_ASSET_CANNOT_BE_DOWNLOADED, asset));
    }
    Path resolved;
    boolean fileAlreadyExists = false;
    try {
        Optional<Path> optionalPath = FileUtils.resolveAssetPath(dir, file, overwriteStrategy);
        if (optionalPath.isPresent()) {
            // new or overwrite
            resolved = optionalPath.get();
            if (overwriteStrategy == AssetOverwriteStrategy.OVERWRITE) {
                getLogger().warn(getString(ARTIFACT_DOWNLOAD_FILE_OVERWRITTEN, resolved, asset.getLogicalPath(), asset.artifact.getFullName()));
            }
        } else {
            // preventing original file - just warning and return FileAsset pointing to it
            resolved = dir.resolve(file);
            this.getLogger().warn(getString(ARTIFACT_ASSETS_FILE_EXISTS_PRESERVING, resolved, asset.artifact.getFullName()));
            return new ArtifactAssetImpl(asset.getLogicalPath(), resolved, Files.size(resolved), asset.getMetadata(), asset.getAssetType());
        }
    } catch (FileAlreadyExistsException e) {
        if (overwriteStrategy == AssetOverwriteStrategy.FAIL_IF_DIFFERENT) {
            try {
                resolved = Files.createTempFile(asset.getLogicalPath(), null);
                this.getLogger().debug("File '{}' already exists for asset {} and FAIL override strategy selected. " + "Start downloading to the temporary file '{}'", file, asset, resolved);
            } catch (IOException ex) {
                String msg = getString(FAILED_TO_CREATE_TEMPORARY_ASSET_DOWNLOAD_FILE, file, asset);
                this.getLogger().error(msg, ex);
                throw new ArtifactDownloadException(msg, ex);
            }
            fileAlreadyExists = true;
        } else {
            this.getLogger().error(getString(FAILED_TO_DOWNLOAD_ASSET_FILE_ALREADY_EXISTS, asset, file), e);
            throw new ArtifactDownloadException(getString(FAILED_TO_DOWNLOAD_ASSET_FILE_ALREADY_EXISTS, asset, file), e);
        }
    } catch (IOException e) {
        this.getLogger().error(getString(FAILED_TO_RESOLVE_ASSET_FILE, file, asset), e);
        throw new ArtifactDownloadException(getString(FAILED_TO_RESOLVE_ASSET_FILE, file, asset), e);
    }
    DownloadArtifactAssetOptions opts = new DownloadArtifactAssetOptions(asset.getAssetId(), asset.getArtifactVersionId(), resolved.toFile());
    RestApiResponse response = validateAndGetExperimentKey().concatMap(experimentKey -> getRestApiClient().downloadArtifactAsset(opts, experimentKey)).blockingGet();
    if (response.hasFailed()) {
        this.getLogger().error(getString(FAILED_TO_DOWNLOAD_ASSET, asset, response));
        throw new ArtifactDownloadException(getString(FAILED_TO_DOWNLOAD_ASSET, asset, response));
    }
    // this is just to mirror the Python SDK's behavior - potential performance bottleneck and system resource eater
    if (fileAlreadyExists) {
        Path assetFilePath = FileUtils.assetFilePath(dir, file);
        try {
            if (!FileUtils.fileContentsEquals(assetFilePath, resolved)) {
                this.getLogger().error(getString(FAILED_TO_DOWNLOAD_ASSET_FILE_ALREADY_EXISTS, asset, file));
                throw new ArtifactDownloadException(getString(FAILED_TO_DOWNLOAD_ASSET_FILE_ALREADY_EXISTS, asset, file));
            }
        } catch (IOException e) {
            this.getLogger().error(getString(FAILED_TO_COMPARE_CONTENT_OF_FILES, file, resolved), e);
            throw new ArtifactDownloadException(getString(FAILED_TO_COMPARE_CONTENT_OF_FILES, file, resolved), e);
        } finally {
            try {
                Files.deleteIfExists(resolved);
            } catch (IOException e) {
                this.getLogger().error(getString(FAILED_TO_DELETE_TEMPORARY_ASSET_FILE, resolved, asset), e);
            }
        }
        resolved = assetFilePath;
    }
    getLogger().info(getString(COMPLETED_DOWNLOAD_ARTIFACT_ASSET, asset.getLogicalPath(), resolved));
    try {
        return new ArtifactAssetImpl(asset.getLogicalPath(), resolved, Files.size(resolved), asset.getMetadata(), asset.getAssetType());
    } catch (IOException e) {
        this.getLogger().error(getString(FAILED_TO_READ_DOWNLOADED_FILE_SIZE, resolved), e);
        throw new ArtifactDownloadException(getString(FAILED_TO_READ_DOWNLOADED_FILE_SIZE, resolved), e);
    }
}
Also used : Path(java.nio.file.Path) Connection(ml.comet.experiment.impl.http.Connection) RestApiUtils.createArtifactUpsertRequest(ml.comet.experiment.impl.utils.RestApiUtils.createArtifactUpsertRequest) LoggedExperimentAsset(ml.comet.experiment.asset.LoggedExperimentAsset) EXPERIMENT_LIVE(ml.comet.experiment.impl.resources.LogMessages.EXPERIMENT_LIVE) ArtifactDownloadException(ml.comet.experiment.artifact.ArtifactDownloadException) LoggedArtifactAsset(ml.comet.experiment.artifact.LoggedArtifactAsset) RestApiUtils.createLogEndTimeRequest(ml.comet.experiment.impl.utils.RestApiUtils.createLogEndTimeRequest) StringUtils(org.apache.commons.lang3.StringUtils) ExperimentMetadata(ml.comet.experiment.model.ExperimentMetadata) FAILED_TO_DOWNLOAD_ASSET_FILE_ALREADY_EXISTS(ml.comet.experiment.impl.resources.LogMessages.FAILED_TO_DOWNLOAD_ASSET_FILE_ALREADY_EXISTS) SOURCE_CODE(ml.comet.experiment.impl.asset.AssetType.SOURCE_CODE) RestApiUtils.createGraphRequest(ml.comet.experiment.impl.utils.RestApiUtils.createGraphRequest) Duration(java.time.Duration) RestApiUtils.createLogMetricRequest(ml.comet.experiment.impl.utils.RestApiUtils.createLogMetricRequest) Path(java.nio.file.Path) SdkErrorCodes.artifactVersionStateNotClosed(ml.comet.experiment.impl.constants.SdkErrorCodes.artifactVersionStateNotClosed) FAILED_TO_DELETE_TEMPORARY_ASSET_FILE(ml.comet.experiment.impl.resources.LogMessages.FAILED_TO_DELETE_TEMPORARY_ASSET_FILE) NonNull(lombok.NonNull) AssetUtils.createAssetFromData(ml.comet.experiment.impl.utils.AssetUtils.createAssetFromData) FAILED_TO_DOWNLOAD_ASSET(ml.comet.experiment.impl.resources.LogMessages.FAILED_TO_DOWNLOAD_ASSET) ARTIFACT_NOT_FOUND(ml.comet.experiment.impl.resources.LogMessages.ARTIFACT_NOT_FOUND) FAILED_TO_UPSERT_ARTIFACT(ml.comet.experiment.impl.resources.LogMessages.FAILED_TO_UPSERT_ARTIFACT) StandardCharsets(java.nio.charset.StandardCharsets) SdkErrorCodes.noArtifactFound(ml.comet.experiment.impl.constants.SdkErrorCodes.noArtifactFound) SdkErrorCodes.artifactVersionStateNotClosedErrorOccurred(ml.comet.experiment.impl.constants.SdkErrorCodes.artifactVersionStateNotClosedErrorOccurred) ARTIFACT_DOWNLOAD_FILE_OVERWRITTEN(ml.comet.experiment.impl.resources.LogMessages.ARTIFACT_DOWNLOAD_FILE_OVERWRITTEN) FAILED_TO_RESOLVE_ASSET_FILE(ml.comet.experiment.impl.resources.LogMessages.FAILED_TO_RESOLVE_ASSET_FILE) Experiment(ml.comet.experiment.Experiment) DownloadArtifactAssetOptions(ml.comet.experiment.impl.asset.DownloadArtifactAssetOptions) Optional.empty(java.util.Optional.empty) Single(io.reactivex.rxjava3.core.Single) FAILED_TO_COMPARE_CONTENT_OF_FILES(ml.comet.experiment.impl.resources.LogMessages.FAILED_TO_COMPARE_CONTENT_OF_FILES) ArtifactNotFoundException(ml.comet.experiment.artifact.ArtifactNotFoundException) ArtifactRequest(ml.comet.experiment.impl.rest.ArtifactRequest) ArrayList(java.util.ArrayList) Artifact(ml.comet.experiment.artifact.Artifact) ARTIFACT_VERSION_CREATED_WITHOUT_PREVIOUS(ml.comet.experiment.impl.resources.LogMessages.ARTIFACT_VERSION_CREATED_WITHOUT_PREVIOUS) SystemUtils(ml.comet.experiment.impl.utils.SystemUtils) ALL(ml.comet.experiment.impl.asset.AssetType.ALL) FAILED_REGISTER_EXPERIMENT(ml.comet.experiment.impl.resources.LogMessages.FAILED_REGISTER_EXPERIMENT) GitMetaData(ml.comet.experiment.model.GitMetaData) RestApiResponse(ml.comet.experiment.impl.rest.RestApiResponse) Files(java.nio.file.Files) IOException(java.io.IOException) ExperimentContext(ml.comet.experiment.context.ExperimentContext) File(java.io.File) ARTIFACT_NOT_READY(ml.comet.experiment.impl.resources.LogMessages.ARTIFACT_NOT_READY) ExecutionException(java.util.concurrent.ExecutionException) EXPERIMENT_CREATED(ml.comet.experiment.impl.resources.LogMessages.EXPERIMENT_CREATED) Function(io.reactivex.rxjava3.functions.Function) CometGeneralException(ml.comet.experiment.exception.CometGeneralException) AssetUtils.createAssetFromFile(ml.comet.experiment.impl.utils.AssetUtils.createAssetFromFile) ArtifactVersionAssetResponse(ml.comet.experiment.impl.rest.ArtifactVersionAssetResponse) ExperimentStatusResponse(ml.comet.experiment.impl.rest.ExperimentStatusResponse) ArtifactEntry(ml.comet.experiment.impl.rest.ArtifactEntry) RestApiUtils.createLogParamRequest(ml.comet.experiment.impl.utils.RestApiUtils.createLogParamRequest) RestApiUtils.createLogStartTimeRequest(ml.comet.experiment.impl.utils.RestApiUtils.createLogStartTimeRequest) AssetImpl(ml.comet.experiment.impl.asset.AssetImpl) LoggedArtifact(ml.comet.experiment.artifact.LoggedArtifact) ArtifactException(ml.comet.experiment.artifact.ArtifactException) RestApiUtils.createLogLineRequest(ml.comet.experiment.impl.utils.RestApiUtils.createLogLineRequest) RestApiUtils.createGitMetadataRequest(ml.comet.experiment.impl.utils.RestApiUtils.createGitMetadataRequest) ARTIFACT_VERSION_CREATED_WITH_PREVIOUS(ml.comet.experiment.impl.resources.LogMessages.ARTIFACT_VERSION_CREATED_WITH_PREVIOUS) CreateExperimentRequest(ml.comet.experiment.impl.rest.CreateExperimentRequest) ArtifactAsset(ml.comet.experiment.artifact.ArtifactAsset) LogMessages.getString(ml.comet.experiment.impl.resources.LogMessages.getString) Collection(java.util.Collection) RestApiUtils.createLogHtmlRequest(ml.comet.experiment.impl.utils.RestApiUtils.createLogHtmlRequest) ArtifactVersionDetail(ml.comet.experiment.impl.rest.ArtifactVersionDetail) GET_ARTIFACT_FAILED_UNEXPECTEDLY(ml.comet.experiment.impl.resources.LogMessages.GET_ARTIFACT_FAILED_UNEXPECTEDLY) Value(ml.comet.experiment.model.Value) List(java.util.List) FAILED_TO_CREATE_TEMPORARY_ASSET_DOWNLOAD_FILE(ml.comet.experiment.impl.resources.LogMessages.FAILED_TO_CREATE_TEMPORARY_ASSET_DOWNLOAD_FILE) FAILED_TO_READ_DOWNLOADED_FILE_SIZE(ml.comet.experiment.impl.resources.LogMessages.FAILED_TO_READ_DOWNLOADED_FILE_SIZE) BiFunction(io.reactivex.rxjava3.functions.BiFunction) Disposable(io.reactivex.rxjava3.disposables.Disposable) Optional(java.util.Optional) GetArtifactOptions(ml.comet.experiment.artifact.GetArtifactOptions) MinMaxResponse(ml.comet.experiment.impl.rest.MinMaxResponse) CreateExperimentResponse(ml.comet.experiment.impl.rest.CreateExperimentResponse) Getter(lombok.Getter) CompletableFuture(java.util.concurrent.CompletableFuture) ArtifactAssetImpl(ml.comet.experiment.impl.asset.ArtifactAssetImpl) ExceptionUtils(ml.comet.experiment.impl.utils.ExceptionUtils) AssetOverwriteStrategy(ml.comet.experiment.artifact.AssetOverwriteStrategy) ARTIFACT_HAS_NO_DETAILS(ml.comet.experiment.impl.resources.LogMessages.ARTIFACT_HAS_NO_DETAILS) RestApiUtils.createTagRequest(ml.comet.experiment.impl.utils.RestApiUtils.createTagRequest) InvalidArtifactStateException(ml.comet.experiment.artifact.InvalidArtifactStateException) REMOTE_ASSET_CANNOT_BE_DOWNLOADED(ml.comet.experiment.impl.resources.LogMessages.REMOTE_ASSET_CANNOT_BE_DOWNLOADED) COMPLETED_DOWNLOAD_ARTIFACT_ASSET(ml.comet.experiment.impl.resources.LogMessages.COMPLETED_DOWNLOAD_ARTIFACT_ASSET) FAILED_TO_UPDATE_ARTIFACT_VERSION_STATE(ml.comet.experiment.impl.resources.LogMessages.FAILED_TO_UPDATE_ARTIFACT_VERSION_STATE) ArtifactVersionState(ml.comet.experiment.impl.rest.ArtifactVersionState) RestApiUtils.createLogOtherRequest(ml.comet.experiment.impl.utils.RestApiUtils.createLogOtherRequest) RestApiUtils.createArtifactVersionStateRequest(ml.comet.experiment.impl.utils.RestApiUtils.createArtifactVersionStateRequest) ArtifactDto(ml.comet.experiment.impl.rest.ArtifactDto) CometUtils(ml.comet.experiment.impl.utils.CometUtils) ARTIFACT_ASSETS_FILE_EXISTS_PRESERVING(ml.comet.experiment.impl.resources.LogMessages.ARTIFACT_ASSETS_FILE_EXISTS_PRESERVING) Logger(org.slf4j.Logger) FileUtils(ml.comet.experiment.impl.utils.FileUtils) ConnectionInitializer(ml.comet.experiment.impl.http.ConnectionInitializer) FileAlreadyExistsException(java.nio.file.FileAlreadyExistsException) CometApiException(ml.comet.experiment.exception.CometApiException) FAILED_TO_READ_LOGGED_ARTIFACT_ASSETS(ml.comet.experiment.impl.resources.LogMessages.FAILED_TO_READ_LOGGED_ARTIFACT_ASSETS) FAILED_READ_DATA_FOR_EXPERIMENT(ml.comet.experiment.impl.resources.LogMessages.FAILED_READ_DATA_FOR_EXPERIMENT) FileAlreadyExistsException(java.nio.file.FileAlreadyExistsException) ArtifactAssetImpl(ml.comet.experiment.impl.asset.ArtifactAssetImpl) IOException(java.io.IOException) LogMessages.getString(ml.comet.experiment.impl.resources.LogMessages.getString) RestApiResponse(ml.comet.experiment.impl.rest.RestApiResponse) ArtifactDownloadException(ml.comet.experiment.artifact.ArtifactDownloadException) DownloadArtifactAssetOptions(ml.comet.experiment.impl.asset.DownloadArtifactAssetOptions)

Example 9 with ArtifactAsset

use of ml.comet.experiment.artifact.ArtifactAsset in project comet-java-sdk by comet-ml.

the class BaseExperimentAsync method logArtifact.

/**
 * Asynchronously logs provided {@link Artifact}. First it synchronously upserts the artifact into the Comet
 * backend. If successful then artifact assets uploaded to the server. Finally, the artifact status committed
 * to the backend to confirm transaction status.
 *
 * @param artifact   the Comet artifact to be sent to the server.
 * @param onComplete the optional {@link Action} to be called upon operation completed,
 *                   either successful or failure.
 * @return the instance of {@link CompletableFuture} which can be used to query for {@link LoggedArtifact} with
 * details about new artifact version.
 * @throws ArtifactException if operation failed.
 */
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
CompletableFuture<LoggedArtifact> logArtifact(@NonNull final Artifact artifact, @NonNull Optional<Action> onComplete) throws ArtifactException {
    // upsert artifact
    final ArtifactEntry entry = super.upsertArtifact(artifact);
    // get new artifact's version details
    final LoggedArtifactImpl loggedArtifact = (LoggedArtifactImpl) this.getArtifactVersionDetail(Op().artifactId(entry.getArtifactId()).versionId(entry.getArtifactVersionId()).build());
    // try to log artifact assets asynchronously
    final ArtifactImpl artifactImpl = (ArtifactImpl) artifact;
    if (artifactImpl.getAssets().size() == 0) {
        getLogger().warn(getString(ARTIFACT_LOGGED_WITHOUT_ASSETS, artifactImpl.getName()));
        return CompletableFuture.completedFuture(loggedArtifact);
    }
    getLogger().info(getString(ARTIFACT_UPLOAD_STARTED, loggedArtifact.getFullName(), artifactImpl.getAssets().size()));
    CompletableFuture<LoggedArtifact> future = new CompletableFuture<>();
    // upload artifact assets
    final String artifactVersionId = entry.getArtifactVersionId();
    Stream<ArtifactAsset> assets = artifactImpl.getAssets().stream().peek(asset -> ((ArtifactAssetImpl) asset).setArtifactVersionId(artifactVersionId));
    // create parallel execution flow with errors delaying
    // allowing processing of items even if some of them failed
    AtomicInteger successfullySentCount = new AtomicInteger();
    Observable<RestApiResponse> observable = Observable.fromStream(assets).flatMap(asset -> Observable.fromSingle(this.sendArtifactAssetAsync(asset).doOnSuccess(restApiResponse -> {
        if (!restApiResponse.hasFailed()) {
            successfullySentCount.incrementAndGet();
        }
    })), true);
    if (onComplete.isPresent()) {
        observable = observable.doFinally(onComplete.get());
    }
    // subscribe to get processing results
    // noinspection ResultOfMethodCallIgnored
    observable.ignoreElements().subscribe(() -> {
        getLogger().info(getString(ARTIFACT_UPLOAD_COMPLETED, loggedArtifact.getFullName(), successfullySentCount.get()));
        // mark artifact version status as closed
        this.updateArtifactVersionState(loggedArtifact, ArtifactVersionState.CLOSED, future);
        // mark future as completed
        if (!future.isCompletedExceptionally()) {
            future.complete(loggedArtifact);
        }
    }, (throwable) -> {
        getLogger().error(getString(FAILED_TO_UPLOAD_SOME_ARTIFACT_ASSET, loggedArtifact.getFullName()), throwable);
        // mark artifact version status as failed
        this.updateArtifactVersionState(loggedArtifact, ArtifactVersionState.ERROR, future);
        // mark future as failed
        if (!future.isCompletedExceptionally()) {
            future.obtrudeException(throwable);
        }
    });
    return future;
}
Also used : ArtifactEntry(ml.comet.experiment.impl.rest.ArtifactEntry) LoggedArtifact(ml.comet.experiment.artifact.LoggedArtifact) CompletableFuture(java.util.concurrent.CompletableFuture) ArtifactAsset(ml.comet.experiment.artifact.ArtifactAsset) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) LogMessages.getString(ml.comet.experiment.impl.resources.LogMessages.getString) RestApiResponse(ml.comet.experiment.impl.rest.RestApiResponse)

Example 10 with ArtifactAsset

use of ml.comet.experiment.artifact.ArtifactAsset 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));
}
Also used : RestApiUtils.createLogParamRequest(ml.comet.experiment.impl.utils.RestApiUtils.createLogParamRequest) RestApiUtils.createLogStartTimeRequest(ml.comet.experiment.impl.utils.RestApiUtils.createLogStartTimeRequest) AssetImpl(ml.comet.experiment.impl.asset.AssetImpl) RemoteAssetImpl(ml.comet.experiment.impl.asset.RemoteAssetImpl) FAILED_TO_FINALIZE_ARTIFACT_VERSION(ml.comet.experiment.impl.resources.LogMessages.FAILED_TO_FINALIZE_ARTIFACT_VERSION) RestApiUtils.createLogEndTimeRequest(ml.comet.experiment.impl.utils.RestApiUtils.createLogEndTimeRequest) StringUtils(org.apache.commons.lang3.StringUtils) LoggedArtifact(ml.comet.experiment.artifact.LoggedArtifact) ArtifactException(ml.comet.experiment.artifact.ArtifactException) RemoteAsset(ml.comet.experiment.asset.RemoteAsset) OutputUpdate(ml.comet.experiment.impl.rest.OutputUpdate) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) RestApiUtils.createGraphRequest(ml.comet.experiment.impl.utils.RestApiUtils.createGraphRequest) Duration(java.time.Duration) Map(java.util.Map) ARTIFACT_UPLOAD_STARTED(ml.comet.experiment.impl.resources.LogMessages.ARTIFACT_UPLOAD_STARTED) RestApiUtils.createLogLineRequest(ml.comet.experiment.impl.utils.RestApiUtils.createLogLineRequest) RestApiUtils.createGitMetadataRequest(ml.comet.experiment.impl.utils.RestApiUtils.createGitMetadataRequest) URI(java.net.URI) RestApiUtils.createLogMetricRequest(ml.comet.experiment.impl.utils.RestApiUtils.createLogMetricRequest) ArtifactAsset(ml.comet.experiment.artifact.ArtifactAsset) LogMessages.getString(ml.comet.experiment.impl.resources.LogMessages.getString) FAILED_TO_SEND_LOG_REQUEST(ml.comet.experiment.impl.resources.LogMessages.FAILED_TO_SEND_LOG_REQUEST) FAILED_TO_LOG_ASSET_FOLDER(ml.comet.experiment.impl.resources.LogMessages.FAILED_TO_LOG_ASSET_FOLDER) FAILED_TO_UPLOAD_SOME_ARTIFACT_ASSET(ml.comet.experiment.impl.resources.LogMessages.FAILED_TO_UPLOAD_SOME_ARTIFACT_ASSET) NonNull(lombok.NonNull) AssetUtils.createAssetFromData(ml.comet.experiment.impl.utils.AssetUtils.createAssetFromData) RestApiUtils.createLogHtmlRequest(ml.comet.experiment.impl.utils.RestApiUtils.createLogHtmlRequest) Action(io.reactivex.rxjava3.functions.Action) HtmlRest(ml.comet.experiment.impl.rest.HtmlRest) AssetType(ml.comet.experiment.impl.asset.AssetType) Objects(java.util.Objects) Stream(java.util.stream.Stream) Asset(ml.comet.experiment.asset.Asset) BiFunction(io.reactivex.rxjava3.functions.BiFunction) AssetUtils(ml.comet.experiment.impl.utils.AssetUtils) Optional(java.util.Optional) FAILED_TO_SEND_LOG_ASSET_REQUEST(ml.comet.experiment.impl.resources.LogMessages.FAILED_TO_SEND_LOG_ASSET_REQUEST) Optional.empty(java.util.Optional.empty) Single(io.reactivex.rxjava3.core.Single) ASSETS_FOLDER_UPLOAD_COMPLETED(ml.comet.experiment.impl.resources.LogMessages.ASSETS_FOLDER_UPLOAD_COMPLETED) CompletableFuture(java.util.concurrent.CompletableFuture) ArtifactAssetImpl(ml.comet.experiment.impl.asset.ArtifactAssetImpl) Schedulers(io.reactivex.rxjava3.schedulers.Schedulers) MetricRest(ml.comet.experiment.impl.rest.MetricRest) RestApiUtils.createTagRequest(ml.comet.experiment.impl.utils.RestApiUtils.createTagRequest) ParameterRest(ml.comet.experiment.impl.rest.ParameterRest) Artifact(ml.comet.experiment.artifact.Artifact) Observable(io.reactivex.rxjava3.core.Observable) Scheduler(io.reactivex.rxjava3.core.Scheduler) LogOtherRest(ml.comet.experiment.impl.rest.LogOtherRest) ArtifactVersionState(ml.comet.experiment.impl.rest.ArtifactVersionState) RestApiUtils.createLogOtherRequest(ml.comet.experiment.impl.utils.RestApiUtils.createLogOtherRequest) GitMetaData(ml.comet.experiment.model.GitMetaData) RestApiResponse(ml.comet.experiment.impl.rest.RestApiResponse) Logger(org.slf4j.Logger) ARTIFACT_LOGGED_WITHOUT_ASSETS(ml.comet.experiment.impl.resources.LogMessages.ARTIFACT_LOGGED_WITHOUT_ASSETS) ExperimentContext(ml.comet.experiment.context.ExperimentContext) File(java.io.File) ARTIFACT_UPLOAD_COMPLETED(ml.comet.experiment.impl.resources.LogMessages.ARTIFACT_UPLOAD_COMPLETED) LOG_REMOTE_ASSET_URI_FILE_NAME_TO_DEFAULT(ml.comet.experiment.impl.resources.LogMessages.LOG_REMOTE_ASSET_URI_FILE_NAME_TO_DEFAULT) FAILED_TO_SEND_LOG_ARTIFACT_ASSET_REQUEST(ml.comet.experiment.impl.resources.LogMessages.FAILED_TO_SEND_LOG_ARTIFACT_ASSET_REQUEST) AssetUtils.createAssetFromFile(ml.comet.experiment.impl.utils.AssetUtils.createAssetFromFile) LOG_ASSET_FOLDER_EMPTY(ml.comet.experiment.impl.resources.LogMessages.LOG_ASSET_FOLDER_EMPTY) FAILED_TO_LOG_SOME_ASSET_FROM_FOLDER(ml.comet.experiment.impl.resources.LogMessages.FAILED_TO_LOG_SOME_ASSET_FROM_FOLDER) ArtifactEntry(ml.comet.experiment.impl.rest.ArtifactEntry) Op(ml.comet.experiment.artifact.GetArtifactOptions.Op) Scheduler(io.reactivex.rxjava3.core.Scheduler) RestApiResponse(ml.comet.experiment.impl.rest.RestApiResponse)

Aggregations

ArtifactAsset (ml.comet.experiment.artifact.ArtifactAsset)14 LoggedArtifact (ml.comet.experiment.artifact.LoggedArtifact)11 LogMessages.getString (ml.comet.experiment.impl.resources.LogMessages.getString)11 LoggedArtifactAsset (ml.comet.experiment.artifact.LoggedArtifactAsset)10 Path (java.nio.file.Path)9 DownloadedArtifact (ml.comet.experiment.artifact.DownloadedArtifact)8 File (java.io.File)7 CompletableFuture (java.util.concurrent.CompletableFuture)6 ArtifactAssetImpl (ml.comet.experiment.impl.asset.ArtifactAssetImpl)6 URI (java.net.URI)5 Files (java.nio.file.Files)5 ArrayList (java.util.ArrayList)5 Artifact (ml.comet.experiment.artifact.Artifact)5 ArtifactException (ml.comet.experiment.artifact.ArtifactException)5 Test (org.junit.jupiter.api.Test)5 Timeout (org.junit.jupiter.api.Timeout)5 HashSet (java.util.HashSet)4 RestApiResponse (ml.comet.experiment.impl.rest.RestApiResponse)4 IOException (java.io.IOException)3 InputStream (java.io.InputStream)3