posit-dev / rsconnect-python

Command line interface for publishing to Posit Connect
https://docs.posit.co/rsconnect-python/
GNU General Public License v2.0
28 stars 22 forks source link

KeyError: 'id' when deploying jupyter notebook #523

Open dbkegley opened 10 months ago

dbkegley commented 10 months ago

We have a report of a keyerror when deploying a jupyter notebook.

After doing some code reading, it's unclear to me how this could occur if we get a successful response from self.app_create

https://github.com/rstudio/rsconnect-python/blob/b583723fbc0157f2ed83d8501aeaadb9baa51f06/rsconnect/api.py#L253-L257

We'll follow up with additional diagnostic information but I thought we should file an issue here in case others have run into this problem.

rsconnect deploy notebook -v ./snowflake_pythonconnector_demo.ipynb

Connect detected CLI commands and/or environment variables that overlap with stored credential.

Check your environment variables (e.g. CONNECT_API_KEY) to make sure you want them to be used.
Credential paremeters are taken with the following precedence: stored > CLI > environment.
To ignore an environment variable, override it in the CLI with an empty string (e.g. -k '').
Validating server... [OK]
Validating app mode... [OK]
Making bundle ...[VERBOSE] 2023-11-02T09:43:20-0500 Adding file: manifest.json
[VERBOSE] 2023-11-02T09:43:20-0500 Adding file: requirements.txt
[VERBOSE] 2023-11-02T09:43:20-0500 Adding file: ./snowflake_pythonconnector_demo.ipynb
  [OK]
Deploying bundle ... [ERROR]: 'id'

Traceback (most recent call last):
  File "/Users/user/.pyenv/versions/3.9.15/lib/python3.9/site-packages/rsconnect/main.py", line 96, in wrapper
    result = func(*args, **kwargs)
  File "/Users/user/.pyenv/versions/3.9.15/lib/python3.9/site-packages/rsconnect/main.py", line 901, in deploy_notebook
    ce.deploy_bundle().save_deployed_info().emit_task_log()
  File "/Users/user/.pyenv/versions/3.9.15/lib/python3.9/site-packages/rsconnect/log.py", line 189, in wrapper
    result = method(self, *args, **kw)
  File "/Users/user/.pyenv/versions/3.9.15/lib/python3.9/site-packages/rsconnect/api.py", line 712, in deploy_bundle
    result = self.client.deploy(
  File "/Users/user/.pyenv/versions/3.9.15/lib/python3.9/site-packages/rsconnect/api.py", line 257, in deploy
    app_id = app["id"]
KeyError: 'id'
Internal error: 'id' 

Is it possible there's 2 api keys in play as a result of the environment var being different than the api key from the cache?

kgartland-rstudio commented 10 months ago

Is it possible there's 2 api keys in play as a result of the environment var being different than the api key from the cache?

I attempted to reproduce this by assigning CONNECT_SERVER and CONNECT_API_KEY to values but we still use the stored credentials as expected. I suspect we're calling out to Connect to get an App ID but Connect isn't able to return one for whatever reason. I haven't been able to reproduce though. I tried a Connect server...

All scenarios throw the expected errors.

I think we'll need to get some Connect logs and try to find out if a Connect app_id was ever created on their server.

nkvaltine commented 10 months ago

Hey y'all, thanks for looking in on my problem. Maybe this will be useful...I went into rsconnect-python's 'api.py' code on my local machine and added a couple print statements:


    def deploy(self, app_id, app_name, app_title, title_is_default, tarball, env_vars=None):
        if app_id is None:
            # create an app if id is not provided
            app = self.app_create(app_name)
            self._server.handle_bad_response(app)
            print(f"type of app: {type(app)}")
            print(f"app keys: {app.keys()}")
            app_id = app["id"]

The output is like so:

type of app: <class 'dict'>
app keys: dict_keys(['applications', 'count', 'total', 'continuation'])

You can see there is no "id" key. 'applications' looks like an up-to-date list of the things we've published to our connect server, so it appears to be connecting properly to the server at least.

kgartland-rstudio commented 10 months ago

Good idea, I tried the same and I get back:

type of app: <class 'dict'>
app keys: dict_keys(['id', 'guid', 'access_type', 'connection_timeout', 'read_timeout', 'init_timeout', 'idle_timeout', 'max_processes', 'min_processes', 'max_conns_per_process', 'load_factor', 'memory_request', 'memory_limit', 'cpu_request', 'cpu_limit', 'amd_gpu_limit', 'nvidia_gpu_limit', 'url', 'vanity_url', 'name', 'title', 'bundle_id', 'app_mode', 'content_category', 'has_parameters', 'created_time', 'last_deployed_time', 'build_status', 'cluster_name', 'image_name', 'default_image_name', 'service_account_name', 'r_version', 'py_version', 'quarto_version', 'r_environment_management', 'default_r_environment_management', 'py_environment_management', 'default_py_environment_management', 'run_as', 'run_as_current_user', 'description', 'EnvironmentJson'])

I've been following your ticket with support. Can you try rsconnect remove -n positServer and then specify both -s and -k in your deploy command?

I noticed when you sent the output of servers.json, the url line was missing quotes around the URL string and I just want to avoid that causing any issues.

nkvaltine commented 10 months ago

Ahh, would you look at that, it worked!

nkvaltine commented 10 months ago

Though looking back, I think the lack of quotes in the URL was an Outlook thing - it "helpfully" replaced the URL with a link. In the actual servers.json file the quotes are there.

kgartland-rstudio commented 10 months ago

Great! Any idea how you added that server to get the servers.json file? I've been trying to reproduce, and I can't seem to hit the same error. I get an error when I break the string but not the same thing you were hitting. There's a bug in there somewhere...

kgartland-rstudio commented 10 months ago

Sorry, I missed your previous response. If you re-add the server does it continue to work? rsconnect add -s CONNECT_URL -k API_KEY -n positServer

nkvaltine commented 10 months ago

Ahh, to you first question - I assume I used

rsconnect add --server http://posit-connect.wwce.ea.com// --name positServer --api-key notmyrealkey

since that is in my zsh history.

I remade the server with rsconnect add and deleted the --new, -s, and -k options from the rsconnect deploy command and it gives the same error again, about ['id']

kgartland-rstudio commented 10 months ago

Can you remove the slashes at the end of the url? I tried a double slash with my test server but it continued to work.

rsconnect add --server http://posit-connect.wwce.ea.com --name positServer --api-key notmyrealkey

If removing the slashes doesn't help, for the time-being remove the server and continue to use the -s and -k flags with your deploy commands. In the meantime, I'll keep looking into this.

kgartland-rstudio commented 10 months ago

We also added a -vv option in rsconnect-python 1.21. That will include all the API calls to Connect which is how we should be getting the app_id. There's a lot of output so you'll want to save the output to a file.

rsconnect deploy notebook ./notebook.ipynb -s {CONNECT_SERVER} -k {API_KEY} -vv 2>&1  | tee deploy-output.log

Give that a shot and send us the output either here, or in the support ticket you have opened.

nkvaltine commented 10 months ago

Followed up through support email - in summary: I'm now unblocked, but the '//' at the end of the url is causing the issue for as-yet-unknown reasons.