Skip to main content

A simple utility package for string and math functions

Project description

What I Learned from Task 1 - CI/CD-Based Python Package

Module: Agentic AI Framework (Prodigal AI)

In the first task, I was assigned to build a CI/CD based Python packa ge (funcationality of the Python package was upto us we could create a simple python package).

1️⃣ Understanding CI/CD in Python Packaging

  • CI/CD (Continuous Integration & Continuous Deployment) automates the build, test, and deployment of software.

  • It helps in maintaining high-quality code and streamlining software updates.


2️⃣ Steps to Build a Python Package

  • Step 1:

    • Create a seperate project folder for your Python Package.
    • The name of the Folder should be the name what you want to give it to your Python Package.
  • Step 2:

    • Inside your project folder, you need to create few folders and files.

    • Package Souce Code Folder:

      • Create a folder for your package source code.
      • Inside the Package Souce Code folder you will be writing your code in main.py (you can split your code accross multiple number of .py files if needed).
      • You must also create a Python Special file named __init__.py inside this folder.
    • Testing Folder

      • After, completing of your code, you should test it. For this, create a seperate folder named tests.
      • Inside the tests folder, create a test_main.py file to write test cases.
    • GitHub Actions CI/CD Setup:

      • Create a .githuh folder to set up GitHub Actions CI/CD.

      • Inside .github, create another folder named workflows.

      • Inside workflows, create a .yml file for CI/CD. This file should be named after your project, such as your-project-name.yml(eg: my_package.yml).

    • Additional Files:

      • .gitignore – To ignore unnecessary files from being tracked by Git.

      • pyproject.toml – For modern package configuration.

      • README.md – To provide documentation for the package.

      • LICENSE.txt – To define the package’s license.

      • requirements.txt – To list package dependencies.


Here is the Structure in visual form:

my_package/
│── my_package/            # Package source code   ├── __init__.py        # Required for a Python package   ├── main.py            # Main module
│
│── tests/                 # Unit tests   ├── test_main.py
│
│── .github/               # GitHub Actions CI/CD   ├── workflows/
│       ├── python-package.yml
│
│── .gitignore             # Ignore unnecessary files
│── pyproject.toml         # Modern package configuration
│── README.md              # Documentation
│── LICENSE                # License file
│── requirements.txt       # Dependencies

3️⃣ Write Code for Your Package

🔹 You need to write the code for your Package inside main.py which is present in your my_package folder.

🔹 Here is my code for math_utils.py:

#Calculates the factorial of a number.
def factorial(n):
    try:
        if n < 0:
            raise ValueError("Factorial is not defined for negative numbers.")
        if n == 0 or n == 1:
            return 1
        result = 1
        for i in range(2, n + 1):
            result *= i
        return result
    except ValueError as e:
        return f"{e}"
    except Exception as e:
        return f"An unexpected error occurred: {e}"

🔹 Here is my code for string_utils,py:

def convert_to_uppercase(text):
    return text.upper()  # Converts a string to uppercase.

def reverse_string(text):
    return text[::-1]  # Reverses a given string.

def character_count(text):
    return len(text)  # Returns the length of the string.

🔹Now add the created files inside __init__.py

from .string_utils import convert_to_uppercase, reverse_string, character_count
from .math_utils import factorial

4️⃣ Code Test

  • Now, after writing the code we must test it by Unit Test:
    • You must test for all files.

    • Here is the test code for math_utils.py file.

      import pytest
      from logictools import math_utils
      
      def test_factorial():
          assert math_utils.factorial(5) == 120
          assert math_utils.factorial(0) == 1
      

  • Here is the test code for string_util.py file.
    import pytest
    from logictools import string_utils
    
    def test_convert_to_uppercase():
        assert string_utils.convert_to_uppercase("hello") == "HELLO"
    
    def test_reverse_string():
        assert string_utils.reverse_string("hello") == "olleh"
    
    def test_character_count():
        assert string_utils.character_count("Hello") == 5
    

5️⃣ Content inside pyproject.toml file

  • This is the modern way to define a package.

    🔹 pyproject.toml

[tool.poetry]
name = "logictools"           # Name of your package
version = "0.1.3"             # Current version of your package
description = "A simple utility package for string and math functions"
authors = ["RANGDAL PAVANSAI <psai49779@gmail.com>"]
license = "MIT"               # License type (MIT in this case)
readme = "README.md"          # Points to your README file

[tool.poetry.dependencies]
python = "^3.7"               # Your package supports Python 3.7 and later.

[tool.poetry.group.dev.dependencies]
pytest = "^7.0"               # Your package requires pytest version 7.0 or higher for testing.

[build-system]
requires = ["poetry-core>=1.0.0"]       # Specifies that poetry-core (version 1.0.0 or later) is required to build the package.
build-backend = "poetry.core.masonry.api"    # Uses poetry.core.masonry.api as the build system.

6️⃣ Create requirements.txt

  • This lists dependencies

    touch requirements.txt
    
  • In requirements.txt add the packages that are required or your project to run.


7️⃣ Create .gitignore

  • To ignore unnecessary files:
    # Ignore Python cache & build files
    __pycache__/
    *.pyc
    *.pyo
    *.pyd
    *.egg-info/
    build/
    dist/
    venv/
    

8️⃣ Build & Test Your Package Locally

1. Install build Tool

pip install build

2. Build your package

python -m build
  • This creates a dist/ folder containing:

    dist/
      my_package-0.1.0-py3-none-any.whl
      my_package-0.1.0.tar.gz
    

3. Test Your Package

pip install dist/NAME-OF-YOUR-PACKAGE-0.1.0-py3-none-any.whl
python -c "import NAME-OF-YOUR-PACKAGE; print(NAME-OF-YOUR-PACKAGE.factorial(5))"

9️⃣ Set Up GitHub Actions for CI/CD

  1. Create .github/workflows/python-package.yml

    name: Python Package CI/CD
    
    on:
      push:
        branches:
          - main
      pull_request:
        branches:
          - main
      release:
        types: [created]
    
    jobs:
      test:
        name: Run Tests
        runs-on: ubuntu-latest
    
        steps:
          - name: Checkout repository
            uses: actions/checkout@v3
    
          - name: Set up Python
            uses: actions/setup-python@v4
            with:
              python-version: '3.10'
    
          - name: Install dependencies
            run: |
              python -m pip install --upgrade pip
              pip install -r requirements.txt
              pip install pytest
    
          - name: Run tests
            run: pytest
    
      build:
        name: Build and Publish Package
        runs-on: ubuntu-latest
        needs: test
        if: github.event_name == 'release'
    
        steps:
          - name: Checkout repository
            uses: actions/checkout@v3
    
          - name: Set up Python
            uses: actions/setup-python@v4
            with:
              python-version: '3.10'
    
          - name: Install Build Tools
            run: |
              python -m pip install --upgrade pip
              pip install build twine
    
          - name: Build Package
            run: python -m build
    
          - name: Publish to PyPI
            env:
              PYPI_USERNAME: ${{ secrets.PYPI_USERNAME }}
              PYPI_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
            run: |
              twine upload dist/* -u "$PYPI_USERNAME" -p "$PYPI_PASSWORD"
    

🔟 Securely Store PyPI Credentials

  1. Go to your GitHub repo → Settings

  2. Click Secrets and variables → Actions

  3. Add these GitHub Secrets:

1️1 Publish Your Package

  1. Push to GitHub

    git init
    git add .
    git commit -m "Initial commit"
    git branch -M main
    git remote add origin https://github.com/yourusername/my_package.git
    git push -u origin main
    
  2. Create a GitHub Release

  • Go to GitHubReleasesCreate New Release
  • Tag it as v0.1.3 (match pyproject.toml version)
  • Click Publish Release
  • GitHub Actions will automatically build & upload your package to PyPI!

12. Confirmation of Package

  • After uploading successfull go check github actions.
  • If it successfully completes it's job that means your package is ready to use.
  • Now, confirm your pip package in https://pypi.org/YOUR-PACKAGE-NAME.

13. Install, and use

- pip install NAME-OF-YOUR-PACKAGE
- python -c "import NAME-OF-YOUR-PACKAGE; print(NAME-OF-YOUR-PACKAGE.factorial(5))"

Note:

  • Everytime you commit new file you much change the version of your package in pyproject.toml

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

logictools-0.1.5.tar.gz (4.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

logictools-0.1.5-py3-none-any.whl (6.1 kB view details)

Uploaded Python 3

File details

Details for the file logictools-0.1.5.tar.gz.

File metadata

  • Download URL: logictools-0.1.5.tar.gz
  • Upload date:
  • Size: 4.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.1.1 CPython/3.9.21 Linux/6.8.0-1021-azure

File hashes

Hashes for logictools-0.1.5.tar.gz
Algorithm Hash digest
SHA256 061f838dd674cb192b6ac6ecc02f9c9071d23b7219bdb3ccbe9aadf1ecfafc28
MD5 b6605f227f65e9eeb4bb38c094daac45
BLAKE2b-256 6290645d3b12247de1ced05fd1bf368091765c375b10bc3a37112696ad21a6b3

See more details on using hashes here.

File details

Details for the file logictools-0.1.5-py3-none-any.whl.

File metadata

  • Download URL: logictools-0.1.5-py3-none-any.whl
  • Upload date:
  • Size: 6.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.1.1 CPython/3.9.21 Linux/6.8.0-1021-azure

File hashes

Hashes for logictools-0.1.5-py3-none-any.whl
Algorithm Hash digest
SHA256 f50de7639eaf9cdd31f743cd45823d23648414ff31c706ddcff1624e330c0a38
MD5 e1b31df39ae51b9707f5604240120a68
BLAKE2b-256 c93cab5e1644570517aeddd672fbba58c622f7aa9774a26d51e6e0a385443da1

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page