remotivelabs-cli 0.0.1a2__py3-none-any.whl → 0.0.1a4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
cli/brokers.py CHANGED
@@ -1,27 +1,17 @@
1
1
  import json
2
- import time
3
- import typer
4
- #import network
5
- from .lib.broker import Broker
6
- #from network import MDNS
7
-
8
-
9
- import argparse
10
- import logging
11
2
  from time import sleep
12
- from typing import cast
13
3
 
4
+ import typer
14
5
  from zeroconf import (
15
6
  IPVersion,
16
7
  ServiceBrowser,
17
8
  ServiceStateChange,
18
9
  Zeroconf,
19
- ZeroconfServiceTypes,
20
10
  )
21
11
 
22
- app = typer.Typer()
23
-
12
+ from .lib.broker import Broker
24
13
 
14
+ app = typer.Typer()
25
15
 
26
16
 
27
17
  @app.command(help="List signals on broker")
@@ -30,7 +20,7 @@ def signals(
30
20
  api_key: str = typer.Option("offline", help="Cloud Broker API-KEY", envvar='REMOTIVE_BROKER_API_KEY')
31
21
  ):
32
22
  broker = Broker(url, api_key)
33
- print("Listing available signals")
23
+ # print("Listing available signals")
34
24
  available_signals = broker.list_signal_names()
35
25
  print(json.dumps(available_signals))
36
26
 
@@ -41,17 +31,18 @@ def namespaces(
41
31
  api_key: str = typer.Option("offline", help="Cloud Broker API-KEY", envvar='REMOTIVE_BROKER_API_KEY')
42
32
  ):
43
33
  broker = Broker(url, api_key)
44
- namespaces = broker.list_namespaces()
45
- print(json.dumps(namespaces))
34
+ namespaces_json = broker.list_namespaces()
35
+ print(json.dumps(namespaces_json))
36
+
46
37
 
47
38
  @app.command(help="Discover brokers on this network")
48
39
  def discover():
49
- #print("Not implemented")
40
+ # print("Not implemented")
50
41
 
51
42
  zeroconf = Zeroconf(ip_version=IPVersion.V4Only)
52
43
 
53
- services = ["_remotivebroker._tcp.local.","_googlecast._tcp.local."]
54
- #services = list(ZeroconfServiceTypes.find(zc=zeroconf))
44
+ services = ["_remotivebroker._tcp.local.", "_googlecast._tcp.local."]
45
+ # services = list(ZeroconfServiceTypes.find(zc=zeroconf))
55
46
 
56
47
  print("\nLooking for RemotiveBrokers on your network, press Ctrl-C to exit...\n")
57
48
  browser = ServiceBrowser(zeroconf, services, handlers=[on_service_state_change])
@@ -64,25 +55,11 @@ def discover():
64
55
  finally:
65
56
  zeroconf.close()
66
57
 
67
- #network.MDNS.init()
68
-
69
- # Perform a query for 2000 ms
70
- #q = MDNS.query(2000, "broker", MDNS.PROTO_TCP)
71
-
72
- # Print out the query's result
73
- #if q is not None:
74
- # for elem in q:
75
- # print(elem.instance_name())
76
- # print(elem.hostname())
77
- # print(elem.addr())
78
- # print(elem.port())
79
- # print(elem.txt())
80
-
81
58
 
82
59
  def on_service_state_change(
83
60
  zeroconf: Zeroconf, service_type: str, name: str, state_change: ServiceStateChange
84
61
  ) -> None:
85
- #print(f"Service {name} state changed: {state_change}")
62
+ # print(f"Service {name} state changed: {state_change}")
86
63
 
87
64
  if state_change is ServiceStateChange.Removed:
88
65
  print(f"Service {name} was removed")
@@ -93,23 +70,24 @@ def on_service_state_change(
93
70
  if state_change is ServiceStateChange.Added:
94
71
  print(f"Discovered {name} ")
95
72
  info = zeroconf.get_service_info(service_type, name)
96
- #print("Info from zeroconf.get_service_info: %r" % (info))
73
+ # print("Info from zeroconf.get_service_info: %r" % (info))
97
74
 
98
75
  if info:
99
- #addresses = ["%s:%d" % (addr, cast(int, info.port)) for addr in info.parsed_scoped_addresses()]
76
+ # addresses = ["%s:%d" % (addr, cast(int, info.port)) for addr in info.parsed_scoped_addresses()]
100
77
  for addr in info.parsed_scoped_addresses():
101
78
  print(addr)
102
- #print(" Weight: %d, priority: %d" % (info.weight, info.priority))
103
- #print(f" Server: {info.server}")
104
- #if info.properties:
79
+ # print(" Weight: %d, priority: %d" % (info.weight, info.priority))
80
+ # print(f" Server: {info.server}")
81
+ # if info.properties:
105
82
  # print(" Properties are:")
106
83
  # for key, value in info.properties.items():
107
84
  # print(f" {key}: {value}")
108
- #else:
85
+ # else:
109
86
  # print(" No properties")
110
87
  else:
111
88
  print(" No info")
112
89
  print('\n')
113
90
 
91
+
114
92
  if __name__ == "__main__":
115
93
  app()
cli/cloud/auth.py CHANGED
@@ -8,19 +8,21 @@ from pathlib import Path
8
8
  from threading import Thread
9
9
  import typer
10
10
  from . import rest_helper as rest
11
+ from . import auth_keys
11
12
 
12
13
  app = typer.Typer()
13
-
14
+ app.add_typer(auth_keys.app, name="keys", help="Manage users personal access keys")
14
15
  config_dir_name = str(Path.home()) + "/.config/.remotive/"
15
16
  token_file_name = str(Path.home()) + "/.config/.remotive/cloud.secret.token"
16
17
 
17
18
 
19
+
18
20
  class S(BaseHTTPRequestHandler):
19
21
  def _set_response(self):
20
22
  self.send_response(200)
21
- #self.send_response(301)
22
- #self.send_header('Location', 'https://cloud.remotivelabs.com')
23
- #self.end_headers()
23
+ # self.send_response(301)
24
+ # self.send_header('Location', 'https://cloud.remotivelabs.com')
25
+ # self.end_headers()
24
26
  self.send_header('Content-type', 'text/html')
25
27
  self.end_headers()
26
28
 
@@ -55,26 +57,32 @@ def login():
55
57
  webbrowser.open(f'{rest.base_url}/login?redirectUrl=http://localhost:8089', new=1, autoraise=True)
56
58
  start_local_webserver()
57
59
 
60
+ @app.command(help="Who am I?")
61
+ def whoami():
62
+ rest.handle_get('/api/whoami')
58
63
 
59
64
  @app.command(help="Print access token")
60
65
  def print_access_token():
61
66
  print(read_token())
62
67
 
68
+
63
69
  @app.command(help="List available auth tokens")
64
70
  def list():
65
71
  for file in os.listdir(config_dir_name):
66
72
  print(file)
67
73
 
74
+
68
75
  @app.command(help="Show token file")
69
76
  def describe(
70
77
  file: str = typer.Option(..., help="File name")):
71
78
  print(read_file(file))
72
79
 
73
80
 
81
+
82
+
74
83
  @app.command(help="Activate the account file")
75
84
  def activate(
76
85
  file: str = typer.Option(..., help="File name")):
77
-
78
86
  # Best effort to read file
79
87
  if os.path.exists(file):
80
88
  token_file = json.loads(read_file_with_path(file))
@@ -106,23 +114,29 @@ def read_token():
106
114
  f.close()
107
115
  return token
108
116
 
117
+
109
118
  def read_file_with_path(file):
110
119
  f = open(file, "r")
111
120
  token = f.read()
112
121
  f.close()
113
122
  return token
114
123
 
124
+
115
125
  def read_file(file):
116
126
  f = open(str(Path.home()) + f"/.config/.remotive/{file}", "r")
117
127
  token = f.read()
118
128
  f.close()
119
129
  return token
120
130
 
131
+
121
132
  def write_token(token):
122
133
  f = open(token_file_name, "w")
123
134
  f.write(token)
124
135
  f.close()
125
136
 
137
+
138
+
139
+
126
140
  # Key stuff
127
141
  # f = open(str(Path.home())+ "/.remotivelabs/privatekey.json", "r")
128
142
  # j = json.loads(f.read())
cli/cloud/auth_keys.py ADDED
@@ -0,0 +1,46 @@
1
+ from pathlib import Path
2
+
3
+ import typer
4
+ from . import rest_helper as rest
5
+
6
+ app = typer.Typer()
7
+
8
+
9
+ @app.command(name="create", help="Create and download a new personal access token")
10
+ def get_personal_access_token():
11
+ rest.ensure_auth_token()
12
+ rest.handle_post('/api/me/keys')
13
+
14
+ response = rest.handle_post(url='/api/me/keys',
15
+ return_response=True)
16
+
17
+ if response.status_code == 200:
18
+ name = response.json()['name']
19
+ write_personal_token(f"personal-{name}-key.json", response.text)
20
+ else:
21
+ print(f'Got status code: {response.status_code}')
22
+ print(response.text)
23
+
24
+
25
+ @app.command(name="list", help="List personal access tokens")
26
+ def list_personal_access_tokens():
27
+ rest.ensure_auth_token()
28
+ rest.handle_get('/api/me/keys')
29
+
30
+
31
+ @app.command(name="revoke", help="Revoke the specified key")
32
+ def revoke(
33
+ key_name: str = typer.Option(..., help="Name of the key to revoke")
34
+ ):
35
+ rest.ensure_auth_token()
36
+ rest.handle_delete(f'/api/me/keys/{key_name}')
37
+
38
+
39
+ def write_personal_token(file, token):
40
+ path = str(Path.home()) + f"/.config/.remotive/{file}"
41
+ f = open(path, "w")
42
+ f.write(token)
43
+ f.close()
44
+ print(f"Personal key written to {path}")
45
+ print("Use 'remotive cloud auth activate filename' to use this key from cli")
46
+ print('\033[93m This file contains secrets and must never be compromised')
cli/cloud/brokers.py CHANGED
@@ -2,7 +2,7 @@ import typer
2
2
  import json
3
3
  from rich.progress import Progress, SpinnerColumn, TextColumn
4
4
  from . import rest_helper as rest
5
-
5
+ from rich import print
6
6
  app = typer.Typer()
7
7
 
8
8
 
cli/cloud/cloud_cli.py CHANGED
@@ -1,19 +1,11 @@
1
- import time
2
-
3
1
  import typer
4
- import json
5
- from rich.progress import Progress, SpinnerColumn, TextColumn
6
- from . import recordings, brokers, configs, auth, service_accounts
2
+
3
+ from . import recordings, brokers, configs, auth, service_accounts, projects
7
4
  from . import rest_helper as rest
8
5
 
9
6
  app = typer.Typer()
10
7
 
11
8
 
12
- @app.command(help="Who am I?")
13
- def whoami():
14
- rest.handle_get('/api/whoami')
15
-
16
-
17
9
  @app.command(help="List licenses for an organisation")
18
10
  def licenses(
19
11
  organisation: str = typer.Option(..., help="Organisation ID", envvar='REMOTIVE_CLOUD_ORGANISATION'),
@@ -41,10 +33,11 @@ def users(
41
33
  rest.handle_get(f"/api/bu/{organisation}/users")
42
34
 
43
35
 
36
+ app.add_typer(projects.app, name="projects", help="Manage projects")
37
+ app.add_typer(auth.app, name="auth", help="Manage access to cloud resources")
44
38
  app.add_typer(brokers.app, name="brokers", help="Manage cloud broker lifecycle")
45
39
  app.add_typer(recordings.app, name="recordings", help="Manage recordings")
46
- app.add_typer(configs.app, name="configs", help="Manage signal databases")
47
- app.add_typer(auth.app, name="auth", help="Manage access to cloud resources")
40
+ app.add_typer(configs.app, name="signal-databases", help="Manage signal databases")
48
41
  app.add_typer(service_accounts.app, name="service-accounts", help="Manage project service account keys")
49
42
 
50
43
 
cli/cloud/configs.py CHANGED
@@ -1,11 +1,10 @@
1
+ import shutil
1
2
  import sys
2
3
 
3
- import typer
4
4
  import requests
5
- import os
6
- import json
7
- import shutil
5
+ import typer
8
6
  from rich.progress import Progress, SpinnerColumn, TextColumn
7
+
9
8
  from . import rest_helper as rest
10
9
 
11
10
  app = typer.Typer()
cli/cloud/projects.py ADDED
@@ -0,0 +1,30 @@
1
+ import json
2
+
3
+ import typer
4
+ from . import rest_helper as rest
5
+ app = typer.Typer()
6
+
7
+
8
+ @app.command(name="list", help="List your projects")
9
+ def list_projects(organisation: str = typer.Option(..., help="Organisation ID", envvar='REMOTIVE_CLOUD_ORGANISATION')):
10
+ r = rest.handle_get(url=f'/api/bu/{organisation}/me', return_response=True)
11
+ if r.status_code == 200:
12
+ projects = r.json()['projects']
13
+ projects = map(lambda p: p['uid'], projects)
14
+ print(json.dumps(list(projects)))
15
+
16
+
17
+ @app.command(name="create")
18
+ def create_project(
19
+ organisation: str = typer.Option(..., help="Organisation ID", envvar='REMOTIVE_CLOUD_ORGANISATION'),
20
+ project_uid: str = typer.Option(..., help="Project UID"),
21
+ project_display_name: str = typer.Option(default="", help="Project display name")
22
+ ):
23
+
24
+ create_project_req = {
25
+ 'uid': project_uid,
26
+ 'displayName': project_display_name if project_display_name != "" else project_uid,
27
+ 'description': ''
28
+ }
29
+
30
+ rest.handle_post(url=f'/api/bu/{organisation}/project', body=json.dumps(create_project_req))
cli/cloud/rest_helper.py CHANGED
@@ -6,7 +6,7 @@ import json
6
6
  import logging
7
7
  from pathlib import Path
8
8
  from os.path import exists
9
-
9
+ #from rich import print
10
10
  import typer
11
11
 
12
12
  if 'REMOTIVE_CLOUD_HTTP_LOGGING' in os.environ:
@@ -51,9 +51,13 @@ def ensure_auth_token():
51
51
  headers = {"Authorization": "Bearer " + token.strip()}
52
52
 
53
53
 
54
- def handle_get(url, params={}):
54
+ def handle_get(url, params={},return_response: bool = False):
55
55
  ensure_auth_token()
56
56
  r = requests.get(f'{base_url}{url}', headers=headers, params=params)
57
+
58
+ if return_response:
59
+ return r
60
+
57
61
  if r.status_code == 200:
58
62
  print(json.dumps(r.json()))
59
63
  else:
@@ -97,3 +101,4 @@ def handle_post(url, body=None, params={}, return_response: bool = False):
97
101
  print(r.status_code)
98
102
  else:
99
103
  print(f'Got status code: {r.status_code}')
104
+ print(r.text)
@@ -35,6 +35,14 @@ def list_keys(
35
35
  rest.handle_get(f"/api/project/{project}/admin/accounts/{service_account}/keys")
36
36
 
37
37
 
38
+ @app.command(name="revoke", help="Revoke service account key")
39
+ def revoke(
40
+ service_account: str = typer.Option(..., help="Service account name"),
41
+ key_name: str = typer.Option(..., help="Key name"),
42
+ project: str = typer.Option(..., help="Project ID", envvar='REMOTIVE_CLOUD_PROJECT')):
43
+ rest.handle_delete(f"/api/project/{project}/admin/accounts/{service_account}/keys/{key_name}")
44
+
45
+
38
46
  def write_token(file, token):
39
47
  path = str(Path.home()) + f"/.config/.remotive/{file}"
40
48
  f = open(path, "w")
@@ -1,10 +1,8 @@
1
+ import json
2
+ from typing import List
3
+
1
4
  import typer
2
- # from typing_extensions import Annotated
3
- from typing import List, Optional
4
5
 
5
- import json
6
- from rich.progress import Progress, SpinnerColumn, TextColumn
7
- import sys
8
6
  from . import rest_helper as rest
9
7
  from . import service_account_keys
10
8
 
@@ -12,12 +10,12 @@ app = typer.Typer()
12
10
 
13
11
 
14
12
  @app.command(name="list", help="List service-accounts")
15
- def list(project: str = typer.Option(..., help="Project ID", envvar='REMOTIVE_CLOUD_PROJECT')):
13
+ def list_service_accounts(project: str = typer.Option(..., help="Project ID", envvar='REMOTIVE_CLOUD_PROJECT')):
16
14
  rest.handle_get(f"/api/project/{project}/admin/accounts")
17
15
 
18
16
 
19
17
  @app.command(name="create", help="Create service account")
20
- def create(
18
+ def create_service_account(
21
19
  name: str,
22
20
  role: List[str] = typer.Option(..., help="Roles to apply"),
23
21
  project: str = typer.Option(..., help="Project ID", envvar='REMOTIVE_CLOUD_PROJECT')):
@@ -29,7 +27,7 @@ def create(
29
27
 
30
28
 
31
29
  @app.command(name="delete", help="Create service account")
32
- def delete(
30
+ def delete_service_account(
33
31
  name: str,
34
32
  project: str = typer.Option(..., help="Project ID", envvar='REMOTIVE_CLOUD_PROJECT')):
35
33
  rest.handle_delete(url=f"/api/project/{project}/admin/accounts/{name}")
cli/remotive.py CHANGED
@@ -1,13 +1,9 @@
1
1
  import typer
2
2
  from .brokers import app as broker_app
3
3
  from .cloud.cloud_cli import app as cloud_app
4
-
5
- # from cloud import cloud_cli
4
+ from rich import print
6
5
 
7
6
  app = typer.Typer()
8
7
 
9
-
10
- # def run_cli():
11
-
12
8
  app.add_typer(broker_app, name="broker", help="Manage a single broker - local or cloud")
13
9
  app.add_typer(cloud_app, name="cloud", help="Manage resources in RemotiveCloud", )
@@ -0,0 +1,17 @@
1
+ Apache-2.0
2
+
3
+ RemotiveLabs CLI
4
+ Copyright 2022 RemotiveLabs <hello@remotivelabs.com>
5
+
6
+ Licensed under the Apache License, Version 2.0 (the "License");
7
+ you may not use this file except in compliance with the License.
8
+ You may obtain a copy of the License at
9
+
10
+ http://www.apache.org/licenses/LICENSE-2.0
11
+
12
+ Unless required by applicable law or agreed to in writing, software
13
+ distributed under the License is distributed on an "AS IS" BASIS,
14
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ See the License for the specific language governing permissions and
16
+ limitations under the License.
17
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: remotivelabs-cli
3
- Version: 0.0.1a2
3
+ Version: 0.0.1a4
4
4
  Summary:
5
5
  Author: Johan Rask
6
6
  Author-email: johan.rask@remotivelabs.com
@@ -0,0 +1,24 @@
1
+ cli/__about__.py,sha256=tcTE7G1_tGq5vqrGkFTYv986sz3ebNRnnkAmNlkF0rE,122
2
+ cli/__init__.py,sha256=Mjnyow0Ngm-b-SdPz4HAkREzch7wKZ2Wy_hxLez49Lc,26
3
+ cli/brokers.py,sha256=2rs9W7p6BG6rXlEuMvd4EmJHwUWaWa2lUuhBDsoFtc4,2910
4
+ cli/cloud/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
5
+ cli/cloud/auth.py,sha256=jcaQX-GMD4gpthTjSTe_rtfBZHnKjnbe9ez-NHbxqmU,3875
6
+ cli/cloud/auth_keys.py,sha256=B2C0tKkA2ggFjL1y1goY3YCljXUJaGUX9GWWFsIamrg,1392
7
+ cli/cloud/brokers.py,sha256=0aD2K_NWhaWUDiswkDeZbjSctn2dKWuytstmv-YIsls,2306
8
+ cli/cloud/cloud_cli.py,sha256=KSTXOTOLucuFjW4ZapYld1D4E2DQ9XoQaAxzZQuLLfI,1611
9
+ cli/cloud/configs.py,sha256=Y5XVYwfPLJzRvc46DjDyYGON8tINV5xcowcHBk8dKO0,3132
10
+ cli/cloud/projects.py,sha256=J-hQTNRbM7oY3rhkZVrmuezOQF___oke3EajjqxAgQM,1083
11
+ cli/cloud/recordings.py,sha256=m0aMNGAblPGiw8zIjpoPsX4RmRVdyhHtyWIkjRjrsRc,6887
12
+ cli/cloud/rest_helper.py,sha256=-qER-i9y5yeLHypBhoCWTBJZoL1LASjARjJK2uHKH1M,2979
13
+ cli/cloud/service_account_keys.py,sha256=hA_hSqP9fjx6OblmxjJPFdsumXQg-7n2rWJ7m8PsJVo,1990
14
+ cli/cloud/service_accounts.py,sha256=LNae9imZYsOY2zTHwyiG9syIZ7EYs7hgLxZyUthu8eI,1176
15
+ cli/lib/__about__.py,sha256=GLOW8iEx5xn9rbJvxUH3elZiLi47SAWamMjdJTd52k0,141
16
+ cli/lib/broker.py,sha256=zYCgABQZSBfR5Ps3jDCuL6jwlJNU4Q8D1UoiMX5vjHc,4905
17
+ cli/remotive.py,sha256=9OkfLJT7ebAShkZ0aCitXsYywCJYxrkwmbpUTzum_8o,315
18
+ cli/requirements.txt,sha256=k2SdtUayWWypl_24paMPHrMu7oH0E3_S_9w9zdAng-Y,77
19
+ cli/test/test_simple.py,sha256=c60_dg5EmhNVmBC6rDcDP-tvKJCBqjIA2Z5Ym9ums4M,63
20
+ remotivelabs_cli-0.0.1a4.dist-info/LICENSE,sha256=qDPP_yfuv1fF-u7EfexN-cN3M8aFgGVndGhGLovLKz0,608
21
+ remotivelabs_cli-0.0.1a4.dist-info/METADATA,sha256=IQyQM8cGfNMsy0D2HoLZRQ9rbI_80z9T_HrC7u_tuDo,2744
22
+ remotivelabs_cli-0.0.1a4.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
23
+ remotivelabs_cli-0.0.1a4.dist-info/entry_points.txt,sha256=lvDhPgagLqW_KTnLPCwKSqfYlEp-1uYVosRiPjsVj10,45
24
+ remotivelabs_cli-0.0.1a4.dist-info/RECORD,,
@@ -1,21 +0,0 @@
1
- cli/__about__.py,sha256=tcTE7G1_tGq5vqrGkFTYv986sz3ebNRnnkAmNlkF0rE,122
2
- cli/__init__.py,sha256=Mjnyow0Ngm-b-SdPz4HAkREzch7wKZ2Wy_hxLez49Lc,26
3
- cli/brokers.py,sha256=epYd78ol7kUSVsneQg7HShv9c1ml8blPEN7SmusZbbs,3392
4
- cli/cloud/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
5
- cli/cloud/auth.py,sha256=fng1uXlCjuabzISHl502VfWB0gwAoyRpD5MWWvGTVWQ,3675
6
- cli/cloud/brokers.py,sha256=UudXB5XU1c3NFCl_zm8ma3SHzaTWGab-QhqsWp3u_mE,2284
7
- cli/cloud/cloud_cli.py,sha256=0acQIOLg-M60x4971XVx46Wi0drUL5UuMbAl1KyW-qY,1691
8
- cli/cloud/configs.py,sha256=ujl6Fa5dz_MkO_3NEcv8MpAP7aKXsrkM5mN8hBp1_Hs,3153
9
- cli/cloud/recordings.py,sha256=m0aMNGAblPGiw8zIjpoPsX4RmRVdyhHtyWIkjRjrsRc,6887
10
- cli/cloud/rest_helper.py,sha256=MBxPo8_oOePtt-4Wm_6UXBwgRs2XX7VUiDI5waI5qrE,2861
11
- cli/cloud/service_account_keys.py,sha256=sYCA-XjeqPOIcRcY1cLG90FHSwykV3pRHY3K2sSr9bE,1580
12
- cli/cloud/service_accounts.py,sha256=T24Qn-OrlAwF9JkA2RyQh9am_jGEO01zUQIxCTYyHk8,1251
13
- cli/lib/__about__.py,sha256=GLOW8iEx5xn9rbJvxUH3elZiLi47SAWamMjdJTd52k0,141
14
- cli/lib/broker.py,sha256=zYCgABQZSBfR5Ps3jDCuL6jwlJNU4Q8D1UoiMX5vjHc,4905
15
- cli/remotive.py,sha256=Xe_4ktWvCKwez3iUUYW_kVY7tPZw4Zln2d19ht3A-Kg,342
16
- cli/requirements.txt,sha256=k2SdtUayWWypl_24paMPHrMu7oH0E3_S_9w9zdAng-Y,77
17
- cli/test/test_simple.py,sha256=c60_dg5EmhNVmBC6rDcDP-tvKJCBqjIA2Z5Ym9ums4M,63
18
- remotivelabs_cli-0.0.1a2.dist-info/METADATA,sha256=5OK1nb4dO6EwayG515DxdLaWhv5FwkPqLoiDVmGZivA,2744
19
- remotivelabs_cli-0.0.1a2.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
20
- remotivelabs_cli-0.0.1a2.dist-info/entry_points.txt,sha256=lvDhPgagLqW_KTnLPCwKSqfYlEp-1uYVosRiPjsVj10,45
21
- remotivelabs_cli-0.0.1a2.dist-info/RECORD,,