python github action

How To Run Python Script Using a GitHub Action

In this post, we’re going to make a simple Python script and we’ll run it using a GitHub action. Additionally, we’ll log the data this script is going to fetch for us, and save it into a file. Therefore, we’ll demonstrate how to commit and push file changes with an action as well.

Before we delve into the project at hand, I want to explain what GitHub actions are and what we can use them for. Basically, they’re events we can trigger to run a series of steps, like for example checking out the contents of repository, setting up the environment, and running scripts on GitHub.

They’re useful for automating continuous integration and continuous deployment (CI/CD) to deliver the latest version of software. In other words, we can automate building, testing and deployment processes.

Setting up the project

We’ll keep it simple as possible in our case here. What we’re going to do is schedule a GitHub action to run a Python script every 2 hours. Furthermore, this script will call a weather API for fetching temperature in a specified city. In our case, we’re going to check for temperature in Ljubljana, the capital of Slovenia.

Creating new repository

First of all, we’re going to make a new repository on GitHub and clone it to our local working directory. We’re also going to need to change the permission setting for our actions to read and write permissions. You can find this setting if you click the settings tab and navigate to the Actions general settings in the sidebar menu.

github actions workflow permissions settings

Once you open these settings, change the Workflow permissions to Read and write permissions. To explain, this is necessary because we’re also going to include the commit and push steps in our action, which will write data to an existing file in the repository.

Structuring project directory

Next thing that we need to take care of is to create all files and folders in the project. Additionally, it’s important that we make a yaml file, which acts as a action configuration file. Furtthermore, we need to place this file inside a “.github / workflows” directory.

To clarify, first we need to create a folder named .github, and inside it we need to create a folder named workflows. Furthermore, we can create multiple yaml action configuration files for one project.

The following list displays the entire project structure we’re going to work on:

  • .github (folder)
    • workflows (folder)
      • actions.yml
  • .gitignore
  • main.py
  • requirements.txt

Configuring GitHub action for running Python script

In the following step of this guide, we’re going to focus on creating that configuration yaml file we mentioned above. Furthermore, we need to specify the name of the action, what triggers it, and what it needs to execute.

Each action needs to have at least one job, for which we need to specify the OS it’s running on and the steps it needs to take. Furthermore, steps are a series of commands it executes in a sequence.

In our case, these steps will be:

  • Checkout the contents of the repository
  • Setup Python
  • Install necessary Python packages for our script
  • Execute the script
  • Commit the updated repository
  • Push changes

As for what will trigger our action, we’ll schedule it so it run every 2 hours. This requires a specific cron syntax, which you can also make using cron schedule expressions tool.

Here is also the entire code for actions.yml file.

name: run main.py

on:
  schedule:
    - cron: '0 */2 * * *'

jobs:
  build:
    runs-on: ubuntu-latest
    steps:

      - name: checkout repo content
        uses: actions/checkout@v3
      
      - name: setup python
        uses: actions/setup-python@v4
        with:
          python-version: '3.9'
      
      - name: install python packages
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt
        
      - name: execute py script
        env:
          SOME_SECRET: ${{ secrets.SOME_SECRET }}
        run: python main.py
      
      - name: commit files
        run: |
          git config --global user.email "[email protected]"
          git config --global user.name "Your Name"
          git add -A
          git diff-index --quiet HEAD || (git commit -a -m "updated logs" --allow-empty)

      - name: push changes
        uses: ad-m/github-push-action@master
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          branch: main

Coding the Python script for our GitHub action

Next, we’re going to write a simple Python script for fetching current temperature value of Ljubljana. In addition, we’ll log this information and save it into a status.log file in the root directory of our project.

Because we’re going to update this log file with every execution, we’ll need to commit and push changes to the repository.

Here is the entire code for the main.py file.

import logging
import logging.handlers
import os

import requests

ROOT = os.path.dirname(__file__)

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
logger_file_handler = logging.handlers.RotatingFileHandler(
    os.path.join(ROOT, "status.log"),
    maxBytes=1024 * 1024,
    backupCount=1,
    encoding="utf8",
)
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
logger_file_handler.setFormatter(formatter)
logger.addHandler(logger_file_handler)

try:
    SOME_SECRET = os.environ["SOME_SECRET"]
except KeyError:
    SOME_SECRET = "Token not available!"
    #logger.info("Token not available!")
    #raise


if __name__ == "__main__":
    logger.info(f"Token value: {SOME_SECRET}")

    r = requests.get('https://weather.talkpython.fm/api/weather/?city=Ljubljana&country=SI')
    if r.status_code == 200:
        data = r.json()
        temperature = data["forecast"]["temp"]
        logger.info(f'Weather in Ljubljana: {temperature}')

The code above uses requests package, which is not included in the installation of the Python. Therefore, we need to add it in the requirements.txt file.

Conclusion

To conclude, we made a simple demo project, where we utilized GitHub actions to run a Python script. Furthermore, you can monitor their executions under Actions tab. I learned a lot while working on this project and I hope it proves itself helpful to you as well.

Share this article:

Related posts

Discussion(0)