From 8d179c5ecf4fa746c59c1cd1babc84f3a53c5bdc Mon Sep 17 00:00:00 2001 From: Matthew Lynch Date: Thu, 1 Dec 2022 10:27:13 -0600 Subject: [PATCH] Posit Cloud rebrand --- rsconnect/actions.py | 4 ++-- rsconnect/api.py | 48 ++++++++++++++++++++--------------------- rsconnect/main.py | 12 +++++------ rsconnect/validation.py | 6 +++--- tests/test_main.py | 34 ++++++++++++++--------------- 5 files changed, 52 insertions(+), 52 deletions(-) diff --git a/rsconnect/actions.py b/rsconnect/actions.py index 5d31e6cb..46c994ba 100644 --- a/rsconnect/actions.py +++ b/rsconnect/actions.py @@ -225,8 +225,8 @@ def test_server(connect_server): raise RSConnectException("\n".join(failures)) -def test_rstudio_server(server: api.RStudioServer): - with api.RStudioClient(server) as client: +def test_rstudio_server(server: api.PositServer): + with api.PositClient(server) as client: try: result = client.get_current_user() server.handle_bad_response(result) diff --git a/rsconnect/api.py b/rsconnect/api.py index 22c2f2b4..c3e45699 100644 --- a/rsconnect/api.py +++ b/rsconnect/api.py @@ -64,9 +64,9 @@ def handle_bad_response(self, response): ) -class RStudioServer(AbstractRemoteServer): +class PositServer(AbstractRemoteServer): """ - A class used to represent the server of the shinyapps.io and RStudio Cloud APIs. + A class used to represent the server of the shinyapps.io and Posit Cloud APIs. """ def __init__(self, remote_name: str, url: str, account_name: str, token: str, secret: str): @@ -76,7 +76,7 @@ def __init__(self, remote_name: str, url: str, account_name: str, token: str, se self.secret = secret -class ShinyappsServer(RStudioServer): +class ShinyappsServer(PositServer): """ A class to encapsulate the information needed to interact with an instance of the shinyapps.io server. @@ -89,16 +89,16 @@ def __init__(self, url: str, account_name: str, token: str, secret: str): super().__init__(remote_name=remote_name, url=url, account_name=account_name, token=token, secret=secret) -class CloudServer(RStudioServer): +class CloudServer(PositServer): """ A class to encapsulate the information needed to interact with an - instance of the RStudio Cloud server. + instance of the Posit Cloud server. """ def __init__(self, url: str, account_name: str, token: str, secret: str): - remote_name = "RStudio Cloud" - if url == "rstudio.cloud" or url is None: - url = "https://api.rstudio.cloud" + remote_name = "Posit Cloud" + if url in {"posit.cloud", "rstudio.cloud", None}: + url = "https://api.posit.cloud" super().__init__(remote_name=remote_name, url=url, account_name=account_name, token=token, secret=secret) @@ -475,7 +475,7 @@ def setup_remote_server( if api_key: self.remote_server = RSConnectServer(url, api_key, insecure, ca_data) elif token and secret: - if url and "rstudio.cloud" in url: + if url and ("rstudio.cloud" in url or "posit.cloud" in url): self.remote_server = CloudServer(url, account_name, token, secret) else: self.remote_server = ShinyappsServer(url, account_name, token, secret) @@ -485,8 +485,8 @@ def setup_remote_server( def setup_client(self, cookies=None, timeout=30, **kwargs): if isinstance(self.remote_server, RSConnectServer): self.client = RSConnectClient(self.remote_server, cookies, timeout) - elif isinstance(self.remote_server, RStudioServer): - self.client = RStudioClient(self.remote_server, timeout) + elif isinstance(self.remote_server, PositServer): + self.client = PositClient(self.remote_server, timeout) else: raise RSConnectException("Unable to infer Connect client.") @@ -515,7 +515,7 @@ def validate_server( ): if (url and api_key) or isinstance(self.remote_server, RSConnectServer): self.validate_connect_server(name, url, api_key, insecure, cacert, api_key_is_required) - elif (url and token and secret) or isinstance(self.remote_server, RStudioServer): + elif (url and token and secret) or isinstance(self.remote_server, PositServer): self.validate_rstudio_server(url, account_name, token, secret) else: raise RSConnectException("Unable to validate server from information provided.") @@ -596,11 +596,11 @@ def validate_rstudio_server( secret = secret or self.remote_server.secret server = ( CloudServer(url, account_name, token, secret) - if "rstudio.cloud" in url + if "rstudio.cloud" in url or "posit.cloud" in url else ShinyappsServer(url, account_name, token, secret) ) - with RStudioClient(server) as client: + with PositClient(server) as client: try: result = client.get_current_user() server.handle_bad_response(result) @@ -657,7 +657,7 @@ def check_server_capabilities(self, capability_functions): :param details_source: the source for obtaining server details, gather_server_details(), by default. """ - if isinstance(self.remote_server, RStudioServer): + if isinstance(self.remote_server, PositServer): return self details = self.server_details @@ -847,7 +847,7 @@ def validate_app_mode(self, *args, **kwargs): if isinstance(self.remote_server, RSConnectServer): app = get_app_info(self.remote_server, app_id) existing_app_mode = AppModes.get_by_ordinal(app.get("app_mode", 0), True) - elif isinstance(self.remote_server, RStudioServer): + elif isinstance(self.remote_server, PositServer): app = get_rstudio_app_info(self.remote_server, app_id) existing_app_mode = AppModes.get_by_cloud_name(app.json_data["mode"]) else: @@ -1008,14 +1008,14 @@ def __init__( self.output_id = output_id -class RStudioClient(HTTPServer): +class PositClient(HTTPServer): """ - An HTTP client to call the RStudio Cloud and shinyapps.io APIs. + An HTTP client to call the Posit Cloud and shinyapps.io APIs. """ _TERMINAL_STATUSES = {"success", "failed", "error"} - def __init__(self, rstudio_server: RStudioServer, timeout: int = 30): + def __init__(self, rstudio_server: PositServer, timeout: int = 30): self._token = rstudio_server.token try: self._key = base64.b64decode(rstudio_server.secret) @@ -1156,7 +1156,7 @@ class ShinyappsService: Encapsulates operations involving multiple API calls to shinyapps.io. """ - def __init__(self, rstudio_client: RStudioClient, server: ShinyappsServer): + def __init__(self, rstudio_client: PositClient, server: ShinyappsServer): self._rstudio_client = rstudio_client self._server = server @@ -1202,10 +1202,10 @@ def do_deploy(self, bundle_id, app_id): class CloudService: """ - Encapsulates operations involving multiple API calls to RStudio Cloud. + Encapsulates operations involving multiple API calls to Posit Cloud. """ - def __init__(self, rstudio_client: RStudioClient, server: CloudServer): + def __init__(self, rstudio_client: PositClient, server: CloudServer): self._rstudio_client = rstudio_client self._server = server @@ -1332,7 +1332,7 @@ def get_app_info(connect_server, app_id): def get_rstudio_app_info(server, app_id): - with RStudioClient(server) as client: + with PositClient(server) as client: result = client.get_application(app_id) server.handle_bad_response(result) return result @@ -1541,7 +1541,7 @@ def find_unique_name(remote_server: TargetableServer, name: str): mapping_function=lambda client, app: app["name"], ) elif isinstance(remote_server, ShinyappsServer): - client = RStudioClient(remote_server) + client = PositClient(remote_server) existing_names = client.get_applications_like_name(name) else: # non-unique names are permitted in cloud diff --git a/rsconnect/main.py b/rsconnect/main.py index 5221cbfe..35322dc5 100644 --- a/rsconnect/main.py +++ b/rsconnect/main.py @@ -152,13 +152,13 @@ def rstudio_args(func): "--token", "-T", envvar=["SHINYAPPS_TOKEN", "RSCLOUD_TOKEN"], - help="The shinyapps.io/RStudio Cloud token.", + help="The shinyapps.io/Posit Cloud token.", ) @click.option( "--secret", "-S", envvar=["SHINYAPPS_SECRET", "RSCLOUD_SECRET"], - help="The shinyapps.io/RStudio Cloud token secret.", + help="The shinyapps.io/Posit Cloud token secret.", ) @functools.wraps(func) def wrapper(*args, **kwargs): @@ -245,8 +245,8 @@ def cli(future): certificate file to use for TLS. The last two items are only relevant if the URL specifies the "https" protocol. - For RStudio Cloud and shinyapps.io, the information needed to connect includes - the account, auth token, auth secret, and server ('rstudio.cloud' or 'shinyapps.io'). + For Posit Cloud and shinyapps.io, the information needed to connect includes + the account, auth token, auth secret, and server ('posit.cloud' or 'shinyapps.io'). """ global future_enabled future_enabled = future @@ -284,7 +284,7 @@ def _test_server_and_api(server, api_key, insecure, ca_cert): return real_server, me -def _test_rstudio_creds(server: api.RStudioServer): +def _test_rstudio_creds(server: api.PositServer): with cli_feedback("Checking {} credential".format(server.remote_name)): test_rstudio_server(server) @@ -433,7 +433,7 @@ def add(ctx, name, server, api_key, insecure, cacert, account, token, secret, ve old_server = server_store.get_by_name(name) if token: - if server and "rstudio.cloud" in server: + if server and ("rstudio.cloud" in server or "posit.cloud" in server): real_server = api.CloudServer(server, account, token, secret) else: real_server = api.ShinyappsServer(server, account, token, secret) diff --git a/rsconnect/validation.py b/rsconnect/validation.py index 5e470602..33c4df43 100644 --- a/rsconnect/validation.py +++ b/rsconnect/validation.py @@ -35,15 +35,15 @@ def validate_connection_options(url, api_key, insecure, cacert, account_name, to if present_connect_options and present_shinyapps_options: raise RSConnectException( - "Connect options ({}) may not be passed alongside shinyapps.io or RStudio Cloud options ({}).".format( + "Connect options ({}) may not be passed alongside shinyapps.io or Posit Cloud options ({}).".format( ", ".join(present_connect_options), ", ".join(present_shinyapps_options) ) ) - if url and 'rstudio.cloud' in url: + if url and ('posit.cloud' in url or 'rstudio.cloud' in url): if len(present_cloud_options) != len(cloud_options): raise RSConnectException( - "-T/--token and -S/--secret must be provided for RStudio Cloud." + "-T/--token and -S/--secret must be provided for Posit Cloud." ) elif present_shinyapps_options: if len(present_shinyapps_options) != len(shinyapps_options): diff --git a/tests/test_main.py b/tests/test_main.py index d239614b..091a0801 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -270,13 +270,13 @@ def test_deploy_manifest_cloud(self, project_application_id, project_id): httpretty.register_uri( httpretty.GET, - "https://api.rstudio.cloud/v1/users/me", + "https://api.posit.cloud/v1/users/me", body=open("tests/testdata/rstudio-responses/get-user.json", "r").read(), status=200, ) httpretty.register_uri( httpretty.GET, - "https://api.rstudio.cloud/v1/applications" + "https://api.posit.cloud/v1/applications" "?filter=name:like:shinyapp&offset=0&count=100&use_advanced_filters=true", body=open("tests/testdata/rstudio-responses/get-applications.json", "r").read(), adding_headers={"Content-Type": "application/json"}, @@ -284,7 +284,7 @@ def test_deploy_manifest_cloud(self, project_application_id, project_id): ) httpretty.register_uri( httpretty.GET, - "https://api.rstudio.cloud/v1/accounts/", + "https://api.posit.cloud/v1/accounts/", body=open("tests/testdata/rstudio-responses/get-accounts.json", "r").read(), adding_headers={"Content-Type": "application/json"}, status=200, @@ -293,21 +293,21 @@ def test_deploy_manifest_cloud(self, project_application_id, project_id): if project_application_id: httpretty.register_uri( httpretty.GET, - "https://api.rstudio.cloud/v1/applications/444", + "https://api.posit.cloud/v1/applications/444", body=open("tests/testdata/rstudio-responses/get-project-application.json", "r").read(), adding_headers={"Content-Type": "application/json"}, status=200, ) httpretty.register_uri( httpretty.GET, - "https://api.rstudio.cloud/v1/content/555", + "https://api.posit.cloud/v1/content/555", body=open("tests/testdata/rstudio-responses/get-content.json", "r").read(), adding_headers={"Content-Type": "application/json"}, status=200, ) httpretty.register_uri( httpretty.GET, - "https://api.rstudio.cloud/v1/content/1", + "https://api.posit.cloud/v1/content/1", body=open("tests/testdata/rstudio-responses/create-output.json", "r").read(), adding_headers={"Content-Type": "application/json"}, status=200, @@ -328,7 +328,7 @@ def post_output_callback(request, uri, response_headers): httpretty.register_uri( httpretty.GET, - "https://api.rstudio.cloud/v1/applications/8442", + "https://api.posit.cloud/v1/applications/8442", body=open("tests/testdata/rstudio-responses/get-output-application.json", "r").read(), adding_headers={"Content-Type": "application/json"}, status=200, @@ -336,7 +336,7 @@ def post_output_callback(request, uri, response_headers): httpretty.register_uri( httpretty.POST, - "https://api.rstudio.cloud/v1/outputs/", + "https://api.posit.cloud/v1/outputs/", body=post_output_callback, ) @@ -359,7 +359,7 @@ def post_bundle_callback(request, uri, response_headers): httpretty.register_uri( httpretty.POST, - "https://api.rstudio.cloud/v1/bundles", + "https://api.posit.cloud/v1/bundles", body=post_bundle_callback, ) @@ -382,17 +382,17 @@ def post_bundle_status_callback(request, uri, response_headers): assert parsed_request == {"status": "ready"} except AssertionError as e: return _error_to_response(e) - return [303, {"Location": "https://api.rstudio.cloud/v1/bundles/12640"}, ""] + return [303, {"Location": "https://api.posit.cloud/v1/bundles/12640"}, ""] httpretty.register_uri( httpretty.POST, - "https://api.rstudio.cloud/v1/bundles/12640/status", + "https://api.posit.cloud/v1/bundles/12640/status", body=post_bundle_status_callback, ) httpretty.register_uri( httpretty.GET, - "https://api.rstudio.cloud/v1/bundles/12640", + "https://api.posit.cloud/v1/bundles/12640", body=open("tests/testdata/rstudio-responses/get-accounts.json", "r").read(), adding_headers={"Content-Type": "application/json"}, status=200, @@ -406,19 +406,19 @@ def post_deploy_callback(request, uri, response_headers): return _error_to_response(e) return [ 303, - {"Location": "https://api.rstudio.cloud/v1/tasks/333"}, + {"Location": "https://api.posit.cloud/v1/tasks/333"}, open("tests/testdata/rstudio-responses/post-deploy.json", "r").read(), ] httpretty.register_uri( httpretty.POST, - "https://api.rstudio.cloud/v1/applications/8442/deploy", + "https://api.posit.cloud/v1/applications/8442/deploy", body=post_deploy_callback, ) httpretty.register_uri( httpretty.GET, - "https://api.rstudio.cloud/v1/tasks/333", + "https://api.posit.cloud/v1/tasks/333", body=open("tests/testdata/rstudio-responses/get-task.json", "r").read(), adding_headers={"Content-Type": "application/json"}, status=200, @@ -505,7 +505,7 @@ def test_add_cloud(self): original_server_value = os.environ.pop("CONNECT_SERVER", None) try: httpretty.register_uri( - httpretty.GET, "https://api.rstudio.cloud/v1/users/me", body='{"id": 1000}', status=200 + httpretty.GET, "https://api.posit.cloud/v1/users/me", body='{"id": 1000}', status=200 ) runner = CliRunner() @@ -524,7 +524,7 @@ def test_add_cloud(self): ], ) assert result.exit_code == 0, result.output - assert "RStudio Cloud credential" in result.output + assert "Posit Cloud credential" in result.output finally: if original_api_key_value: