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