Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 19 additions & 21 deletions rsconnect/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ def _tweak_response(self, response: HTTPResponse) -> JsonData | HTTPResponse:
)

def me(self) -> UserRecord:
response = cast(Union[UserRecord, HTTPResponse], self.get("me"))
response = cast(Union[UserRecord, HTTPResponse], self.get("v1/user"))
response = self._server.handle_bad_response(response)
return response

Expand All @@ -426,22 +426,22 @@ def app_get(self, app_id: str) -> ContentItemV0:
response = self._server.handle_bad_response(response)
return response

def app_add_environment_vars(self, app_guid: str, env_vars: list[tuple[str, str]]):
def add_environment_vars(self, content_guid: str, env_vars: list[tuple[str, str]]):
env_body = [dict(name=kv[0], value=kv[1]) for kv in env_vars]
return self.patch("v1/content/%s/environment" % app_guid, body=env_body)
return self.patch("v1/content/%s/environment" % content_guid, body=env_body)

def is_app_failed_response(self, response: HTTPResponse | JsonData) -> bool:
def is_failed_response(self, response: HTTPResponse | JsonData) -> bool:
return isinstance(response, HTTPResponse) and response.status >= 500

def app_access(self, app_guid: str) -> None:
def access_content(self, content_guid: str) -> None:
method = "GET"
base = dirname(self._url.path) # remove __api__
path = f"{base}/content/{app_guid}/"
path = f"{base}/content/{content_guid}/"
response = self._do_request(method, path, None, None, 3, {}, False)

if self.is_app_failed_response(response):
if self.is_failed_response(response):
# Get content metadata to construct logs URL
content = self.content_get(app_guid)
content = self.content_get(content_guid)
logs_url = content["dashboard_url"] + "/logs"
raise RSConnectException(
"Could not access the deployed content. "
Expand All @@ -467,20 +467,20 @@ def content_get(self, content_guid: str) -> ContentItemV1:
response = self._server.handle_bad_response(response)
return response

def get_content_by_id(self, app_id: str) -> ContentItemV1:
def get_content_by_id(self, id: str) -> ContentItemV1:
"""
Get content by ID, which can be either a numeric ID (legacy) or GUID.

:param app_id: Either a numeric ID (e.g., "1234") or GUID (e.g., "abc-def-123")
:return: ContentItemV1 data
"""
# Check if it looks like a GUID (contains hyphens)
if "-" in str(app_id):
return self.content_get(app_id)
if "-" in str(id):
return self.content_get(id)
else:
# Legacy numeric ID - get v0 content first to get GUID
# TODO: deprecation warning
app_v0 = self.app_get(app_id)
app_v0 = self.app_get(id)
# TODO: deprecation warning here
return self.content_get(app_v0["guid"])

def content_create(self, name: str) -> ContentItemV1:
Expand Down Expand Up @@ -516,7 +516,9 @@ def content_build(
response = self._server.handle_bad_response(response)
return response

def content_deploy(self, app_guid: str, bundle_id: Optional[str] = None, activate: bool = True) -> BuildOutputDTO:
def content_deploy(
self, content_guid: str, bundle_id: Optional[str] = None, activate: bool = True
) -> BuildOutputDTO:
body: dict[str, str | bool | None] = {"bundle_id": bundle_id}
if not activate:
# The default behavior is to activate the app after deploying.
Expand All @@ -525,7 +527,7 @@ def content_deploy(self, app_guid: str, bundle_id: Optional[str] = None, activat
body["activate"] = False
response = cast(
Union[BuildOutputDTO, HTTPResponse],
self.post("v1/content/%s/deploy" % app_guid, body=body),
self.post("v1/content/%s/deploy" % content_guid, body=body),
)
response = self._server.handle_bad_response(response)
return response
Expand Down Expand Up @@ -590,7 +592,7 @@ def deploy(

app_guid = app["guid"]
if env_vars:
result = self.app_add_environment_vars(app_guid, list(env_vars.items()))
result = self.add_environment_vars(app_guid, list(env_vars.items()))
result = self._server.handle_bad_response(result)

if app["title"] != app_title and not title_is_default:
Expand Down Expand Up @@ -683,10 +685,6 @@ def output_task_log(
log_callback(line)


# for backwards compatibility with rsconnect-jupyter
RSConnect = RSConnectClient


class ServerDetailsPython(TypedDict):
api_enabled: bool
versions: list[str]
Expand Down Expand Up @@ -1175,7 +1173,7 @@ def verify_deployment(self):
raise RSConnectException("To verify deployment, client must be a RSConnectClient.")
deployed_info = self.deployed_info
app_guid = deployed_info["app_guid"]
self.client.app_access(app_guid)
self.client.access_content(app_guid)

@cls_logged("Validating app mode...")
def validate_app_mode(self, app_mode: AppMode):
Expand Down
2 changes: 2 additions & 0 deletions rsconnect/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -601,10 +601,12 @@ class UserRecord(TypedDict):
first_name: str
last_name: str
password: str
user_role: str
created_time: str
updated_time: str
active_time: str | None
confirmed: bool
locked: bool
guid: str
preferences: dict[str, object]
privileges: list[str]
4 changes: 2 additions & 2 deletions tests/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,8 @@ def test_deploy_draft(self, command, target, expected_activate, caplog):
)
httpretty.register_uri(
httpretty.GET,
"http://fake_server/__api__/me",
body=open("tests/testdata/rstudio-responses/get-user.json", "r").read(),
"http://fake_server/__api__/v1/user",
body=open("tests/testdata/connect-responses/me.json", "r").read(),
adding_headers={"Content-Type": "application/json"},
status=200,
)
Expand Down
2 changes: 1 addition & 1 deletion tests/test_main_content.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def register_content_endpoints(i: int, guid: str):
)
httpretty.register_uri(
httpretty.GET,
f"{connect_server}/__api__/me",
f"{connect_server}/__api__/v1/user",
body=open("tests/testdata/connect-responses/me.json", "r").read(),
adding_headers={"Content-Type": "application/json"},
)
Expand Down
Loading