Skip to content

Commit f8e2cac

Browse files
authored
Merge pull request #468 from rstudio/shinyapps-target-app-id-fix
use get application API when calling get_rstudio_app_info
2 parents eea813e + a46722f commit f8e2cac

File tree

4 files changed

+176
-6
lines changed

4 files changed

+176
-6
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99
### Fixed
1010
- Python virtualenvs are now detected in Windows environments, and are automatically
1111
excluded from the uploaded bundle.
12+
- Error deploying to shinyapps.io when `--app-id` is provided [#464](https://github.com/rstudio/rsconnect-python/issues/464).
1213

1314
### Added
1415

rsconnect/api.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ def deploy(self, app_id, app_name, app_title, title_is_default, tarball, env_var
249249
try:
250250
self._server.handle_bad_response(app)
251251
except RSConnectException as e:
252-
raise RSConnectException(f"{e} Try setting the --new flag to overwrite the previous deployment.")
252+
raise RSConnectException(f"{e} Try setting the --new flag to overwrite the previous deployment.") from e
253253

254254
app_guid = app["guid"]
255255
if env_vars:
@@ -847,15 +847,15 @@ def validate_app_mode(self, *args, **kwargs):
847847
except RSConnectException as e:
848848
raise RSConnectException(
849849
f"{e} Try setting the --new flag to overwrite the previous deployment."
850-
)
850+
) from e
851851
elif isinstance(self.remote_server, PositServer):
852852
try:
853853
app = get_rstudio_app_info(self.remote_server, app_id)
854854
existing_app_mode = AppModes.get_by_cloud_name(app["mode"])
855855
except RSConnectException as e:
856856
raise RSConnectException(
857857
f"{e} Try setting the --new flag to overwrite the previous deployment."
858-
)
858+
) from e
859859
else:
860860
raise RSConnectException("Unable to infer Connect client.")
861861
if existing_app_mode and existing_app_mode not in (None, AppModes.UNKNOWN, app_mode):
@@ -1485,8 +1485,11 @@ def get_app_info(connect_server, app_id):
14851485

14861486
def get_rstudio_app_info(server, app_id):
14871487
with PositClient(server) as client:
1488-
response = client.get_content(app_id)
1489-
return response["source"]
1488+
if isinstance(server, ShinyappsServer):
1489+
return client.get_application(app_id)
1490+
else:
1491+
response = client.get_content(app_id)
1492+
return response["source"]
14901493

14911494

14921495
def get_app_config(connect_server, app_id):

tests/test_main.py

Lines changed: 167 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ def post_application_callback(request, uri, response_headers):
140140
return [
141141
201,
142142
{"Content-Type": "application/json"},
143-
open("tests/testdata/rstudio-responses/create-application.json", "r").read(),
143+
open("tests/testdata/rstudio-responses/application.json", "r").read(),
144144
]
145145

146146
httpretty.register_uri(
@@ -278,6 +278,172 @@ def post_deploy_callback(request, uri, response_headers):
278278
if original_server_value:
279279
os.environ["CONNECT_SERVER"] = original_server_value
280280

281+
@httpretty.activate(verbose=True, allow_net_connect=False)
282+
def test_redeploy_manifest_shinyapps(self):
283+
original_api_key_value = os.environ.pop("CONNECT_API_KEY", None)
284+
original_server_value = os.environ.pop("CONNECT_SERVER", None)
285+
286+
httpretty.register_uri(
287+
httpretty.GET,
288+
"https://api.shinyapps.io/v1/users/me",
289+
body=open("tests/testdata/rstudio-responses/get-user.json", "r").read(),
290+
status=200,
291+
)
292+
httpretty.register_uri(
293+
httpretty.GET,
294+
"https://api.shinyapps.io/v1/applications"
295+
"?filter=name:like:shinyapp&offset=0&count=100&use_advanced_filters=true",
296+
body=open("tests/testdata/rstudio-responses/get-applications.json", "r").read(),
297+
adding_headers={"Content-Type": "application/json"},
298+
status=200,
299+
)
300+
httpretty.register_uri(
301+
httpretty.GET,
302+
"https://api.shinyapps.io/v1/accounts/",
303+
body=open("tests/testdata/rstudio-responses/get-accounts.json", "r").read(),
304+
adding_headers={"Content-Type": "application/json"},
305+
status=200,
306+
)
307+
308+
httpretty.register_uri(
309+
httpretty.GET,
310+
"https://api.shinyapps.io/v1/applications/8442",
311+
body=open("tests/testdata/rstudio-responses/application.json", "r").read(),
312+
adding_headers={"Content-Type": "application/json"},
313+
status=200,
314+
)
315+
316+
def post_application_property_callback(request, uri, response_headers):
317+
parsed_request = _load_json(request.body)
318+
try:
319+
assert parsed_request == {"value": "private"}
320+
except AssertionError as e:
321+
return _error_to_response(e)
322+
return [
323+
201,
324+
{},
325+
b"",
326+
]
327+
328+
httpretty.register_uri(
329+
httpretty.PUT,
330+
"https://api.shinyapps.io/v1/applications/8442/properties/application.visibility",
331+
body=post_application_property_callback,
332+
status=200,
333+
)
334+
335+
def post_bundle_callback(request, uri, response_headers):
336+
parsed_request = _load_json(request.body)
337+
del parsed_request["checksum"]
338+
del parsed_request["content_length"]
339+
try:
340+
assert parsed_request == {
341+
"application": 8442,
342+
"content_type": "application/x-tar",
343+
}
344+
except AssertionError as e:
345+
return _error_to_response(e)
346+
return [
347+
201,
348+
{"Content-Type": "application/json"},
349+
open("tests/testdata/rstudio-responses/create-bundle.json", "r").read(),
350+
]
351+
352+
httpretty.register_uri(
353+
httpretty.POST,
354+
"https://api.shinyapps.io/v1/bundles",
355+
body=post_bundle_callback,
356+
)
357+
358+
httpretty.register_uri(
359+
httpretty.PUT,
360+
"https://lucid-uploads-staging.s3.amazonaws.com/bundles/application-8442/"
361+
"6c9ed0d91ee9426687d9ac231d47dc83.tar.gz"
362+
"?AWSAccessKeyId=theAccessKeyId"
363+
"&Signature=dGhlU2lnbmF0dXJlCg%3D%3D"
364+
"&content-md5=D1blMI4qTiI3tgeUOYXwkg%3D%3D"
365+
"&content-type=application%2Fx-tar"
366+
"&x-amz-security-token=dGhlVG9rZW4K"
367+
"&Expires=1656715153",
368+
body="",
369+
)
370+
371+
def post_bundle_status_callback(request, uri, response_headers):
372+
parsed_request = _load_json(request.body)
373+
try:
374+
assert parsed_request == {"status": "ready"}
375+
except AssertionError as e:
376+
return _error_to_response(e)
377+
return [303, {"Location": "https://api.shinyapps.io/v1/bundles/12640"}, ""]
378+
379+
httpretty.register_uri(
380+
httpretty.POST,
381+
"https://api.shinyapps.io/v1/bundles/12640/status",
382+
body=post_bundle_status_callback,
383+
)
384+
385+
httpretty.register_uri(
386+
httpretty.GET,
387+
"https://api.shinyapps.io/v1/bundles/12640",
388+
body=open("tests/testdata/rstudio-responses/get-accounts.json", "r").read(),
389+
adding_headers={"Content-Type": "application/json"},
390+
status=200,
391+
)
392+
393+
def post_deploy_callback(request, uri, response_headers):
394+
parsed_request = _load_json(request.body)
395+
try:
396+
assert parsed_request == {"bundle": 12640, "rebuild": False}
397+
except AssertionError as e:
398+
return _error_to_response(e)
399+
return [
400+
303,
401+
{"Location": "https://api.shinyapps.io/v1/tasks/333"},
402+
open("tests/testdata/rstudio-responses/post-deploy.json", "r").read(),
403+
]
404+
405+
httpretty.register_uri(
406+
httpretty.POST,
407+
"https://api.shinyapps.io/v1/applications/8442/deploy",
408+
body=post_deploy_callback,
409+
)
410+
411+
httpretty.register_uri(
412+
httpretty.GET,
413+
"https://api.shinyapps.io/v1/tasks/333",
414+
body=open("tests/testdata/rstudio-responses/get-task.json", "r").read(),
415+
adding_headers={"Content-Type": "application/json"},
416+
status=200,
417+
)
418+
419+
runner = CliRunner()
420+
args = [
421+
"deploy",
422+
"manifest",
423+
get_manifest_path("shinyapp"),
424+
"--account",
425+
"some-account",
426+
"--token",
427+
"someToken",
428+
"--secret",
429+
"c29tZVNlY3JldAo=",
430+
"--title",
431+
"myApp",
432+
"--visibility",
433+
"private",
434+
"--app-id",
435+
"8442",
436+
]
437+
try:
438+
result = runner.invoke(cli, args)
439+
assert result.exit_code == 0, result.output
440+
finally:
441+
if original_api_key_value:
442+
os.environ["CONNECT_API_KEY"] = original_api_key_value
443+
if original_server_value:
444+
os.environ["CONNECT_SERVER"] = original_server_value
445+
446+
281447
@httpretty.activate(verbose=True, allow_net_connect=False)
282448
@pytest.mark.parametrize(
283449
"project_application_id,project_id",

0 commit comments

Comments
 (0)