Skip to content

Commit

Permalink
Generate Javadoc for Tracking API to publish with site (mlflow#430)
Browse files Browse the repository at this point in the history
  • Loading branch information
aarondav committed Sep 5, 2018
1 parent 27c4d12 commit e79920f
Show file tree
Hide file tree
Showing 16 changed files with 91 additions and 75 deletions.
1 change: 1 addition & 0 deletions docs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ clean:
.PHONY: html
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
./build-javadoc.sh
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."

Expand Down
9 changes: 9 additions & 0 deletions docs/build-javadoc.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Builds the MLflow Javadoc and places it into build/html/java_api/

set -ex
pushd ../mlflow/java/client/
mvn javadoc:javadoc
popd
mkdir -p build/html/java_api/
cp -r ../mlflow/java/client/target/site/apidocs/* build/html/java_api/
echo "Copied JavaDoc into docs/build/html/java_api/"
1 change: 1 addition & 0 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Get started using the :ref:`quickstart` or by reading about the :ref:`key concep
models
cli
python_api/index
java_api/index
rest-api

.. warning::
Expand Down
6 changes: 6 additions & 0 deletions docs/source/java_api/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.. _java_api:

Java API
==========

This file is a placeholder. Javadoc is filled in by the build-javadoc.sh script, executed during "make html".
12 changes: 11 additions & 1 deletion mlflow/java/client/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<artifactId>mlflow-client</artifactId>
<packaging>jar</packaging>
<version>0.5.2</version>
<name>MLflow Client SDK</name>
<name>MLflow Tracking API</name>
<url>http://mlflow.org</url>
<properties>
<mlflow.shade.packageName>org.mlflow_project</mlflow.shade.packageName>
Expand Down Expand Up @@ -60,6 +60,16 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<configuration>
<sourcepath>${project.basedir}/src/main/java</sourcepath>
<excludePackageNames>com.databricks.api.proto.databricks:org.mlflow.scalapb_interface:org.mlflow.tracking.samples</excludePackageNames>
<groups>
<group>
<title>Tracking API</title>
<packages>org.mlflow.tracking:org.mlflow.tracking.*</packages>
</group>
</groups>
</configuration>
</plugin>

<plugin>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,31 +32,40 @@ public MlflowClient(String trackingUri) {
}

/**
* Creates a new MlflowClient. Users should prefer constructing ApiClients via
* {@link #MlflowClient()} ()} or {@link #MlflowClient(String)} if possible.
* Creates a new MlflowClient; users should prefer constructing ApiClients via
* {@link #MlflowClient()} or {@link #MlflowClient(String)} if possible.
*/
public MlflowClient(MlflowHostCredsProvider hostCredsProvider) {
this.hostCredsProvider = hostCredsProvider;
this.httpCaller = new MlflowHttpCaller(hostCredsProvider);
}

/** Returns the run associated with the id. */
/** @return run associated with the id. */
public Run getRun(String runUuid) {
URIBuilder builder = newURIBuilder("runs/get").setParameter("run_uuid", runUuid);
return mapper.toGetRunResponse(httpCaller.get(builder.toString())).getRun();
}

/** Creates a new run under the default experiment with no application name. */
/**
* Creates a new run under the default experiment with no application name.
* @return RunInfo created by the server
*/
public RunInfo createRun() {
return createRun(DEFAULT_EXPERIMENT_ID);
}

/** Creates a new run under the given experiment with no application name. */
/**
* Creates a new run under the given experiment with no application name.
* @return RunInfo created by the server
*/
public RunInfo createRun(long experimentId) {
return createRun(experimentId, "Java Application");
}

/** Creates a new run under the given experiment with the given application name. */
/**
* Creates a new run under the given experiment with the given application name.
* @return RunInfo created by the server
*/
public RunInfo createRun(long experimentId, String appName) {
CreateRun.Builder request = CreateRun.newBuilder();
request.setExperimentId(experimentId);
Expand All @@ -70,42 +79,49 @@ public RunInfo createRun(long experimentId, String appName) {
return createRun(request.build());
}

/** Creates a new run. */
/**
* Creates a new run.
* @return RunInfo created by the server
*/
public RunInfo createRun(CreateRun request) {
String ijson = mapper.toJson(request);
String ojson = doPost("runs/create", ijson);
String ojson = sendPost("runs/create", ijson);
return mapper.toCreateRunResponse(ojson).getRun().getInfo();
}

/** Returns a list of all RunInfos associated with the given experiment. */
/** @return a list of all RunInfos associated with the given experiment. */
public List<RunInfo> listRunInfos(long experimentId) {
SearchRuns request = SearchRuns.newBuilder().addExperimentIds(experimentId).build();
String ijson = mapper.toJson(request);
String ojson = doPost("runs/search", ijson);
String ojson = sendPost("runs/search", ijson);
return mapper.toSearchRunsResponse(ojson).getRunsList().stream().map(Run::getInfo)
.collect(Collectors.toList());
}

/** Returns a list of all Experiments. */
/** @return a list of all Experiments. */
public List<Experiment> listExperiments() {
return mapper.toListExperimentsResponse(httpCaller.get("experiments/list"))
.getExperimentsList();
}

/** Returns an experiment with the given id. */
/** @return an experiment with the given id. */
public GetExperiment.Response getExperiment(long experimentId) {
URIBuilder builder = newURIBuilder("experiments/get")
.setParameter("experiment_id", "" + experimentId);
return mapper.toGetExperimentResponse(httpCaller.get(builder.toString()));
}

/** Returns the experiment associated with the given name or Optional.empty if none exists. */
/** @return the experiment associated with the given name or Optional.empty if none exists. */
public Optional<Experiment> getExperimentByName(String experimentName) {
return listExperiments().stream().filter(e -> e.getName()
.equals(experimentName)).findFirst();
}

/** Creates a new experiment using the default artifact location provided by the server. */
/**
* Creates a new experiment using the default artifact location provided by the server.
* @param experimentName Name of the experiment. This must be unique across all experiments.
* @return experiment id of the newly created experiment.
*/
public long createExperiment(String experimentName) {
String ijson = mapper.makeCreateExperimentRequest(experimentName);
String ojson = httpCaller.post("experiments/create", ijson);
Expand All @@ -117,15 +133,15 @@ public long createExperiment(String experimentName) {
* This cannot be called against the same parameter key more than once.
*/
public void logParam(String runUuid, String key, String value) {
doPost("runs/log-parameter", mapper.makeLogParam(runUuid, key, value));
sendPost("runs/log-parameter", mapper.makeLogParam(runUuid, key, value));
}

/**
* Logs a new metric against the given run, as a key-value pair.
* New values for the same metric may be recorded over time, and are marked with a timestamp.
* */
public void logMetric(String runUuid, String key, float value) {
doPost("runs/log-metric", mapper.makeLogMetric(runUuid, key, value,
sendPost("runs/log-metric", mapper.makeLogMetric(runUuid, key, value,
System.currentTimeMillis()));
}

Expand All @@ -141,10 +157,10 @@ public void setTerminated(String runUuid, RunStatus status) {

/** Sets the status of a run to be completed at the given endTime. */
public void setTerminated(String runUuid, RunStatus status, long endTime) {
doPost("runs/update", mapper.makeUpdateRun(runUuid, status, endTime));
sendPost("runs/update", mapper.makeUpdateRun(runUuid, status, endTime));
}

/** Returns a list of all artifacts under the given artifact path within the run. */
/** @return a list of all artifacts under the given artifact path within the run. */
public ListArtifacts.Response listArtifacts(String runUuid, String path) {
URIBuilder builder = newURIBuilder("artifacts/list")
.setParameter("run_uuid", runUuid)
Expand All @@ -155,22 +171,24 @@ public ListArtifacts.Response listArtifacts(String runUuid, String path) {
/**
* Send a GET to the following path, including query parameters.
* This is mostly an internal API, but allows making lower-level or unsupported requests.
* @return JSON response from the server
*/
public String doGet(String path) {
public String sendGet(String path) {
return httpCaller.get(path);
}

/**
* Send a POST to the following path, with a String-encoded JSON body.
* This is mostly an internal API, but allows making lower-level or unsupported requests.
* @return JSON response from the server
*/
public String doPost(String path, String json) {
public String sendPost(String path, String json) {
return httpCaller.post(path, json);
}

/**
* Returns the HostCredsProvider backing this MlflowClient.
* Intended for internal usage, and may be removed in future versions.
* @return HostCredsProvider backing this MlflowClient.
*/
public MlflowHostCredsProvider getInternalHostCredsProvider() {
return hostCredsProvider;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.mlflow.tracking;

/** Superclass of all exceptions thrown by the MlflowClient API. */
public class MlflowClientException extends RuntimeException {
public MlflowClientException(String message) {
super(message);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class MlflowHttpCaller {
private HttpClient httpClient;
private final MlflowHostCredsProvider hostCredsProvider;

public MlflowHttpCaller(MlflowHostCredsProvider hostCredsProvider) {
MlflowHttpCaller(MlflowHostCredsProvider hostCredsProvider) {
this.hostCredsProvider = hostCredsProvider;
}

Expand Down Expand Up @@ -89,10 +89,10 @@ private void checkError(HttpResponse response) throws MlflowClientException, IOE
if (isError(statusCode)) {
String bodyMessage = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
if (statusCode >= 400 && statusCode <= 499) {
throw new MlflowHttpClientException(statusCode, reasonPhrase, bodyMessage);
throw new MlflowHttpException(statusCode, reasonPhrase, bodyMessage);
}
if (statusCode >= 500 && statusCode <= 599) {
throw new MlflowHttpServerException(statusCode, reasonPhrase, bodyMessage);
throw new MlflowHttpException(statusCode, reasonPhrase, bodyMessage);
}
throw new MlflowHttpException(statusCode, reasonPhrase, bodyMessage);
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.mlflow.tracking;

/**
* HTTP exception.
* Returned when an HTTP API request to a remote Tracking service returns an error code.
*/
public class MlflowHttpException extends MlflowClientException {

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,24 @@ public void afterAll() throws InterruptedException {
testClientProvider.cleanupClientAndServer();
}

@Test(expectedExceptions = MlflowHttpClientException.class)
@Test(expectedExceptions = MlflowHttpException.class)
public void nonExistentPath() {
client.doGet("BAD_PATH");
client.sendGet("BAD_PATH");
}

@Test(expectedExceptions = MlflowHttpServerException.class) // TODO: server should throw 4xx
@Test(expectedExceptions = MlflowHttpException.class) // TODO: server should throw 4xx
public void getExperiment_NonExistentId() {
client.doGet("experiments/get?experiment_id=NON_EXISTENT_EXPERIMENT_ID");
client.sendGet("experiments/get?experiment_id=NON_EXISTENT_EXPERIMENT_ID");
}

@Test(expectedExceptions = MlflowHttpServerException.class) // TODO: server should throw 4xx
@Test(expectedExceptions = MlflowHttpException.class) // TODO: server should throw 4xx
public void createExperiment_IllegalJsonSyntax() {
client.doPost("experiments/create", "NOT_JSON");
client.sendPost("experiments/create", "NOT_JSON");
}

@Test(expectedExceptions = MlflowHttpServerException.class) // TODO: server should throw 4xx
@Test(expectedExceptions = MlflowHttpException.class) // TODO: server should throw 4xx
public void createExperiment_MissingJsonField() {
String data = "{\"BAD_name\": \"EXPERIMENT_NAME\"}";
client.doPost("experiments/create", data);
client.sendPost("experiments/create", data);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public abstract class LoaderModule<T extends Flavor> {
/**
* Loads an MLFlow model as a generic predictor that can be used for inference
*
* @throws {@link PredictorLoadingException} for any failure encountered while attempting to load
* Throws {@link PredictorLoadingException} for any failure encountered while attempting to load
* the model
*/
public Predictor load(Model model) {
Expand All @@ -39,10 +39,10 @@ public Predictor load(Model model) {

/**
* Loads an MLFlow model as a generic predictor that can be used for inference
* Throws {@link PredictorLoadingException} for any failure encountered while attempting to load
* the model
*
* @param modelRootPath The path to the root directory of the MLFlow model
* @throws {@link PredictorLoadingException} for any failure encountered while attempting to load
* the model
*/
public Predictor load(String modelRootPath) throws PredictorLoadingException {
Optional<Model> model = Optional.empty();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public static Model fromRootPath(String modelRootPath) throws IOException {
/**
* Loads the configuration of an MLFlow model and parses it as a {@link Model} object.
*
* @param modelRootPath The path to the `MLModel` configuration file
* @param configPath The path to the `MLModel` configuration file
*/
public static Model fromConfigPath(String configPath) throws IOException {
File configFile = new File(configPath);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ public class MLeapPredictor extends Predictor {
* Constructs an {@link MLeapPredictor}
*
* @param modelDataPath The path to the serialized MLeap model
* @param inputSchema The path to JSON-formatted file containing the input schema that the model
* accepts
* @param inputSchemaPath The path to JSON-formatted file containing the input schema that the
* model accepts
*/
public MLeapPredictor(String modelDataPath, String inputSchemaPath) {
MleapContext mleapContext = new ContextBuilder().createMleapContext();
Expand Down
Loading

0 comments on commit e79920f

Please sign in to comment.