Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CM-1592] Support for logging of assets folder #39

Merged
merged 64 commits into from
Dec 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
0903fef
CM-1597: Added additional query parameter constants to match REST end…
yaricom Nov 24, 2021
7263fd0
CM-1597: Added form parameters enumeration constants.
yaricom Nov 24, 2021
f9ad18c
CM-1597: Added support for form fields/params when creating multipart…
yaricom Nov 24, 2021
14f3f45
CM-1597: Fixed ConnectionUtils to use constants from io.netty. Fixed …
yaricom Nov 25, 2021
3bfc516
CM-1597: Introduced ApiExperiment interface to mark synchronous exper…
yaricom Nov 25, 2021
bdb2d2c
CM-1597: Extracted asynchronous log methods into BaseExperimentAsync …
yaricom Nov 25, 2021
75a8811
CM-1597: Extracted factory methods to create request DTOs into separa…
yaricom Nov 25, 2021
c548afd
CM-1597: Fixed OnlineExperiment javadoc to properly describe interfac…
yaricom Nov 25, 2021
87c4c7c
Merge branch 'master' into CM-1592-log-asset-folder
yaricom Nov 25, 2021
70f4bb0
CM-1597: Refined OnlineExperiment and Experiment interfaces to suppor…
yaricom Nov 25, 2021
b6380b1
CM-1597: Fixed BaseExperiment to support amended Experiment interface.
yaricom Nov 25, 2021
20eeba9
CM-1597: Fixed BaseE
yaricom Nov 25, 2021
0716b7b
CM-1597: Extracted OnlineExperimentBuilderImpl into separate file to …
yaricom Nov 25, 2021
efbf01b
CM-1597: Moved disposables container to the BaseExperimentAsync.
yaricom Nov 25, 2021
aeef809
CM-1597: Implemented resources cleaning in case if experiment failed …
yaricom Nov 25, 2021
c7bc12d
CM-1597: Added logAssetFolder interface contract. Changed names of as…
yaricom Nov 26, 2021
179adf7
CM-1597: Added package-info.java to the model package.
yaricom Nov 26, 2021
69b03d8
CM-1597: Implemented I18N messages bundle access for logging common m…
yaricom Nov 26, 2021
3626d0a
Updated checkstyle configuration to allow suppressions
yaricom Nov 26, 2021
befa974
CM-1597: Implemented file utilities and related test cases.
yaricom Nov 26, 2021
3128442
CM-1597: Marked ApiEndpoints as utility class.
yaricom Nov 26, 2021
271da58
CM-1597: Renamed comet utils test to conform other tests.
yaricom Nov 26, 2021
ebc5a58
CM-1597: Replaced user facing strings with resources retrieved from m…
yaricom Nov 26, 2021
9d7060b
CM-1597: Implemented AutoCloseable interface by OnlineExperiment allo…
yaricom Nov 29, 2021
88b77be
CM-1597: Implemented logic to resolve asset file name.
yaricom Nov 29, 2021
989773a
CM-1597: Implemented AssetUtils and related test cases.
yaricom Nov 29, 2021
3967708
CM-1597: Added FAILED_TO_SEND_LOG_REQUEST message to the resources bu…
yaricom Nov 29, 2021
8072af7
CM-1597: Added check for logged asset file extension
yaricom Nov 29, 2021
de32a91
CM-1597: Implemented logAsset in the RestApiClient
yaricom Nov 29, 2021
1ff264b
CM-1597: Fixed AssetUtils to map only file data to the asset.
yaricom Nov 29, 2021
bd57843
CM-1597: Renamed parameter for better clarity.
yaricom Nov 29, 2021
bb92aab
CM-1597: Introduced ExperimentContext to reduce number of parameters …
yaricom Nov 30, 2021
33c7b80
CM-1597: Fixed logCode to use ExperimentContext.
yaricom Nov 30, 2021
6b14d6f
CM-1597: Implemented setExperimentContext to update asset values.
yaricom Nov 30, 2021
f7f2a0e
CM-1597: Fixed JavaDoc.
yaricom Nov 30, 2021
d7b8c86
CM-1597: Implemented asynchronous upload of the assets' folder.
yaricom Nov 30, 2021
33684c9
CM-1597: Updated logCode and uploadAsset to use asynchronous asset up…
yaricom Nov 30, 2021
7e0498b
CM-1597: Fixed logAsset to automatically dispose observer upon comple…
yaricom Nov 30, 2021
2d2f62c
CM-1597: Fixed testUploadAndGetAssets to wait for completion of each …
yaricom Nov 30, 2021
ced5310
CM-1597: Fixed testLogAndGetFileCode and testLogAndGetRawCode to chec…
yaricom Nov 30, 2021
c6895d6
CM-1597: Fixed logAssetFolder by setting asset type. Implemented test…
yaricom Nov 30, 2021
422a8a6
CM-1597: Fixed logAssetFolder with delaying exceptions allowing to co…
yaricom Dec 1, 2021
0547e22
CM-1597: Added text resources related to assets' folder upload comple…
yaricom Dec 1, 2021
75daab7
CM-1597: Updated OnlineExperimentExample to include example of assets…
yaricom Dec 1, 2021
98b17c7
CM-1597: Fixed testLogAndGetAssetsFolder to assert against list of as…
yaricom Dec 1, 2021
951d79a
CM-1597: Fixed AssetUtilsTest by introducing constant for the file ex…
yaricom Dec 1, 2021
0cf0d27
CM-1597: Fixed AssetUtilsTest by introducing assetFolderFiles holding…
yaricom Dec 1, 2021
82e3fb9
CM-1597: Fixed AssetUtilsTest by renaming temp directory.
yaricom Dec 1, 2021
9f9ac25
CM-1597: Fixed Asset to have optional parameters as nullable objects …
yaricom Dec 1, 2021
cdf56b4
CM-1592: Fixed ExperimentAssetLink to have optional parameters as nul…
yaricom Dec 1, 2021
60bfb79
CM-1592: Fixed ExperimentContext to have optional parameters as nulla…
yaricom Dec 1, 2021
0b7dd4d
CM-1592: Added overloaded logAssetFolder without recursive, i.e., hav…
yaricom Dec 1, 2021
8299abe
CM-1592: Fixed AssetUtils and FileUtils to allow collecting file name…
yaricom Dec 1, 2021
9f9a18a
CM-1592: Fixed AssetUtils and FileUtils to allow collecting file name…
yaricom Dec 1, 2021
de2ab61
CM-1592: Fixed logAssetFolder to have prefixWithFolderName parameter …
yaricom Dec 1, 2021
a4d9781
CM-1592: Fixed OnlineExperimentImpl to check if the optional paramete…
yaricom Dec 1, 2021
4a6be11
CM-1592: Implemented proper merge of the ExperimentContext. Fixed rel…
yaricom Dec 1, 2021
569ff91
CM-1592: Fixed to use StringUtils.isBlank instead of StringUtils.isEm…
yaricom Dec 1, 2021
1c12daa
CM-1592: Updated OnlineExperimentExample to demonstrate ExperimentCon…
yaricom Dec 1, 2021
55809df
CM-1592: Fixed AssetUtils to propagate prefixWithFolderName parameter…
yaricom Dec 2, 2021
621b510
CM-1592: Fixed typo in the AssetUtils.
yaricom Dec 2, 2021
6fdd5b1
CM-1592: Fixed sample code file to be more Pytonish
yaricom Dec 2, 2021
78145b2
CM-1592: Fixed parenthesis
yaricom Dec 2, 2021
17c4dee
CM-1592: Added missed @Override annotations.
yaricom Dec 2, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 13 additions & 5 deletions .github/linters/comet-checkstyle.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@
<property name="fileNamePattern" value="module\-info\.java$"/>
</module>
<!-- https://checkstyle.org/config_filters.html#SuppressionFilter -->
<module name="SuppressionFilter">
<property name="file" value="${org.checkstyle.google.suppressionfilter.config}"
default="checkstyle-suppressions.xml" />
<property name="optional" value="true"/>
</module>
<!-- <module name="SuppressionFilter">-->
<!-- <property name="file" value="${org.checkstyle.google.suppressionfilter.config}"-->
<!-- default="checkstyle-suppressions.xml" />-->
<!-- <property name="optional" value="true"/>-->
<!-- </module>-->

<!-- Checks for whitespace -->
<!-- See http://checkstyle.org/config_whitespace.html -->
Expand All @@ -47,7 +47,15 @@
<property name="ignorePattern" value="^package.*|^import.*|a href|href|http://|https://|ftp://"/>
</module>

<module name="SuppressWarningsFilter"/>

<module name="TreeWalker">
<module name="SuppressionCommentFilter">
<property name="offCommentFormat" value="@cs-\: ([\w\|]+)"/>
<property name="checkFormat" value="$1"/>
</module>
<module name="SuppressWarningsHolder" />

<module name="OuterTypeFilename"/>
<module name="IllegalTokenText">
<property name="tokens" value="STRING_LITERAL, CHAR_LITERAL"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@

import ml.comet.experiment.ExperimentBuilder;
import ml.comet.experiment.OnlineExperiment;
import ml.comet.experiment.context.ExperimentContext;
import org.apache.commons.io.file.PathUtils;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Objects;

import static ml.comet.examples.Utils.getResourceFile;
import static ml.comet.examples.Utils.readResourceToString;
Expand All @@ -22,21 +27,19 @@
*/
public class OnlineExperimentExample {

private static final String CHART_IMAGE_FILE = "chart.png";
private static final String MODEL_FILE = "model.hd5";
private static final String HTML_REPORT_FILE = "report.html";
private static final String GRAPH_JSON_FILE = "graph.json";
private static final String CODE_FILE = "code_sample.py";

/**
* The main entry point to the example.
*
* @param args the command line arguments if any.
*/
public static void main(String[] args) {
OnlineExperimentExample main = new OnlineExperimentExample();
try {
main.run();
} catch (IOException e) {
e.printStackTrace();
}
}

private void run() throws IOException {
//this will take configs from /comet-java-sdk/comet-examples/src/main/resources/application.conf
//be sure you have set up apiKey, project, workspace in defaults.conf before you start!

Expand All @@ -48,6 +51,16 @@ private void run() throws IOException {
//you can use a default builder or just inject params
//OnlineExperiment experiment = ExperimentBuilder.OnlineExperiment().builder();

try {
OnlineExperimentExample.run(experiment);
} catch (IOException e) {
e.printStackTrace();
} finally {
experiment.end();
}
}

private static void run(OnlineExperiment experiment) throws IOException {
experiment.setExperimentName("Java-SDK 2.0.2");
experiment.nextStep();

Expand All @@ -68,20 +81,33 @@ private void run() throws IOException {
experiment.logParameter("batch_size", "500");
experiment.logParameter("learning_rate", 12);

experiment.uploadAsset(getResourceFile("chart.png"), "amazing chart.png", false);
experiment.uploadAsset(getResourceFile("model.hd5"), false);
experiment.uploadAsset(getResourceFile(CHART_IMAGE_FILE), "amazing chart.png", false);
experiment.uploadAsset(getResourceFile(MODEL_FILE), false,
ExperimentContext.builder().withContext("train").build());

experiment.nextStep();

// upload assets from folder
Path assetDir = copyResourcesToTmpDir();
experiment.logAssetFolder(assetDir.toFile(), true, true);

experiment.logOther("Parameter", 4);

System.out.println("Epoch 1/20");
System.out.println("- loss: 0.7858 - acc: 0.7759 - val_loss: 0.3416 - val_acc: 0.9026");

experiment.logGraph(readResourceToString("graph.json"));
experiment.logGraph(readResourceToString(GRAPH_JSON_FILE));

experiment.logCode(getResourceFile(CODE_FILE),
ExperimentContext.builder().withContext("test").build());

System.out.println("===== Experiment completed ====");

// will close connection, if not called connection will close on jvm exit
experiment.end();

// remove tmp directory
PathUtils.deleteDirectory(assetDir);
}

private static void generateCharts(OnlineExperiment experiment) {
Expand All @@ -108,4 +134,20 @@ private static long getUpdatedEpochValue(OnlineExperiment experiment) {
return experiment.getEpoch() + experiment.getStep() / 5;
}

private static Path copyResourcesToTmpDir() throws IOException {
Path root = Files.createTempDirectory("onlineExperimentExample");
PathUtils.copyFileToDirectory(
Objects.requireNonNull(getResourceFile(CHART_IMAGE_FILE)).toPath(), root);
PathUtils.copyFileToDirectory(
Objects.requireNonNull(getResourceFile(MODEL_FILE)).toPath(), root);
Files.createTempFile(root, "empty_file", ".txt");

Path subDir = Files.createTempDirectory(root, "subDir");
PathUtils.copyFileToDirectory(
Objects.requireNonNull(getResourceFile(HTML_REPORT_FILE)).toPath(), subDir);
PathUtils.copyFileToDirectory(
Objects.requireNonNull(getResourceFile(GRAPH_JSON_FILE)).toPath(), subDir);

return root;
}
}
1 change: 1 addition & 0 deletions comet-examples/src/main/resources/code_sample.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# some code goes here
5 changes: 5 additions & 0 deletions comet-java-client/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
<dependency>
<groupId>com.typesafe</groupId>
<artifactId>config</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,7 @@
package ml.comet.experiment;

import lombok.NonNull;
import lombok.experimental.UtilityClass;
import ml.comet.experiment.builder.ApiExperimentBuilder;
import ml.comet.experiment.impl.ApiExperimentImpl;

/**
* This is stub to support backward compatibility.
*
* @deprecated It would be replaced in the future with new experiment creation API.
* The {@code ApiExperiment} can be used to synchronously read/update data of your Comet.ml experiment.
*/
@UtilityClass
public final class ApiExperiment {
/**
* Returns builder to create {@link Experiment} instance.
*
* @param experimentKey the unique identifier of the existing experiment.
* @return the initialized ApiExperiment instance.
*/
public static ApiExperimentBuilder builder(@NonNull final String experimentKey) {
return ApiExperimentImpl.builder(experimentKey);
}
public interface ApiExperiment extends Experiment {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package ml.comet.experiment;

import lombok.NonNull;
import lombok.experimental.UtilityClass;
import ml.comet.experiment.builder.ApiExperimentBuilder;

/**
* This is stub to support backward compatibility.
*
* @deprecated It would be replaced in the future with new experiment creation API.
*/
@UtilityClass
public final class ApiExperimentImpl {
/**
* Returns builder to create {@link Experiment} instance.
*
* @param experimentKey the unique identifier of the existing experiment.
* @return the initialized ApiExperiment instance.
*/
public static ApiExperimentBuilder builder(@NonNull final String experimentKey) {
return ml.comet.experiment.impl.ApiExperimentImpl.builder(experimentKey);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ml.comet.experiment;

import ml.comet.experiment.impl.constants.AssetType;
import ml.comet.experiment.context.ExperimentContext;
import ml.comet.experiment.impl.asset.AssetType;
import ml.comet.experiment.model.ExperimentAssetLink;
import ml.comet.experiment.model.ExperimentMetadataRest;
import ml.comet.experiment.model.GitMetadata;
Expand Down Expand Up @@ -140,11 +141,22 @@ public interface Experiment {
/**
* Send logs to Comet.
*
* @param line Text to be logged
* @param offset Offset describes the place for current text to be inserted
* @param stderr the flag to indicate if this is StdErr message.
* @param line Text to be logged
* @param offset Offset describes the place for current text to be inserted
* @param stderr the flag to indicate if this is StdErr message.
* @param context the context to be associated with the parameter.
*/
void logLine(String line, long offset, boolean stderr);
void logLine(String line, long offset, boolean stderr, String context);

/**
* Logs a metric with Comet. For running experiment updates current step to one from param!
* Metrics are generally values that change from step to step.
*
* @param metricName The name for the metric to be logged
* @param metricValue The new value for the metric. If the values for a metric are plottable we will plot them.
* @param context the context to be associated with the metric.
*/
void logMetric(String metricName, Object metricValue, ExperimentContext context);

/**
* Logs a metric with Comet. For running experiment updates current step to one from param!
Expand All @@ -153,18 +165,27 @@ public interface Experiment {
* @param metricName The name for the metric to be logged
* @param metricValue The new value for the metric. If the values for a metric are plottable we will plot them
* @param step The current step for this metric, this will set the given step for this experiment
* @param epoch The current epoch for this metric, this will set the given epoch for this experiment
* @param epoch The current epoch for this metric, this will set the given epoch for this experiment.
*/
void logMetric(String metricName, Object metricValue, long step, long epoch);

/**
* Logs a param with Comet. For running experiment updates current step to one from param!
* Params should be set at the start of the experiment.
*
* @param parameterName The name of the param being logged
* @param paramValue The value for the param being logged
* @param context the context to be associated with the parameter.
*/
void logParameter(String parameterName, Object paramValue, ExperimentContext context);

/**
* Logs a param with Comet. For running experiment updates current step to one from param!
* Params should be set at the start of the experiment.
*
* @param parameterName The name of the param being logged
* @param paramValue The value for the param being logged
* @param step The current step for this metric, this will set the given step for this experiment
* @param step The current step for this metric, this will set the given step for this experiment.
*/
void logParameter(String parameterName, Object paramValue, long step);

Expand Down Expand Up @@ -214,6 +235,15 @@ public interface Experiment {
*/
void logEndTime(long endTimeMillis);

/**
* Allows you to report code for the experiment.
*
* @param code Code to be sent to Comet
* @param fileName Name of source file to be displayed on UI 'code' tab
* @param context the context to be associated with the asset.
*/
void logCode(String code, String fileName, ExperimentContext context);

/**
* Allows you to report code for the experiment.
*
Expand All @@ -222,6 +252,14 @@ public interface Experiment {
*/
void logCode(String code, String fileName);

/**
* Allows you to report code for the experiment.
*
* @param file Asset with source code to be sent
* @param context the context to be associated with the asset.
*/
void logCode(File file, ExperimentContext context);

/**
* Allows you to report code for the experiment.
*
Expand All @@ -236,11 +274,41 @@ public interface Experiment {
* @param asset The asset to be stored
* @param fileName The file name under which the asset should be stored in Comet. E.g. "someFile.txt"
* @param overwrite Whether to overwrite files of the same name in Comet
* @param step the step to be associated with asset
* @param epoch the epoch to be associated with asset
* @param context the context to be associated with the asset.
*/
void uploadAsset(File asset, String fileName, boolean overwrite, ExperimentContext context);

/**
* Upload an asset to be associated with the experiment, for example the trained weights of a neural net.
* For running experiment updates current step to one from param!
*
* @param asset The asset to be stored
* @param fileName The file name under which the asset should be stored in Comet. E.g. "someFile.txt"
* @param overwrite Whether to overwrite files of the same name in Comet
* @param step the step to be associated with the asset
* @param epoch the epoch to be associated with the asset
*/
void uploadAsset(File asset, String fileName, boolean overwrite, long step, long epoch);

/**
* Upload an asset to be associated with the experiment, for example the trained weights of a neural net.
* For running experiment updates current step to one from param!
*
* @param asset The file asset to be stored. The name of the file will be used as assets identifier on Comet.
* @param overwrite Whether to overwrite files of the same name in Comet
* @param context the context to be associated with the asset.
*/
void uploadAsset(File asset, boolean overwrite, ExperimentContext context);

/**
* Upload an asset to be associated with the experiment, for example the trained weights of a neural net.
* For running experiment updates current step to one from param!
*
* @param asset The file asset to be stored. The name of the file will be used as assets identifier on Comet.
* @param overwrite Whether to overwrite files of the same name in Comet
* @param step the step to be associated with the asset
* @param epoch the epoch to be associated with the asset
*/
void uploadAsset(File asset, boolean overwrite, long step, long epoch);

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package ml.comet.experiment;

import lombok.experimental.UtilityClass;
import ml.comet.experiment.builder.ApiExperimentBuilder;
import ml.comet.experiment.builder.OnlineExperimentBuilder;
import ml.comet.experiment.impl.ApiExperimentImpl;
import ml.comet.experiment.impl.OnlineExperimentImpl;

/**
Expand All @@ -23,7 +25,19 @@ public class ExperimentBuilder {
*
* @return the instance of the {@link OnlineExperimentBuilder}.
*/
@SuppressWarnings({"MethodName"})
public static OnlineExperimentBuilder OnlineExperiment() {
return OnlineExperimentImpl.builder();
}

/**
* The factory to create instance of the {@link ApiExperimentBuilder} which can be used
* to configure and create fully initialized instance of the {@link ApiExperiment}.
*
* @return the initialized instance of the {@link ApiExperimentBuilder}.
*/
@SuppressWarnings({"MethodName"})
public static ApiExperimentBuilder ApiExperiment() {
return ApiExperimentImpl.builder();
}
}
Loading