Pushing to my repo from a deployed app

I’m building an app to keep track of my expenses. I want to save the changes every time I add one. I’ve been saving them to disk locally, but then when the app went to sleep because of inactivity, I lost everything I added. So now I want to push to the data folder in my repo directly.
But the problem is that the key that Streamlit uses in the repo has only read access (which makes sense btw, but doesn’t help me)
So I created a new key, and added it to the secrets configuration.
Then in the code I do this:

from git import Repo
st.session_state.repo = Repo('.')

  def add_file_to_repo(file_path, update=False):
      if get_status_file(file_path) in ['untracked', 'modified']:
          st.session_state.repo.index.add([file_path])
          st.session_state.repo.index.commit(commit_msg)
          origin = st.session_state.repo.remote('origin')
          try:
              origin.push()
          except Exception as e:
              fn_key = '/tmp/id_rsa'
              with open(fn_key, 'w') as fid:
                  fid.write(st.secrets['GITHUB_KEY'])
              ssh_cmd = f'ssh -i {fn_key}'
              try:
                  with st.session_state.repo.git.custom_environment(GIT_SSH_COMMAND=ssh_cmd):
                      origin = st.session_state.repo.remote('origin')
                      origin.push()
              except Exception as ee: 
                  st.error(e)
                  st.error(ee)
                  my_env = os.environ.copy()
                  my_env['GIT_SSH_COMMAND'] = f"ssh -i {fn_key}"
                  output = subprocess.check_output(['cat', fn_key])
                  st.write(output)
                  output = subprocess.check_output(['git', 'push'], env=my_env)
                  st.write(output)

So I try to push directly, then if that fails, I try to push using the GIT_SSH_COMMAND env variable in the git custom environment, and if that fails I try to run it as a process with the same GIT_SSH_COMMAND env variable.
To test it locally I moved the ssh key from ~/.ssh/ folder so it doesn’t work in the first call, forcing the usage of streamlit secrets (you need to save it in a file ./.streamlit/secrets.toml), but when I try to run it from the online web app, it fails:

git.exc.GitCommandError: Cmd('git') failed due to: exit code(128)

  cmdline: git push --porcelain -- origin

  stderr: 'fatal: Could not read from remote repository.'


During handling of the above exception, another exception occurred:


Traceback (most recent call last):

  File "/home/appuser/venv/lib/python3.9/site-packages/streamlit/runtime/scriptrunner/script_runner.py", line 565, in _run_script

    exec(code, module.__dict__)

  File "/app/credit_card_analyzer/app.py", line 61, in <module>

    show_edit_variable_expenses(fn, stored_data)

  File "/app/credit_card_analyzer/variable_expenses.py", line 31, in show_edit_variable_expenses

    save_available_budget(fn, available_budget)

  File "/app/credit_card_analyzer/variable_expenses.py", line 25, in save_available_budget

    add_file_to_repo(fn)

  File "/app/credit_card_analyzer/utils.py", line 55, in add_file_to_repo

    output = subprocess.check_output(['git', 'push'], env=my_env)

  File "/usr/local/lib/python3.9/subprocess.py", line 424, in check_output

    return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,

  File "/usr/local/lib/python3.9/subprocess.py", line 528, in run

    raise CalledProcessError(retcode, process.args,

subprocess.CalledProcessError: Command '['git', 'push']' returned non-zero exit status 128.

Why can’t I do a git push with my private key? Is it because git is configured differently in the servers?
Thanks

Besides the issue itself, i would not go further down this approach.
Connect your app to an external data source:
https://docs.streamlit.io/knowledge-base/tutorials/databases

2 Likes

Yeah, I figured I would get this answer :sweat_smile:
Ok, I’ll see what I can do with Deta databases
Thanks!

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.