You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@submarine.apache.org by zt...@apache.org on 2020/06/18 05:46:23 UTC
[submarine] branch master updated: SUBMARINE-516. Automatically
generate python API from swagger
This is an automated email from the ASF dual-hosted git repository.
ztang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/submarine.git
The following commit(s) were added to refs/heads/master by this push:
new 0f281ca SUBMARINE-516. Automatically generate python API from swagger
0f281ca is described below
commit 0f281cad18ed5c1549b1286a9358a1eceba5991e
Author: pingsutw <pi...@gmail.com>
AuthorDate: Thu Jun 18 09:06:30 2020 +0800
SUBMARINE-516. Automatically generate python API from swagger
### What is this PR for?
Generate Python SDK in one command `/dev-support/pysubmarine/gen-sdk.sh`
1. could we merge https://github.com/apache/submarine/pull/312 firstly, the code generated by swagger has some code style issues.
2. I will add an abstract class for current client API in the next JIRA so that users can more easily use this API.
Here is a [Jupyter example](https://github.com/pingsutw/hadoop-submarine/blob/SUBMARINE-516/submarine-sdk/pysubmarine/example/submarine_experiment_sdk.ipynb)
### What type of PR is it?
[Improvement]
### Todos
* [ ] - Task
### What is the Jira issue?
https://issues.apache.org/jira/browse/SUBMARINE-516
### How should this be tested?
https://travis-ci.org/github/pingsutw/hadoop-submarine/builds/699154337
### Screenshots (if appropriate)
### Questions:
* Does the licenses files need update? No
* Is there breaking changes for older versions? No
* Does this needs documentation? No
Author: pingsutw <pi...@gmail.com>
Author: HUAN-PING SU <pi...@gmail.com>
Closes #314 from pingsutw/SUBMARINE-516 and squashes the following commits:
407d7a1 [pingsutw] Rename file
7c8bcec [pingsutw] update iphnb
c128a07 [HUAN-PING SU] Update __init__.py
065a530 [pingsutw] Update ipynb
5f58830 [pingsutw] Update
3aa7a79 [pingsutw] Fix code style
bbb3974 [pingsutw] Fix code style
5fbbafd [pingsutw] update
ead12d6 [pingsutw] update
57a3cc4 [HUAN-PING SU] Update gen-sdk.sh
fc12f68 [HUAN-PING SU] Delete generate_api.md
19dd882 [HUAN-PING SU] Update README.md
098c5cf [pingsutw] SUBMARINE-516. Automatically generate python API from swagger
---
.gitignore | 1 +
dev-support/pysubmarine/gen-sdk.sh | 66 ++
.../pysubmarine/license-header.txt | 12 +-
dev-support/pysubmarine/openapi.json | 363 ++++++++
dev-support/pysubmarine/swagger_config.json | 5 +
docs/submarine-sdk/pysubmarine/README.md | 6 +-
docs/submarine-sdk/pysubmarine/generate_api.md | 31 -
docs/submarine-sdk/pysubmarine/openapi.yaml | 244 ------
.../example/submarine_experiment_sdk.ipynb | 289 +++++++
.../pysubmarine/example/submarine_job_sdk.ipynb | 608 -------------
submarine-sdk/pysubmarine/github-actions/lint.sh | 2 +-
submarine-sdk/pysubmarine/submarine/__init__.py | 12 +-
.../pysubmarine/submarine/experiment/__init__.py | 46 +
.../submarine/{job => experiment}/api/__init__.py | 12 +-
.../submarine/experiment/api/experiment_api.py | 943 +++++++++++++++++++++
.../submarine/{job => experiment}/api_client.py | 215 +++--
.../submarine/experiment/configuration.py | 391 +++++++++
.../pysubmarine/submarine/experiment/exceptions.py | 139 +++
.../{job => experiment}/models/__init__.py | 22 +-
.../submarine/experiment/models/environment.py | 136 +++
.../submarine/experiment/models/experiment_meta.py | 240 ++++++
.../submarine/experiment/models/experiment_spec.py | 188 ++++
.../models/experiment_task_spec.py} | 235 ++---
.../{job => experiment}/models/json_response.py | 66 +-
.../submarine/{job => experiment}/rest.py | 60 +-
.../pysubmarine/submarine/job/__init__.py | 40 -
.../pysubmarine/submarine/job/api/jobs_api.py | 783 -----------------
.../pysubmarine/submarine/job/configuration.py | 257 ------
.../submarine/job/models/job_library_spec.py | 233 -----
.../pysubmarine/submarine/job/models/job_spec.py | 233 -----
.../org/apache/submarine/server/Bootstrap.java | 8 +-
31 files changed, 3140 insertions(+), 2746 deletions(-)
diff --git a/.gitignore b/.gitignore
index af83984..c4c7f50 100644
--- a/.gitignore
+++ b/.gitignore
@@ -58,6 +58,7 @@ venv.bak/
*.jar
target
dev-support/mini-submarine/database
+dev-support/pysubmarine/sdk
submarine-workbench/workbench-web/node
submarine-workbench/workbench-web/node_modules
submarine-workbench/workbench-web/dist
diff --git a/dev-support/pysubmarine/gen-sdk.sh b/dev-support/pysubmarine/gen-sdk.sh
new file mode 100755
index 0000000..3afc89a
--- /dev/null
+++ b/dev-support/pysubmarine/gen-sdk.sh
@@ -0,0 +1,66 @@
+#!/bin/bash
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+FWDIR="$(cd "$(dirname "$0")"; pwd)"
+cd "$FWDIR"
+
+SUBMARINE_PROJECT_PATH="$FWDIR/../.."
+SWAGGER_JAR_URL="https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/4.3.1/openapi-generator-cli-4.3.1.jar"
+SWAGGER_CODEGEN_JAR="openapi-generator-cli.jar"
+SWAGGER_CODEGEN_CONF="swagger_config.json"
+SWAGGER_CODEGEN_FILE="openapi.json"
+SDK_OUTPUT_PATH="sdk/python"
+
+submarine_dist_exists=$(find -L "${SUBMARINE_PROJECT_PATH}/submarine-dist/target" -name "submarine-dist-*.tar.gz")
+# Build source code if the package doesn't exist.
+if [[ -z "${submarine_dist_exists}" ]]; then
+ cd "${SUBMARINE_PROJECT_PATH}"
+ mvn clean package -DskipTests
+fi
+
+echo "Generating openAPI 3.0 definition file ..."
+# TODO(pingsutw): generate openapi.json without starting submarine server
+bash ${SUBMARINE_PROJECT_PATH}/submarine-dist/target//submarine-dist-*/submarine-dist-*/bin/submarine-daemon.sh start getMysqlJar
+sleep 5
+rm openapi.json
+wget http://localhost:8080/v1/openapi.json
+bash ${SUBMARINE_PROJECT_PATH}/submarine-dist/target//submarine-dist-*/submarine-dist-*/bin/submarine-daemon.sh stop
+
+openapi_generator_cli_exists=$(find -L "${FWDIR}" -name "openapi-generator-cli*")
+if [[ -z "${openapi_generator_cli_exists}" ]]; then
+ echo "Downloading the swagger-codegen JAR package ..."
+ wget -O "${SWAGGER_CODEGEN_JAR}" "${SWAGGER_JAR_URL}"
+fi
+
+echo "Generating Python SDK for Submarine ..."
+rm -r sdk/
+java -jar ${SWAGGER_CODEGEN_JAR} generate \
+ -i "${SWAGGER_CODEGEN_FILE}" \
+ -g python \
+ -o ${SDK_OUTPUT_PATH} \
+ -c ${SWAGGER_CODEGEN_CONF}
+
+echo "Insert apache license at the top of file ..."
+for filename in $(find ${SDK_OUTPUT_PATH}/submarine/experiment -type f); do
+ echo "$filename"
+ sed -i -e '1 e cat license-header.txt' "$filename"
+done
+
+echo "Move Experiment API to pysubmarine"
+cp -r sdk/python/submarine/experiment ${SUBMARINE_PROJECT_PATH}/submarine-sdk/pysubmarine/submarine/
+
+echo "Fix Python SDK code style"
+${SUBMARINE_PROJECT_PATH}/submarine-sdk/pysubmarine/github-actions/auto-format.sh
diff --git a/submarine-sdk/pysubmarine/submarine/job/api/__init__.py b/dev-support/pysubmarine/license-header.txt
similarity index 66%
copy from submarine-sdk/pysubmarine/submarine/job/api/__init__.py
copy to dev-support/pysubmarine/license-header.txt
index 952d741..09697dc 100644
--- a/submarine-sdk/pysubmarine/submarine/job/api/__init__.py
+++ b/dev-support/pysubmarine/license-header.txt
@@ -1,11 +1,11 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
+# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
+# the License. You may obtain a copy of the License at
#
-# http://www.apache.org/licenses/LICENSE-2.0
+# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
@@ -13,9 +13,3 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from __future__ import absolute_import
-
-# import apis into api package
-from submarine.job.api.jobs_api import JobsApi
-
-# flake8: noqa
diff --git a/dev-support/pysubmarine/openapi.json b/dev-support/pysubmarine/openapi.json
new file mode 100644
index 0000000..9f4074b
--- /dev/null
+++ b/dev-support/pysubmarine/openapi.json
@@ -0,0 +1,363 @@
+{
+ "openapi" : "3.0.1",
+ "info" : {
+ "title" : "Submarine Experiment API",
+ "description" : "The Submarine REST API allows you to create, list, and get experiments. The\nAPI is hosted under the /v1/experiment route on the Submarine server. For example,\nto list experiments on a server hosted at http://localhost:8080, access\nhttp://localhost:8080/api/v1/experiment/",
+ "termsOfService" : "http://swagger.io/terms/",
+ "contact" : {
+ "email" : "submarine-dev@submarine.apache.org"
+ },
+ "license" : {
+ "name" : "Apache 2.0",
+ "url" : "http://www.apache.org/licenses/LICENSE-2.0.html"
+ },
+ "version" : "0.4.0-SNAPSHOT"
+ },
+ "servers" : [ {
+ "url" : "/api"
+ } ],
+ "paths" : {
+ "/v1/experiment/{id}" : {
+ "get" : {
+ "tags" : [ "experiment" ],
+ "summary" : "Get the experiment's detailed info by id",
+ "operationId" : "getExperiment",
+ "parameters" : [ {
+ "name" : "id",
+ "in" : "path",
+ "required" : true,
+ "schema" : {
+ "type" : "string"
+ }
+ } ],
+ "responses" : {
+ "default" : {
+ "description" : "successful operation",
+ "content" : {
+ "application/json; charset=utf-8" : {
+ "schema" : {
+ "$ref" : "#/components/schemas/JsonResponse"
+ }
+ }
+ }
+ },
+ "404" : {
+ "description" : "Experiment not found"
+ }
+ }
+ },
+ "delete" : {
+ "tags" : [ "experiment" ],
+ "summary" : "Delete the experiment",
+ "operationId" : "deleteExperiment",
+ "parameters" : [ {
+ "name" : "id",
+ "in" : "path",
+ "required" : true,
+ "schema" : {
+ "type" : "string"
+ }
+ } ],
+ "responses" : {
+ "default" : {
+ "description" : "successful operation",
+ "content" : {
+ "application/json; charset=utf-8" : {
+ "schema" : {
+ "$ref" : "#/components/schemas/JsonResponse"
+ }
+ }
+ }
+ },
+ "404" : {
+ "description" : "Experiment not found"
+ }
+ }
+ },
+ "patch" : {
+ "tags" : [ "experiment" ],
+ "summary" : "Update the experiment in the submarine server with spec",
+ "operationId" : "patchExperiment",
+ "parameters" : [ {
+ "name" : "id",
+ "in" : "path",
+ "required" : true,
+ "schema" : {
+ "type" : "string"
+ }
+ } ],
+ "requestBody" : {
+ "content" : {
+ "application/yaml" : {
+ "schema" : {
+ "$ref" : "#/components/schemas/ExperimentSpec"
+ }
+ },
+ "application/json" : {
+ "schema" : {
+ "$ref" : "#/components/schemas/ExperimentSpec"
+ }
+ }
+ }
+ },
+ "responses" : {
+ "default" : {
+ "description" : "successful operation",
+ "content" : {
+ "application/json; charset=utf-8" : {
+ "schema" : {
+ "$ref" : "#/components/schemas/JsonResponse"
+ }
+ }
+ }
+ },
+ "404" : {
+ "description" : "Experiment not found"
+ }
+ }
+ }
+ },
+ "/v1/experiment/logs" : {
+ "get" : {
+ "tags" : [ "experiment" ],
+ "summary" : "List experiment's log",
+ "operationId" : "listLog",
+ "parameters" : [ {
+ "name" : "status",
+ "in" : "query",
+ "schema" : {
+ "type" : "string"
+ }
+ } ],
+ "responses" : {
+ "default" : {
+ "description" : "successful operation",
+ "content" : {
+ "application/json; charset=utf-8" : {
+ "schema" : {
+ "$ref" : "#/components/schemas/JsonResponse"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/experiment" : {
+ "get" : {
+ "tags" : [ "experiment" ],
+ "summary" : "List experiments",
+ "operationId" : "listExperiments",
+ "parameters" : [ {
+ "name" : "status",
+ "in" : "query",
+ "schema" : {
+ "type" : "string"
+ }
+ } ],
+ "responses" : {
+ "default" : {
+ "description" : "successful operation",
+ "content" : {
+ "application/json; charset=utf-8" : {
+ "schema" : {
+ "$ref" : "#/components/schemas/JsonResponse"
+ }
+ }
+ }
+ }
+ }
+ },
+ "post" : {
+ "tags" : [ "experiment" ],
+ "summary" : "Create an experiment",
+ "operationId" : "createExperiment",
+ "requestBody" : {
+ "content" : {
+ "application/yaml" : {
+ "schema" : {
+ "$ref" : "#/components/schemas/ExperimentSpec"
+ }
+ },
+ "application/json" : {
+ "schema" : {
+ "$ref" : "#/components/schemas/ExperimentSpec"
+ }
+ }
+ }
+ },
+ "responses" : {
+ "default" : {
+ "description" : "successful operation",
+ "content" : {
+ "application/json; charset=utf-8" : {
+ "schema" : {
+ "$ref" : "#/components/schemas/JsonResponse"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/experiment/logs/{id}" : {
+ "get" : {
+ "tags" : [ "experiment" ],
+ "summary" : "Log experiment by id",
+ "operationId" : "getLog",
+ "parameters" : [ {
+ "name" : "id",
+ "in" : "path",
+ "required" : true,
+ "schema" : {
+ "type" : "string"
+ }
+ } ],
+ "responses" : {
+ "default" : {
+ "description" : "successful operation",
+ "content" : {
+ "application/json; charset=utf-8" : {
+ "schema" : {
+ "$ref" : "#/components/schemas/JsonResponse"
+ }
+ }
+ }
+ },
+ "404" : {
+ "description" : "Experiment not found"
+ }
+ }
+ }
+ },
+ "/v1/experiment/ping" : {
+ "get" : {
+ "tags" : [ "experiment" ],
+ "summary" : "Ping submarine server",
+ "description" : "Return the Pong message for test the connectivity",
+ "operationId" : "ping",
+ "responses" : {
+ "200" : {
+ "description" : "successful operation",
+ "content" : {
+ "application/json; charset=utf-8" : {
+ "schema" : {
+ "type" : "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "components" : {
+ "schemas" : {
+ "JsonResponse" : {
+ "type" : "object",
+ "properties" : {
+ "code" : {
+ "type" : "integer",
+ "format" : "int32"
+ },
+ "success" : {
+ "type" : "boolean"
+ },
+ "result" : {
+ "type" : "object"
+ },
+ "attributes" : {
+ "type" : "object",
+ "additionalProperties" : {
+ "type" : "object"
+ }
+ }
+ }
+ },
+ "Environment" : {
+ "type" : "object",
+ "properties" : {
+ "image" : {
+ "type" : "string"
+ }
+ }
+ },
+ "ExperimentMeta" : {
+ "type" : "object",
+ "properties" : {
+ "name" : {
+ "type" : "string"
+ },
+ "namespace" : {
+ "type" : "string"
+ },
+ "framework" : {
+ "type" : "string"
+ },
+ "cmd" : {
+ "type" : "string"
+ },
+ "envVars" : {
+ "type" : "object",
+ "additionalProperties" : {
+ "type" : "string"
+ }
+ }
+ }
+ },
+ "ExperimentSpec" : {
+ "type" : "object",
+ "properties" : {
+ "meta" : {
+ "$ref" : "#/components/schemas/ExperimentMeta"
+ },
+ "environment" : {
+ "$ref" : "#/components/schemas/Environment"
+ },
+ "spec" : {
+ "type" : "object",
+ "additionalProperties" : {
+ "$ref" : "#/components/schemas/ExperimentTaskSpec"
+ }
+ }
+ }
+ },
+ "ExperimentTaskSpec" : {
+ "type" : "object",
+ "properties" : {
+ "replicas" : {
+ "type" : "integer",
+ "format" : "int32"
+ },
+ "resources" : {
+ "type" : "string"
+ },
+ "name" : {
+ "type" : "string"
+ },
+ "image" : {
+ "type" : "string"
+ },
+ "cmd" : {
+ "type" : "string"
+ },
+ "envVars" : {
+ "type" : "object",
+ "additionalProperties" : {
+ "type" : "string"
+ }
+ },
+ "cpu" : {
+ "type" : "string"
+ },
+ "gpu" : {
+ "type" : "string"
+ },
+ "memory" : {
+ "type" : "string"
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/dev-support/pysubmarine/swagger_config.json b/dev-support/pysubmarine/swagger_config.json
new file mode 100644
index 0000000..be5877c
--- /dev/null
+++ b/dev-support/pysubmarine/swagger_config.json
@@ -0,0 +1,5 @@
+{
+ "packageName" : "submarine.experiment",
+ "projectName" : "submarine.experiment",
+ "packageVersion": "0.4.0-SNAPSHOT"
+}
diff --git a/docs/submarine-sdk/pysubmarine/README.md b/docs/submarine-sdk/pysubmarine/README.md
index a401ef6..0e7441b 100644
--- a/docs/submarine-sdk/pysubmarine/README.md
+++ b/docs/submarine-sdk/pysubmarine/README.md
@@ -43,7 +43,9 @@ pytest --cov=submarine -vs
./submarine-sdk/pysubmarine/github-actions/lint.sh
```
## How to generate REST SDK from swagger
-- [Generate REST SDK from swagger](./generate_api.md)
+```bash
+./dev-support/pysubmarine/gen-sdk.sh
+```
## Easy-to-use model trainers
- [FM](../../../submarine-sdk/pysubmarine/example/deepfm)
@@ -51,7 +53,7 @@ pytest --cov=submarine -vs
## Submarine experiment management
Makes it easy to run distributed or non-distributed TensorFlow, PyTorch experiments on Kubernetes.
-- [mnist example](../../../submarine-sdk/pysubmarine/example/submarine_job_sdk.ipynb)
+- [mnist example](../../../submarine-sdk/pysubmarine/example/submarine_experiment_sdk.ipynb)
## PySubmarine API Reference
- [Tracking](tracking.md)
diff --git a/docs/submarine-sdk/pysubmarine/generate_api.md b/docs/submarine-sdk/pysubmarine/generate_api.md
deleted file mode 100644
index c331a42..0000000
--- a/docs/submarine-sdk/pysubmarine/generate_api.md
+++ /dev/null
@@ -1,31 +0,0 @@
-<!---
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License. See accompanying LICENSE file.
--->
-
-# How to generate Experiment API
-
-### Build Submarine project
-- git clone git@github.com:apache/submarine.git
-- mvn clean package -DskipTests
-### Start Submarine server
-- cd submarine-dist/target/submarine-dist-0.4.0-SNAPSHOT-hadoop-2.9/submarine-dist-0.4.0-SNAPSHOT-hadoop-2.9/
-- ./bin/submarine-daemon.sh start getMysqlJar
-### Generate experiment API
-- open localhost:8080/v1/openapi.json
-- copy `openapi.json` file to [swagger editor](https://editor.swagger.io/)
-- click *generate client* -> *python* to generate experiment API archive
-### Add experiment API to pysubmarine
-- mv `./python-client-generated/swagger-client/*` to `pysubmarine/submarine/job`
-- rename all `swagger_client` in `submarine/job/*.py` to `submarine.job`.
- - e.g. `from swagger_client.models.job_task_spec import JobTaskSpec` -> `from submarine.job.models.job_task_spec import JobTaskSpec`
-- import experiment API in [\_\_init__.py](../__init__.py)
diff --git a/docs/submarine-sdk/pysubmarine/openapi.yaml b/docs/submarine-sdk/pysubmarine/openapi.yaml
deleted file mode 100644
index d9264eb..0000000
--- a/docs/submarine-sdk/pysubmarine/openapi.yaml
+++ /dev/null
@@ -1,244 +0,0 @@
-openapi: 3.0.1
-info:
- title: Submarine Experiment API
- description: 'The Submarine REST API allows you to create, list, and get experiments. TheAPI is hosted under the /v1/jobs route on the Submarine server. For example,to list experiments on a server hosted at http://localhost:8080, accesshttp://localhost:8080/api/v1/jobs/'
- termsOfService: 'http://swagger.io/terms/'
- contact:
- email: submarine-dev@submarine.apache.org
- license:
- name: Apache 2.0
- url: 'http://www.apache.org/licenses/LICENSE-2.0.html'
- version: 0.4.0-SNAPSHOT
-servers:
- - url: /api
-paths:
- /v1/jobs:
- get:
- tags:
- - jobs
- summary: List jobs
- operationId: listJob
- parameters:
- - name: status
- in: query
- schema:
- type: string
- responses:
- default:
- description: successful operation
- content:
- application/json; charset=utf-8:
- schema:
- $ref: '#/components/schemas/JsonResponse'
- post:
- tags:
- - jobs
- summary: Create a job
- operationId: createJob
- requestBody:
- content:
- application/yaml:
- schema:
- $ref: '#/components/schemas/JobSpec'
- application/json:
- schema:
- $ref: '#/components/schemas/JobSpec'
- responses:
- default:
- description: successful operation
- content:
- application/json; charset=utf-8:
- schema:
- $ref: '#/components/schemas/JsonResponse'
- '/v1/jobs/{id}':
- get:
- tags:
- - jobs
- summary: Find job by id
- operationId: getJob
- parameters:
- - name: id
- in: path
- required: true
- schema:
- type: string
- responses:
- '404':
- description: Job not found
- default:
- description: successful operation
- content:
- application/json; charset=utf-8:
- schema:
- $ref: '#/components/schemas/JsonResponse'
- delete:
- tags:
- - jobs
- summary: Delete the job
- operationId: deleteJob
- parameters:
- - name: id
- in: path
- required: true
- schema:
- type: string
- responses:
- '404':
- description: Job not found
- default:
- description: successful operation
- content:
- application/json; charset=utf-8:
- schema:
- $ref: '#/components/schemas/JsonResponse'
- patch:
- tags:
- - jobs
- summary: Update the job in the submarine server with job spec
- operationId: patchJob
- parameters:
- - name: id
- in: path
- required: true
- schema:
- type: string
- requestBody:
- content:
- application/yaml:
- schema:
- $ref: '#/components/schemas/JobSpec'
- application/json:
- schema:
- $ref: '#/components/schemas/JobSpec'
- responses:
- '404':
- description: Job not found
- default:
- description: successful operation
- content:
- application/json; charset=utf-8:
- schema:
- $ref: '#/components/schemas/JsonResponse'
- /v1/jobs/logs:
- get:
- tags:
- - jobs
- summary: Log jobs
- operationId: listLog
- parameters:
- - name: status
- in: query
- schema:
- type: string
- responses:
- default:
- description: successful operation
- content:
- application/json; charset=utf-8:
- schema:
- $ref: '#/components/schemas/JsonResponse'
- '/v1/jobs/logs/{id}':
- get:
- tags:
- - jobs
- summary: Log job by id
- operationId: getLog
- parameters:
- - name: id
- in: path
- required: true
- schema:
- type: string
- responses:
- '404':
- description: Job not found
- default:
- description: successful operation
- content:
- application/json; charset=utf-8:
- schema:
- $ref: '#/components/schemas/JsonResponse'
- /v1/jobs/ping:
- get:
- tags:
- - jobs
- summary: Ping submarine server
- description: Return the Pong message for test the connectivity
- operationId: ping
- responses:
- '200':
- description: successful operation
- content:
- application/json; charset=utf-8:
- schema:
- type: string
-components:
- schemas:
- JsonResponse:
- type: object
- properties:
- code:
- type: integer
- format: int32
- success:
- type: boolean
- result:
- type: object
- attributes:
- type: object
- additionalProperties:
- type: object
- JobLibrarySpec:
- type: object
- properties:
- name:
- type: string
- version:
- type: string
- image:
- type: string
- cmd:
- type: string
- envVars:
- type: object
- additionalProperties:
- type: string
- JobSpec:
- type: object
- properties:
- name:
- type: string
- namespace:
- type: string
- librarySpec:
- $ref: '#/components/schemas/JobLibrarySpec'
- taskSpecs:
- type: object
- additionalProperties:
- $ref: '#/components/schemas/JobTaskSpec'
- projects:
- type: string
- JobTaskSpec:
- type: object
- properties:
- name:
- type: string
- image:
- type: string
- cmd:
- type: string
- envVars:
- type: object
- additionalProperties:
- type: string
- resources:
- type: string
- replicas:
- type: integer
- format: int32
- cpu:
- type: string
- gpu:
- type: string
- memory:
- type: string
diff --git a/submarine-sdk/pysubmarine/example/submarine_experiment_sdk.ipynb b/submarine-sdk/pysubmarine/example/submarine_experiment_sdk.ipynb
new file mode 100644
index 0000000..9c1f5e2
--- /dev/null
+++ b/submarine-sdk/pysubmarine/example/submarine_experiment_sdk.ipynb
@@ -0,0 +1,289 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Sample for Submarine Experiment SDK\n",
+ "\n",
+ "The notebook shows how to use Submarine Experiment SDK to create, get, list, log, delete Submarine Experiment."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 21,
+ "metadata": {
+ "pycharm": {
+ "is_executing": false
+ }
+ },
+ "outputs": [],
+ "source": [
+ "from __future__ import print_function\n",
+ "from submarine.experiment.configuration import Configuration\n",
+ "from submarine.experiment.api_client import ApiClient\n",
+ "from submarine.experiment.api.experiment_api import ExperimentApi\n",
+ "from submarine.experiment.models.environment import Environment\n",
+ "from submarine.experiment.models.experiment_spec import ExperimentSpec\n",
+ "from submarine.experiment.models.experiment_task_spec import ExperimentTaskSpec\n",
+ "from submarine.experiment.models.experiment_meta import ExperimentMeta"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Create Submarine Client"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 22,
+ "metadata": {
+ "pycharm": {
+ "is_executing": false,
+ "name": "#%%\n"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "configuration = Configuration()\n",
+ "configuration.host = 'http://192.168.103.9:8080/api'\n",
+ "api_client = ApiClient(configuration=configuration)\n",
+ "submarine_client = ExperimentApi(api_client=api_client)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "pycharm": {
+ "name": "#%% md\n"
+ }
+ },
+ "source": [
+ "### Define TensorFlow experiment spec¶\n",
+ "Define Submarine spec¶\n",
+ "The demo only creates a worker of TF experiment to run mnist sample."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 23,
+ "metadata": {
+ "pycharm": {
+ "is_executing": false,
+ "name": "#%%\n"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "experiment_meta = ExperimentMeta(name='mnist',\n",
+ " namespace='submarine',\n",
+ " framework='Tensorflow',\n",
+ " cmd='python /var/tf_mnist/mnist_with_summaries.py'\n",
+ " ' --log_dir=/train/log --learning_rate=0.01'\n",
+ " ' --batch_size=150',\n",
+ " env_vars={'ENV1': 'ENV1'})\n",
+ "\n",
+ "worker_spec = ExperimentTaskSpec(resources='cpu=4,memory=2048M',\n",
+ " replicas=1)\n",
+ "\n",
+ "environment = Environment(image='gcr.io/kubeflow-ci/tf-mnist-with-summaries:1.0')\n",
+ "\n",
+ "experiment_spec = ExperimentSpec(meta=experiment_meta,\n",
+ " environment=environment,\n",
+ " spec={'Worker': worker_spec}) \n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Create experiment"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 24,
+ "metadata": {
+ "pycharm": {
+ "name": "#%%\n",
+ "is_executing": false
+ },
+ "scrolled": true
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": "{'attributes': {},\n 'code': 200,\n 'result': {'acceptedTime': '2020-06-18T08:25:14.000+08:00',\n 'createdTime': None,\n 'experimentId': 'experiment_1592409071112_0002',\n 'finishedTime': None,\n 'name': 'mnist',\n 'runningTime': None,\n 'spec': {'environment': {'image': 'gcr.io/kubeflow-ci/tf-mnist-with-summaries:1.0'},\n 'meta': {'cmd': 'python '\n [...]
+ },
+ "metadata": {},
+ "output_type": "execute_result",
+ "execution_count": 24
+ }
+ ],
+ "source": [
+ "submarine_client.create_experiment(experiment_spec=experiment_spec)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Get the created experiment"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 26,
+ "metadata": {
+ "pycharm": {
+ "name": "#%%\n",
+ "is_executing": false
+ }
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": "{'attributes': {},\n 'code': 200,\n 'result': {'acceptedTime': '2020-06-18T08:25:14.000+08:00',\n 'createdTime': '2020-06-18T08:25:14.000+08:00',\n 'experimentId': 'experiment_1592409071112_0002',\n 'finishedTime': None,\n 'name': 'mnist',\n 'runningTime': '2020-06-18T08:25:16.000+08:00',\n 'spec': {'environment': {'image': 'gcr.io/kubeflow-ci/tf-mnist-with-summaries:1.0'},\n 'meta' [...]
+ },
+ "metadata": {},
+ "output_type": "execute_result",
+ "execution_count": 26
+ }
+ ],
+ "source": [
+ "id = 'experiment_1592409071112_0002'\n",
+ "submarine_client.get_experiment(id)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### List all running experiments"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 27,
+ "metadata": {
+ "pycharm": {
+ "name": "#%%\n",
+ "is_executing": false
+ }
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": "{'attributes': {},\n 'code': 200,\n 'result': [{'acceptedTime': '2020-06-18T08:25:14.000+08:00',\n 'createdTime': '2020-06-18T08:25:14.000+08:00',\n 'experimentId': 'experiment_1592409071112_0002',\n 'finishedTime': None,\n 'name': 'mnist',\n 'runningTime': '2020-06-18T08:25:16.000+08:00',\n 'spec': {'environment': {'image': 'gcr.io/kubeflow-ci/tf-mnist-with-summaries:1.0'},\n [...]
+ },
+ "metadata": {},
+ "output_type": "execute_result",
+ "execution_count": 27
+ }
+ ],
+ "source": [
+ "status = 'running'\n",
+ "submarine_client.list_experiments(status=status)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Get specific experiment training log "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 32,
+ "metadata": {
+ "pycharm": {
+ "name": "#%%\n",
+ "is_executing": false
+ }
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": "{'attributes': {},\n 'code': 200,\n 'result': {'experimentId': 'experiment_1592409071112_0002',\n 'logContent': [{'podLog': ['WARNING:tensorflow:From '\n '/var/tf_mnist/mnist_with_summaries.py:39: '\n 'read_data_sets (from '\n 'tensorflow.contrib.learn.python.learn.datasets.mnist) '\n 'is deprecated and wil [...]
+ },
+ "metadata": {},
+ "output_type": "execute_result",
+ "execution_count": 32
+ }
+ ],
+ "source": [
+ "submarine_client.get_log(id)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Delete the experiment"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 33,
+ "metadata": {
+ "pycharm": {
+ "name": "#%%\n",
+ "is_executing": false
+ }
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": "{'attributes': {},\n 'code': 200,\n 'result': {'acceptedTime': '2020-06-18T08:25:14.000+08:00',\n 'createdTime': '2020-06-18T08:25:14.000+08:00',\n 'experimentId': 'experiment_1592409071112_0002',\n 'finishedTime': '2020-06-18T08:29:02.000+08:00',\n 'name': 'mnist',\n 'runningTime': '2020-06-18T08:25:16.000+08:00',\n 'spec': {'environment': {'image': 'gcr.io/kubeflow-ci/tf-mnist-with-summaries:1.0'},\n [...]
+ },
+ "metadata": {},
+ "output_type": "execute_result",
+ "execution_count": 33
+ }
+ ],
+ "source": [
+ "submarine_client.delete_experiment(id)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.7.6"
+ },
+ "pycharm": {
+ "stem_cell": {
+ "cell_type": "raw",
+ "source": [],
+ "metadata": {
+ "collapsed": false
+ }
+ }
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 1
+}
diff --git a/submarine-sdk/pysubmarine/example/submarine_job_sdk.ipynb b/submarine-sdk/pysubmarine/example/submarine_job_sdk.ipynb
deleted file mode 100644
index 9ff9550..0000000
--- a/submarine-sdk/pysubmarine/example/submarine_job_sdk.ipynb
+++ /dev/null
@@ -1,608 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Sample for Submarine Experiment SDK\n",
- "\n",
- "The notebook shows how to use Subamrine Experiment SDK to create, get, list, log, delete Submarine Experiment."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "metadata": {
- "pycharm": {
- "is_executing": false
- }
- },
- "outputs": [],
- "source": [
- "from __future__ import print_function\n",
- "import submarine\n",
- "\n",
- "from submarine import JobLibrarySpec\n",
- "from submarine import JobTaskSpec\n",
- "from submarine import JobSpec"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Create Submarine Client"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 7,
- "metadata": {
- "pycharm": {
- "is_executing": false,
- "name": "#%%\n"
- }
- },
- "outputs": [],
- "source": [
- "configuration = submarine.Configuration()\n",
- "configuration.host = 'http://192.168.103.9:8080/api'\n",
- "api_client = submarine.ApiClient(configuration=configuration)\n",
- "submarine_client = submarine.JobsApi(api_client=api_client)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "pycharm": {
- "name": "#%% md\n"
- }
- },
- "source": [
- "### Define TFJob¶\n",
- "Define Submarine spec¶\n",
- "The demo only creates a worker of TFJob to run mnist sample."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 8,
- "metadata": {
- "pycharm": {
- "is_executing": false,
- "name": "#%%\n"
- }
- },
- "outputs": [],
- "source": [
- "jobLibrarySpec = JobLibrarySpec(name='tensorflow',\n",
- " version='2.1.0',\n",
- " image='gcr.io/kubeflow-ci/tf-mnist-with-summaries:1.0',\n",
- " cmd='python /var/tf_mnist/mnist_with_summaries.py'\n",
- " ' --log_dir=/train/log --learning_rate=0.01'\n",
- " ' --batch_size=150',\n",
- " env_vars={'ENV1': 'ENV1'})\n",
- "\n",
- "worker = JobTaskSpec(name='tensorlfow',\n",
- " image=None,\n",
- " cmd=None,\n",
- " env_vars=None,\n",
- " resources='cpu=4,memory=2048M',\n",
- " replicas=1)\n",
- "\n",
- "body = JobSpec(name='mnist',\n",
- " namespace='submarine',\n",
- " library_spec=jobLibrarySpec,\n",
- " task_specs={\"Worker\": worker})"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Create experiment"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 19,
- "metadata": {
- "pycharm": {
- "name": "#%%\n"
- },
- "scrolled": true
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "{'attributes': {},\n",
- " 'code': 200,\n",
- " 'result': {'acceptedTime': '2020-05-21T18:23:09.000+08:00',\n",
- " 'createdTime': None,\n",
- " 'finishedTime': None,\n",
- " 'jobId': 'job_1590056548552_0001',\n",
- " 'name': 'mnist',\n",
- " 'runningTime': None,\n",
- " 'spec': {'librarySpec': {'cmd': 'python '\n",
- " '/var/tf_mnist/mnist_with_summaries.py '\n",
- " '--log_dir=/train/log '\n",
- " '--learning_rate=0.01 '\n",
- " '--batch_size=150',\n",
- " 'envVars': {'ENV1': 'ENV1'},\n",
- " 'image': 'gcr.io/kubeflow-ci/tf-mnist-with-summaries:1.0',\n",
- " 'name': 'tensorflow',\n",
- " 'version': '2.1.0'},\n",
- " 'name': 'mnist',\n",
- " 'namespace': 'submarine',\n",
- " 'projects': None,\n",
- " 'taskSpecs': {'Worker': {'cmd': None,\n",
- " 'envVars': None,\n",
- " 'image': None,\n",
- " 'name': 'tensorlfow',\n",
- " 'replicas': 1,\n",
- " 'resourceMap': {'cpu': '4',\n",
- " 'memory': '2048M'},\n",
- " 'resources': 'cpu=4,memory=2048M'}}},\n",
- " 'status': 'Accepted',\n",
- " 'uid': '10b226b9-3710-40e9-9f13-9322e03dcb8d'},\n",
- " 'success': True}"
- ]
- },
- "execution_count": 19,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "submarine_client.create_job(body=body)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Get the created experiment"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 20,
- "metadata": {
- "pycharm": {
- "name": "#%%\n"
- }
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "{'attributes': {},\n",
- " 'code': 200,\n",
- " 'result': {'acceptedTime': '2020-05-21T18:23:09.000+08:00',\n",
- " 'createdTime': '2020-05-21T18:23:09.000+08:00',\n",
- " 'finishedTime': None,\n",
- " 'jobId': 'job_1590056548552_0001',\n",
- " 'name': 'mnist',\n",
- " 'runningTime': '2020-05-21T18:23:11.000+08:00',\n",
- " 'spec': {'librarySpec': {'cmd': 'python '\n",
- " '/var/tf_mnist/mnist_with_summaries.py '\n",
- " '--log_dir=/train/log '\n",
- " '--learning_rate=0.01 '\n",
- " '--batch_size=150',\n",
- " 'envVars': {'ENV1': 'ENV1'},\n",
- " 'image': 'gcr.io/kubeflow-ci/tf-mnist-with-summaries:1.0',\n",
- " 'name': 'tensorflow',\n",
- " 'version': '2.1.0'},\n",
- " 'name': 'mnist',\n",
- " 'namespace': 'submarine',\n",
- " 'projects': None,\n",
- " 'taskSpecs': {'Worker': {'cmd': None,\n",
- " 'envVars': None,\n",
- " 'image': None,\n",
- " 'name': 'tensorlfow',\n",
- " 'replicas': 1,\n",
- " 'resourceMap': {'cpu': '4',\n",
- " 'memory': '2048M'},\n",
- " 'resources': 'cpu=4,memory=2048M'}}},\n",
- " 'status': 'Running',\n",
- " 'uid': '10b226b9-3710-40e9-9f13-9322e03dcb8d'},\n",
- " 'success': True}"
- ]
- },
- "execution_count": 20,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "id = 'job_1590056548552_0001'\n",
- "submarine_client.get_job(id)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### List all running experiments"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 21,
- "metadata": {
- "pycharm": {
- "name": "#%%\n"
- }
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "{'attributes': {},\n",
- " 'code': 200,\n",
- " 'result': [{'acceptedTime': '2020-05-21T18:23:09.000+08:00',\n",
- " 'createdTime': '2020-05-21T18:23:09.000+08:00',\n",
- " 'finishedTime': None,\n",
- " 'jobId': 'job_1590056548552_0001',\n",
- " 'name': 'mnist',\n",
- " 'runningTime': '2020-05-21T18:23:11.000+08:00',\n",
- " 'spec': {'librarySpec': {'cmd': 'python '\n",
- " '/var/tf_mnist/mnist_with_summaries.py '\n",
- " '--log_dir=/train/log '\n",
- " '--learning_rate=0.01 '\n",
- " '--batch_size=150',\n",
- " 'envVars': {'ENV1': 'ENV1'},\n",
- " 'image': 'gcr.io/kubeflow-ci/tf-mnist-with-summaries:1.0',\n",
- " 'name': 'tensorflow',\n",
- " 'version': '2.1.0'},\n",
- " 'name': 'mnist',\n",
- " 'namespace': 'submarine',\n",
- " 'projects': None,\n",
- " 'taskSpecs': {'Worker': {'cmd': None,\n",
- " 'envVars': None,\n",
- " 'image': None,\n",
- " 'name': 'tensorlfow',\n",
- " 'replicas': 1,\n",
- " 'resourceMap': {'cpu': '4',\n",
- " 'memory': '2048M'},\n",
- " 'resources': 'cpu=4,memory=2048M'}}},\n",
- " 'status': 'Running',\n",
- " 'uid': '10b226b9-3710-40e9-9f13-9322e03dcb8d'}],\n",
- " 'success': True}"
- ]
- },
- "execution_count": 21,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "status = 'running'\n",
- "submarine_client.list_job(status=status)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Get specific experiment training log "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 24,
- "metadata": {
- "pycharm": {
- "name": "#%%\n"
- }
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "{'attributes': {},\n",
- " 'code': 200,\n",
- " 'result': {'jobId': 'job_1590056548552_0001',\n",
- " 'logContent': [{'podLog': 'WARNING:tensorflow:From '\n",
- " '/var/tf_mnist/mnist_with_summaries.py:39: '\n",
- " 'read_data_sets (from '\n",
- " 'tensorflow.contrib.learn.python.learn.datasets.mnist) '\n",
- " 'is deprecated and will be removed in a '\n",
- " 'future version.\\n'\n",
- " 'Instructions for updating:\\n'\n",
- " 'Please use alternatives such as '\n",
- " 'official/mnist/dataset.py from '\n",
- " 'tensorflow/models.\\n'\n",
- " 'WARNING:tensorflow:From '\n",
- " '/usr/local/lib/python2.7/dist-packages/tensorflow/contrib/learn/python/learn/datasets/mnist.py:260: '\n",
- " 'maybe_download (from '\n",
- " 'tensorflow.contrib.learn.python.learn.datasets.base) '\n",
- " 'is deprecated and will be removed in a '\n",
- " 'future version.\\n'\n",
- " 'Instructions for updating:\\n'\n",
- " 'Please write your own downloading '\n",
- " 'logic.\\n'\n",
- " 'WARNING:tensorflow:From '\n",
- " '/usr/local/lib/python2.7/dist-packages/tensorflow/contrib/learn/python/learn/datasets/base.py:252: '\n",
- " 'wrapped_fn (from '\n",
- " 'tensorflow.contrib.learn.python.learn.datasets.base) '\n",
- " 'is deprecated and will be removed in a '\n",
- " 'future version.\\n'\n",
- " 'Instructions for updating:\\n'\n",
- " 'Please use urllib or similar directly.\\n'\n",
- " 'WARNING:tensorflow:From '\n",
- " '/usr/local/lib/python2.7/dist-packages/tensorflow/contrib/learn/python/learn/datasets/mnist.py:262: '\n",
- " 'extract_images (from '\n",
- " 'tensorflow.contrib.learn.python.learn.datasets.mnist) '\n",
- " 'is deprecated and will be removed in a '\n",
- " 'future version.\\n'\n",
- " 'Instructions for updating:\\n'\n",
- " 'Please use tf.data to implement this '\n",
- " 'functionality.\\n'\n",
- " 'WARNING:tensorflow:From '\n",
- " '/usr/local/lib/python2.7/dist-packages/tensorflow/contrib/learn/python/learn/datasets/mnist.py:267: '\n",
- " 'extract_labels (from '\n",
- " 'tensorflow.contrib.learn.python.learn.datasets.mnist) '\n",
- " 'is deprecated and will be removed in a '\n",
- " 'future version.\\n'\n",
- " 'Instructions for updating:\\n'\n",
- " 'Please use tf.data to implement this '\n",
- " 'functionality.\\n'\n",
- " 'WARNING:tensorflow:From '\n",
- " '/usr/local/lib/python2.7/dist-packages/tensorflow/contrib/learn/python/learn/datasets/mnist.py:290: '\n",
- " '__init__ (from '\n",
- " 'tensorflow.contrib.learn.python.learn.datasets.mnist) '\n",
- " 'is deprecated and will be removed in a '\n",
- " 'future version.\\n'\n",
- " 'Instructions for updating:\\n'\n",
- " 'Please use alternatives such as '\n",
- " 'official/mnist/dataset.py from '\n",
- " 'tensorflow/models.\\n'\n",
- " '2020-05-21 10:23:16.050386: I '\n",
- " 'tensorflow/core/platform/cpu_feature_guard.cc:141] '\n",
- " 'Your CPU supports instructions that '\n",
- " 'this TensorFlow binary was not compiled '\n",
- " 'to use: AVX2 FMA\\n'\n",
- " 'Successfully downloaded '\n",
- " 'train-images-idx3-ubyte.gz 9912422 '\n",
- " 'bytes.\\n'\n",
- " 'Extracting '\n",
- " '/tmp/tensorflow/mnist/input_data/train-images-idx3-ubyte.gz\\n'\n",
- " 'Successfully downloaded '\n",
- " 'train-labels-idx1-ubyte.gz 28881 '\n",
- " 'bytes.\\n'\n",
- " 'Extracting '\n",
- " '/tmp/tensorflow/mnist/input_data/train-labels-idx1-ubyte.gz\\n'\n",
- " 'Successfully downloaded '\n",
- " 't10k-images-idx3-ubyte.gz 1648877 '\n",
- " 'bytes.\\n'\n",
- " 'Extracting '\n",
- " '/tmp/tensorflow/mnist/input_data/t10k-images-idx3-ubyte.gz\\n'\n",
- " 'Successfully downloaded '\n",
- " 't10k-labels-idx1-ubyte.gz 4542 bytes.\\n'\n",
- " 'Extracting '\n",
- " '/tmp/tensorflow/mnist/input_data/t10k-labels-idx1-ubyte.gz\\n'\n",
- " 'Accuracy at step 0: 0.1102\\n'\n",
- " 'Accuracy at step 10: 0.6304\\n'\n",
- " 'Accuracy at step 20: 0.8477\\n'\n",
- " 'Accuracy at step 30: 0.886\\n'\n",
- " 'Accuracy at step 40: 0.9034\\n'\n",
- " 'Accuracy at step 50: 0.9165\\n'\n",
- " 'Accuracy at step 60: 0.9248\\n'\n",
- " 'Accuracy at step 70: 0.9211\\n'\n",
- " 'Accuracy at step 80: 0.9304\\n'\n",
- " 'Accuracy at step 90: 0.9333\\n'\n",
- " 'Adding run metadata for 99\\n'\n",
- " 'Accuracy at step 100: 0.9388\\n'\n",
- " 'Accuracy at step 110: 0.9345\\n'\n",
- " 'Accuracy at step 120: 0.9427\\n'\n",
- " 'Accuracy at step 130: 0.9452\\n'\n",
- " 'Accuracy at step 140: 0.9393\\n'\n",
- " 'Accuracy at step 150: 0.9474\\n'\n",
- " 'Accuracy at step 160: 0.9506\\n'\n",
- " 'Accuracy at step 170: 0.9539\\n'\n",
- " 'Accuracy at step 180: 0.9491\\n'\n",
- " 'Accuracy at step 190: 0.946\\n'\n",
- " 'Adding run metadata for 199\\n'\n",
- " 'Accuracy at step 200: 0.9524\\n'\n",
- " 'Accuracy at step 210: 0.9466\\n'\n",
- " 'Accuracy at step 220: 0.9466\\n'\n",
- " 'Accuracy at step 230: 0.9516\\n'\n",
- " 'Accuracy at step 240: 0.9521\\n'\n",
- " 'Accuracy at step 250: 0.9516\\n'\n",
- " 'Accuracy at step 260: 0.9511\\n'\n",
- " 'Accuracy at step 270: 0.9515\\n'\n",
- " 'Accuracy at step 280: 0.9535\\n'\n",
- " 'Accuracy at step 290: 0.956\\n'\n",
- " 'Adding run metadata for 299\\n'\n",
- " 'Accuracy at step 300: 0.9594\\n'\n",
- " 'Accuracy at step 310: 0.9584\\n'\n",
- " 'Accuracy at step 320: 0.9595\\n'\n",
- " 'Accuracy at step 330: 0.9584\\n'\n",
- " 'Accuracy at step 340: 0.9605\\n'\n",
- " 'Accuracy at step 350: 0.9593\\n'\n",
- " 'Accuracy at step 360: 0.9637\\n'\n",
- " 'Accuracy at step 370: 0.9598\\n'\n",
- " 'Accuracy at step 380: 0.96\\n'\n",
- " 'Accuracy at step 390: 0.9576\\n'\n",
- " 'Adding run metadata for 399\\n'\n",
- " 'Accuracy at step 400: 0.9589\\n'\n",
- " 'Accuracy at step 410: 0.9587\\n'\n",
- " 'Accuracy at step 420: 0.9643\\n'\n",
- " 'Accuracy at step 430: 0.9626\\n'\n",
- " 'Accuracy at step 440: 0.964\\n'\n",
- " 'Accuracy at step 450: 0.9641\\n'\n",
- " 'Accuracy at step 460: 0.9622\\n'\n",
- " 'Accuracy at step 470: 0.9634\\n'\n",
- " 'Accuracy at step 480: 0.9669\\n'\n",
- " 'Accuracy at step 490: 0.9675\\n'\n",
- " 'Adding run metadata for 499\\n'\n",
- " 'Accuracy at step 500: 0.9599\\n'\n",
- " 'Accuracy at step 510: 0.9653\\n'\n",
- " 'Accuracy at step 520: 0.9665\\n'\n",
- " 'Accuracy at step 530: 0.9643\\n'\n",
- " 'Accuracy at step 540: 0.96\\n'\n",
- " 'Accuracy at step 550: 0.9582\\n'\n",
- " 'Accuracy at step 560: 0.9644\\n'\n",
- " 'Accuracy at step 570: 0.9587\\n'\n",
- " 'Accuracy at step 580: 0.9662\\n'\n",
- " 'Accuracy at step 590: 0.9612\\n'\n",
- " 'Adding run metadata for 599\\n'\n",
- " 'Accuracy at step 600: 0.9574\\n'\n",
- " 'Accuracy at step 610: 0.9643\\n'\n",
- " 'Accuracy at step 620: 0.9665\\n'\n",
- " 'Accuracy at step 630: 0.9657\\n'\n",
- " 'Accuracy at step 640: 0.9659\\n'\n",
- " 'Accuracy at step 650: 0.9644\\n'\n",
- " 'Accuracy at step 660: 0.9683\\n'\n",
- " 'Accuracy at step 670: 0.969\\n'\n",
- " 'Accuracy at step 680: 0.9618\\n'\n",
- " 'Accuracy at step 690: 0.968\\n'\n",
- " 'Adding run metadata for 699\\n'\n",
- " 'Accuracy at step 700: 0.9641\\n'\n",
- " 'Accuracy at step 710: 0.9681\\n'\n",
- " 'Accuracy at step 720: 0.967\\n'\n",
- " 'Accuracy at step 730: 0.9661\\n'\n",
- " 'Accuracy at step 740: 0.9679\\n'\n",
- " 'Accuracy at step 750: 0.9676\\n'\n",
- " 'Accuracy at step 760: 0.9681\\n'\n",
- " 'Accuracy at step 770: 0.9668\\n'\n",
- " 'Accuracy at step 780: 0.9657\\n'\n",
- " 'Accuracy at step 790: 0.9597\\n'\n",
- " 'Adding run metadata for 799\\n'\n",
- " 'Accuracy at step 800: 0.964\\n'\n",
- " 'Accuracy at step 810: 0.9655\\n'\n",
- " 'Accuracy at step 820: 0.966\\n'\n",
- " 'Accuracy at step 830: 0.9706\\n'\n",
- " 'Accuracy at step 840: 0.9702\\n'\n",
- " 'Accuracy at step 850: 0.969\\n'\n",
- " 'Accuracy at step 860: 0.97\\n'\n",
- " 'Accuracy at step 870: 0.9712\\n'\n",
- " 'Accuracy at step 880: 0.9677\\n'\n",
- " 'Accuracy at step 890: 0.9655\\n'\n",
- " 'Adding run metadata for 899\\n'\n",
- " 'Accuracy at step 900: 0.9696\\n'\n",
- " 'Accuracy at step 910: 0.9718\\n'\n",
- " 'Accuracy at step 920: 0.9708\\n'\n",
- " 'Accuracy at step 930: 0.971\\n'\n",
- " 'Accuracy at step 940: 0.9697\\n'\n",
- " 'Accuracy at step 950: 0.9698\\n'\n",
- " 'Accuracy at step 960: 0.969\\n'\n",
- " 'Accuracy at step 970: 0.9685\\n'\n",
- " 'Accuracy at step 980: 0.968\\n'\n",
- " 'Accuracy at step 990: 0.9682\\n'\n",
- " 'Adding run metadata for 999\\n',\n",
- " 'podName': 'mnist-worker-0'}]},\n",
- " 'success': True}"
- ]
- },
- "execution_count": 24,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "submarine_client.get_log(id)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Delete the experiment"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 25,
- "metadata": {
- "pycharm": {
- "name": "#%%\n"
- }
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "{'attributes': {},\n",
- " 'code': 200,\n",
- " 'result': {'acceptedTime': '2020-05-21T18:23:09.000+08:00',\n",
- " 'createdTime': '2020-05-21T18:23:09.000+08:00',\n",
- " 'finishedTime': '2020-05-21T18:35:44.000+08:00',\n",
- " 'jobId': 'job_1590056548552_0001',\n",
- " 'name': 'mnist',\n",
- " 'runningTime': '2020-05-21T18:23:11.000+08:00',\n",
- " 'spec': {'librarySpec': {'cmd': 'python '\n",
- " '/var/tf_mnist/mnist_with_summaries.py '\n",
- " '--log_dir=/train/log '\n",
- " '--learning_rate=0.01 '\n",
- " '--batch_size=150',\n",
- " 'envVars': {'ENV1': 'ENV1'},\n",
- " 'image': 'gcr.io/kubeflow-ci/tf-mnist-with-summaries:1.0',\n",
- " 'name': 'tensorflow',\n",
- " 'version': '2.1.0'},\n",
- " 'name': 'mnist',\n",
- " 'namespace': 'submarine',\n",
- " 'projects': None,\n",
- " 'taskSpecs': {'Worker': {'cmd': None,\n",
- " 'envVars': None,\n",
- " 'image': None,\n",
- " 'name': 'tensorlfow',\n",
- " 'replicas': 1,\n",
- " 'resourceMap': {'cpu': '4',\n",
- " 'memory': '2048M'},\n",
- " 'resources': 'cpu=4,memory=2048M'}}},\n",
- " 'status': 'Deleted',\n",
- " 'uid': '10b226b9-3710-40e9-9f13-9322e03dcb8d'},\n",
- " 'success': True}"
- ]
- },
- "execution_count": 25,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "submarine_client.delete_job(id)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.7.6"
- },
- "pycharm": {
- "stem_cell": {
- "cell_type": "raw",
- "source": [],
- "metadata": {
- "collapsed": false
- }
- }
- }
- },
- "nbformat": 4,
- "nbformat_minor": 1
-}
diff --git a/submarine-sdk/pysubmarine/github-actions/lint.sh b/submarine-sdk/pysubmarine/github-actions/lint.sh
index 83a7fac..07d92c0 100755
--- a/submarine-sdk/pysubmarine/github-actions/lint.sh
+++ b/submarine-sdk/pysubmarine/github-actions/lint.sh
@@ -21,7 +21,7 @@ cd "$FWDIR"
cd ..
pycodestyle --max-line-length=100 -- submarine tests
-pylint --ignore job --msg-template="{path} ({line},{column}): [{msg_id} {symbol}] {msg}" --rcfile=pylintrc -- submarine tests
+pylint --ignore experiment --msg-template="{path} ({line},{column}): [{msg_id} {symbol}] {msg}" --rcfile=pylintrc -- submarine tests
./github-actions/auto-format.sh
GIT_STATUS="$(git status --porcelain)"
diff --git a/submarine-sdk/pysubmarine/submarine/__init__.py b/submarine-sdk/pysubmarine/submarine/__init__.py
index 5484d8b..2f11da9 100644
--- a/submarine-sdk/pysubmarine/submarine/__init__.py
+++ b/submarine-sdk/pysubmarine/submarine/__init__.py
@@ -15,16 +15,14 @@
import submarine.tracking as tracking
import submarine.tracking.fluent
-from submarine.job import (ApiClient, Configuration, JobLibrarySpec, JobsApi,
- JobSpec, JobTaskSpec)
log_param = submarine.tracking.fluent.log_param
log_metric = submarine.tracking.fluent.log_metric
set_tracking_uri = tracking.set_tracking_uri
get_tracking_uri = tracking.get_tracking_uri
-__all__ = [
- "log_metric", "log_param", "set_tracking_uri", "get_tracking_uri",
- "ApiClient", "JobLibrarySpec", "JobSpec", "JobTaskSpec", "Configuration",
- "JobsApi"
-]
+__all__ = ["log_metric",
+ "log_param",
+ "set_tracking_uri",
+ "get_tracking_uri"
+ ]
diff --git a/submarine-sdk/pysubmarine/submarine/experiment/__init__.py b/submarine-sdk/pysubmarine/submarine/experiment/__init__.py
new file mode 100644
index 0000000..2f3973c
--- /dev/null
+++ b/submarine-sdk/pysubmarine/submarine/experiment/__init__.py
@@ -0,0 +1,46 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# coding: utf-8
+
+# flake8: noqa
+"""
+ Submarine Experiment API
+
+ The Submarine REST API allows you to create, list, and get experiments. The API is hosted under the /v1/experiment route on the Submarine server. For example, to list experiments on a server hosted at http://localhost:8080, access http://localhost:8080/api/v1/experiment/ # noqa: E501
+
+ The version of the OpenAPI document: 0.4.0-SNAPSHOT
+ Contact: submarine-dev@submarine.apache.org
+ Generated by: https://openapi-generator.tech
+"""
+
+from __future__ import absolute_import
+
+# import apis into sdk package
+from submarine.experiment.api.experiment_api import ExperimentApi
+# import ApiClient
+from submarine.experiment.api_client import ApiClient
+from submarine.experiment.configuration import Configuration
+from submarine.experiment.exceptions import (ApiException, ApiKeyError,
+ ApiTypeError, ApiValueError,
+ OpenApiException)
+# import models into sdk package
+from submarine.experiment.models.environment import Environment
+from submarine.experiment.models.experiment_meta import ExperimentMeta
+from submarine.experiment.models.experiment_spec import ExperimentSpec
+from submarine.experiment.models.experiment_task_spec import ExperimentTaskSpec
+from submarine.experiment.models.json_response import JsonResponse
+
+__version__ = "0.4.0-SNAPSHOT"
diff --git a/submarine-sdk/pysubmarine/submarine/job/api/__init__.py b/submarine-sdk/pysubmarine/submarine/experiment/api/__init__.py
similarity index 74%
rename from submarine-sdk/pysubmarine/submarine/job/api/__init__.py
rename to submarine-sdk/pysubmarine/submarine/experiment/api/__init__.py
index 952d741..62dc60e 100644
--- a/submarine-sdk/pysubmarine/submarine/job/api/__init__.py
+++ b/submarine-sdk/pysubmarine/submarine/experiment/api/__init__.py
@@ -1,11 +1,11 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
+# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
+# the License. You may obtain a copy of the License at
#
-# http://www.apache.org/licenses/LICENSE-2.0
+# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
@@ -15,7 +15,7 @@
from __future__ import absolute_import
-# import apis into api package
-from submarine.job.api.jobs_api import JobsApi
-
# flake8: noqa
+
+# import apis into api package
+from submarine.experiment.api.experiment_api import ExperimentApi
diff --git a/submarine-sdk/pysubmarine/submarine/experiment/api/experiment_api.py b/submarine-sdk/pysubmarine/submarine/experiment/api/experiment_api.py
new file mode 100644
index 0000000..b23180c
--- /dev/null
+++ b/submarine-sdk/pysubmarine/submarine/experiment/api/experiment_api.py
@@ -0,0 +1,943 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# coding: utf-8
+
+"""
+ Submarine Experiment API
+
+ The Submarine REST API allows you to create, list, and get experiments. The API is hosted under the /v1/experiment route on the Submarine server. For example, to list experiments on a server hosted at http://localhost:8080, access http://localhost:8080/api/v1/experiment/ # noqa: E501
+
+ The version of the OpenAPI document: 0.4.0-SNAPSHOT
+ Contact: submarine-dev@submarine.apache.org
+ Generated by: https://openapi-generator.tech
+"""
+
+
+from __future__ import absolute_import
+
+import re # noqa: F401
+
+# python 2 and python 3 compatibility library
+import six
+
+from submarine.experiment.api_client import ApiClient
+from submarine.experiment.exceptions import ( # noqa: F401
+ ApiTypeError,
+ ApiValueError
+)
+
+
+class ExperimentApi(object):
+ """NOTE: This class is auto generated by OpenAPI Generator
+ Ref: https://openapi-generator.tech
+
+ Do not edit the class manually.
+ """
+
+ def __init__(self, api_client=None):
+ if api_client is None:
+ api_client = ApiClient()
+ self.api_client = api_client
+
+ def create_experiment(self, **kwargs): # noqa: E501
+ """Create an experiment # noqa: E501
+
+ This method makes a synchronous HTTP request by default. To make an
+ asynchronous HTTP request, please pass async_req=True
+ >>> thread = api.create_experiment(async_req=True)
+ >>> result = thread.get()
+
+ :param async_req bool: execute request asynchronously
+ :param ExperimentSpec experiment_spec:
+ :param _preload_content: if False, the urllib3.HTTPResponse object will
+ be returned without reading/decoding response
+ data. Default is True.
+ :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: JsonResponse
+ If the method is called asynchronously,
+ returns the request thread.
+ """
+ kwargs['_return_http_data_only'] = True
+ return self.create_experiment_with_http_info(**kwargs) # noqa: E501
+
+ def create_experiment_with_http_info(self, **kwargs): # noqa: E501
+ """Create an experiment # noqa: E501
+
+ This method makes a synchronous HTTP request by default. To make an
+ asynchronous HTTP request, please pass async_req=True
+ >>> thread = api.create_experiment_with_http_info(async_req=True)
+ >>> result = thread.get()
+
+ :param async_req bool: execute request asynchronously
+ :param ExperimentSpec experiment_spec:
+ :param _return_http_data_only: response data without head status code
+ and headers
+ :param _preload_content: if False, the urllib3.HTTPResponse object will
+ be returned without reading/decoding response
+ data. Default is True.
+ :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: tuple(JsonResponse, status_code(int), headers(HTTPHeaderDict))
+ If the method is called asynchronously,
+ returns the request thread.
+ """
+
+ local_var_params = locals()
+
+ all_params = [
+ 'experiment_spec'
+ ]
+ all_params.extend(
+ [
+ 'async_req',
+ '_return_http_data_only',
+ '_preload_content',
+ '_request_timeout'
+ ]
+ )
+
+ for key, val in six.iteritems(local_var_params['kwargs']):
+ if key not in all_params:
+ raise ApiTypeError(
+ "Got an unexpected keyword argument '%s'"
+ " to method create_experiment" % key
+ )
+ local_var_params[key] = val
+ del local_var_params['kwargs']
+
+ collection_formats = {}
+
+ path_params = {}
+
+ query_params = []
+
+ header_params = {}
+
+ form_params = []
+ local_var_files = {}
+
+ body_params = None
+ if 'experiment_spec' in local_var_params:
+ body_params = local_var_params['experiment_spec']
+ # HTTP header `Accept`
+ header_params['Accept'] = self.api_client.select_header_accept(
+ ['application/json; charset=utf-8']) # noqa: E501
+
+ # HTTP header `Content-Type`
+ header_params['Content-Type'] = self.api_client.select_header_content_type( # noqa: E501
+ ['application/yaml', 'application/json']) # noqa: E501
+
+ # Authentication setting
+ auth_settings = [] # noqa: E501
+
+ return self.api_client.call_api(
+ '/v1/experiment', 'POST',
+ path_params,
+ query_params,
+ header_params,
+ body=body_params,
+ post_params=form_params,
+ files=local_var_files,
+ response_type='JsonResponse', # noqa: E501
+ auth_settings=auth_settings,
+ async_req=local_var_params.get('async_req'),
+ _return_http_data_only=local_var_params.get('_return_http_data_only'), # noqa: E501
+ _preload_content=local_var_params.get('_preload_content', True),
+ _request_timeout=local_var_params.get('_request_timeout'),
+ collection_formats=collection_formats)
+
+ def delete_experiment(self, id, **kwargs): # noqa: E501
+ """Delete the experiment # noqa: E501
+
+ This method makes a synchronous HTTP request by default. To make an
+ asynchronous HTTP request, please pass async_req=True
+ >>> thread = api.delete_experiment(id, async_req=True)
+ >>> result = thread.get()
+
+ :param async_req bool: execute request asynchronously
+ :param str id: (required)
+ :param _preload_content: if False, the urllib3.HTTPResponse object will
+ be returned without reading/decoding response
+ data. Default is True.
+ :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: JsonResponse
+ If the method is called asynchronously,
+ returns the request thread.
+ """
+ kwargs['_return_http_data_only'] = True
+ return self.delete_experiment_with_http_info(id, **kwargs) # noqa: E501
+
+ def delete_experiment_with_http_info(self, id, **kwargs): # noqa: E501
+ """Delete the experiment # noqa: E501
+
+ This method makes a synchronous HTTP request by default. To make an
+ asynchronous HTTP request, please pass async_req=True
+ >>> thread = api.delete_experiment_with_http_info(id, async_req=True)
+ >>> result = thread.get()
+
+ :param async_req bool: execute request asynchronously
+ :param str id: (required)
+ :param _return_http_data_only: response data without head status code
+ and headers
+ :param _preload_content: if False, the urllib3.HTTPResponse object will
+ be returned without reading/decoding response
+ data. Default is True.
+ :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: tuple(JsonResponse, status_code(int), headers(HTTPHeaderDict))
+ If the method is called asynchronously,
+ returns the request thread.
+ """
+
+ local_var_params = locals()
+
+ all_params = [
+ 'id'
+ ]
+ all_params.extend(
+ [
+ 'async_req',
+ '_return_http_data_only',
+ '_preload_content',
+ '_request_timeout'
+ ]
+ )
+
+ for key, val in six.iteritems(local_var_params['kwargs']):
+ if key not in all_params:
+ raise ApiTypeError(
+ "Got an unexpected keyword argument '%s'"
+ " to method delete_experiment" % key
+ )
+ local_var_params[key] = val
+ del local_var_params['kwargs']
+ # verify the required parameter 'id' is set
+ if self.api_client.client_side_validation and ('id' not in local_var_params or # noqa: E501
+ local_var_params['id'] is None): # noqa: E501
+ raise ApiValueError("Missing the required parameter `id` when calling `delete_experiment`") # noqa: E501
+
+ collection_formats = {}
+
+ path_params = {}
+ if 'id' in local_var_params:
+ path_params['id'] = local_var_params['id'] # noqa: E501
+
+ query_params = []
+
+ header_params = {}
+
+ form_params = []
+ local_var_files = {}
+
+ body_params = None
+ # HTTP header `Accept`
+ header_params['Accept'] = self.api_client.select_header_accept(
+ ['application/json; charset=utf-8']) # noqa: E501
+
+ # Authentication setting
+ auth_settings = [] # noqa: E501
+
+ return self.api_client.call_api(
+ '/v1/experiment/{id}', 'DELETE',
+ path_params,
+ query_params,
+ header_params,
+ body=body_params,
+ post_params=form_params,
+ files=local_var_files,
+ response_type='JsonResponse', # noqa: E501
+ auth_settings=auth_settings,
+ async_req=local_var_params.get('async_req'),
+ _return_http_data_only=local_var_params.get('_return_http_data_only'), # noqa: E501
+ _preload_content=local_var_params.get('_preload_content', True),
+ _request_timeout=local_var_params.get('_request_timeout'),
+ collection_formats=collection_formats)
+
+ def get_experiment(self, id, **kwargs): # noqa: E501
+ """Get the experiment's detailed info by id # noqa: E501
+
+ This method makes a synchronous HTTP request by default. To make an
+ asynchronous HTTP request, please pass async_req=True
+ >>> thread = api.get_experiment(id, async_req=True)
+ >>> result = thread.get()
+
+ :param async_req bool: execute request asynchronously
+ :param str id: (required)
+ :param _preload_content: if False, the urllib3.HTTPResponse object will
+ be returned without reading/decoding response
+ data. Default is True.
+ :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: JsonResponse
+ If the method is called asynchronously,
+ returns the request thread.
+ """
+ kwargs['_return_http_data_only'] = True
+ return self.get_experiment_with_http_info(id, **kwargs) # noqa: E501
+
+ def get_experiment_with_http_info(self, id, **kwargs): # noqa: E501
+ """Get the experiment's detailed info by id # noqa: E501
+
+ This method makes a synchronous HTTP request by default. To make an
+ asynchronous HTTP request, please pass async_req=True
+ >>> thread = api.get_experiment_with_http_info(id, async_req=True)
+ >>> result = thread.get()
+
+ :param async_req bool: execute request asynchronously
+ :param str id: (required)
+ :param _return_http_data_only: response data without head status code
+ and headers
+ :param _preload_content: if False, the urllib3.HTTPResponse object will
+ be returned without reading/decoding response
+ data. Default is True.
+ :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: tuple(JsonResponse, status_code(int), headers(HTTPHeaderDict))
+ If the method is called asynchronously,
+ returns the request thread.
+ """
+
+ local_var_params = locals()
+
+ all_params = [
+ 'id'
+ ]
+ all_params.extend(
+ [
+ 'async_req',
+ '_return_http_data_only',
+ '_preload_content',
+ '_request_timeout'
+ ]
+ )
+
+ for key, val in six.iteritems(local_var_params['kwargs']):
+ if key not in all_params:
+ raise ApiTypeError(
+ "Got an unexpected keyword argument '%s'"
+ " to method get_experiment" % key
+ )
+ local_var_params[key] = val
+ del local_var_params['kwargs']
+ # verify the required parameter 'id' is set
+ if self.api_client.client_side_validation and ('id' not in local_var_params or # noqa: E501
+ local_var_params['id'] is None): # noqa: E501
+ raise ApiValueError("Missing the required parameter `id` when calling `get_experiment`") # noqa: E501
+
+ collection_formats = {}
+
+ path_params = {}
+ if 'id' in local_var_params:
+ path_params['id'] = local_var_params['id'] # noqa: E501
+
+ query_params = []
+
+ header_params = {}
+
+ form_params = []
+ local_var_files = {}
+
+ body_params = None
+ # HTTP header `Accept`
+ header_params['Accept'] = self.api_client.select_header_accept(
+ ['application/json; charset=utf-8']) # noqa: E501
+
+ # Authentication setting
+ auth_settings = [] # noqa: E501
+
+ return self.api_client.call_api(
+ '/v1/experiment/{id}', 'GET',
+ path_params,
+ query_params,
+ header_params,
+ body=body_params,
+ post_params=form_params,
+ files=local_var_files,
+ response_type='JsonResponse', # noqa: E501
+ auth_settings=auth_settings,
+ async_req=local_var_params.get('async_req'),
+ _return_http_data_only=local_var_params.get('_return_http_data_only'), # noqa: E501
+ _preload_content=local_var_params.get('_preload_content', True),
+ _request_timeout=local_var_params.get('_request_timeout'),
+ collection_formats=collection_formats)
+
+ def get_log(self, id, **kwargs): # noqa: E501
+ """Log experiment by id # noqa: E501
+
+ This method makes a synchronous HTTP request by default. To make an
+ asynchronous HTTP request, please pass async_req=True
+ >>> thread = api.get_log(id, async_req=True)
+ >>> result = thread.get()
+
+ :param async_req bool: execute request asynchronously
+ :param str id: (required)
+ :param _preload_content: if False, the urllib3.HTTPResponse object will
+ be returned without reading/decoding response
+ data. Default is True.
+ :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: JsonResponse
+ If the method is called asynchronously,
+ returns the request thread.
+ """
+ kwargs['_return_http_data_only'] = True
+ return self.get_log_with_http_info(id, **kwargs) # noqa: E501
+
+ def get_log_with_http_info(self, id, **kwargs): # noqa: E501
+ """Log experiment by id # noqa: E501
+
+ This method makes a synchronous HTTP request by default. To make an
+ asynchronous HTTP request, please pass async_req=True
+ >>> thread = api.get_log_with_http_info(id, async_req=True)
+ >>> result = thread.get()
+
+ :param async_req bool: execute request asynchronously
+ :param str id: (required)
+ :param _return_http_data_only: response data without head status code
+ and headers
+ :param _preload_content: if False, the urllib3.HTTPResponse object will
+ be returned without reading/decoding response
+ data. Default is True.
+ :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: tuple(JsonResponse, status_code(int), headers(HTTPHeaderDict))
+ If the method is called asynchronously,
+ returns the request thread.
+ """
+
+ local_var_params = locals()
+
+ all_params = [
+ 'id'
+ ]
+ all_params.extend(
+ [
+ 'async_req',
+ '_return_http_data_only',
+ '_preload_content',
+ '_request_timeout'
+ ]
+ )
+
+ for key, val in six.iteritems(local_var_params['kwargs']):
+ if key not in all_params:
+ raise ApiTypeError(
+ "Got an unexpected keyword argument '%s'"
+ " to method get_log" % key
+ )
+ local_var_params[key] = val
+ del local_var_params['kwargs']
+ # verify the required parameter 'id' is set
+ if self.api_client.client_side_validation and ('id' not in local_var_params or # noqa: E501
+ local_var_params['id'] is None): # noqa: E501
+ raise ApiValueError("Missing the required parameter `id` when calling `get_log`") # noqa: E501
+
+ collection_formats = {}
+
+ path_params = {}
+ if 'id' in local_var_params:
+ path_params['id'] = local_var_params['id'] # noqa: E501
+
+ query_params = []
+
+ header_params = {}
+
+ form_params = []
+ local_var_files = {}
+
+ body_params = None
+ # HTTP header `Accept`
+ header_params['Accept'] = self.api_client.select_header_accept(
+ ['application/json; charset=utf-8']) # noqa: E501
+
+ # Authentication setting
+ auth_settings = [] # noqa: E501
+
+ return self.api_client.call_api(
+ '/v1/experiment/logs/{id}', 'GET',
+ path_params,
+ query_params,
+ header_params,
+ body=body_params,
+ post_params=form_params,
+ files=local_var_files,
+ response_type='JsonResponse', # noqa: E501
+ auth_settings=auth_settings,
+ async_req=local_var_params.get('async_req'),
+ _return_http_data_only=local_var_params.get('_return_http_data_only'), # noqa: E501
+ _preload_content=local_var_params.get('_preload_content', True),
+ _request_timeout=local_var_params.get('_request_timeout'),
+ collection_formats=collection_formats)
+
+ def list_experiments(self, **kwargs): # noqa: E501
+ """List experiments # noqa: E501
+
+ This method makes a synchronous HTTP request by default. To make an
+ asynchronous HTTP request, please pass async_req=True
+ >>> thread = api.list_experiments(async_req=True)
+ >>> result = thread.get()
+
+ :param async_req bool: execute request asynchronously
+ :param str status:
+ :param _preload_content: if False, the urllib3.HTTPResponse object will
+ be returned without reading/decoding response
+ data. Default is True.
+ :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: JsonResponse
+ If the method is called asynchronously,
+ returns the request thread.
+ """
+ kwargs['_return_http_data_only'] = True
+ return self.list_experiments_with_http_info(**kwargs) # noqa: E501
+
+ def list_experiments_with_http_info(self, **kwargs): # noqa: E501
+ """List experiments # noqa: E501
+
+ This method makes a synchronous HTTP request by default. To make an
+ asynchronous HTTP request, please pass async_req=True
+ >>> thread = api.list_experiments_with_http_info(async_req=True)
+ >>> result = thread.get()
+
+ :param async_req bool: execute request asynchronously
+ :param str status:
+ :param _return_http_data_only: response data without head status code
+ and headers
+ :param _preload_content: if False, the urllib3.HTTPResponse object will
+ be returned without reading/decoding response
+ data. Default is True.
+ :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: tuple(JsonResponse, status_code(int), headers(HTTPHeaderDict))
+ If the method is called asynchronously,
+ returns the request thread.
+ """
+
+ local_var_params = locals()
+
+ all_params = [
+ 'status'
+ ]
+ all_params.extend(
+ [
+ 'async_req',
+ '_return_http_data_only',
+ '_preload_content',
+ '_request_timeout'
+ ]
+ )
+
+ for key, val in six.iteritems(local_var_params['kwargs']):
+ if key not in all_params:
+ raise ApiTypeError(
+ "Got an unexpected keyword argument '%s'"
+ " to method list_experiments" % key
+ )
+ local_var_params[key] = val
+ del local_var_params['kwargs']
+
+ collection_formats = {}
+
+ path_params = {}
+
+ query_params = []
+ if 'status' in local_var_params and local_var_params['status'] is not None: # noqa: E501
+ query_params.append(('status', local_var_params['status'])) # noqa: E501
+
+ header_params = {}
+
+ form_params = []
+ local_var_files = {}
+
+ body_params = None
+ # HTTP header `Accept`
+ header_params['Accept'] = self.api_client.select_header_accept(
+ ['application/json; charset=utf-8']) # noqa: E501
+
+ # Authentication setting
+ auth_settings = [] # noqa: E501
+
+ return self.api_client.call_api(
+ '/v1/experiment', 'GET',
+ path_params,
+ query_params,
+ header_params,
+ body=body_params,
+ post_params=form_params,
+ files=local_var_files,
+ response_type='JsonResponse', # noqa: E501
+ auth_settings=auth_settings,
+ async_req=local_var_params.get('async_req'),
+ _return_http_data_only=local_var_params.get('_return_http_data_only'), # noqa: E501
+ _preload_content=local_var_params.get('_preload_content', True),
+ _request_timeout=local_var_params.get('_request_timeout'),
+ collection_formats=collection_formats)
+
+ def list_log(self, **kwargs): # noqa: E501
+ """List experiment's log # noqa: E501
+
+ This method makes a synchronous HTTP request by default. To make an
+ asynchronous HTTP request, please pass async_req=True
+ >>> thread = api.list_log(async_req=True)
+ >>> result = thread.get()
+
+ :param async_req bool: execute request asynchronously
+ :param str status:
+ :param _preload_content: if False, the urllib3.HTTPResponse object will
+ be returned without reading/decoding response
+ data. Default is True.
+ :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: JsonResponse
+ If the method is called asynchronously,
+ returns the request thread.
+ """
+ kwargs['_return_http_data_only'] = True
+ return self.list_log_with_http_info(**kwargs) # noqa: E501
+
+ def list_log_with_http_info(self, **kwargs): # noqa: E501
+ """List experiment's log # noqa: E501
+
+ This method makes a synchronous HTTP request by default. To make an
+ asynchronous HTTP request, please pass async_req=True
+ >>> thread = api.list_log_with_http_info(async_req=True)
+ >>> result = thread.get()
+
+ :param async_req bool: execute request asynchronously
+ :param str status:
+ :param _return_http_data_only: response data without head status code
+ and headers
+ :param _preload_content: if False, the urllib3.HTTPResponse object will
+ be returned without reading/decoding response
+ data. Default is True.
+ :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: tuple(JsonResponse, status_code(int), headers(HTTPHeaderDict))
+ If the method is called asynchronously,
+ returns the request thread.
+ """
+
+ local_var_params = locals()
+
+ all_params = [
+ 'status'
+ ]
+ all_params.extend(
+ [
+ 'async_req',
+ '_return_http_data_only',
+ '_preload_content',
+ '_request_timeout'
+ ]
+ )
+
+ for key, val in six.iteritems(local_var_params['kwargs']):
+ if key not in all_params:
+ raise ApiTypeError(
+ "Got an unexpected keyword argument '%s'"
+ " to method list_log" % key
+ )
+ local_var_params[key] = val
+ del local_var_params['kwargs']
+
+ collection_formats = {}
+
+ path_params = {}
+
+ query_params = []
+ if 'status' in local_var_params and local_var_params['status'] is not None: # noqa: E501
+ query_params.append(('status', local_var_params['status'])) # noqa: E501
+
+ header_params = {}
+
+ form_params = []
+ local_var_files = {}
+
+ body_params = None
+ # HTTP header `Accept`
+ header_params['Accept'] = self.api_client.select_header_accept(
+ ['application/json; charset=utf-8']) # noqa: E501
+
+ # Authentication setting
+ auth_settings = [] # noqa: E501
+
+ return self.api_client.call_api(
+ '/v1/experiment/logs', 'GET',
+ path_params,
+ query_params,
+ header_params,
+ body=body_params,
+ post_params=form_params,
+ files=local_var_files,
+ response_type='JsonResponse', # noqa: E501
+ auth_settings=auth_settings,
+ async_req=local_var_params.get('async_req'),
+ _return_http_data_only=local_var_params.get('_return_http_data_only'), # noqa: E501
+ _preload_content=local_var_params.get('_preload_content', True),
+ _request_timeout=local_var_params.get('_request_timeout'),
+ collection_formats=collection_formats)
+
+ def patch_experiment(self, id, **kwargs): # noqa: E501
+ """Update the experiment in the submarine server with spec # noqa: E501
+
+ This method makes a synchronous HTTP request by default. To make an
+ asynchronous HTTP request, please pass async_req=True
+ >>> thread = api.patch_experiment(id, async_req=True)
+ >>> result = thread.get()
+
+ :param async_req bool: execute request asynchronously
+ :param str id: (required)
+ :param ExperimentSpec experiment_spec:
+ :param _preload_content: if False, the urllib3.HTTPResponse object will
+ be returned without reading/decoding response
+ data. Default is True.
+ :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: JsonResponse
+ If the method is called asynchronously,
+ returns the request thread.
+ """
+ kwargs['_return_http_data_only'] = True
+ return self.patch_experiment_with_http_info(id, **kwargs) # noqa: E501
+
+ def patch_experiment_with_http_info(self, id, **kwargs): # noqa: E501
+ """Update the experiment in the submarine server with spec # noqa: E501
+
+ This method makes a synchronous HTTP request by default. To make an
+ asynchronous HTTP request, please pass async_req=True
+ >>> thread = api.patch_experiment_with_http_info(id, async_req=True)
+ >>> result = thread.get()
+
+ :param async_req bool: execute request asynchronously
+ :param str id: (required)
+ :param ExperimentSpec experiment_spec:
+ :param _return_http_data_only: response data without head status code
+ and headers
+ :param _preload_content: if False, the urllib3.HTTPResponse object will
+ be returned without reading/decoding response
+ data. Default is True.
+ :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: tuple(JsonResponse, status_code(int), headers(HTTPHeaderDict))
+ If the method is called asynchronously,
+ returns the request thread.
+ """
+
+ local_var_params = locals()
+
+ all_params = [
+ 'id',
+ 'experiment_spec'
+ ]
+ all_params.extend(
+ [
+ 'async_req',
+ '_return_http_data_only',
+ '_preload_content',
+ '_request_timeout'
+ ]
+ )
+
+ for key, val in six.iteritems(local_var_params['kwargs']):
+ if key not in all_params:
+ raise ApiTypeError(
+ "Got an unexpected keyword argument '%s'"
+ " to method patch_experiment" % key
+ )
+ local_var_params[key] = val
+ del local_var_params['kwargs']
+ # verify the required parameter 'id' is set
+ if self.api_client.client_side_validation and ('id' not in local_var_params or # noqa: E501
+ local_var_params['id'] is None): # noqa: E501
+ raise ApiValueError("Missing the required parameter `id` when calling `patch_experiment`") # noqa: E501
+
+ collection_formats = {}
+
+ path_params = {}
+ if 'id' in local_var_params:
+ path_params['id'] = local_var_params['id'] # noqa: E501
+
+ query_params = []
+
+ header_params = {}
+
+ form_params = []
+ local_var_files = {}
+
+ body_params = None
+ if 'experiment_spec' in local_var_params:
+ body_params = local_var_params['experiment_spec']
+ # HTTP header `Accept`
+ header_params['Accept'] = self.api_client.select_header_accept(
+ ['application/json; charset=utf-8']) # noqa: E501
+
+ # HTTP header `Content-Type`
+ header_params['Content-Type'] = self.api_client.select_header_content_type( # noqa: E501
+ ['application/yaml', 'application/json']) # noqa: E501
+
+ # Authentication setting
+ auth_settings = [] # noqa: E501
+
+ return self.api_client.call_api(
+ '/v1/experiment/{id}', 'PATCH',
+ path_params,
+ query_params,
+ header_params,
+ body=body_params,
+ post_params=form_params,
+ files=local_var_files,
+ response_type='JsonResponse', # noqa: E501
+ auth_settings=auth_settings,
+ async_req=local_var_params.get('async_req'),
+ _return_http_data_only=local_var_params.get('_return_http_data_only'), # noqa: E501
+ _preload_content=local_var_params.get('_preload_content', True),
+ _request_timeout=local_var_params.get('_request_timeout'),
+ collection_formats=collection_formats)
+
+ def ping(self, **kwargs): # noqa: E501
+ """Ping submarine server # noqa: E501
+
+ Return the Pong message for test the connectivity # noqa: E501
+ This method makes a synchronous HTTP request by default. To make an
+ asynchronous HTTP request, please pass async_req=True
+ >>> thread = api.ping(async_req=True)
+ >>> result = thread.get()
+
+ :param async_req bool: execute request asynchronously
+ :param _preload_content: if False, the urllib3.HTTPResponse object will
+ be returned without reading/decoding response
+ data. Default is True.
+ :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: str
+ If the method is called asynchronously,
+ returns the request thread.
+ """
+ kwargs['_return_http_data_only'] = True
+ return self.ping_with_http_info(**kwargs) # noqa: E501
+
+ def ping_with_http_info(self, **kwargs): # noqa: E501
+ """Ping submarine server # noqa: E501
+
+ Return the Pong message for test the connectivity # noqa: E501
+ This method makes a synchronous HTTP request by default. To make an
+ asynchronous HTTP request, please pass async_req=True
+ >>> thread = api.ping_with_http_info(async_req=True)
+ >>> result = thread.get()
+
+ :param async_req bool: execute request asynchronously
+ :param _return_http_data_only: response data without head status code
+ and headers
+ :param _preload_content: if False, the urllib3.HTTPResponse object will
+ be returned without reading/decoding response
+ data. Default is True.
+ :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: tuple(str, status_code(int), headers(HTTPHeaderDict))
+ If the method is called asynchronously,
+ returns the request thread.
+ """
+
+ local_var_params = locals()
+
+ all_params = [
+ ]
+ all_params.extend(
+ [
+ 'async_req',
+ '_return_http_data_only',
+ '_preload_content',
+ '_request_timeout'
+ ]
+ )
+
+ for key, val in six.iteritems(local_var_params['kwargs']):
+ if key not in all_params:
+ raise ApiTypeError(
+ "Got an unexpected keyword argument '%s'"
+ " to method ping" % key
+ )
+ local_var_params[key] = val
+ del local_var_params['kwargs']
+
+ collection_formats = {}
+
+ path_params = {}
+
+ query_params = []
+
+ header_params = {}
+
+ form_params = []
+ local_var_files = {}
+
+ body_params = None
+ # HTTP header `Accept`
+ header_params['Accept'] = self.api_client.select_header_accept(
+ ['application/json; charset=utf-8']) # noqa: E501
+
+ # Authentication setting
+ auth_settings = [] # noqa: E501
+
+ return self.api_client.call_api(
+ '/v1/experiment/ping', 'GET',
+ path_params,
+ query_params,
+ header_params,
+ body=body_params,
+ post_params=form_params,
+ files=local_var_files,
+ response_type='str', # noqa: E501
+ auth_settings=auth_settings,
+ async_req=local_var_params.get('async_req'),
+ _return_http_data_only=local_var_params.get('_return_http_data_only'), # noqa: E501
+ _preload_content=local_var_params.get('_preload_content', True),
+ _request_timeout=local_var_params.get('_request_timeout'),
+ collection_formats=collection_formats)
diff --git a/submarine-sdk/pysubmarine/submarine/job/api_client.py b/submarine-sdk/pysubmarine/submarine/experiment/api_client.py
similarity index 79%
rename from submarine-sdk/pysubmarine/submarine/job/api_client.py
rename to submarine-sdk/pysubmarine/submarine/experiment/api_client.py
index 3267628..46a45e3 100644
--- a/submarine-sdk/pysubmarine/submarine/job/api_client.py
+++ b/submarine-sdk/pysubmarine/submarine/experiment/api_client.py
@@ -1,11 +1,11 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
+# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
+# the License. You may obtain a copy of the License at
#
-# http://www.apache.org/licenses/LICENSE-2.0
+# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
@@ -17,14 +17,16 @@
"""
Submarine Experiment API
- The Submarine REST API allows you to create, list, and get experiments. TheAPI is hosted under the /v1/jobs route on the Submarine server. For example,to list experiments on a server hosted at http://localhost:8080, accesshttp://localhost:8080/api/v1/jobs/ # noqa: E501
+ The Submarine REST API allows you to create, list, and get experiments. The API is hosted under the /v1/experiment route on the Submarine server. For example, to list experiments on a server hosted at http://localhost:8080, access http://localhost:8080/api/v1/experiment/ # noqa: E501
- OpenAPI spec version: 0.4.0-SNAPSHOT
+ The version of the OpenAPI document: 0.4.0-SNAPSHOT
Contact: submarine-dev@submarine.apache.org
- Generated by: https://github.com/swagger-api/swagger-codegen.git
+ Generated by: https://openapi-generator.tech
"""
+
from __future__ import absolute_import
+import atexit
import datetime
import json
import mimetypes
@@ -35,23 +37,25 @@ from multiprocessing.pool import ThreadPool
# python 2 and python 3 compatibility library
import six
+from dateutil.parser import parse
from six.moves.urllib.parse import quote
-import submarine.job.models
-from submarine.job import rest
-from submarine.job.configuration import Configuration
+import submarine.experiment.models
+from submarine.experiment import rest
+from submarine.experiment.configuration import Configuration
+from submarine.experiment.exceptions import ApiException, ApiValueError
class ApiClient(object):
- """Generic API client for Swagger client library builds.
+ """Generic API client for OpenAPI client library builds.
- Swagger generic API client. This client handles the client-
+ OpenAPI generic API client. This client handles the client-
server communication, and is invariant across implementations. Specifics of
- the methods and models for each application are generated from the Swagger
+ the methods and models for each application are generated from the OpenAPI
templates.
- NOTE: This class is auto generated by the swagger code generator program.
- Ref: https://github.com/swagger-api/swagger-codegen
+ NOTE: This class is auto generated by OpenAPI Generator.
+ Ref: https://openapi-generator.tech
Do not edit the class manually.
:param configuration: .Configuration object for this client
@@ -60,6 +64,8 @@ class ApiClient(object):
the API.
:param cookie: a cookie to include in the header when making calls
to the API
+ :param pool_threads: The number of threads to use for async requests
+ to the API. More threads means more concurrent API requests.
"""
PRIMITIVE_TYPES = (float, bool, bytes, six.text_type) + six.integer_types
@@ -73,28 +79,51 @@ class ApiClient(object):
'datetime': datetime.datetime,
'object': object,
}
+ _pool = None
def __init__(self,
configuration=None,
header_name=None,
header_value=None,
- cookie=None):
+ cookie=None,
+ pool_threads=1):
if configuration is None:
- configuration = Configuration()
+ configuration = Configuration.get_default_copy()
self.configuration = configuration
+ self.pool_threads = pool_threads
- self.pool = ThreadPool()
self.rest_client = rest.RESTClientObject(configuration)
self.default_headers = {}
if header_name is not None:
self.default_headers[header_name] = header_value
self.cookie = cookie
# Set default User-Agent.
- self.user_agent = 'Swagger-Codegen/1.0.0/python'
+ self.user_agent = 'OpenAPI-Generator/0.4.0-SNAPSHOT/python'
+ self.client_side_validation = configuration.client_side_validation
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, exc_type, exc_value, traceback):
+ self.close()
- def __del__(self):
- self.pool.close()
- self.pool.join()
+ def close(self):
+ if self._pool:
+ self._pool.close()
+ self._pool.join()
+ self._pool = None
+ if hasattr(atexit, 'unregister'):
+ atexit.unregister(self.close)
+
+ @property
+ def pool(self):
+ """Create thread pool on first request
+ avoids instantiating unused threadpool for blocking clients.
+ """
+ if self._pool is None:
+ atexit.register(self.close)
+ self._pool = ThreadPool(self.pool_threads)
+ return self._pool
@property
def user_agent(self):
@@ -122,7 +151,8 @@ class ApiClient(object):
_return_http_data_only=None,
collection_formats=None,
_preload_content=True,
- _request_timeout=None):
+ _request_timeout=None,
+ _host=None):
config = self.configuration
@@ -155,10 +185,11 @@ class ApiClient(object):
# post parameters
if post_params or files:
- post_params = self.prepare_post_parameters(post_params, files)
+ post_params = post_params if post_params else []
post_params = self.sanitize_for_serialization(post_params)
post_params = self.parameters_to_tuples(post_params,
collection_formats)
+ post_params.extend(self.files_parameters(files))
# auth setting
self.update_params_for_auth(header_params, query_params, auth_settings)
@@ -168,27 +199,48 @@ class ApiClient(object):
body = self.sanitize_for_serialization(body)
# request url
- url = self.configuration.host + resource_path
-
- # perform request and return response
- response_data = self.request(method,
- url,
- query_params=query_params,
- headers=header_params,
- post_params=post_params,
- body=body,
- _preload_content=_preload_content,
- _request_timeout=_request_timeout)
+ if _host is None:
+ url = self.configuration.host + resource_path
+ else:
+ # use server/host defined in path or operation instead
+ url = _host + resource_path
+
+ try:
+ # perform request and return response
+ response_data = self.request(method,
+ url,
+ query_params=query_params,
+ headers=header_params,
+ post_params=post_params,
+ body=body,
+ _preload_content=_preload_content,
+ _request_timeout=_request_timeout)
+ except ApiException as e:
+ e.body = e.body.decode('utf-8') if six.PY3 else e.body
+ raise e
+
+ content_type = response_data.getheader('content-type')
self.last_response = response_data
return_data = response_data
- if _preload_content:
- # deserialize response data
- if response_type:
- return_data = self.deserialize(response_data, response_type)
- else:
- return_data = None
+
+ if not _preload_content:
+ return return_data
+
+ if six.PY3 and response_type not in ["file", "bytes"]:
+ match = None
+ if content_type is not None:
+ match = re.search(r"charset=([a-zA-Z\-\d]+)[\s\;]?",
+ content_type)
+ encoding = match.group(1) if match else "utf-8"
+ response_data.data = response_data.data.decode(encoding)
+
+ # deserialize response data
+ if response_type:
+ return_data = self.deserialize(response_data, response_type)
+ else:
+ return_data = None
if _return_http_data_only:
return (return_data)
@@ -205,7 +257,7 @@ class ApiClient(object):
convert to string in iso8601 format.
If obj is list, sanitize each element in the list.
If obj is dict, return the dict.
- If obj is swagger model, return the properties dict.
+ If obj is OpenAPI model, return the properties dict.
:param obj: The data to serialize.
:return: The serialized form of data.
@@ -226,13 +278,13 @@ class ApiClient(object):
obj_dict = obj
else:
# Convert model obj to dict except
- # attributes `swagger_types`, `attribute_map`
+ # attributes `openapi_types`, `attribute_map`
# and attributes which value is not None.
# Convert attribute name to json key in
# model definition for request.
obj_dict = {
obj.attribute_map[attr]: getattr(obj, attr)
- for attr, _ in six.iteritems(obj.swagger_types)
+ for attr, _ in six.iteritems(obj.openapi_types)
if getattr(obj, attr) is not None
}
@@ -292,7 +344,7 @@ class ApiClient(object):
if klass in self.NATIVE_TYPES_MAPPING:
klass = self.NATIVE_TYPES_MAPPING[klass]
else:
- klass = getattr(submarine.job.models, klass)
+ klass = getattr(submarine.experiment.models, klass)
if klass in self.PRIMITIVE_TYPES:
return self.__deserialize_primitive(data, klass)
@@ -301,7 +353,7 @@ class ApiClient(object):
elif klass == datetime.date:
return self.__deserialize_date(data)
elif klass == datetime.datetime:
- return self.__deserialize_datatime(data)
+ return self.__deserialize_datetime(data)
else:
return self.__deserialize_model(data, klass)
@@ -320,10 +372,11 @@ class ApiClient(object):
_return_http_data_only=None,
collection_formats=None,
_preload_content=True,
- _request_timeout=None):
+ _request_timeout=None,
+ _host=None):
"""Makes the HTTP request (synchronous) and returns deserialized data.
- To make an async request, set the async_req parameter.
+ To make an async_req request, set the async_req parameter.
:param resource_path: Path to method endpoint.
:param method: Method to call.
@@ -363,15 +416,14 @@ class ApiClient(object):
post_params, files, response_type,
auth_settings, _return_http_data_only,
collection_formats, _preload_content,
- _request_timeout)
- else:
- thread = self.pool.apply_async(
- self.__call_api,
- (resource_path, method, path_params, query_params,
- header_params, body, post_params, files, response_type,
- auth_settings, _return_http_data_only, collection_formats,
- _preload_content, _request_timeout))
- return thread
+ _request_timeout, _host)
+
+ return self.pool.apply_async(
+ self.__call_api,
+ (resource_path, method, path_params, query_params, header_params,
+ body, post_params, files, response_type, auth_settings,
+ _return_http_data_only, collection_formats, _preload_content,
+ _request_timeout, _host))
def request(self,
method,
@@ -399,10 +451,8 @@ class ApiClient(object):
return self.rest_client.OPTIONS(url,
query_params=query_params,
headers=headers,
- post_params=post_params,
_preload_content=_preload_content,
- _request_timeout=_request_timeout,
- body=body)
+ _request_timeout=_request_timeout)
elif method == "POST":
return self.rest_client.POST(url,
query_params=query_params,
@@ -435,8 +485,8 @@ class ApiClient(object):
_request_timeout=_request_timeout,
body=body)
else:
- raise ValueError("http method must be `GET`, `HEAD`, `OPTIONS`,"
- " `POST`, `PATCH`, `PUT` or `DELETE`.")
+ raise ApiValueError("http method must be `GET`, `HEAD`, `OPTIONS`,"
+ " `POST`, `PATCH`, `PUT` or `DELETE`.")
def parameters_to_tuples(self, params, collection_formats):
"""Get parameters as list of tuples, formatting collections.
@@ -469,18 +519,14 @@ class ApiClient(object):
new_params.append((k, v))
return new_params
- def prepare_post_parameters(self, post_params=None, files=None):
+ def files_parameters(self, files=None):
"""Builds form parameters.
- :param post_params: Normal form parameters.
:param files: File parameters.
:return: Form parameters with files.
"""
params = []
- if post_params:
- params = post_params
-
if files:
for k, v in six.iteritems(files):
if not v:
@@ -542,14 +588,14 @@ class ApiClient(object):
for auth in auth_settings:
auth_setting = self.configuration.auth_settings().get(auth)
if auth_setting:
- if not auth_setting['value']:
- continue
+ if auth_setting['in'] == 'cookie':
+ headers['Cookie'] = auth_setting['value']
elif auth_setting['in'] == 'header':
headers[auth_setting['key']] = auth_setting['value']
elif auth_setting['in'] == 'query':
querys.append((auth_setting['key'], auth_setting['value']))
else:
- raise ValueError(
+ raise ApiValueError(
'Authentication token must be in `query` or `header`')
def __deserialize_file(self, response):
@@ -592,7 +638,7 @@ class ApiClient(object):
return data
def __deserialize_object(self, value):
- """Return a original value.
+ """Return an original value.
:return: object.
"""
@@ -605,7 +651,6 @@ class ApiClient(object):
:return: date.
"""
try:
- from dateutil.parser import parse
return parse(string).date()
except ImportError:
return string
@@ -614,7 +659,7 @@ class ApiClient(object):
status=0,
reason="Failed to parse `{0}` as date object".format(string))
- def __deserialize_datatime(self, string):
+ def __deserialize_datetime(self, string):
"""Deserializes string to datetime.
The string should be in iso8601 datetime format.
@@ -623,7 +668,6 @@ class ApiClient(object):
:return: datetime.
"""
try:
- from dateutil.parser import parse
return parse(string)
except ImportError:
return string
@@ -633,9 +677,6 @@ class ApiClient(object):
reason=(
"Failed to parse `{0}` as datetime object".format(string)))
- def __hasattr(self, object, name):
- return name in object.__class__.__dict__
-
def __deserialize_model(self, data, klass):
"""Deserializes list or dict to model.
@@ -643,27 +684,25 @@ class ApiClient(object):
:param klass: class literal.
:return: model object.
"""
+ has_discriminator = False
+ if (hasattr(klass, 'get_real_child_model') and
+ klass.discriminator_value_class_map):
+ has_discriminator = True
- if not klass.swagger_types and not self.__hasattr(
- klass, 'get_real_child_model'):
+ if not klass.openapi_types and has_discriminator is False:
return data
kwargs = {}
- if klass.swagger_types is not None:
- for attr, attr_type in six.iteritems(klass.swagger_types):
- if (data is not None and klass.attribute_map[attr] in data and
- isinstance(data, (list, dict))):
+ if (data is not None and klass.openapi_types is not None and
+ isinstance(data, (list, dict))):
+ for attr, attr_type in six.iteritems(klass.openapi_types):
+ if klass.attribute_map[attr] in data:
value = data[klass.attribute_map[attr]]
kwargs[attr] = self.__deserialize(value, attr_type)
instance = klass(**kwargs)
- if (isinstance(instance, dict) and klass.swagger_types is not None and
- isinstance(data, dict)):
- for key, value in data.items():
- if key not in klass.swagger_types:
- instance[key] = value
- if self.__hasattr(instance, 'get_real_child_model'):
+ if has_discriminator:
klass_name = instance.get_real_child_model(data)
if klass_name:
instance = self.__deserialize(data, klass_name)
diff --git a/submarine-sdk/pysubmarine/submarine/experiment/configuration.py b/submarine-sdk/pysubmarine/submarine/experiment/configuration.py
new file mode 100644
index 0000000..ee281ac
--- /dev/null
+++ b/submarine-sdk/pysubmarine/submarine/experiment/configuration.py
@@ -0,0 +1,391 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# coding: utf-8
+"""
+ Submarine Experiment API
+
+ The Submarine REST API allows you to create, list, and get experiments. The API is hosted under the /v1/experiment route on the Submarine server. For example, to list experiments on a server hosted at http://localhost:8080, access http://localhost:8080/api/v1/experiment/ # noqa: E501
+
+ The version of the OpenAPI document: 0.4.0-SNAPSHOT
+ Contact: submarine-dev@submarine.apache.org
+ Generated by: https://openapi-generator.tech
+"""
+
+from __future__ import absolute_import
+
+import copy
+import logging
+import multiprocessing
+import sys
+
+import six
+import urllib3
+from six.moves import http_client as httplib
+
+
+class Configuration(object):
+ """NOTE: This class is auto generated by OpenAPI Generator
+
+ Ref: https://openapi-generator.tech
+ Do not edit the class manually.
+
+ :param host: Base url
+ :param api_key: Dict to store API key(s).
+ Each entry in the dict specifies an API key.
+ The dict key is the name of the security scheme in the OAS specification.
+ The dict value is the API key secret.
+ :param api_key_prefix: Dict to store API prefix (e.g. Bearer)
+ The dict key is the name of the security scheme in the OAS specification.
+ The dict value is an API key prefix when generating the auth data.
+ :param username: Username for HTTP basic authentication
+ :param password: Password for HTTP basic authentication
+ :param discard_unknown_keys: Boolean value indicating whether to discard
+ unknown properties. A server may send a response that includes additional
+ properties that are not known by the client in the following scenarios:
+ 1. The OpenAPI document is incomplete, i.e. it does not match the server
+ implementation.
+ 2. The client was generated using an older version of the OpenAPI document
+ and the server has been upgraded since then.
+ If a schema in the OpenAPI document defines the additionalProperties attribute,
+ then all undeclared properties received by the server are injected into the
+ additional properties map. In that case, there are undeclared properties, and
+ nothing to discard.
+
+ """
+
+ _default = None
+
+ def __init__(
+ self,
+ host="http://localhost/api",
+ api_key=None,
+ api_key_prefix=None,
+ username=None,
+ password=None,
+ discard_unknown_keys=False,
+ ):
+ """Constructor
+ """
+ self.host = host
+ """Default Base url
+ """
+ self.temp_folder_path = None
+ """Temp file folder for downloading files
+ """
+ # Authentication Settings
+ self.api_key = {}
+ if api_key:
+ self.api_key = api_key
+ """dict to store API key(s)
+ """
+ self.api_key_prefix = {}
+ if api_key_prefix:
+ self.api_key_prefix = api_key_prefix
+ """dict to store API prefix (e.g. Bearer)
+ """
+ self.refresh_api_key_hook = None
+ """function hook to refresh API key if expired
+ """
+ self.username = username
+ """Username for HTTP basic authentication
+ """
+ self.password = password
+ """Password for HTTP basic authentication
+ """
+ self.discard_unknown_keys = discard_unknown_keys
+ self.logger = {}
+ """Logging Settings
+ """
+ self.logger["package_logger"] = logging.getLogger(
+ "submarine.experiment")
+ self.logger["urllib3_logger"] = logging.getLogger("urllib3")
+ self.logger_format = '%(asctime)s %(levelname)s %(message)s'
+ """Log format
+ """
+ self.logger_stream_handler = None
+ """Log stream handler
+ """
+ self.logger_file_handler = None
+ """Log file handler
+ """
+ self.logger_file = None
+ """Debug file location
+ """
+ self.debug = False
+ """Debug switch
+ """
+
+ self.verify_ssl = True
+ """SSL/TLS verification
+ Set this to false to skip verifying SSL certificate when calling API
+ from https server.
+ """
+ self.ssl_ca_cert = None
+ """Set this to customize the certificate file to verify the peer.
+ """
+ self.cert_file = None
+ """client certificate file
+ """
+ self.key_file = None
+ """client key file
+ """
+ self.assert_hostname = None
+ """Set this to True/False to enable/disable SSL hostname verification.
+ """
+
+ self.connection_pool_maxsize = multiprocessing.cpu_count() * 5
+ """urllib3 connection pool's maximum number of connections saved
+ per pool. urllib3 uses 1 connection as default value, but this is
+ not the best value when you are making a lot of possibly parallel
+ requests to the same host, which is often the case here.
+ cpu_count * 5 is used as default value to increase performance.
+ """
+
+ self.proxy = None
+ """Proxy URL
+ """
+ self.proxy_headers = None
+ """Proxy headers
+ """
+ self.safe_chars_for_path_param = ''
+ """Safe chars for path_param
+ """
+ self.retries = None
+ """Adding retries to override urllib3 default value 3
+ """
+ # Disable client side validation
+ self.client_side_validation = True
+
+ def __deepcopy__(self, memo):
+ cls = self.__class__
+ result = cls.__new__(cls)
+ memo[id(self)] = result
+ for k, v in self.__dict__.items():
+ if k not in ('logger', 'logger_file_handler'):
+ setattr(result, k, copy.deepcopy(v, memo))
+ # shallow copy of loggers
+ result.logger = copy.copy(self.logger)
+ # use setters to configure loggers
+ result.logger_file = self.logger_file
+ result.debug = self.debug
+ return result
+
+ def __setattr__(self, name, value):
+ object.__setattr__(self, name, value)
+
+ @classmethod
+ def set_default(cls, default):
+ """Set default instance of configuration.
+
+ It stores default configuration, which can be
+ returned by get_default_copy method.
+
+ :param default: object of Configuration
+ """
+ cls._default = copy.deepcopy(default)
+
+ @classmethod
+ def get_default_copy(cls):
+ """Return new instance of configuration.
+
+ This method returns newly created, based on default constructor,
+ object of Configuration class or returns a copy of default
+ configuration passed by the set_default method.
+
+ :return: The configuration object.
+ """
+ if cls._default is not None:
+ return copy.deepcopy(cls._default)
+ return Configuration()
+
+ @property
+ def logger_file(self):
+ """The logger file.
+
+ If the logger_file is None, then add stream handler and remove file
+ handler. Otherwise, add file handler and remove stream handler.
+
+ :param value: The logger_file path.
+ :type: str
+ """
+ return self.__logger_file
+
+ @logger_file.setter
+ def logger_file(self, value):
+ """The logger file.
+
+ If the logger_file is None, then add stream handler and remove file
+ handler. Otherwise, add file handler and remove stream handler.
+
+ :param value: The logger_file path.
+ :type: str
+ """
+ self.__logger_file = value
+ if self.__logger_file:
+ # If set logging file,
+ # then add file handler and remove stream handler.
+ self.logger_file_handler = logging.FileHandler(self.__logger_file)
+ self.logger_file_handler.setFormatter(self.logger_formatter)
+ for _, logger in six.iteritems(self.logger):
+ logger.addHandler(self.logger_file_handler)
+
+ @property
+ def debug(self):
+ """Debug status
+
+ :param value: The debug status, True or False.
+ :type: bool
+ """
+ return self.__debug
+
+ @debug.setter
+ def debug(self, value):
+ """Debug status
+
+ :param value: The debug status, True or False.
+ :type: bool
+ """
+ self.__debug = value
+ if self.__debug:
+ # if debug status is True, turn on debug logging
+ for _, logger in six.iteritems(self.logger):
+ logger.setLevel(logging.DEBUG)
+ # turn on httplib debug
+ httplib.HTTPConnection.debuglevel = 1
+ else:
+ # if debug status is False, turn off debug logging,
+ # setting log level to default `logging.WARNING`
+ for _, logger in six.iteritems(self.logger):
+ logger.setLevel(logging.WARNING)
+ # turn off httplib debug
+ httplib.HTTPConnection.debuglevel = 0
+
+ @property
+ def logger_format(self):
+ """The logger format.
+
+ The logger_formatter will be updated when sets logger_format.
+
+ :param value: The format string.
+ :type: str
+ """
+ return self.__logger_format
+
+ @logger_format.setter
+ def logger_format(self, value):
+ """The logger format.
+
+ The logger_formatter will be updated when sets logger_format.
+
+ :param value: The format string.
+ :type: str
+ """
+ self.__logger_format = value
+ self.logger_formatter = logging.Formatter(self.__logger_format)
+
+ def get_api_key_with_prefix(self, identifier):
+ """Gets API key (with prefix if set).
+
+ :param identifier: The identifier of apiKey.
+ :return: The token for api key authentication.
+ """
+ if self.refresh_api_key_hook is not None:
+ self.refresh_api_key_hook(self)
+ key = self.api_key.get(identifier)
+ if key:
+ prefix = self.api_key_prefix.get(identifier)
+ if prefix:
+ return "%s %s" % (prefix, key)
+ else:
+ return key
+
+ def get_basic_auth_token(self):
+ """Gets HTTP basic authentication header (string).
+
+ :return: The token for basic HTTP authentication.
+ """
+ username = ""
+ if self.username is not None:
+ username = self.username
+ password = ""
+ if self.password is not None:
+ password = self.password
+ return urllib3.util.make_headers(basic_auth=username + ':' +
+ password).get('authorization')
+
+ def auth_settings(self):
+ """Gets Auth Settings dict for api client.
+
+ :return: The Auth Settings information dict.
+ """
+ auth = {}
+ return auth
+
+ def to_debug_report(self):
+ """Gets the essential information for debugging.
+
+ :return: The report for debugging.
+ """
+ return "Python SDK Debug Report:\n"\
+ "OS: {env}\n"\
+ "Python Version: {pyversion}\n"\
+ "Version of the API: 0.4.0-SNAPSHOT\n"\
+ "SDK Package Version: 0.4.0-SNAPSHOT".\
+ format(env=sys.platform, pyversion=sys.version)
+
+ def get_host_settings(self):
+ """Gets an array of host settings
+
+ :return: An array of host settings
+ """
+ return [{
+ 'url': "/api",
+ 'description': "No description provided",
+ }]
+
+ def get_host_from_settings(self, index, variables=None):
+ """Gets host URL based on the index and variables
+ :param index: array index of the host settings
+ :param variables: hash of variable and the corresponding value
+ :return: URL based on host settings
+ """
+ variables = {} if variables is None else variables
+ servers = self.get_host_settings()
+
+ try:
+ server = servers[index]
+ except IndexError:
+ raise ValueError(
+ "Invalid index {0} when selecting the host settings. "
+ "Must be less than {1}".format(index, len(servers)))
+
+ url = server['url']
+
+ # go through variables and replace placeholders
+ for variable_name, variable in server['variables'].items():
+ used_value = variables.get(variable_name, variable['default_value'])
+
+ if 'enum_values' in variable \
+ and used_value not in variable['enum_values']:
+ raise ValueError(
+ "The variable `{0}` in the host URL has invalid value "
+ "{1}. Must be {2}.".format(variable_name,
+ variables[variable_name],
+ variable['enum_values']))
+
+ url = url.replace("{" + variable_name + "}", used_value)
+
+ return url
diff --git a/submarine-sdk/pysubmarine/submarine/experiment/exceptions.py b/submarine-sdk/pysubmarine/submarine/experiment/exceptions.py
new file mode 100644
index 0000000..dc56965
--- /dev/null
+++ b/submarine-sdk/pysubmarine/submarine/experiment/exceptions.py
@@ -0,0 +1,139 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# coding: utf-8
+"""
+ Submarine Experiment API
+
+ The Submarine REST API allows you to create, list, and get experiments. The API is hosted under the /v1/experiment route on the Submarine server. For example, to list experiments on a server hosted at http://localhost:8080, access http://localhost:8080/api/v1/experiment/ # noqa: E501
+
+ The version of the OpenAPI document: 0.4.0-SNAPSHOT
+ Contact: submarine-dev@submarine.apache.org
+ Generated by: https://openapi-generator.tech
+"""
+
+import six
+
+
+class OpenApiException(Exception):
+ """The base exception class for all OpenAPIExceptions"""
+
+
+class ApiTypeError(OpenApiException, TypeError):
+
+ def __init__(self,
+ msg,
+ path_to_item=None,
+ valid_classes=None,
+ key_type=None):
+ """ Raises an exception for TypeErrors
+
+ Args:
+ msg (str): the exception message
+
+ Keyword Args:
+ path_to_item (list): a list of keys an indices to get to the
+ current_item
+ None if unset
+ valid_classes (tuple): the primitive classes that current item
+ should be an instance of
+ None if unset
+ key_type (bool): False if our value is a value in a dict
+ True if it is a key in a dict
+ False if our item is an item in a list
+ None if unset
+ """
+ self.path_to_item = path_to_item
+ self.valid_classes = valid_classes
+ self.key_type = key_type
+ full_msg = msg
+ if path_to_item:
+ full_msg = "{0} at {1}".format(msg, render_path(path_to_item))
+ super(ApiTypeError, self).__init__(full_msg)
+
+
+class ApiValueError(OpenApiException, ValueError):
+
+ def __init__(self, msg, path_to_item=None):
+ """
+ Args:
+ msg (str): the exception message
+
+ Keyword Args:
+ path_to_item (list) the path to the exception in the
+ received_data dict. None if unset
+ """
+
+ self.path_to_item = path_to_item
+ full_msg = msg
+ if path_to_item:
+ full_msg = "{0} at {1}".format(msg, render_path(path_to_item))
+ super(ApiValueError, self).__init__(full_msg)
+
+
+class ApiKeyError(OpenApiException, KeyError):
+
+ def __init__(self, msg, path_to_item=None):
+ """
+ Args:
+ msg (str): the exception message
+
+ Keyword Args:
+ path_to_item (None/list) the path to the exception in the
+ received_data dict
+ """
+ self.path_to_item = path_to_item
+ full_msg = msg
+ if path_to_item:
+ full_msg = "{0} at {1}".format(msg, render_path(path_to_item))
+ super(ApiKeyError, self).__init__(full_msg)
+
+
+class ApiException(OpenApiException):
+
+ def __init__(self, status=None, reason=None, http_resp=None):
+ if http_resp:
+ self.status = http_resp.status
+ self.reason = http_resp.reason
+ self.body = http_resp.data
+ self.headers = http_resp.getheaders()
+ else:
+ self.status = status
+ self.reason = reason
+ self.body = None
+ self.headers = None
+
+ def __str__(self):
+ """Custom error messages for exception"""
+ error_message = "({0})\n"\
+ "Reason: {1}\n".format(self.status, self.reason)
+ if self.headers:
+ error_message += "HTTP response headers: {0}\n".format(self.headers)
+
+ if self.body:
+ error_message += "HTTP response body: {0}\n".format(self.body)
+
+ return error_message
+
+
+def render_path(path_to_item):
+ """Returns a string representation of a path"""
+ result = ""
+ for pth in path_to_item:
+ if isinstance(pth, six.integer_types):
+ result += "[{0}]".format(pth)
+ else:
+ result += "['{0}']".format(pth)
+ return result
diff --git a/submarine-sdk/pysubmarine/submarine/job/models/__init__.py b/submarine-sdk/pysubmarine/submarine/experiment/models/__init__.py
similarity index 50%
rename from submarine-sdk/pysubmarine/submarine/job/models/__init__.py
rename to submarine-sdk/pysubmarine/submarine/experiment/models/__init__.py
index c827ebe..4976022 100644
--- a/submarine-sdk/pysubmarine/submarine/job/models/__init__.py
+++ b/submarine-sdk/pysubmarine/submarine/experiment/models/__init__.py
@@ -1,11 +1,11 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
+# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
+# the License. You may obtain a copy of the License at
#
-# http://www.apache.org/licenses/LICENSE-2.0
+# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
@@ -19,17 +19,19 @@
"""
Submarine Experiment API
- The Submarine REST API allows you to create, list, and get experiments. TheAPI is hosted under the /v1/jobs route on the Submarine server. For example,to list experiments on a server hosted at http://localhost:8080, accesshttp://localhost:8080/api/v1/jobs/ # noqa: E501
+ The Submarine REST API allows you to create, list, and get experiments. The API is hosted under the /v1/experiment route on the Submarine server. For example, to list experiments on a server hosted at http://localhost:8080, access http://localhost:8080/api/v1/experiment/ # noqa: E501
- OpenAPI spec version: 0.4.0-SNAPSHOT
+ The version of the OpenAPI document: 0.4.0-SNAPSHOT
Contact: submarine-dev@submarine.apache.org
- Generated by: https://github.com/swagger-api/swagger-codegen.git
+ Generated by: https://openapi-generator.tech
"""
+
from __future__ import absolute_import
# import models into model package
-from submarine.job.models.job_library_spec import JobLibrarySpec
-from submarine.job.models.job_spec import JobSpec
-from submarine.job.models.job_task_spec import JobTaskSpec
-from submarine.job.models.json_response import JsonResponse
+from submarine.experiment.models.environment import Environment
+from submarine.experiment.models.experiment_meta import ExperimentMeta
+from submarine.experiment.models.experiment_spec import ExperimentSpec
+from submarine.experiment.models.experiment_task_spec import ExperimentTaskSpec
+from submarine.experiment.models.json_response import JsonResponse
diff --git a/submarine-sdk/pysubmarine/submarine/experiment/models/environment.py b/submarine-sdk/pysubmarine/submarine/experiment/models/environment.py
new file mode 100644
index 0000000..d362902
--- /dev/null
+++ b/submarine-sdk/pysubmarine/submarine/experiment/models/environment.py
@@ -0,0 +1,136 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# coding: utf-8
+
+"""
+ Submarine Experiment API
+
+ The Submarine REST API allows you to create, list, and get experiments. The API is hosted under the /v1/experiment route on the Submarine server. For example, to list experiments on a server hosted at http://localhost:8080, access http://localhost:8080/api/v1/experiment/ # noqa: E501
+
+ The version of the OpenAPI document: 0.4.0-SNAPSHOT
+ Contact: submarine-dev@submarine.apache.org
+ Generated by: https://openapi-generator.tech
+"""
+
+
+import pprint
+import re # noqa: F401
+
+import six
+
+from submarine.experiment.configuration import Configuration
+
+
+class Environment(object):
+ """NOTE: This class is auto generated by OpenAPI Generator.
+ Ref: https://openapi-generator.tech
+
+ Do not edit the class manually.
+ """
+
+ """
+ Attributes:
+ openapi_types (dict): The key is attribute name
+ and the value is attribute type.
+ attribute_map (dict): The key is attribute name
+ and the value is json key in definition.
+ """
+ openapi_types = {
+ 'image': 'str'
+ }
+
+ attribute_map = {
+ 'image': 'image'
+ }
+
+ def __init__(self, image=None, local_vars_configuration=None): # noqa: E501
+ """Environment - a model defined in OpenAPI""" # noqa: E501
+ if local_vars_configuration is None:
+ local_vars_configuration = Configuration()
+ self.local_vars_configuration = local_vars_configuration
+
+ self._image = None
+ self.discriminator = None
+
+ if image is not None:
+ self.image = image
+
+ @property
+ def image(self):
+ """Gets the image of this Environment. # noqa: E501
+
+
+ :return: The image of this Environment. # noqa: E501
+ :rtype: str
+ """
+ return self._image
+
+ @image.setter
+ def image(self, image):
+ """Sets the image of this Environment.
+
+
+ :param image: The image of this Environment. # noqa: E501
+ :type: str
+ """
+
+ self._image = image
+
+ def to_dict(self):
+ """Returns the model properties as a dict"""
+ result = {}
+
+ for attr, _ in six.iteritems(self.openapi_types):
+ value = getattr(self, attr)
+ if isinstance(value, list):
+ result[attr] = list(map(
+ lambda x: x.to_dict() if hasattr(x, "to_dict") else x,
+ value
+ ))
+ elif hasattr(value, "to_dict"):
+ result[attr] = value.to_dict()
+ elif isinstance(value, dict):
+ result[attr] = dict(map(
+ lambda item: (item[0], item[1].to_dict())
+ if hasattr(item[1], "to_dict") else item,
+ value.items()
+ ))
+ else:
+ result[attr] = value
+
+ return result
+
+ def to_str(self):
+ """Returns the string representation of the model"""
+ return pprint.pformat(self.to_dict())
+
+ def __repr__(self):
+ """For `print` and `pprint`"""
+ return self.to_str()
+
+ def __eq__(self, other):
+ """Returns true if both objects are equal"""
+ if not isinstance(other, Environment):
+ return False
+
+ return self.to_dict() == other.to_dict()
+
+ def __ne__(self, other):
+ """Returns true if both objects are not equal"""
+ if not isinstance(other, Environment):
+ return True
+
+ return self.to_dict() != other.to_dict()
diff --git a/submarine-sdk/pysubmarine/submarine/experiment/models/experiment_meta.py b/submarine-sdk/pysubmarine/submarine/experiment/models/experiment_meta.py
new file mode 100644
index 0000000..b5cbe9c
--- /dev/null
+++ b/submarine-sdk/pysubmarine/submarine/experiment/models/experiment_meta.py
@@ -0,0 +1,240 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# coding: utf-8
+
+"""
+ Submarine Experiment API
+
+ The Submarine REST API allows you to create, list, and get experiments. The API is hosted under the /v1/experiment route on the Submarine server. For example, to list experiments on a server hosted at http://localhost:8080, access http://localhost:8080/api/v1/experiment/ # noqa: E501
+
+ The version of the OpenAPI document: 0.4.0-SNAPSHOT
+ Contact: submarine-dev@submarine.apache.org
+ Generated by: https://openapi-generator.tech
+"""
+
+
+import pprint
+import re # noqa: F401
+
+import six
+
+from submarine.experiment.configuration import Configuration
+
+
+class ExperimentMeta(object):
+ """NOTE: This class is auto generated by OpenAPI Generator.
+ Ref: https://openapi-generator.tech
+
+ Do not edit the class manually.
+ """
+
+ """
+ Attributes:
+ openapi_types (dict): The key is attribute name
+ and the value is attribute type.
+ attribute_map (dict): The key is attribute name
+ and the value is json key in definition.
+ """
+ openapi_types = {
+ 'name': 'str',
+ 'namespace': 'str',
+ 'framework': 'str',
+ 'cmd': 'str',
+ 'env_vars': 'dict(str, str)'
+ }
+
+ attribute_map = {
+ 'name': 'name',
+ 'namespace': 'namespace',
+ 'framework': 'framework',
+ 'cmd': 'cmd',
+ 'env_vars': 'envVars'
+ }
+
+ def __init__(self, name=None, namespace=None, framework=None, cmd=None, env_vars=None, local_vars_configuration=None): # noqa: E501
+ """ExperimentMeta - a model defined in OpenAPI""" # noqa: E501
+ if local_vars_configuration is None:
+ local_vars_configuration = Configuration()
+ self.local_vars_configuration = local_vars_configuration
+
+ self._name = None
+ self._namespace = None
+ self._framework = None
+ self._cmd = None
+ self._env_vars = None
+ self.discriminator = None
+
+ if name is not None:
+ self.name = name
+ if namespace is not None:
+ self.namespace = namespace
+ if framework is not None:
+ self.framework = framework
+ if cmd is not None:
+ self.cmd = cmd
+ if env_vars is not None:
+ self.env_vars = env_vars
+
+ @property
+ def name(self):
+ """Gets the name of this ExperimentMeta. # noqa: E501
+
+
+ :return: The name of this ExperimentMeta. # noqa: E501
+ :rtype: str
+ """
+ return self._name
+
+ @name.setter
+ def name(self, name):
+ """Sets the name of this ExperimentMeta.
+
+
+ :param name: The name of this ExperimentMeta. # noqa: E501
+ :type: str
+ """
+
+ self._name = name
+
+ @property
+ def namespace(self):
+ """Gets the namespace of this ExperimentMeta. # noqa: E501
+
+
+ :return: The namespace of this ExperimentMeta. # noqa: E501
+ :rtype: str
+ """
+ return self._namespace
+
+ @namespace.setter
+ def namespace(self, namespace):
+ """Sets the namespace of this ExperimentMeta.
+
+
+ :param namespace: The namespace of this ExperimentMeta. # noqa: E501
+ :type: str
+ """
+
+ self._namespace = namespace
+
+ @property
+ def framework(self):
+ """Gets the framework of this ExperimentMeta. # noqa: E501
+
+
+ :return: The framework of this ExperimentMeta. # noqa: E501
+ :rtype: str
+ """
+ return self._framework
+
+ @framework.setter
+ def framework(self, framework):
+ """Sets the framework of this ExperimentMeta.
+
+
+ :param framework: The framework of this ExperimentMeta. # noqa: E501
+ :type: str
+ """
+
+ self._framework = framework
+
+ @property
+ def cmd(self):
+ """Gets the cmd of this ExperimentMeta. # noqa: E501
+
+
+ :return: The cmd of this ExperimentMeta. # noqa: E501
+ :rtype: str
+ """
+ return self._cmd
+
+ @cmd.setter
+ def cmd(self, cmd):
+ """Sets the cmd of this ExperimentMeta.
+
+
+ :param cmd: The cmd of this ExperimentMeta. # noqa: E501
+ :type: str
+ """
+
+ self._cmd = cmd
+
+ @property
+ def env_vars(self):
+ """Gets the env_vars of this ExperimentMeta. # noqa: E501
+
+
+ :return: The env_vars of this ExperimentMeta. # noqa: E501
+ :rtype: dict(str, str)
+ """
+ return self._env_vars
+
+ @env_vars.setter
+ def env_vars(self, env_vars):
+ """Sets the env_vars of this ExperimentMeta.
+
+
+ :param env_vars: The env_vars of this ExperimentMeta. # noqa: E501
+ :type: dict(str, str)
+ """
+
+ self._env_vars = env_vars
+
+ def to_dict(self):
+ """Returns the model properties as a dict"""
+ result = {}
+
+ for attr, _ in six.iteritems(self.openapi_types):
+ value = getattr(self, attr)
+ if isinstance(value, list):
+ result[attr] = list(map(
+ lambda x: x.to_dict() if hasattr(x, "to_dict") else x,
+ value
+ ))
+ elif hasattr(value, "to_dict"):
+ result[attr] = value.to_dict()
+ elif isinstance(value, dict):
+ result[attr] = dict(map(
+ lambda item: (item[0], item[1].to_dict())
+ if hasattr(item[1], "to_dict") else item,
+ value.items()
+ ))
+ else:
+ result[attr] = value
+
+ return result
+
+ def to_str(self):
+ """Returns the string representation of the model"""
+ return pprint.pformat(self.to_dict())
+
+ def __repr__(self):
+ """For `print` and `pprint`"""
+ return self.to_str()
+
+ def __eq__(self, other):
+ """Returns true if both objects are equal"""
+ if not isinstance(other, ExperimentMeta):
+ return False
+
+ return self.to_dict() == other.to_dict()
+
+ def __ne__(self, other):
+ """Returns true if both objects are not equal"""
+ if not isinstance(other, ExperimentMeta):
+ return True
+
+ return self.to_dict() != other.to_dict()
diff --git a/submarine-sdk/pysubmarine/submarine/experiment/models/experiment_spec.py b/submarine-sdk/pysubmarine/submarine/experiment/models/experiment_spec.py
new file mode 100644
index 0000000..47bb9a5
--- /dev/null
+++ b/submarine-sdk/pysubmarine/submarine/experiment/models/experiment_spec.py
@@ -0,0 +1,188 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# coding: utf-8
+
+"""
+ Submarine Experiment API
+
+ The Submarine REST API allows you to create, list, and get experiments. The API is hosted under the /v1/experiment route on the Submarine server. For example, to list experiments on a server hosted at http://localhost:8080, access http://localhost:8080/api/v1/experiment/ # noqa: E501
+
+ The version of the OpenAPI document: 0.4.0-SNAPSHOT
+ Contact: submarine-dev@submarine.apache.org
+ Generated by: https://openapi-generator.tech
+"""
+
+
+import pprint
+import re # noqa: F401
+
+import six
+
+from submarine.experiment.configuration import Configuration
+
+
+class ExperimentSpec(object):
+ """NOTE: This class is auto generated by OpenAPI Generator.
+ Ref: https://openapi-generator.tech
+
+ Do not edit the class manually.
+ """
+
+ """
+ Attributes:
+ openapi_types (dict): The key is attribute name
+ and the value is attribute type.
+ attribute_map (dict): The key is attribute name
+ and the value is json key in definition.
+ """
+ openapi_types = {
+ 'meta': 'ExperimentMeta',
+ 'environment': 'Environment',
+ 'spec': 'dict(str, ExperimentTaskSpec)'
+ }
+
+ attribute_map = {
+ 'meta': 'meta',
+ 'environment': 'environment',
+ 'spec': 'spec'
+ }
+
+ def __init__(self, meta=None, environment=None, spec=None, local_vars_configuration=None): # noqa: E501
+ """ExperimentSpec - a model defined in OpenAPI""" # noqa: E501
+ if local_vars_configuration is None:
+ local_vars_configuration = Configuration()
+ self.local_vars_configuration = local_vars_configuration
+
+ self._meta = None
+ self._environment = None
+ self._spec = None
+ self.discriminator = None
+
+ if meta is not None:
+ self.meta = meta
+ if environment is not None:
+ self.environment = environment
+ if spec is not None:
+ self.spec = spec
+
+ @property
+ def meta(self):
+ """Gets the meta of this ExperimentSpec. # noqa: E501
+
+
+ :return: The meta of this ExperimentSpec. # noqa: E501
+ :rtype: ExperimentMeta
+ """
+ return self._meta
+
+ @meta.setter
+ def meta(self, meta):
+ """Sets the meta of this ExperimentSpec.
+
+
+ :param meta: The meta of this ExperimentSpec. # noqa: E501
+ :type: ExperimentMeta
+ """
+
+ self._meta = meta
+
+ @property
+ def environment(self):
+ """Gets the environment of this ExperimentSpec. # noqa: E501
+
+
+ :return: The environment of this ExperimentSpec. # noqa: E501
+ :rtype: Environment
+ """
+ return self._environment
+
+ @environment.setter
+ def environment(self, environment):
+ """Sets the environment of this ExperimentSpec.
+
+
+ :param environment: The environment of this ExperimentSpec. # noqa: E501
+ :type: Environment
+ """
+
+ self._environment = environment
+
+ @property
+ def spec(self):
+ """Gets the spec of this ExperimentSpec. # noqa: E501
+
+
+ :return: The spec of this ExperimentSpec. # noqa: E501
+ :rtype: dict(str, ExperimentTaskSpec)
+ """
+ return self._spec
+
+ @spec.setter
+ def spec(self, spec):
+ """Sets the spec of this ExperimentSpec.
+
+
+ :param spec: The spec of this ExperimentSpec. # noqa: E501
+ :type: dict(str, ExperimentTaskSpec)
+ """
+
+ self._spec = spec
+
+ def to_dict(self):
+ """Returns the model properties as a dict"""
+ result = {}
+
+ for attr, _ in six.iteritems(self.openapi_types):
+ value = getattr(self, attr)
+ if isinstance(value, list):
+ result[attr] = list(map(
+ lambda x: x.to_dict() if hasattr(x, "to_dict") else x,
+ value
+ ))
+ elif hasattr(value, "to_dict"):
+ result[attr] = value.to_dict()
+ elif isinstance(value, dict):
+ result[attr] = dict(map(
+ lambda item: (item[0], item[1].to_dict())
+ if hasattr(item[1], "to_dict") else item,
+ value.items()
+ ))
+ else:
+ result[attr] = value
+
+ return result
+
+ def to_str(self):
+ """Returns the string representation of the model"""
+ return pprint.pformat(self.to_dict())
+
+ def __repr__(self):
+ """For `print` and `pprint`"""
+ return self.to_str()
+
+ def __eq__(self, other):
+ """Returns true if both objects are equal"""
+ if not isinstance(other, ExperimentSpec):
+ return False
+
+ return self.to_dict() == other.to_dict()
+
+ def __ne__(self, other):
+ """Returns true if both objects are not equal"""
+ if not isinstance(other, ExperimentSpec):
+ return True
+
+ return self.to_dict() != other.to_dict()
diff --git a/submarine-sdk/pysubmarine/submarine/job/models/job_task_spec.py b/submarine-sdk/pysubmarine/submarine/experiment/models/experiment_task_spec.py
similarity index 54%
rename from submarine-sdk/pysubmarine/submarine/job/models/job_task_spec.py
rename to submarine-sdk/pysubmarine/submarine/experiment/models/experiment_task_spec.py
index 2d5ac5b..44e5fa0 100644
--- a/submarine-sdk/pysubmarine/submarine/job/models/job_task_spec.py
+++ b/submarine-sdk/pysubmarine/submarine/experiment/models/experiment_task_spec.py
@@ -1,11 +1,11 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
+# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
+# the License. You may obtain a copy of the License at
#
-# http://www.apache.org/licenses/LICENSE-2.0
+# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,79 +14,85 @@
# limitations under the License.
# coding: utf-8
+
"""
Submarine Experiment API
- The Submarine REST API allows you to create, list, and get experiments. TheAPI is hosted under the /v1/jobs route on the Submarine server. For example,to list experiments on a server hosted at http://localhost:8080, accesshttp://localhost:8080/api/v1/jobs/ # noqa: E501
+ The Submarine REST API allows you to create, list, and get experiments. The API is hosted under the /v1/experiment route on the Submarine server. For example, to list experiments on a server hosted at http://localhost:8080, access http://localhost:8080/api/v1/experiment/ # noqa: E501
- OpenAPI spec version: 0.4.0-SNAPSHOT
+ The version of the OpenAPI document: 0.4.0-SNAPSHOT
Contact: submarine-dev@submarine.apache.org
- Generated by: https://github.com/swagger-api/swagger-codegen.git
+ Generated by: https://openapi-generator.tech
"""
+
import pprint
import re # noqa: F401
import six
+from submarine.experiment.configuration import Configuration
+
-class JobTaskSpec(object):
- """NOTE: This class is auto generated by the swagger code generator program.
+class ExperimentTaskSpec(object):
+ """NOTE: This class is auto generated by OpenAPI Generator.
+ Ref: https://openapi-generator.tech
Do not edit the class manually.
"""
+
"""
Attributes:
- swagger_types (dict): The key is attribute name
+ openapi_types (dict): The key is attribute name
and the value is attribute type.
attribute_map (dict): The key is attribute name
and the value is json key in definition.
"""
- swagger_types = {
+ openapi_types = {
+ 'replicas': 'int',
+ 'resources': 'str',
'name': 'str',
'image': 'str',
'cmd': 'str',
'env_vars': 'dict(str, str)',
- 'resources': 'str',
- 'replicas': 'int',
'cpu': 'str',
'gpu': 'str',
'memory': 'str'
}
attribute_map = {
+ 'replicas': 'replicas',
+ 'resources': 'resources',
'name': 'name',
'image': 'image',
'cmd': 'cmd',
'env_vars': 'envVars',
- 'resources': 'resources',
- 'replicas': 'replicas',
'cpu': 'cpu',
'gpu': 'gpu',
'memory': 'memory'
}
- def __init__(self,
- name=None,
- image=None,
- cmd=None,
- env_vars=None,
- resources=None,
- replicas=None,
- cpu=None,
- gpu=None,
- memory=None): # noqa: E501
- """JobTaskSpec - a model defined in Swagger""" # noqa: E501
+ def __init__(self, replicas=None, resources=None, name=None, image=None, cmd=None, env_vars=None, cpu=None, gpu=None, memory=None, local_vars_configuration=None): # noqa: E501
+ """ExperimentTaskSpec - a model defined in OpenAPI""" # noqa: E501
+ if local_vars_configuration is None:
+ local_vars_configuration = Configuration()
+ self.local_vars_configuration = local_vars_configuration
+
+ self._replicas = None
+ self._resources = None
self._name = None
self._image = None
self._cmd = None
self._env_vars = None
- self._resources = None
- self._replicas = None
self._cpu = None
self._gpu = None
self._memory = None
self.discriminator = None
+
+ if replicas is not None:
+ self.replicas = replicas
+ if resources is not None:
+ self.resources = resources
if name is not None:
self.name = name
if image is not None:
@@ -95,10 +101,6 @@ class JobTaskSpec(object):
self.cmd = cmd
if env_vars is not None:
self.env_vars = env_vars
- if resources is not None:
- self.resources = resources
- if replicas is not None:
- self.replicas = replicas
if cpu is not None:
self.cpu = cpu
if gpu is not None:
@@ -107,21 +109,63 @@ class JobTaskSpec(object):
self.memory = memory
@property
+ def replicas(self):
+ """Gets the replicas of this ExperimentTaskSpec. # noqa: E501
+
+
+ :return: The replicas of this ExperimentTaskSpec. # noqa: E501
+ :rtype: int
+ """
+ return self._replicas
+
+ @replicas.setter
+ def replicas(self, replicas):
+ """Sets the replicas of this ExperimentTaskSpec.
+
+
+ :param replicas: The replicas of this ExperimentTaskSpec. # noqa: E501
+ :type: int
+ """
+
+ self._replicas = replicas
+
+ @property
+ def resources(self):
+ """Gets the resources of this ExperimentTaskSpec. # noqa: E501
+
+
+ :return: The resources of this ExperimentTaskSpec. # noqa: E501
+ :rtype: str
+ """
+ return self._resources
+
+ @resources.setter
+ def resources(self, resources):
+ """Sets the resources of this ExperimentTaskSpec.
+
+
+ :param resources: The resources of this ExperimentTaskSpec. # noqa: E501
+ :type: str
+ """
+
+ self._resources = resources
+
+ @property
def name(self):
- """Gets the name of this JobTaskSpec. # noqa: E501
+ """Gets the name of this ExperimentTaskSpec. # noqa: E501
- :return: The name of this JobTaskSpec. # noqa: E501
+ :return: The name of this ExperimentTaskSpec. # noqa: E501
:rtype: str
"""
return self._name
@name.setter
def name(self, name):
- """Sets the name of this JobTaskSpec.
+ """Sets the name of this ExperimentTaskSpec.
- :param name: The name of this JobTaskSpec. # noqa: E501
+ :param name: The name of this ExperimentTaskSpec. # noqa: E501
:type: str
"""
@@ -129,20 +173,20 @@ class JobTaskSpec(object):
@property
def image(self):
- """Gets the image of this JobTaskSpec. # noqa: E501
+ """Gets the image of this ExperimentTaskSpec. # noqa: E501
- :return: The image of this JobTaskSpec. # noqa: E501
+ :return: The image of this ExperimentTaskSpec. # noqa: E501
:rtype: str
"""
return self._image
@image.setter
def image(self, image):
- """Sets the image of this JobTaskSpec.
+ """Sets the image of this ExperimentTaskSpec.
- :param image: The image of this JobTaskSpec. # noqa: E501
+ :param image: The image of this ExperimentTaskSpec. # noqa: E501
:type: str
"""
@@ -150,20 +194,20 @@ class JobTaskSpec(object):
@property
def cmd(self):
- """Gets the cmd of this JobTaskSpec. # noqa: E501
+ """Gets the cmd of this ExperimentTaskSpec. # noqa: E501
- :return: The cmd of this JobTaskSpec. # noqa: E501
+ :return: The cmd of this ExperimentTaskSpec. # noqa: E501
:rtype: str
"""
return self._cmd
@cmd.setter
def cmd(self, cmd):
- """Sets the cmd of this JobTaskSpec.
+ """Sets the cmd of this ExperimentTaskSpec.
- :param cmd: The cmd of this JobTaskSpec. # noqa: E501
+ :param cmd: The cmd of this ExperimentTaskSpec. # noqa: E501
:type: str
"""
@@ -171,83 +215,41 @@ class JobTaskSpec(object):
@property
def env_vars(self):
- """Gets the env_vars of this JobTaskSpec. # noqa: E501
+ """Gets the env_vars of this ExperimentTaskSpec. # noqa: E501
- :return: The env_vars of this JobTaskSpec. # noqa: E501
+ :return: The env_vars of this ExperimentTaskSpec. # noqa: E501
:rtype: dict(str, str)
"""
return self._env_vars
@env_vars.setter
def env_vars(self, env_vars):
- """Sets the env_vars of this JobTaskSpec.
+ """Sets the env_vars of this ExperimentTaskSpec.
- :param env_vars: The env_vars of this JobTaskSpec. # noqa: E501
+ :param env_vars: The env_vars of this ExperimentTaskSpec. # noqa: E501
:type: dict(str, str)
"""
self._env_vars = env_vars
@property
- def resources(self):
- """Gets the resources of this JobTaskSpec. # noqa: E501
-
-
- :return: The resources of this JobTaskSpec. # noqa: E501
- :rtype: str
- """
- return self._resources
-
- @resources.setter
- def resources(self, resources):
- """Sets the resources of this JobTaskSpec.
-
-
- :param resources: The resources of this JobTaskSpec. # noqa: E501
- :type: str
- """
-
- self._resources = resources
-
- @property
- def replicas(self):
- """Gets the replicas of this JobTaskSpec. # noqa: E501
-
-
- :return: The replicas of this JobTaskSpec. # noqa: E501
- :rtype: int
- """
- return self._replicas
-
- @replicas.setter
- def replicas(self, replicas):
- """Sets the replicas of this JobTaskSpec.
-
-
- :param replicas: The replicas of this JobTaskSpec. # noqa: E501
- :type: int
- """
-
- self._replicas = replicas
-
- @property
def cpu(self):
- """Gets the cpu of this JobTaskSpec. # noqa: E501
+ """Gets the cpu of this ExperimentTaskSpec. # noqa: E501
- :return: The cpu of this JobTaskSpec. # noqa: E501
+ :return: The cpu of this ExperimentTaskSpec. # noqa: E501
:rtype: str
"""
return self._cpu
@cpu.setter
def cpu(self, cpu):
- """Sets the cpu of this JobTaskSpec.
+ """Sets the cpu of this ExperimentTaskSpec.
- :param cpu: The cpu of this JobTaskSpec. # noqa: E501
+ :param cpu: The cpu of this ExperimentTaskSpec. # noqa: E501
:type: str
"""
@@ -255,20 +257,20 @@ class JobTaskSpec(object):
@property
def gpu(self):
- """Gets the gpu of this JobTaskSpec. # noqa: E501
+ """Gets the gpu of this ExperimentTaskSpec. # noqa: E501
- :return: The gpu of this JobTaskSpec. # noqa: E501
+ :return: The gpu of this ExperimentTaskSpec. # noqa: E501
:rtype: str
"""
return self._gpu
@gpu.setter
def gpu(self, gpu):
- """Sets the gpu of this JobTaskSpec.
+ """Sets the gpu of this ExperimentTaskSpec.
- :param gpu: The gpu of this JobTaskSpec. # noqa: E501
+ :param gpu: The gpu of this ExperimentTaskSpec. # noqa: E501
:type: str
"""
@@ -276,20 +278,20 @@ class JobTaskSpec(object):
@property
def memory(self):
- """Gets the memory of this JobTaskSpec. # noqa: E501
+ """Gets the memory of this ExperimentTaskSpec. # noqa: E501
- :return: The memory of this JobTaskSpec. # noqa: E501
+ :return: The memory of this ExperimentTaskSpec. # noqa: E501
:rtype: str
"""
return self._memory
@memory.setter
def memory(self, memory):
- """Sets the memory of this JobTaskSpec.
+ """Sets the memory of this ExperimentTaskSpec.
- :param memory: The memory of this JobTaskSpec. # noqa: E501
+ :param memory: The memory of this ExperimentTaskSpec. # noqa: E501
:type: str
"""
@@ -299,25 +301,23 @@ class JobTaskSpec(object):
"""Returns the model properties as a dict"""
result = {}
- for attr, _ in six.iteritems(self.swagger_types):
+ for attr, _ in six.iteritems(self.openapi_types):
value = getattr(self, attr)
if isinstance(value, list):
- result[attr] = list(
- map(lambda x: x.to_dict()
- if hasattr(x, "to_dict") else x, value))
+ result[attr] = list(map(
+ lambda x: x.to_dict() if hasattr(x, "to_dict") else x,
+ value
+ ))
elif hasattr(value, "to_dict"):
result[attr] = value.to_dict()
elif isinstance(value, dict):
- result[attr] = dict(
- map(
- lambda item: (item[0], item[1].to_dict())
- if hasattr(item[1], "to_dict") else item,
- value.items()))
+ result[attr] = dict(map(
+ lambda item: (item[0], item[1].to_dict())
+ if hasattr(item[1], "to_dict") else item,
+ value.items()
+ ))
else:
result[attr] = value
- if issubclass(JobTaskSpec, dict):
- for key, value in self.items():
- result[key] = value
return result
@@ -331,11 +331,14 @@ class JobTaskSpec(object):
def __eq__(self, other):
"""Returns true if both objects are equal"""
- if not isinstance(other, JobTaskSpec):
+ if not isinstance(other, ExperimentTaskSpec):
return False
- return self.__dict__ == other.__dict__
+ return self.to_dict() == other.to_dict()
def __ne__(self, other):
"""Returns true if both objects are not equal"""
- return not self == other
+ if not isinstance(other, ExperimentTaskSpec):
+ return True
+
+ return self.to_dict() != other.to_dict()
diff --git a/submarine-sdk/pysubmarine/submarine/job/models/json_response.py b/submarine-sdk/pysubmarine/submarine/experiment/models/json_response.py
similarity index 72%
rename from submarine-sdk/pysubmarine/submarine/job/models/json_response.py
rename to submarine-sdk/pysubmarine/submarine/experiment/models/json_response.py
index 9a3c94d..3e01803 100644
--- a/submarine-sdk/pysubmarine/submarine/job/models/json_response.py
+++ b/submarine-sdk/pysubmarine/submarine/experiment/models/json_response.py
@@ -1,11 +1,11 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
+# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
+# the License. You may obtain a copy of the License at
#
-# http://www.apache.org/licenses/LICENSE-2.0
+# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,35 +14,41 @@
# limitations under the License.
# coding: utf-8
+
"""
Submarine Experiment API
- The Submarine REST API allows you to create, list, and get experiments. TheAPI is hosted under the /v1/jobs route on the Submarine server. For example,to list experiments on a server hosted at http://localhost:8080, accesshttp://localhost:8080/api/v1/jobs/ # noqa: E501
+ The Submarine REST API allows you to create, list, and get experiments. The API is hosted under the /v1/experiment route on the Submarine server. For example, to list experiments on a server hosted at http://localhost:8080, access http://localhost:8080/api/v1/experiment/ # noqa: E501
- OpenAPI spec version: 0.4.0-SNAPSHOT
+ The version of the OpenAPI document: 0.4.0-SNAPSHOT
Contact: submarine-dev@submarine.apache.org
- Generated by: https://github.com/swagger-api/swagger-codegen.git
+ Generated by: https://openapi-generator.tech
"""
+
import pprint
import re # noqa: F401
import six
+from submarine.experiment.configuration import Configuration
+
class JsonResponse(object):
- """NOTE: This class is auto generated by the swagger code generator program.
+ """NOTE: This class is auto generated by OpenAPI Generator.
+ Ref: https://openapi-generator.tech
Do not edit the class manually.
"""
+
"""
Attributes:
- swagger_types (dict): The key is attribute name
+ openapi_types (dict): The key is attribute name
and the value is attribute type.
attribute_map (dict): The key is attribute name
and the value is json key in definition.
"""
- swagger_types = {
+ openapi_types = {
'code': 'int',
'success': 'bool',
'result': 'object',
@@ -56,17 +62,18 @@ class JsonResponse(object):
'attributes': 'attributes'
}
- def __init__(self,
- code=None,
- success=None,
- result=None,
- attributes=None): # noqa: E501
- """JsonResponse - a model defined in Swagger""" # noqa: E501
+ def __init__(self, code=None, success=None, result=None, attributes=None, local_vars_configuration=None): # noqa: E501
+ """JsonResponse - a model defined in OpenAPI""" # noqa: E501
+ if local_vars_configuration is None:
+ local_vars_configuration = Configuration()
+ self.local_vars_configuration = local_vars_configuration
+
self._code = None
self._success = None
self._result = None
self._attributes = None
self.discriminator = None
+
if code is not None:
self.code = code
if success is not None:
@@ -164,25 +171,23 @@ class JsonResponse(object):
"""Returns the model properties as a dict"""
result = {}
- for attr, _ in six.iteritems(self.swagger_types):
+ for attr, _ in six.iteritems(self.openapi_types):
value = getattr(self, attr)
if isinstance(value, list):
- result[attr] = list(
- map(lambda x: x.to_dict()
- if hasattr(x, "to_dict") else x, value))
+ result[attr] = list(map(
+ lambda x: x.to_dict() if hasattr(x, "to_dict") else x,
+ value
+ ))
elif hasattr(value, "to_dict"):
result[attr] = value.to_dict()
elif isinstance(value, dict):
- result[attr] = dict(
- map(
- lambda item: (item[0], item[1].to_dict())
- if hasattr(item[1], "to_dict") else item,
- value.items()))
+ result[attr] = dict(map(
+ lambda item: (item[0], item[1].to_dict())
+ if hasattr(item[1], "to_dict") else item,
+ value.items()
+ ))
else:
result[attr] = value
- if issubclass(JsonResponse, dict):
- for key, value in self.items():
- result[key] = value
return result
@@ -199,8 +204,11 @@ class JsonResponse(object):
if not isinstance(other, JsonResponse):
return False
- return self.__dict__ == other.__dict__
+ return self.to_dict() == other.to_dict()
def __ne__(self, other):
"""Returns true if both objects are not equal"""
- return not self == other
+ if not isinstance(other, JsonResponse):
+ return True
+
+ return self.to_dict() != other.to_dict()
diff --git a/submarine-sdk/pysubmarine/submarine/job/rest.py b/submarine-sdk/pysubmarine/submarine/experiment/rest.py
similarity index 88%
rename from submarine-sdk/pysubmarine/submarine/job/rest.py
rename to submarine-sdk/pysubmarine/submarine/experiment/rest.py
index 94f0288..46be388 100644
--- a/submarine-sdk/pysubmarine/submarine/job/rest.py
+++ b/submarine-sdk/pysubmarine/submarine/experiment/rest.py
@@ -1,11 +1,11 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
+# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
+# the License. You may obtain a copy of the License at
#
-# http://www.apache.org/licenses/LICENSE-2.0
+# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
@@ -17,11 +17,11 @@
"""
Submarine Experiment API
- The Submarine REST API allows you to create, list, and get experiments. TheAPI is hosted under the /v1/jobs route on the Submarine server. For example,to list experiments on a server hosted at http://localhost:8080, accesshttp://localhost:8080/api/v1/jobs/ # noqa: E501
+ The Submarine REST API allows you to create, list, and get experiments. The API is hosted under the /v1/experiment route on the Submarine server. For example, to list experiments on a server hosted at http://localhost:8080, access http://localhost:8080/api/v1/experiment/ # noqa: E501
- OpenAPI spec version: 0.4.0-SNAPSHOT
+ The version of the OpenAPI document: 0.4.0-SNAPSHOT
Contact: submarine-dev@submarine.apache.org
- Generated by: https://github.com/swagger-api/swagger-codegen.git
+ Generated by: https://openapi-generator.tech
"""
from __future__ import absolute_import
@@ -35,12 +35,10 @@ import ssl
import certifi
# python 2 and python 3 compatibility library
import six
+import urllib3
from six.moves.urllib.parse import urlencode
-try:
- import urllib3
-except ImportError:
- raise ImportError('Swagger python client requires urllib3.')
+from submarine.experiment.exceptions import ApiException, ApiValueError
logger = logging.getLogger(__name__)
@@ -89,6 +87,9 @@ class RESTClientObject(object):
addition_pool_args[
'assert_hostname'] = configuration.assert_hostname # noqa: E501
+ if configuration.retries is not None:
+ addition_pool_args['retries'] = configuration.retries
+
if maxsize is None:
if configuration.connection_pool_maxsize is not None:
maxsize = configuration.connection_pool_maxsize
@@ -105,6 +106,7 @@ class RESTClientObject(object):
cert_file=configuration.cert_file,
key_file=configuration.key_file,
proxy_url=configuration.proxy,
+ proxy_headers=configuration.proxy_headers,
**addition_pool_args)
else:
self.pool_manager = urllib3.PoolManager(
@@ -149,7 +151,7 @@ class RESTClientObject(object):
]
if post_params and body:
- raise ValueError(
+ raise ApiValueError(
"body parameter cannot be used with post_params parameter.")
post_params = post_params or {}
@@ -174,7 +176,7 @@ class RESTClientObject(object):
if query_params:
url += '?' + urlencode(query_params)
if re.search('json', headers['Content-Type'], re.IGNORECASE):
- request_body = '{}'
+ request_body = None
if body is not None:
request_body = json.dumps(body)
r = self.pool_manager.request(
@@ -210,7 +212,7 @@ class RESTClientObject(object):
# Pass a `string` parameter directly in the body to support
# other content types than Json when `body` argument is
# provided in serialized form
- elif isinstance(body, str):
+ elif isinstance(body, str) or isinstance(body, bytes):
request_body = body
r = self.pool_manager.request(
method,
@@ -240,11 +242,6 @@ class RESTClientObject(object):
if _preload_content:
r = RESTResponse(r)
- # In the python 3, the response.data is bytes.
- # we need to decode it to string.
- if six.PY3:
- r.data = r.data.decode('utf8')
-
# log response body
logger.debug("response body: %s", r.data)
@@ -361,30 +358,3 @@ class RESTClientObject(object):
_preload_content=_preload_content,
_request_timeout=_request_timeout,
body=body)
-
-
-class ApiException(Exception):
-
- def __init__(self, status=None, reason=None, http_resp=None):
- if http_resp:
- self.status = http_resp.status
- self.reason = http_resp.reason
- self.body = http_resp.data
- self.headers = http_resp.getheaders()
- else:
- self.status = status
- self.reason = reason
- self.body = None
- self.headers = None
-
- def __str__(self):
- """Custom error messages for exception"""
- error_message = "({0})\n"\
- "Reason: {1}\n".format(self.status, self.reason)
- if self.headers:
- error_message += "HTTP response headers: {0}\n".format(self.headers)
-
- if self.body:
- error_message += "HTTP response body: {0}\n".format(self.body)
-
- return error_message
diff --git a/submarine-sdk/pysubmarine/submarine/job/__init__.py b/submarine-sdk/pysubmarine/submarine/job/__init__.py
deleted file mode 100644
index ae4d323..0000000
--- a/submarine-sdk/pysubmarine/submarine/job/__init__.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# coding: utf-8
-
-# flake8: noqa
-"""
- Submarine Experiment API
-
- The Submarine REST API allows you to create, list, and get experiments. TheAPI is hosted under the /v1/jobs route on the Submarine server. For example,to list experiments on a server hosted at http://localhost:8080, accesshttp://localhost:8080/api/v1/jobs/ # noqa: E501
-
- OpenAPI spec version: 0.4.0-SNAPSHOT
- Contact: submarine-dev@submarine.apache.org
- Generated by: https://github.com/swagger-api/swagger-codegen.git
-"""
-
-from __future__ import absolute_import
-
-# import apis into sdk package
-from submarine.job.api.jobs_api import JobsApi
-# import ApiClient
-from submarine.job.api_client import ApiClient
-from submarine.job.configuration import Configuration
-# import models into sdk package
-from submarine.job.models.job_library_spec import JobLibrarySpec
-from submarine.job.models.job_spec import JobSpec
-from submarine.job.models.job_task_spec import JobTaskSpec
-from submarine.job.models.json_response import JsonResponse
diff --git a/submarine-sdk/pysubmarine/submarine/job/api/jobs_api.py b/submarine-sdk/pysubmarine/submarine/job/api/jobs_api.py
deleted file mode 100644
index 05195b9..0000000
--- a/submarine-sdk/pysubmarine/submarine/job/api/jobs_api.py
+++ /dev/null
@@ -1,783 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# coding: utf-8
-"""
- Submarine Experiment API
-
- The Submarine REST API allows you to create, list, and get experiments. TheAPI is hosted under the /v1/jobs route on the Submarine server. For example,to list experiments on a server hosted at http://localhost:8080, accesshttp://localhost:8080/api/v1/jobs/ # noqa: E501
-
- OpenAPI spec version: 0.4.0-SNAPSHOT
- Contact: submarine-dev@submarine.apache.org
- Generated by: https://github.com/swagger-api/swagger-codegen.git
-"""
-
-from __future__ import absolute_import
-
-import re # noqa: F401
-
-# python 2 and python 3 compatibility library
-import six
-
-from submarine.job.api_client import ApiClient
-
-
-class JobsApi(object):
- """NOTE: This class is auto generated by the swagger code generator program.
-
- Do not edit the class manually.
- Ref: https://github.com/swagger-api/swagger-codegen
- """
-
- def __init__(self, api_client=None):
- if api_client is None:
- api_client = ApiClient()
- self.api_client = api_client
-
- def create_job(self, **kwargs): # noqa: E501
- """Create a job # noqa: E501
-
- This method makes a synchronous HTTP request by default. To make an
- asynchronous HTTP request, please pass async_req=True
- >>> thread = api.create_job(async_req=True)
- >>> result = thread.get()
-
- :param async_req bool
- :param JobSpec body:
- :return: JsonResponse
- If the method is called asynchronously,
- returns the request thread.
- """
- kwargs['_return_http_data_only'] = True
- if kwargs.get('async_req'):
- return self.create_job_with_http_info(**kwargs) # noqa: E501
- else:
- (data) = self.create_job_with_http_info(**kwargs) # noqa: E501
- return data
-
- def create_job_with_http_info(self, **kwargs): # noqa: E501
- """Create a job # noqa: E501
-
- This method makes a synchronous HTTP request by default. To make an
- asynchronous HTTP request, please pass async_req=True
- >>> thread = api.create_job_with_http_info(async_req=True)
- >>> result = thread.get()
-
- :param async_req bool
- :param JobSpec body:
- :return: JsonResponse
- If the method is called asynchronously,
- returns the request thread.
- """
-
- all_params = ['body'] # noqa: E501
- all_params.append('async_req')
- all_params.append('_return_http_data_only')
- all_params.append('_preload_content')
- all_params.append('_request_timeout')
-
- params = locals()
- for key, val in six.iteritems(params['kwargs']):
- if key not in all_params:
- raise TypeError("Got an unexpected keyword argument '%s'"
- " to method create_job" % key)
- params[key] = val
- del params['kwargs']
-
- collection_formats = {}
-
- path_params = {}
-
- query_params = []
-
- header_params = {}
-
- form_params = []
- local_var_files = {}
-
- body_params = None
- if 'body' in params:
- body_params = params['body']
- # HTTP header `Accept`
- header_params['Accept'] = self.api_client.select_header_accept(
- ['application/json; charset=utf-8']) # noqa: E501
-
- # HTTP header `Content-Type`
- header_params[
- 'Content-Type'] = self.api_client.select_header_content_type( # noqa: E501
- ['application/yaml', 'application/json']) # noqa: E501
-
- # Authentication setting
- auth_settings = [] # noqa: E501
-
- return self.api_client.call_api(
- '/v1/jobs',
- 'POST',
- path_params,
- query_params,
- header_params,
- body=body_params,
- post_params=form_params,
- files=local_var_files,
- response_type='JsonResponse', # noqa: E501
- auth_settings=auth_settings,
- async_req=params.get('async_req'),
- _return_http_data_only=params.get('_return_http_data_only'),
- _preload_content=params.get('_preload_content', True),
- _request_timeout=params.get('_request_timeout'),
- collection_formats=collection_formats)
-
- def delete_job(self, id, **kwargs): # noqa: E501
- """Delete the job # noqa: E501
-
- This method makes a synchronous HTTP request by default. To make an
- asynchronous HTTP request, please pass async_req=True
- >>> thread = api.delete_job(id, async_req=True)
- >>> result = thread.get()
-
- :param async_req bool
- :param str id: (required)
- :return: JsonResponse
- If the method is called asynchronously,
- returns the request thread.
- """
- kwargs['_return_http_data_only'] = True
- if kwargs.get('async_req'):
- return self.delete_job_with_http_info(id, **kwargs) # noqa: E501
- else:
- (data) = self.delete_job_with_http_info(id, **kwargs) # noqa: E501
- return data
-
- def delete_job_with_http_info(self, id, **kwargs): # noqa: E501
- """Delete the job # noqa: E501
-
- This method makes a synchronous HTTP request by default. To make an
- asynchronous HTTP request, please pass async_req=True
- >>> thread = api.delete_job_with_http_info(id, async_req=True)
- >>> result = thread.get()
-
- :param async_req bool
- :param str id: (required)
- :return: JsonResponse
- If the method is called asynchronously,
- returns the request thread.
- """
-
- all_params = ['id'] # noqa: E501
- all_params.append('async_req')
- all_params.append('_return_http_data_only')
- all_params.append('_preload_content')
- all_params.append('_request_timeout')
-
- params = locals()
- for key, val in six.iteritems(params['kwargs']):
- if key not in all_params:
- raise TypeError("Got an unexpected keyword argument '%s'"
- " to method delete_job" % key)
- params[key] = val
- del params['kwargs']
- # verify the required parameter 'id' is set
- if ('id' not in params or params['id'] is None):
- raise ValueError(
- "Missing the required parameter `id` when calling `delete_job`"
- ) # noqa: E501
-
- collection_formats = {}
-
- path_params = {}
- if 'id' in params:
- path_params['id'] = params['id'] # noqa: E501
-
- query_params = []
-
- header_params = {}
-
- form_params = []
- local_var_files = {}
-
- body_params = None
- # HTTP header `Accept`
- header_params['Accept'] = self.api_client.select_header_accept(
- ['application/json; charset=utf-8']) # noqa: E501
-
- # Authentication setting
- auth_settings = [] # noqa: E501
-
- return self.api_client.call_api(
- '/v1/jobs/{id}',
- 'DELETE',
- path_params,
- query_params,
- header_params,
- body=body_params,
- post_params=form_params,
- files=local_var_files,
- response_type='JsonResponse', # noqa: E501
- auth_settings=auth_settings,
- async_req=params.get('async_req'),
- _return_http_data_only=params.get('_return_http_data_only'),
- _preload_content=params.get('_preload_content', True),
- _request_timeout=params.get('_request_timeout'),
- collection_formats=collection_formats)
-
- def get_job(self, id, **kwargs): # noqa: E501
- """Find job by id # noqa: E501
-
- This method makes a synchronous HTTP request by default. To make an
- asynchronous HTTP request, please pass async_req=True
- >>> thread = api.get_job(id, async_req=True)
- >>> result = thread.get()
-
- :param async_req bool
- :param str id: (required)
- :return: JsonResponse
- If the method is called asynchronously,
- returns the request thread.
- """
- kwargs['_return_http_data_only'] = True
- if kwargs.get('async_req'):
- return self.get_job_with_http_info(id, **kwargs) # noqa: E501
- else:
- (data) = self.get_job_with_http_info(id, **kwargs) # noqa: E501
- return data
-
- def get_job_with_http_info(self, id, **kwargs): # noqa: E501
- """Find job by id # noqa: E501
-
- This method makes a synchronous HTTP request by default. To make an
- asynchronous HTTP request, please pass async_req=True
- >>> thread = api.get_job_with_http_info(id, async_req=True)
- >>> result = thread.get()
-
- :param async_req bool
- :param str id: (required)
- :return: JsonResponse
- If the method is called asynchronously,
- returns the request thread.
- """
-
- all_params = ['id'] # noqa: E501
- all_params.append('async_req')
- all_params.append('_return_http_data_only')
- all_params.append('_preload_content')
- all_params.append('_request_timeout')
-
- params = locals()
- for key, val in six.iteritems(params['kwargs']):
- if key not in all_params:
- raise TypeError("Got an unexpected keyword argument '%s'"
- " to method get_job" % key)
- params[key] = val
- del params['kwargs']
- # verify the required parameter 'id' is set
- if ('id' not in params or params['id'] is None):
- raise ValueError(
- "Missing the required parameter `id` when calling `get_job`"
- ) # noqa: E501
-
- collection_formats = {}
-
- path_params = {}
- if 'id' in params:
- path_params['id'] = params['id'] # noqa: E501
-
- query_params = []
-
- header_params = {}
-
- form_params = []
- local_var_files = {}
-
- body_params = None
- # HTTP header `Accept`
- header_params['Accept'] = self.api_client.select_header_accept(
- ['application/json; charset=utf-8']) # noqa: E501
-
- # Authentication setting
- auth_settings = [] # noqa: E501
-
- return self.api_client.call_api(
- '/v1/jobs/{id}',
- 'GET',
- path_params,
- query_params,
- header_params,
- body=body_params,
- post_params=form_params,
- files=local_var_files,
- response_type='JsonResponse', # noqa: E501
- auth_settings=auth_settings,
- async_req=params.get('async_req'),
- _return_http_data_only=params.get('_return_http_data_only'),
- _preload_content=params.get('_preload_content', True),
- _request_timeout=params.get('_request_timeout'),
- collection_formats=collection_formats)
-
- def get_log(self, id, **kwargs): # noqa: E501
- """Log job by id # noqa: E501
-
- This method makes a synchronous HTTP request by default. To make an
- asynchronous HTTP request, please pass async_req=True
- >>> thread = api.get_log(id, async_req=True)
- >>> result = thread.get()
-
- :param async_req bool
- :param str id: (required)
- :return: JsonResponse
- If the method is called asynchronously,
- returns the request thread.
- """
- kwargs['_return_http_data_only'] = True
- if kwargs.get('async_req'):
- return self.get_log_with_http_info(id, **kwargs) # noqa: E501
- else:
- (data) = self.get_log_with_http_info(id, **kwargs) # noqa: E501
- return data
-
- def get_log_with_http_info(self, id, **kwargs): # noqa: E501
- """Log job by id # noqa: E501
-
- This method makes a synchronous HTTP request by default. To make an
- asynchronous HTTP request, please pass async_req=True
- >>> thread = api.get_log_with_http_info(id, async_req=True)
- >>> result = thread.get()
-
- :param async_req bool
- :param str id: (required)
- :return: JsonResponse
- If the method is called asynchronously,
- returns the request thread.
- """
-
- all_params = ['id'] # noqa: E501
- all_params.append('async_req')
- all_params.append('_return_http_data_only')
- all_params.append('_preload_content')
- all_params.append('_request_timeout')
-
- params = locals()
- for key, val in six.iteritems(params['kwargs']):
- if key not in all_params:
- raise TypeError("Got an unexpected keyword argument '%s'"
- " to method get_log" % key)
- params[key] = val
- del params['kwargs']
- # verify the required parameter 'id' is set
- if ('id' not in params or params['id'] is None):
- raise ValueError(
- "Missing the required parameter `id` when calling `get_log`"
- ) # noqa: E501
-
- collection_formats = {}
-
- path_params = {}
- if 'id' in params:
- path_params['id'] = params['id'] # noqa: E501
-
- query_params = []
-
- header_params = {}
-
- form_params = []
- local_var_files = {}
-
- body_params = None
- # HTTP header `Accept`
- header_params['Accept'] = self.api_client.select_header_accept(
- ['application/json; charset=utf-8']) # noqa: E501
-
- # Authentication setting
- auth_settings = [] # noqa: E501
-
- return self.api_client.call_api(
- '/v1/jobs/logs/{id}',
- 'GET',
- path_params,
- query_params,
- header_params,
- body=body_params,
- post_params=form_params,
- files=local_var_files,
- response_type='JsonResponse', # noqa: E501
- auth_settings=auth_settings,
- async_req=params.get('async_req'),
- _return_http_data_only=params.get('_return_http_data_only'),
- _preload_content=params.get('_preload_content', True),
- _request_timeout=params.get('_request_timeout'),
- collection_formats=collection_formats)
-
- def list_job(self, **kwargs): # noqa: E501
- """List jobs # noqa: E501
-
- This method makes a synchronous HTTP request by default. To make an
- asynchronous HTTP request, please pass async_req=True
- >>> thread = api.list_job(async_req=True)
- >>> result = thread.get()
-
- :param async_req bool
- :param str status:
- :return: JsonResponse
- If the method is called asynchronously,
- returns the request thread.
- """
- kwargs['_return_http_data_only'] = True
- if kwargs.get('async_req'):
- return self.list_job_with_http_info(**kwargs) # noqa: E501
- else:
- (data) = self.list_job_with_http_info(**kwargs) # noqa: E501
- return data
-
- def list_job_with_http_info(self, **kwargs): # noqa: E501
- """List jobs # noqa: E501
-
- This method makes a synchronous HTTP request by default. To make an
- asynchronous HTTP request, please pass async_req=True
- >>> thread = api.list_job_with_http_info(async_req=True)
- >>> result = thread.get()
-
- :param async_req bool
- :param str status:
- :return: JsonResponse
- If the method is called asynchronously,
- returns the request thread.
- """
-
- all_params = ['status'] # noqa: E501
- all_params.append('async_req')
- all_params.append('_return_http_data_only')
- all_params.append('_preload_content')
- all_params.append('_request_timeout')
-
- params = locals()
- for key, val in six.iteritems(params['kwargs']):
- if key not in all_params:
- raise TypeError("Got an unexpected keyword argument '%s'"
- " to method list_job" % key)
- params[key] = val
- del params['kwargs']
-
- collection_formats = {}
-
- path_params = {}
-
- query_params = []
- if 'status' in params:
- query_params.append(('status', params['status'])) # noqa: E501
-
- header_params = {}
-
- form_params = []
- local_var_files = {}
-
- body_params = None
- # HTTP header `Accept`
- header_params['Accept'] = self.api_client.select_header_accept(
- ['application/json; charset=utf-8']) # noqa: E501
-
- # Authentication setting
- auth_settings = [] # noqa: E501
-
- return self.api_client.call_api(
- '/v1/jobs',
- 'GET',
- path_params,
- query_params,
- header_params,
- body=body_params,
- post_params=form_params,
- files=local_var_files,
- response_type='JsonResponse', # noqa: E501
- auth_settings=auth_settings,
- async_req=params.get('async_req'),
- _return_http_data_only=params.get('_return_http_data_only'),
- _preload_content=params.get('_preload_content', True),
- _request_timeout=params.get('_request_timeout'),
- collection_formats=collection_formats)
-
- def list_log(self, **kwargs): # noqa: E501
- """Log jobs # noqa: E501
-
- This method makes a synchronous HTTP request by default. To make an
- asynchronous HTTP request, please pass async_req=True
- >>> thread = api.list_log(async_req=True)
- >>> result = thread.get()
-
- :param async_req bool
- :param str status:
- :return: JsonResponse
- If the method is called asynchronously,
- returns the request thread.
- """
- kwargs['_return_http_data_only'] = True
- if kwargs.get('async_req'):
- return self.list_log_with_http_info(**kwargs) # noqa: E501
- else:
- (data) = self.list_log_with_http_info(**kwargs) # noqa: E501
- return data
-
- def list_log_with_http_info(self, **kwargs): # noqa: E501
- """Log jobs # noqa: E501
-
- This method makes a synchronous HTTP request by default. To make an
- asynchronous HTTP request, please pass async_req=True
- >>> thread = api.list_log_with_http_info(async_req=True)
- >>> result = thread.get()
-
- :param async_req bool
- :param str status:
- :return: JsonResponse
- If the method is called asynchronously,
- returns the request thread.
- """
-
- all_params = ['status'] # noqa: E501
- all_params.append('async_req')
- all_params.append('_return_http_data_only')
- all_params.append('_preload_content')
- all_params.append('_request_timeout')
-
- params = locals()
- for key, val in six.iteritems(params['kwargs']):
- if key not in all_params:
- raise TypeError("Got an unexpected keyword argument '%s'"
- " to method list_log" % key)
- params[key] = val
- del params['kwargs']
-
- collection_formats = {}
-
- path_params = {}
-
- query_params = []
- if 'status' in params:
- query_params.append(('status', params['status'])) # noqa: E501
-
- header_params = {}
-
- form_params = []
- local_var_files = {}
-
- body_params = None
- # HTTP header `Accept`
- header_params['Accept'] = self.api_client.select_header_accept(
- ['application/json; charset=utf-8']) # noqa: E501
-
- # Authentication setting
- auth_settings = [] # noqa: E501
-
- return self.api_client.call_api(
- '/v1/jobs/logs',
- 'GET',
- path_params,
- query_params,
- header_params,
- body=body_params,
- post_params=form_params,
- files=local_var_files,
- response_type='JsonResponse', # noqa: E501
- auth_settings=auth_settings,
- async_req=params.get('async_req'),
- _return_http_data_only=params.get('_return_http_data_only'),
- _preload_content=params.get('_preload_content', True),
- _request_timeout=params.get('_request_timeout'),
- collection_formats=collection_formats)
-
- def patch_job(self, id, **kwargs): # noqa: E501
- """Update the job in the submarine server with job spec # noqa: E501
-
- This method makes a synchronous HTTP request by default. To make an
- asynchronous HTTP request, please pass async_req=True
- >>> thread = api.patch_job(id, async_req=True)
- >>> result = thread.get()
-
- :param async_req bool
- :param str id: (required)
- :param JobSpec body:
- :return: JsonResponse
- If the method is called asynchronously,
- returns the request thread.
- """
- kwargs['_return_http_data_only'] = True
- if kwargs.get('async_req'):
- return self.patch_job_with_http_info(id, **kwargs) # noqa: E501
- else:
- (data) = self.patch_job_with_http_info(id, **kwargs) # noqa: E501
- return data
-
- def patch_job_with_http_info(self, id, **kwargs): # noqa: E501
- """Update the job in the submarine server with job spec # noqa: E501
-
- This method makes a synchronous HTTP request by default. To make an
- asynchronous HTTP request, please pass async_req=True
- >>> thread = api.patch_job_with_http_info(id, async_req=True)
- >>> result = thread.get()
-
- :param async_req bool
- :param str id: (required)
- :param JobSpec body:
- :return: JsonResponse
- If the method is called asynchronously,
- returns the request thread.
- """
-
- all_params = ['id', 'body'] # noqa: E501
- all_params.append('async_req')
- all_params.append('_return_http_data_only')
- all_params.append('_preload_content')
- all_params.append('_request_timeout')
-
- params = locals()
- for key, val in six.iteritems(params['kwargs']):
- if key not in all_params:
- raise TypeError("Got an unexpected keyword argument '%s'"
- " to method patch_job" % key)
- params[key] = val
- del params['kwargs']
- # verify the required parameter 'id' is set
- if ('id' not in params or params['id'] is None):
- raise ValueError(
- "Missing the required parameter `id` when calling `patch_job`"
- ) # noqa: E501
-
- collection_formats = {}
-
- path_params = {}
- if 'id' in params:
- path_params['id'] = params['id'] # noqa: E501
-
- query_params = []
-
- header_params = {}
-
- form_params = []
- local_var_files = {}
-
- body_params = None
- if 'body' in params:
- body_params = params['body']
- # HTTP header `Accept`
- header_params['Accept'] = self.api_client.select_header_accept(
- ['application/json; charset=utf-8']) # noqa: E501
-
- # HTTP header `Content-Type`
- header_params[
- 'Content-Type'] = self.api_client.select_header_content_type( # noqa: E501
- ['application/yaml', 'application/json']) # noqa: E501
-
- # Authentication setting
- auth_settings = [] # noqa: E501
-
- return self.api_client.call_api(
- '/v1/jobs/{id}',
- 'PATCH',
- path_params,
- query_params,
- header_params,
- body=body_params,
- post_params=form_params,
- files=local_var_files,
- response_type='JsonResponse', # noqa: E501
- auth_settings=auth_settings,
- async_req=params.get('async_req'),
- _return_http_data_only=params.get('_return_http_data_only'),
- _preload_content=params.get('_preload_content', True),
- _request_timeout=params.get('_request_timeout'),
- collection_formats=collection_formats)
-
- def ping(self, **kwargs): # noqa: E501
- """Ping submarine server # noqa: E501
-
- Return the Pong message for test the connectivity # noqa: E501
- This method makes a synchronous HTTP request by default. To make an
- asynchronous HTTP request, please pass async_req=True
- >>> thread = api.ping(async_req=True)
- >>> result = thread.get()
-
- :param async_req bool
- :return: str
- If the method is called asynchronously,
- returns the request thread.
- """
- kwargs['_return_http_data_only'] = True
- if kwargs.get('async_req'):
- return self.ping_with_http_info(**kwargs) # noqa: E501
- else:
- (data) = self.ping_with_http_info(**kwargs) # noqa: E501
- return data
-
- def ping_with_http_info(self, **kwargs): # noqa: E501
- """Ping submarine server # noqa: E501
-
- Return the Pong message for test the connectivity # noqa: E501
- This method makes a synchronous HTTP request by default. To make an
- asynchronous HTTP request, please pass async_req=True
- >>> thread = api.ping_with_http_info(async_req=True)
- >>> result = thread.get()
-
- :param async_req bool
- :return: str
- If the method is called asynchronously,
- returns the request thread.
- """
-
- all_params = [] # noqa: E501
- all_params.append('async_req')
- all_params.append('_return_http_data_only')
- all_params.append('_preload_content')
- all_params.append('_request_timeout')
-
- params = locals()
- for key, val in six.iteritems(params['kwargs']):
- if key not in all_params:
- raise TypeError("Got an unexpected keyword argument '%s'"
- " to method ping" % key)
- params[key] = val
- del params['kwargs']
-
- collection_formats = {}
-
- path_params = {}
-
- query_params = []
-
- header_params = {}
-
- form_params = []
- local_var_files = {}
-
- body_params = None
- # HTTP header `Accept`
- header_params['Accept'] = self.api_client.select_header_accept(
- ['application/json; charset=utf-8']) # noqa: E501
-
- # Authentication setting
- auth_settings = [] # noqa: E501
-
- return self.api_client.call_api(
- '/v1/jobs/ping',
- 'GET',
- path_params,
- query_params,
- header_params,
- body=body_params,
- post_params=form_params,
- files=local_var_files,
- response_type='str', # noqa: E501
- auth_settings=auth_settings,
- async_req=params.get('async_req'),
- _return_http_data_only=params.get('_return_http_data_only'),
- _preload_content=params.get('_preload_content', True),
- _request_timeout=params.get('_request_timeout'),
- collection_formats=collection_formats)
diff --git a/submarine-sdk/pysubmarine/submarine/job/configuration.py b/submarine-sdk/pysubmarine/submarine/job/configuration.py
deleted file mode 100644
index f8be11a..0000000
--- a/submarine-sdk/pysubmarine/submarine/job/configuration.py
+++ /dev/null
@@ -1,257 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# coding: utf-8
-"""
- Submarine Experiment API
-
- The Submarine REST API allows you to create, list, and get experiments. TheAPI is hosted under the /v1/jobs route on the Submarine server. For example,to list experiments on a server hosted at http://localhost:8080, accesshttp://localhost:8080/api/v1/jobs/ # noqa: E501
-
- OpenAPI spec version: 0.4.0-SNAPSHOT
- Contact: submarine-dev@submarine.apache.org
- Generated by: https://github.com/swagger-api/swagger-codegen.git
-"""
-
-from __future__ import absolute_import
-
-import copy
-import logging
-import multiprocessing
-import sys
-
-import six
-import urllib3
-from six.moves import http_client as httplib
-
-
-class TypeWithDefault(type):
-
- def __init__(cls, name, bases, dct):
- super(TypeWithDefault, cls).__init__(name, bases, dct)
- cls._default = None
-
- def __call__(cls):
- if cls._default is None:
- cls._default = type.__call__(cls)
- return copy.copy(cls._default)
-
- def set_default(cls, default):
- cls._default = copy.copy(default)
-
-
-class Configuration(six.with_metaclass(TypeWithDefault, object)):
- """NOTE: This class is auto generated by the swagger code generator program.
-
- Ref: https://github.com/swagger-api/swagger-codegen
- Do not edit the class manually.
- """
-
- def __init__(self):
- """Constructor"""
- # Default Base url
- self.host = "/api"
- # Temp file folder for downloading files
- self.temp_folder_path = None
-
- # Authentication Settings
- # dict to store API key(s)
- self.api_key = {}
- # dict to store API prefix (e.g. Bearer)
- self.api_key_prefix = {}
- # function to refresh API key if expired
- self.refresh_api_key_hook = None
- # Username for HTTP basic authentication
- self.username = ""
- # Password for HTTP basic authentication
- self.password = ""
- # Logging Settings
- self.logger = {}
- self.logger["package_logger"] = logging.getLogger("submarine.job")
- self.logger["urllib3_logger"] = logging.getLogger("urllib3")
- # Log format
- self.logger_format = '%(asctime)s %(levelname)s %(message)s'
- # Log stream handler
- self.logger_stream_handler = None
- # Log file handler
- self.logger_file_handler = None
- # Debug file location
- self.logger_file = None
- # Debug switch
- self.debug = False
-
- # SSL/TLS verification
- # Set this to false to skip verifying SSL certificate when calling API
- # from https server.
- self.verify_ssl = True
- # Set this to customize the certificate file to verify the peer.
- self.ssl_ca_cert = None
- # client certificate file
- self.cert_file = None
- # client key file
- self.key_file = None
- # Set this to True/False to enable/disable SSL hostname verification.
- self.assert_hostname = None
-
- # urllib3 connection pool's maximum number of connections saved
- # per pool. urllib3 uses 1 connection as default value, but this is
- # not the best value when you are making a lot of possibly parallel
- # requests to the same host, which is often the case here.
- # cpu_count * 5 is used as default value to increase performance.
- self.connection_pool_maxsize = multiprocessing.cpu_count() * 5
-
- # Proxy URL
- self.proxy = None
- # Safe chars for path_param
- self.safe_chars_for_path_param = ''
-
- @property
- def logger_file(self):
- """The logger file.
-
- If the logger_file is None, then add stream handler and remove file
- handler. Otherwise, add file handler and remove stream handler.
-
- :param value: The logger_file path.
- :type: str
- """
- return self.__logger_file
-
- @logger_file.setter
- def logger_file(self, value):
- """The logger file.
-
- If the logger_file is None, then add stream handler and remove file
- handler. Otherwise, add file handler and remove stream handler.
-
- :param value: The logger_file path.
- :type: str
- """
- self.__logger_file = value
- if self.__logger_file:
- # If set logging file,
- # then add file handler and remove stream handler.
- self.logger_file_handler = logging.FileHandler(self.__logger_file)
- self.logger_file_handler.setFormatter(self.logger_formatter)
- for _, logger in six.iteritems(self.logger):
- logger.addHandler(self.logger_file_handler)
- if self.logger_stream_handler:
- logger.removeHandler(self.logger_stream_handler)
- else:
- # If not set logging file,
- # then add stream handler and remove file handler.
- self.logger_stream_handler = logging.StreamHandler()
- self.logger_stream_handler.setFormatter(self.logger_formatter)
- for _, logger in six.iteritems(self.logger):
- logger.addHandler(self.logger_stream_handler)
- if self.logger_file_handler:
- logger.removeHandler(self.logger_file_handler)
-
- @property
- def debug(self):
- """Debug status
-
- :param value: The debug status, True or False.
- :type: bool
- """
- return self.__debug
-
- @debug.setter
- def debug(self, value):
- """Debug status
-
- :param value: The debug status, True or False.
- :type: bool
- """
- self.__debug = value
- if self.__debug:
- # if debug status is True, turn on debug logging
- for _, logger in six.iteritems(self.logger):
- logger.setLevel(logging.DEBUG)
- # turn on httplib debug
- httplib.HTTPConnection.debuglevel = 1
- else:
- # if debug status is False, turn off debug logging,
- # setting log level to default `logging.WARNING`
- for _, logger in six.iteritems(self.logger):
- logger.setLevel(logging.WARNING)
- # turn off httplib debug
- httplib.HTTPConnection.debuglevel = 0
-
- @property
- def logger_format(self):
- """The logger format.
-
- The logger_formatter will be updated when sets logger_format.
-
- :param value: The format string.
- :type: str
- """
- return self.__logger_format
-
- @logger_format.setter
- def logger_format(self, value):
- """The logger format.
-
- The logger_formatter will be updated when sets logger_format.
-
- :param value: The format string.
- :type: str
- """
- self.__logger_format = value
- self.logger_formatter = logging.Formatter(self.__logger_format)
-
- def get_api_key_with_prefix(self, identifier):
- """Gets API key (with prefix if set).
-
- :param identifier: The identifier of apiKey.
- :return: The token for api key authentication.
- """
- if self.refresh_api_key_hook:
- self.refresh_api_key_hook(self)
-
- key = self.api_key.get(identifier)
- if key:
- prefix = self.api_key_prefix.get(identifier)
- if prefix:
- return "%s %s" % (prefix, key)
- else:
- return key
-
- def get_basic_auth_token(self):
- """Gets HTTP basic authentication header (string).
-
- :return: The token for basic HTTP authentication.
- """
- return urllib3.util.make_headers(basic_auth=self.username + ':' +
- self.password).get('authorization')
-
- def auth_settings(self):
- """Gets Auth Settings dict for api client.
-
- :return: The Auth Settings information dict.
- """
- return {}
-
- def to_debug_report(self):
- """Gets the essential information for debugging.
-
- :return: The report for debugging.
- """
- return "Python SDK Debug Report:\n"\
- "OS: {env}\n"\
- "Python Version: {pyversion}\n"\
- "Version of the API: 0.4.0-SNAPSHOT\n"\
- "SDK Package Version: 1.0.0".\
- format(env=sys.platform, pyversion=sys.version)
diff --git a/submarine-sdk/pysubmarine/submarine/job/models/job_library_spec.py b/submarine-sdk/pysubmarine/submarine/job/models/job_library_spec.py
deleted file mode 100644
index 8d017f3..0000000
--- a/submarine-sdk/pysubmarine/submarine/job/models/job_library_spec.py
+++ /dev/null
@@ -1,233 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# coding: utf-8
-"""
- Submarine Experiment API
-
- The Submarine REST API allows you to create, list, and get experiments. TheAPI is hosted under the /v1/jobs route on the Submarine server. For example,to list experiments on a server hosted at http://localhost:8080, accesshttp://localhost:8080/api/v1/jobs/ # noqa: E501
-
- OpenAPI spec version: 0.4.0-SNAPSHOT
- Contact: submarine-dev@submarine.apache.org
- Generated by: https://github.com/swagger-api/swagger-codegen.git
-"""
-
-import pprint
-import re # noqa: F401
-
-import six
-
-
-class JobLibrarySpec(object):
- """NOTE: This class is auto generated by the swagger code generator program.
-
- Do not edit the class manually.
- """
- """
- Attributes:
- swagger_types (dict): The key is attribute name
- and the value is attribute type.
- attribute_map (dict): The key is attribute name
- and the value is json key in definition.
- """
- swagger_types = {
- 'name': 'str',
- 'version': 'str',
- 'image': 'str',
- 'cmd': 'str',
- 'env_vars': 'dict(str, str)'
- }
-
- attribute_map = {
- 'name': 'name',
- 'version': 'version',
- 'image': 'image',
- 'cmd': 'cmd',
- 'env_vars': 'envVars'
- }
-
- def __init__(self,
- name=None,
- version=None,
- image=None,
- cmd=None,
- env_vars=None): # noqa: E501
- """JobLibrarySpec - a model defined in Swagger""" # noqa: E501
- self._name = None
- self._version = None
- self._image = None
- self._cmd = None
- self._env_vars = None
- self.discriminator = None
- if name is not None:
- self.name = name
- if version is not None:
- self.version = version
- if image is not None:
- self.image = image
- if cmd is not None:
- self.cmd = cmd
- if env_vars is not None:
- self.env_vars = env_vars
-
- @property
- def name(self):
- """Gets the name of this JobLibrarySpec. # noqa: E501
-
-
- :return: The name of this JobLibrarySpec. # noqa: E501
- :rtype: str
- """
- return self._name
-
- @name.setter
- def name(self, name):
- """Sets the name of this JobLibrarySpec.
-
-
- :param name: The name of this JobLibrarySpec. # noqa: E501
- :type: str
- """
-
- self._name = name
-
- @property
- def version(self):
- """Gets the version of this JobLibrarySpec. # noqa: E501
-
-
- :return: The version of this JobLibrarySpec. # noqa: E501
- :rtype: str
- """
- return self._version
-
- @version.setter
- def version(self, version):
- """Sets the version of this JobLibrarySpec.
-
-
- :param version: The version of this JobLibrarySpec. # noqa: E501
- :type: str
- """
-
- self._version = version
-
- @property
- def image(self):
- """Gets the image of this JobLibrarySpec. # noqa: E501
-
-
- :return: The image of this JobLibrarySpec. # noqa: E501
- :rtype: str
- """
- return self._image
-
- @image.setter
- def image(self, image):
- """Sets the image of this JobLibrarySpec.
-
-
- :param image: The image of this JobLibrarySpec. # noqa: E501
- :type: str
- """
-
- self._image = image
-
- @property
- def cmd(self):
- """Gets the cmd of this JobLibrarySpec. # noqa: E501
-
-
- :return: The cmd of this JobLibrarySpec. # noqa: E501
- :rtype: str
- """
- return self._cmd
-
- @cmd.setter
- def cmd(self, cmd):
- """Sets the cmd of this JobLibrarySpec.
-
-
- :param cmd: The cmd of this JobLibrarySpec. # noqa: E501
- :type: str
- """
-
- self._cmd = cmd
-
- @property
- def env_vars(self):
- """Gets the env_vars of this JobLibrarySpec. # noqa: E501
-
-
- :return: The env_vars of this JobLibrarySpec. # noqa: E501
- :rtype: dict(str, str)
- """
- return self._env_vars
-
- @env_vars.setter
- def env_vars(self, env_vars):
- """Sets the env_vars of this JobLibrarySpec.
-
-
- :param env_vars: The env_vars of this JobLibrarySpec. # noqa: E501
- :type: dict(str, str)
- """
-
- self._env_vars = env_vars
-
- def to_dict(self):
- """Returns the model properties as a dict"""
- result = {}
-
- for attr, _ in six.iteritems(self.swagger_types):
- value = getattr(self, attr)
- if isinstance(value, list):
- result[attr] = list(
- map(lambda x: x.to_dict()
- if hasattr(x, "to_dict") else x, value))
- elif hasattr(value, "to_dict"):
- result[attr] = value.to_dict()
- elif isinstance(value, dict):
- result[attr] = dict(
- map(
- lambda item: (item[0], item[1].to_dict())
- if hasattr(item[1], "to_dict") else item,
- value.items()))
- else:
- result[attr] = value
- if issubclass(JobLibrarySpec, dict):
- for key, value in self.items():
- result[key] = value
-
- return result
-
- def to_str(self):
- """Returns the string representation of the model"""
- return pprint.pformat(self.to_dict())
-
- def __repr__(self):
- """For `print` and `pprint`"""
- return self.to_str()
-
- def __eq__(self, other):
- """Returns true if both objects are equal"""
- if not isinstance(other, JobLibrarySpec):
- return False
-
- return self.__dict__ == other.__dict__
-
- def __ne__(self, other):
- """Returns true if both objects are not equal"""
- return not self == other
diff --git a/submarine-sdk/pysubmarine/submarine/job/models/job_spec.py b/submarine-sdk/pysubmarine/submarine/job/models/job_spec.py
deleted file mode 100644
index f038d23..0000000
--- a/submarine-sdk/pysubmarine/submarine/job/models/job_spec.py
+++ /dev/null
@@ -1,233 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# coding: utf-8
-"""
- Submarine Experiment API
-
- The Submarine REST API allows you to create, list, and get experiments. TheAPI is hosted under the /v1/jobs route on the Submarine server. For example,to list experiments on a server hosted at http://localhost:8080, accesshttp://localhost:8080/api/v1/jobs/ # noqa: E501
-
- OpenAPI spec version: 0.4.0-SNAPSHOT
- Contact: submarine-dev@submarine.apache.org
- Generated by: https://github.com/swagger-api/swagger-codegen.git
-"""
-
-import pprint
-import re # noqa: F401
-
-import six
-
-
-class JobSpec(object):
- """NOTE: This class is auto generated by the swagger code generator program.
-
- Do not edit the class manually.
- """
- """
- Attributes:
- swagger_types (dict): The key is attribute name
- and the value is attribute type.
- attribute_map (dict): The key is attribute name
- and the value is json key in definition.
- """
- swagger_types = {
- 'name': 'str',
- 'namespace': 'str',
- 'library_spec': 'JobLibrarySpec',
- 'task_specs': 'dict(str, JobTaskSpec)',
- 'projects': 'str'
- }
-
- attribute_map = {
- 'name': 'name',
- 'namespace': 'namespace',
- 'library_spec': 'librarySpec',
- 'task_specs': 'taskSpecs',
- 'projects': 'projects'
- }
-
- def __init__(self,
- name=None,
- namespace=None,
- library_spec=None,
- task_specs=None,
- projects=None): # noqa: E501
- """JobSpec - a model defined in Swagger""" # noqa: E501
- self._name = None
- self._namespace = None
- self._library_spec = None
- self._task_specs = None
- self._projects = None
- self.discriminator = None
- if name is not None:
- self.name = name
- if namespace is not None:
- self.namespace = namespace
- if library_spec is not None:
- self.library_spec = library_spec
- if task_specs is not None:
- self.task_specs = task_specs
- if projects is not None:
- self.projects = projects
-
- @property
- def name(self):
- """Gets the name of this JobSpec. # noqa: E501
-
-
- :return: The name of this JobSpec. # noqa: E501
- :rtype: str
- """
- return self._name
-
- @name.setter
- def name(self, name):
- """Sets the name of this JobSpec.
-
-
- :param name: The name of this JobSpec. # noqa: E501
- :type: str
- """
-
- self._name = name
-
- @property
- def namespace(self):
- """Gets the namespace of this JobSpec. # noqa: E501
-
-
- :return: The namespace of this JobSpec. # noqa: E501
- :rtype: str
- """
- return self._namespace
-
- @namespace.setter
- def namespace(self, namespace):
- """Sets the namespace of this JobSpec.
-
-
- :param namespace: The namespace of this JobSpec. # noqa: E501
- :type: str
- """
-
- self._namespace = namespace
-
- @property
- def library_spec(self):
- """Gets the library_spec of this JobSpec. # noqa: E501
-
-
- :return: The library_spec of this JobSpec. # noqa: E501
- :rtype: JobLibrarySpec
- """
- return self._library_spec
-
- @library_spec.setter
- def library_spec(self, library_spec):
- """Sets the library_spec of this JobSpec.
-
-
- :param library_spec: The library_spec of this JobSpec. # noqa: E501
- :type: JobLibrarySpec
- """
-
- self._library_spec = library_spec
-
- @property
- def task_specs(self):
- """Gets the task_specs of this JobSpec. # noqa: E501
-
-
- :return: The task_specs of this JobSpec. # noqa: E501
- :rtype: dict(str, JobTaskSpec)
- """
- return self._task_specs
-
- @task_specs.setter
- def task_specs(self, task_specs):
- """Sets the task_specs of this JobSpec.
-
-
- :param task_specs: The task_specs of this JobSpec. # noqa: E501
- :type: dict(str, JobTaskSpec)
- """
-
- self._task_specs = task_specs
-
- @property
- def projects(self):
- """Gets the projects of this JobSpec. # noqa: E501
-
-
- :return: The projects of this JobSpec. # noqa: E501
- :rtype: str
- """
- return self._projects
-
- @projects.setter
- def projects(self, projects):
- """Sets the projects of this JobSpec.
-
-
- :param projects: The projects of this JobSpec. # noqa: E501
- :type: str
- """
-
- self._projects = projects
-
- def to_dict(self):
- """Returns the model properties as a dict"""
- result = {}
-
- for attr, _ in six.iteritems(self.swagger_types):
- value = getattr(self, attr)
- if isinstance(value, list):
- result[attr] = list(
- map(lambda x: x.to_dict()
- if hasattr(x, "to_dict") else x, value))
- elif hasattr(value, "to_dict"):
- result[attr] = value.to_dict()
- elif isinstance(value, dict):
- result[attr] = dict(
- map(
- lambda item: (item[0], item[1].to_dict())
- if hasattr(item[1], "to_dict") else item,
- value.items()))
- else:
- result[attr] = value
- if issubclass(JobSpec, dict):
- for key, value in self.items():
- result[key] = value
-
- return result
-
- def to_str(self):
- """Returns the string representation of the model"""
- return pprint.pformat(self.to_dict())
-
- def __repr__(self):
- """For `print` and `pprint`"""
- return self.to_str()
-
- def __eq__(self, other):
- """Returns true if both objects are equal"""
- if not isinstance(other, JobSpec):
- return False
-
- return self.__dict__ == other.__dict__
-
- def __ne__(self, other):
- """Returns true if both objects are not equal"""
- return not self == other
diff --git a/submarine-server/server-core/src/main/java/org/apache/submarine/server/Bootstrap.java b/submarine-server/server-core/src/main/java/org/apache/submarine/server/Bootstrap.java
index c4bee19..e8abd45 100644
--- a/submarine-server/server-core/src/main/java/org/apache/submarine/server/Bootstrap.java
+++ b/submarine-server/server-core/src/main/java/org/apache/submarine/server/Bootstrap.java
@@ -42,10 +42,10 @@ public class Bootstrap extends HttpServlet {
OpenAPI oas = new OpenAPI();
Info info = new Info()
.title("Submarine Experiment API")
- .description("The Submarine REST API allows you to create, list, and get experiments. The" +
- "API is hosted under the /v1/jobs route on the Submarine server. For example," +
- "to list experiments on a server hosted at http://localhost:8080, access" +
- "http://localhost:8080/api/v1/jobs/")
+ .description("The Submarine REST API allows you to create, list, and get experiments. The\n" +
+ "API is hosted under the /v1/experiment route on the Submarine server. For example,\n" +
+ "to list experiments on a server hosted at http://localhost:8080, access\n" +
+ "http://localhost:8080/api/v1/experiment/")
.termsOfService("http://swagger.io/terms/")
.contact(new Contact()
.email("submarine-dev@submarine.apache.org"))
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@submarine.apache.org
For additional commands, e-mail: dev-help@submarine.apache.org