0

I developed a script which predicts some values and saves them into the predictions.csv file using github actions.

I then need to update the predictions.csv file on github, because i need to query it externaly.

But for some reason i get the bad credentials expection. Here is the part of the code which causes the exception.

# github credentials
owner = 'kmeans27'
repo = 'ball-classification'
branch = 'main'
path = 'output'
token = ""


# Push changes to GitHub
g = Github(token)
repo = g.get_repo(f"{owner}/{repo}")
branch = repo.get_branch(branch)
file_name = "predictions.csv"
file_path = f"{path}/{file_name}"
contents = repo.get_contents(file_path, ref=branch.name)
with open(csv_path, "r") as file:
    content = file.read()
if contents:
    repo.update_file(contents.path, f'Update {file_name}', content, contents.sha, branch=branch.name)
else:
    repo.create_file(file_path, f'Add {file_name}', content, branch=branch.name)

here is the link for the github repo: https://github.com/kmeans27/ball-classification owner and repo name should be correct or am i missing something? The rights I set for the github token are: repo (all of them) and read:user

This is the error message im getting:

Traceback (most recent call last):
  File "/home/runner/work/ball-classification/ball-classification/batch_predict.py", line 59, in <module>
    repo = g.get_repo(f"{owner}/{repo}")
  File "/opt/hostedtoolcache/Python/3.9.16/x64/lib/python3.9/site-packages/github/MainClass.py", line 321, in get_repo
    headers, data = self.__requester.requestJsonAndCheck("GET", url)
  File "/opt/hostedtoolcache/Python/3.9.16/x64/lib/python3.9/site-packages/github/Requester.py", line 400, in requestJsonAndCheck
    return self.__check(
  File "/opt/hostedtoolcache/Python/3.9.16/x64/lib/python3.9/site-packages/github/Requester.py", line 425, in __check
    raise self.__createException(status, responseHeaders, output)
github.GithubException.BadCredentialsException: 401 {"message": "Bad credentials", "documentation_url": "https://docs.github.com/rest"}
Error: Process completed with exit code 1.

Thank you for your valuable time!

  • 1
    You need to inform the token in the [workflow](https://github.com/kmeans27/ball-classification/blob/main/.github/workflows/actions.yml) calling the script, and extract this value as env variable in your python script to use it in the implementation. Something like what was used [here](https://github.com/GuillaumeFalourd/poc-github-actions/blob/main/.github/workflows/workflow-tester44.yml) with a secret informing a PAT for example. – GuiFalourd Mar 02 '23 at 14:07
  • thank you for your reply @GuiFalourd i don't exactly get what you mean with that comment. Like how should i extract this value as env variable and use it in the implementation. Check this, here the script was working fine - no problem with the credentials: https://github.com/kmeans27/ball-classification/actions/runs/4314206702 you can check here: https://github.com/kmeans27/ball-classification/commits/main the version with the comment was working, after that i have not modified the code in any way. The only thing i did change was, i set the repo to private and then changed it back to public – Mark Müller Mar 02 '23 at 14:37
  • For what I observed, there are 2 points that we should discuss here. First: What is the PAT permission scope you are using? That may be the reason of the error. Second: You should never hardcode a PAT value in a script, even more on a public repo. This value should be saved as secret in the repository and used only through the workflow run when calling the script, otherwise you'll have a huge security vulnerability (I could use your PAT right now to perform operations as if I was your user, so revoke the ones you used in your script asap). – GuiFalourd Mar 02 '23 at 14:48
  • thank you for your reply @GuiFalourd I deleted the other token, but i don't know how to use the token without hardcoding it, as i didn't set up any env. I now have solved the issue (locally). I just need to add the token to the script without hardcoding it (github) – Mark Müller Mar 02 '23 at 15:05
  • I'll suggest an answer where we could continue the discussion. – GuiFalourd Mar 02 '23 at 16:20

1 Answers1

0

You need to inform the token in the workflow you used to call the python script.

Your workflow would look like this:

name: Batch predictions

on:
  schedule:
    - cron: '0 0 * * *' # Run every day at midnight UTC (https://crontab.guru/#0_0_*_*_*)

  workflow_dispatch: # allows manual triggering of the workflow

jobs:
  predict:
    runs-on: ubuntu-latest
    steps:
    - name: check out repository content
      uses: actions/checkout@v2
      with: 
        lfs: true

    - name: Set up Python
      uses: actions/setup-python@v2
      with:
        python-version: '3.9'

    - name: Install dependencies
      run: |
        python3 -m pip install --upgrade pip
        pip install -r requirements.txt

    - name: Execute py script
      run: python3 batch_predict.py
      env:
         PAT: ${{ secrets.PAT }}

Then, you should extract this value as env variable in your python script to use it in the implementation.

Your python script would look like this:

import os

# github credentials
owner = 'kmeans27'
repo = 'ball-classification'
branch = 'main'
path = 'output'
token = os.getenv("PAT")


# Push changes to GitHub
g = Github(token)
repo = g.get_repo(f"{owner}/{repo}")
branch = repo.get_branch(branch)
file_name = "predictions.csv"
file_path = f"{path}/{file_name}"
contents = repo.get_contents(file_path, ref=branch.name)
with open(csv_path, "r") as file:
    content = file.read()
if contents:
    repo.update_file(contents.path, f'Update {file_name}', content, contents.sha, branch=branch.name)
else:
    repo.create_file(file_path, f'Add {file_name}', content, branch=branch.name)

That way, your secret token won't be exposed in your commit history / files.

Note: Reference to create a Personal Access Token (PAT)

GuiFalourd
  • 15,523
  • 8
  • 44
  • 71