Open In App

Dynamic Quote Generator for GitHub Readme

Last Updated : 20 Apr, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Making a Readme file for a repository is one of the best ways to provide its summary. They are not dynamic because GitHub Readme files do not support JavaScript. So, in today’s article, we’ll demonstrate how to dynamically change the contents of the Readme file using Python and GitHub Actions. We’ll also use GitHub Secrets to keep our sensitive information safe.

Step Involved in the article:

  1. Creation of a Readme File.
  2. Use an API to get Random Quotes in Python.
  3. Update the Quotes and display them on the Readme File using Python Script.
  4. Use GitHub Actions to run the Python Script and schedule the task at regular intervals.
  5. Use GitHub Secrets to hide the Sensitive data.

Creation of a Readme File

Initially, we need to create a readme.md file in Markdown and include all the static material that has to be shown. If you are encountering issues or want to know more about the Basic writing and formatting syntax, please visit here.

While JavaScript files cannot be integrated into GitHub Readme files, we will use Python Script with GitHub Actions to directly manage our Readme file and change the quotes.

HTML




## Dynamic Quotes on GitHub Readme:
 
---
 
<h2 align='center'>Quote of the Moment</h2>
<h3 quote align='center'>Some Random Data!</h3 quote>
 
---


Output:

Dynamic Quotes on GitHub Readme

The output of README.md File

API to get Random Quotes

Several APIs are available that provide Random quotes. Here, we’re going to use API Ninjas. API Ninjas offers a variety of Quotations for free cost. By registering on API Ninjas, you can get the API Key.

Example 

After getting the API we will test for Random Quotes. Here the Python script generates random quotes each time you run the script, a different quote will be generated.

Python3




import random
import json
import requests
import os
 
#Category List for Quotes
category = ['inspirational','attitude','dreams',
            'experience','intelligence','leadership','success']
api_url = 'https://api.api-ninjas.com/v1/\
        quotes?category={}'.format(category[random.randint(0,6)])
 
#Enter your API Key Here
response = requests.get(api_url, headers=
                   {'X-Api-Key': 'XXXXXXXXXXXXXXXXXX'})
 
if response.status_code == requests.codes.ok:
    quote=response.text
    #Load the response into a json object
    quotes = json.loads(quote)
    q=quotes[0]['quote']
     
    #In case of receiving multiple quotes,
    # we will pick the first one
    mainQuote=q.split('.')[0]
else:
    print("Error:", response.status_code, response.text)


Output:

Dynamic Quotes on GitHub Readme

Fetching new Quotes

Python script that modifies the Readme file

We’ll now create a Python script that modifies the Readme file and changes the old quote with the new fetched quote. The complete script which is given below should be placed in the index.py file.

Python3




import random
import json
import requests
import os
 
# Category List for Quotes
category = ['inspirational', 'attitude', 'dreams',
            'experience', 'intelligence', 'leadership', 'success']
api_url = 'https://api.api-ninjas.com/v1/\
quotes?category={}'.format(category[random.randint(0, 6)])
 
# Enter your API Key Here
response = requests.get(api_url, headers=
                        {'X-Api-Key': 'XXXXXXXXXXXXXXXXXX'})
 
if response.status_code == requests.codes.ok:
    quote = response.text
    # Load the response into a json object
    quotes = json.loads(quote)
    q = quotes[0]['quote']
    # In case of receiving multiple quotes,
    # we will pick the first one
    mainQuote = q.split('.')[0]
else:
    print("Error:", response.status_code, response.text)
 
 
# Reading the readme file
with open("README.md", mode="r", encoding="utf8") as f:
    readmeText = f.read()
 
# Finding the tag where the quote is to be replaced
openingTag = "<h3 quote"
closingTag = "</h3 quote"
 
startIndex = readmeText.index(openingTag)
endIndex = readmeText.index(closingTag)
 
quoteMarkdown = "<h3 quote align='center'>" + mainQuote + "." + "</h3 quote>"
 
content = readmeText[startIndex +
                     len(openingTag): endIndex]
newContent = (
    readmeText[:startIndex]
    + quoteMarkdown
    + readmeText[endIndex + len(closingTag) + 1:]
)
 
# Writing new Quote into readme file
readme_file = open("README.md",
                   mode="w", encoding="utf8")
readme_file.write(newContent)


Creation of requirements.txt File

Create a requirements.txt file and place the contents given below in it:

beautifulsoup4
Markdown
requests

Use GitHub Actions to run Python Scripts and Push it again:

To execute the Python script, we must now build a GitHub action.
Steps:

  1. Open the Repository.
  2. Go to Settings.
  3. Select “Pages” from the “Code and Automation” section in the sidebar.
  4. Select “GitHub Actions” from the “Source” dropdown menu.
  5. Click on the “Configure” Button of “GitHub Pages Jekyll”

Now we need to write a .yml script that executes the python code regularly, Here we have used the time interval of 12 hours for running the Python Script. If you wish to modify it, simply enter a different time in the schedule. To obtain the required corn task time, you can take help from the https://crontab.guru/ webpage. Now, Paste the code below:

name: Update Quotes
on:
  schedule: [{cron: "0 */12 * * *"}]
  workflow_dispatch:
  push: {branches: ["master", "main"]}

jobs:
  build:
    runs-on: windows-latest
    steps:
      - uses: actions/checkout@v3
      - name: Setup python
        uses: actions/setup-python@v3
        with:
          python-version: "3.8"
          
      - name: Installing dependencies
        run: pip install -r requirements.txt

      - name : Running script file
        run: python index.py
        
      - name: Update the Quote
        run: |
          git config --global user.name 'GitHubUserName'
          git config --global user.email 'EmailID@gmail.com'
          git add .
          git commit -am "Daily quotes"
          git push origin main --force

Click on “Start Commit”. You may see a yml file in your repository after the file has been committed. That’s it; the quotes will be dynamically updated at the scheduled time.

Dynamic Quotes on GitHub Readme

Structure of the Repository

Use of GitHub Secrets

You may have noticed that we pose a risk by making the API Key public. Thus, we must conceal the key without upsetting the surrounding area. We will make use of GitHub Secrets for this.

Steps to save the API Key as a secret variable:

  1. Open the Repository.
  2. Go to Settings.
  3. Click on “Secrets and Variables” from the Security Section and select “Actions”.
  4. Click on the “New repository secret” button.
  5. Enter the Secret Name and Value.
  6. Click on Add Secret.
Dynamic Quotes on GitHub Readme

Add Secret Variable

We will set this secret key as an environment variable by editing the following code in the yml file. Now, The complete yml script will look as shown below:

env:
  api_key: ${{ secrets.API_KEY }}
Dynamic Quotes on GitHub Readme

Contents of .yml file

Retrieve API from the Environment variables

Now, rather than entering the API key straight into the Python script, we will retrieve it from the environment variables by replacing entering the API with Getting the API key from the env variable. Below is the complete Python script:

# Getting API key from environment variable
API_KEY = os.environ.get('api_key')

Python3




import random
import json
import requests
import os
 
# Getting API key from environment variable
API_KEY = os.environ.get('api_key')
 
# Getting a random quote from the API
category = ['inspirational','attitude','dreams',
            'experience','intelligence',
            'leadership','success']
api_url = 'https://api.api-ninjas.com/v1/\
quotes?category={}'.format(category[random.randint(0,6)])
response = requests.get(api_url, headers=
                        {'X-Api-Key': API_KEY})
 
if response.status_code == requests.codes.ok:
    quote=response.text
    quotes = json.loads(quote)
    q=quotes[0]['quote']
    # In case of receiving multiple quotes,
    # we will take the first one
    mainQuote=q.split('.')[0]
else:
    print("Error:", response.status_code, response.text)
 
 
# Reading the readme file
with open("README.md", mode="r", encoding="utf8") as f:
    readmeText = f.read()
 
# Finding the tag where the quote is to be replaced
openingTag = "<h3 quote"
closingTag = "</h3 quote"
 
startIndex = readmeText.index(openingTag)
endIndex = readmeText.index(closingTag)
 
quoteMarkdown = "<h3 quote align='center'>"
                + mainQuote + "." + "</h3 quote>"
 
content = readmeText[startIndex +
                         len(openingTag) : endIndex]
newContent = (
    readmeText[:startIndex]
    + quoteMarkdown
    + readmeText[endIndex + len(closingTag) + 1 :]
)
 
# Writing new Quote into readme file
readme_file = open("README.md", mode="w", encoding="utf8")
readme_file.write(newContent)


The safest code that dynamically changes the quotes (data) of the Readme file is there once you push the script. In the Action section of the repository, details of all the scheduled tasks are visible.

Dynamic Quotes on GitHub Readme

Task getting scheduled at given Interval

Dynamic Quotes on GitHub Readme

Details of scheduled task

Output:

Dynamic Quotes on GitHub Readme

 

Complete Guide to In Video:



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads