diff --git a/roboflow/__init__.py b/roboflow/__init__.py index 858ce141..ca24f3ca 100644 --- a/roboflow/__init__.py +++ b/roboflow/__init__.py @@ -15,7 +15,7 @@ from roboflow.models import CLIPModel, GazeModel # noqa: F401 from roboflow.util.general import write_line -__version__ = "1.1.40" +__version__ = "1.1.41" def check_key(api_key, model, notebook, num_retries=0): diff --git a/roboflow/adapters/deploymentapi.py b/roboflow/adapters/deploymentapi.py index e763c0e1..cfe88885 100644 --- a/roboflow/adapters/deploymentapi.py +++ b/roboflow/adapters/deploymentapi.py @@ -9,55 +9,49 @@ class DeploymentApiError(Exception): def add_deployment(api_key, machine_type, duration, delete_on_expiration, deployment_name, inference_version): url = f"{DEDICATED_DEPLOYMENT_URL}/add" - response = requests.post( - url, - json={ - "api_key": api_key, - # "security_level": security_level, - "machine_type": machine_type, - "duration": duration, - "delete_on_expiration": delete_on_expiration, - "deployment_name": deployment_name, - "inference_version": inference_version, - }, - ) + params = { + "api_key": api_key, + # "security_level": security_level, + "duration": duration, + "delete_on_expiration": delete_on_expiration, + "deployment_name": deployment_name, + "inference_version": inference_version, + } + if machine_type is not None: + params["machine_type"] = machine_type + response = requests.post(url, json=params) if response.status_code != 200: - raise DeploymentApiError(f"{response.status_code}: {response.text}") - result = response.json() - return result + return response.status_code, response.text + return response.status_code, response.json() -def get_deployment(api_key, deployment_id): - url = f"{DEDICATED_DEPLOYMENT_URL}/get" - response = requests.get(url, json={"api_key": api_key, "deployment_id": deployment_id}) +def get_deployment(api_key, deployment_name): + url = f"{DEDICATED_DEPLOYMENT_URL}/get?api_key={api_key}&deployment_name={deployment_name}" + response = requests.get(url) if response.status_code != 200: - raise DeploymentApiError(f"{response.status_code}: {response.text}") - result = response.json() - return result + return response.status_code, response.text + return response.status_code, response.json() def list_deployment(api_key): - url = f"{DEDICATED_DEPLOYMENT_URL}/list" - response = requests.get(url, json={"api_key": api_key}) + url = f"{DEDICATED_DEPLOYMENT_URL}/list?api_key={api_key}" + response = requests.get(url) if response.status_code != 200: - raise DeploymentApiError(f"{response.status_code}: {response.text}") - result = response.json() - return result + return response.status_code, response.text + return response.status_code, response.json() -def delete_deployment(api_key, deployment_id): +def delete_deployment(api_key, deployment_name): url = f"{DEDICATED_DEPLOYMENT_URL}/delete" - response = requests.post(url, json={"api_key": api_key, "deployment_id": deployment_id}) + response = requests.post(url, json={"api_key": api_key, "deployment_name": deployment_name}) if response.status_code != 200: - raise DeploymentApiError(f"{response.status_code}: {response.text}") - result = response.json() - return result + return response.status_code, response.text + return response.status_code, response.json() def list_machine_types(api_key): - url = f"{DEDICATED_DEPLOYMENT_URL}/machine_types" - response = requests.get(url, json={"api_key": api_key}) + url = f"{DEDICATED_DEPLOYMENT_URL}/machine_types?api_key={api_key}" + response = requests.get(url) if response.status_code != 200: - raise DeploymentApiError(f"{response.status_code}: {response.text}") - result = response.json() - return result + return response.status_code, response.text + return response.status_code, response.json() diff --git a/roboflow/deployment.py b/roboflow/deployment.py index fce12bfa..3c415d7e 100644 --- a/roboflow/deployment.py +++ b/roboflow/deployment.py @@ -1,4 +1,6 @@ import json +import time +from datetime import datetime from roboflow.adapters import deploymentapi from roboflow.config import load_roboflow_api_key @@ -19,78 +21,131 @@ def add_deployment_parser(subparsers): deployment_delete_parser = deployment_subparsers.add_parser("delete", help="delete a dedicated deployment") deployment_machine_type_parser.set_defaults(func=list_machine_types) - deployment_machine_type_parser.add_argument("-a", dest="api_key", help="api key") + deployment_machine_type_parser.add_argument("-a", "--api_key", help="api key") deployment_add_parser.set_defaults(func=add_deployment) - deployment_add_parser.add_argument("-a", dest="api_key", help="api key") + deployment_add_parser.add_argument("-a", "--api_key", help="api key") + deployment_add_parser.add_argument( + "deployment_name", + help="deployment name, must contain 5-15 lowercase characters, first character must be a letter", + ) # deployment_add_parser.add_argument( - # "-s", dest="security_level", help="security level (protected)", default="protected" + # "-s", "--security_level", help="security level (protected)", default="protected" # ) deployment_add_parser.add_argument( - "-m", dest="machine_type", help="machine type, run `roboflow deployment machine_type` to see available options" + "-m", "--machine_type", help="machine type, run `roboflow deployment machine_type` to see available options" ) deployment_add_parser.add_argument( "-t", - dest="duration", + "--duration", help="duration, how long you want to keep the deployment (unit: hour, default: 3)", type=float, default=3, ) deployment_add_parser.add_argument( - "-e", dest="delete_on_expiration", help="delete when expired (default: True)", type=bool, default=True + "-e", "--no_delete_on_expiration", help="keep when expired (default: False)", action="store_true" ) deployment_add_parser.add_argument( - "-n", dest="deployment_name", help="deployment name, must contain 3-10 lowercase characters" + "-v", + "--inference_version", + help="inference server version (default: latest)", + default="latest", ) deployment_add_parser.add_argument( - "-v", dest="inference_version", help="inference server version (default: latest)", default="latest" + "-w", "--wait_on_pending", help="wait if deployment is pending", action="store_true" ) deployment_get_parser.set_defaults(func=get_deployment) - deployment_get_parser.add_argument("-a", dest="api_key", help="api key") - deployment_get_parser.add_argument("-d", dest="deployment_id", help="deployment id") + deployment_get_parser.add_argument("-a", "--api_key", help="api key") + deployment_get_parser.add_argument("deployment_name", help="deployment name") + deployment_get_parser.add_argument( + "-w", "--wait_on_pending", help="wait if deployment is pending", action="store_true" + ) deployment_list_parser.set_defaults(func=list_deployment) - deployment_list_parser.add_argument("-a", dest="api_key", help="api key") + deployment_list_parser.add_argument("-a", "--api_key", help="api key") deployment_delete_parser.set_defaults(func=delete_deployment) - deployment_delete_parser.add_argument("-a", dest="api_key", help="api key") - deployment_delete_parser.add_argument("-d", dest="deployment_id", help="deployment id") + deployment_delete_parser.add_argument("-a", "--api_key", help="api key") + deployment_delete_parser.add_argument("deployment_name", help="deployment name") def list_machine_types(args): api_key = args.api_key or load_roboflow_api_key(None) - ret_json = deploymentapi.list_machine_types(api_key) - print(json.dumps(ret_json, indent=2)) + if api_key is None: + print("Please provide an api key") + return + status_code, msg = deploymentapi.list_machine_types(api_key) + if status_code != 200: + print(f"{status_code}: {msg}") + return + print(json.dumps(msg, indent=2)) def add_deployment(args): api_key = args.api_key or load_roboflow_api_key(None) - ret_json = deploymentapi.add_deployment( + if api_key is None: + print("Please provide an api key") + return + status_code, msg = deploymentapi.add_deployment( api_key, # args.security_level, args.machine_type, args.duration, - args.delete_on_expiration, + (not args.no_delete_on_expiration), args.deployment_name, args.inference_version, ) - print(json.dumps(ret_json, indent=2)) + + if status_code != 200: + print(f"{status_code}: {msg}") + return + else: + print(f"Deployment {args.deployment_name} created successfully") + print(json.dumps(msg, indent=2)) + + if args.wait_on_pending: + get_deployment(args) def get_deployment(args): api_key = args.api_key or load_roboflow_api_key(None) - ret_json = deploymentapi.get_deployment(api_key, args.deployment_id) - print(json.dumps(ret_json, indent=2)) + if api_key is None: + print("Please provide an api key") + return + while True: + status_code, msg = deploymentapi.get_deployment(api_key, args.deployment_name) + if status_code != 200: + print(f"{status_code}: {msg}") + return + + if (not args.wait_on_pending) or msg["status"] != "pending": + print(json.dumps(msg, indent=2)) + break + + print(f'{datetime.now().strftime("%H:%M:%S")} Waiting for deployment {args.deployment_name} to be ready...\n') + time.sleep(30) def list_deployment(args): api_key = args.api_key or load_roboflow_api_key(None) - ret_json = deploymentapi.list_deployment(api_key) - print(json.dumps(ret_json, indent=2)) + if api_key is None: + print("Please provide an api key") + return + status_code, msg = deploymentapi.list_deployment(api_key) + if status_code != 200: + print(f"{status_code}: {msg}") + return + print(json.dumps(msg, indent=2)) def delete_deployment(args): api_key = args.api_key or load_roboflow_api_key(None) - ret_json = deploymentapi.delete_deployment(api_key, args.deployment_id) - print(json.dumps(ret_json, indent=2)) + if api_key is None: + print("Please provide an api key") + return + status_code, msg = deploymentapi.delete_deployment(api_key, args.deployment_name) + if status_code != 200: + print(f"{status_code}: {msg}") + return + print(json.dumps(msg, indent=2)) diff --git a/roboflow/roboflowpy.py b/roboflow/roboflowpy.py index 49228095..025b4391 100755 --- a/roboflow/roboflowpy.py +++ b/roboflow/roboflowpy.py @@ -194,10 +194,32 @@ def _argparser(): _add_get_workspace_project_version_parser(subparsers) _add_run_video_inference_api_parser(subparsers) deployment.add_deployment_parser(subparsers) + _add_whoami_parser(subparsers) + + parser.add_argument("-v", "--version", help="show version info", action="store_true") + parser.set_defaults(func=show_version) return parser +def show_version(args): + print(roboflow.__version__) + + +def show_whoami(args): + RF_WORKSPACES = get_conditional_configuration_variable("workspaces", default={}) + workspaces_by_url = {w["url"]: w for w in RF_WORKSPACES.values()} + default_workspace_url = get_conditional_configuration_variable("RF_WORKSPACE", default=None) + default_workspace = workspaces_by_url.get(default_workspace_url, None) + default_workspace["apiKey"] = "**********" + print(json.dumps(default_workspace, indent=2)) + + +def _add_whoami_parser(subparsers): + download_parser = subparsers.add_parser("whoami", help="show current user info") + download_parser.set_defaults(func=show_whoami) + + def _add_download_parser(subparsers): download_parser = subparsers.add_parser( "download",