-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
creating upload with many CLIUI feats
- Loading branch information
Jochem Berends
committed
Nov 1, 2017
1 parent
11262e2
commit 9cc638d
Showing
8 changed files
with
231 additions
and
33 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
__version__ = '0.2.0' | ||
__version__ = '0.3.0' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,181 @@ | ||
import click as click | ||
import os | ||
|
||
from kecpkg.commands.utils import CONTEXT_SETTINGS | ||
import sys | ||
|
||
import requests | ||
from requests.compat import urljoin | ||
from pykechain import Client, get_project | ||
|
||
from kecpkg.commands.utils import CONTEXT_SETTINGS, echo_info, echo_success, echo_failure | ||
from kecpkg.settings import load_settings | ||
from kecpkg.utils import get_package_dir, get_package_name | ||
|
||
|
||
@click.command(context_settings=CONTEXT_SETTINGS, | ||
short_help="Upload package to a KE-chain 2 scope") | ||
def upload(**options): | ||
"""Upload built kecpkg to KE-chain.""" | ||
print('UPLOAD BUILDED KECPKG HERE ') | ||
@click.argument('package', required=False) | ||
@click.option('--url', '-U', help="URL of the KE-chain instance (eg. https://<instance>.ke-chain.com)") | ||
@click.option('--username', '-u', help="username for KE-chain", default=os.environ.get('USER', '')) | ||
@click.option('--password', '-p', help="password for KE-chain") | ||
@click.option('--token', help="token for KE-chain access") | ||
@click.option('--scope', help="scope name to upload the kecpkg to") | ||
@click.option('--scope-id', help="UUID of the scope to upload the kecpkg to", type=click.UUID) | ||
@click.option('--interactive', '-i', is_flag=True, help="interactive mode; guide me through the upload") | ||
def upload(package=None, url=None, username=None, password=None, token=None, scope=None, scope_id=None, **options): | ||
""" | ||
Upload built kecpkg to KE-chain. | ||
If no options are provided, the interactive mode is triggered. | ||
""" | ||
package_name = package or get_package_name() or click.prompt('Package name') | ||
settings = load_settings(package_dir=get_package_dir(package_name)) | ||
|
||
if not url or not (username and password) or not (token) or not (scope or scope_id) or options.get('interactive'): | ||
url = click.prompt('Url (incl http(s)://)', default=url) | ||
username = click.prompt('Username', default=username) | ||
password = click.prompt('Password', hide_input=True) | ||
|
||
client = Client(url) | ||
client.login(username=username, password=password) | ||
scopes = client.scopes() | ||
str_tpl = "{number} - {id} - {name}" | ||
scope_matcher = [dict(number=i, scope_id=scope.id, scope=scope.name) for i, scope in | ||
zip(range(1, len(scopes)), scopes)] | ||
|
||
# nice UI | ||
echo_info('Choose from following scopes:') | ||
for match_dict in scope_matcher: | ||
echo_info("{number} | {scope_id:.8} | {scope}".format(**match_dict)) | ||
|
||
scope_match = None | ||
while not scope_match: | ||
scope_guess = click.prompt('Row number, part of Id or Scope') | ||
scope_match = validate_scopes(scope_guess, scope_matcher) | ||
|
||
echo_success("Scope selected: '{scope}' ({scope_id})".format(**scope_match)) | ||
scope_id = scope_match['scope_id'] | ||
|
||
# do upload | ||
build_path = os.path.join(get_package_dir(package_name), settings.get('build_dir')) | ||
if not build_path: | ||
echo_failure('Cannot find build path, please do build kecpkg first') | ||
sys.exit(400) | ||
scope_to_upload = get_project(url, username, password, token, scope_id=scope_id) | ||
upload_package(scope_to_upload, build_path, settings) | ||
|
||
|
||
def upload_package(scope, build_path, settings): | ||
""" | ||
Upload the package from build_path to the right scope, create a new KE-chain SIM service | ||
:param scope: scope object (pykechain) | ||
:param build_path: path to the build directory in which the to-be uploaded script resides | ||
:param settings: settings of the package | ||
:return: None | ||
""" | ||
built_kecpkgs = os.listdir(build_path) | ||
if len(built_kecpkgs) > 1 and settings.get('version'): | ||
built_kecpkgs = [f for f in built_kecpkgs if settings.get('version') in f] | ||
if len(built_kecpkgs) == 1: | ||
kecpkg_path = os.path.join(build_path, built_kecpkgs[0]) | ||
else: | ||
echo_info('Provide correct filename to upload') | ||
echo_info('\n'.join(os.listdir(build_path))) | ||
kecpkg_filename = click.prompt('Filename') | ||
kecpkg_path = os.path.join(build_path, kecpkg_filename) | ||
|
||
if kecpkg_path and os.path.exists(kecpkg_path): | ||
# ready to upload | ||
echo_info('Ready to upload `{}`'.format(os.path.basename(kecpkg_path))) | ||
else: | ||
echo_failure('Unable to locate kecpkg to upload') | ||
sys.exit(404) | ||
|
||
# get mata and prepare 2 stage submission | ||
# 1. fill service information | ||
# 2. do upload | ||
|
||
payload = dict( | ||
name=settings.get('package_name'), | ||
description=settings.get('description', ''), | ||
script_version=settings.get('version', ''), | ||
script_type='PYTHON SCRIPT', | ||
env_version=settings.get('python_version'), | ||
id='', | ||
scope=scope.id | ||
) | ||
|
||
create_uri = '/api/services.json' | ||
r = scope._client._request('POST', urljoin(scope._client.api_root, create_uri), data=payload) | ||
if r.status_code != requests.codes.created: | ||
echo_failure('Unexpected response from the server: {}'.format((r, r.text))) | ||
sys.exit(r.status_code) | ||
response = r.json() | ||
new_service = response.get('results')[0] | ||
|
||
# now upload | ||
r = scope._client._request('POST', "{}/{}".format(new_service.get('url'),'upload.json'), | ||
files={'attachment': (os.path.basename(kecpkg_path), open(kecpkg_path, 'rb'))}) | ||
|
||
if r.status_code != requests.codes.accepted: | ||
echo_failure('Unexpected response from the server: {}'.format((r, r.text))) | ||
sys.exit(r.status_code) | ||
|
||
echo_success("kecpkg `{}` successfully uploaded to KE-chain.".format(os.path.basename(kecpkg_path))) | ||
success_url = "{api_root}/#scopes/{scope_id}/scripts/{script_id}".format( | ||
api_root=scope._client.api_root, | ||
scope_id=scope.id, | ||
script_id=new_service.get('id') | ||
) | ||
echo_success("To view the newly created service, go to: `{}`".format(success_url)) | ||
|
||
|
||
def validate_scopes(scope_guess, scope_matcher): | ||
"""Check the scope guess against a set of possible scopes and return correct scope_id""" | ||
for scope_match in scope_matcher: | ||
if scope_guess == str(scope_match['number']): | ||
return scope_match | ||
if len(scope_guess) >= 2 and scope_guess.lower() in scope_match['scope_id'].lower(): | ||
return scope_match | ||
if scope_guess.lower() in scope_match['scope'].lower(): | ||
return scope_match | ||
return None | ||
|
||
|
||
""" | ||
NEW SCRIPT | ||
Request: | ||
URL: https://kec2api.ke-chain.com/api/services.json?_dc=1509571322573 | ||
Request Method:POST | ||
Status Code:201 Created | ||
{"name":"name","description":"descr","script_version":"0.0.1", | ||
"script_type":"PYTHON SCRIPT","env_version":"3.5", | ||
"id":"Service-1", | ||
"scope":"6f7bc9f0-228e-4d3a-9dc0-ec5a75d73e1d"} | ||
Response: | ||
{"results":[ | ||
{"id":"be473cc2-9342-4b33-85dc-8b16ae67d79b", | ||
"url":"https://kec2api.ke-chain.com/api/services/be473cc2-9342-4b33-85dc-8b16ae67d79b", | ||
"name":"name","description":"descr", | ||
"scope":"6f7bc9f0-228e-4d3a-9dc0-ec5a75d73e1d", | ||
"script_file_name":"","script_type":"PYTHON SCRIPT", | ||
"script_version":"0.0.1","env_version":"3.5", | ||
"permissions":{"read":true,"destroy":true,"update":true,"create":true,"write":true,"retrieve_execute":true}}]} | ||
UPLOAD SCRIPT | ||
Request URL:https://kec2api.ke-chain.com/api/services/be473cc2-9342-4b33-85dc-8b16ae67d79b/upload.json | ||
Request Method:POST | ||
Payload: | ||
------WebKitFormBoundarygA6v9Rm8hnD5tPfv | ||
Content-Disposition: form-data; name="attachment"; filename="some_pkg-0.0.1-py3.5.kecpkg" | ||
Content-Type: application/octet-stream | ||
SUCCES URI | ||
https://kec2api.ke-chain.com/#scopes/6f7bc9f0-228e-4d3a-9dc0-ec5a75d73e1d/scripts/66c768d3-8c6d-4a0e-b74f-4b3e5fa92dc3 | ||
""" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters