Commit 08d4609d authored by Grant, Josh's avatar Grant, Josh
Browse files

Merge branch 'develop' into 'main'

Add MS SQL mixin and Enhanced Logging

See merge request nset-utilities/common-package!9
parents 38aaf749 7ad77b74
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
FROM python:3.9-slim

RUN apt-get -yqq update && apt-get -yqq upgrade && \
      apt-get -yqq install vim 
      apt-get -yqq install vim && apt-get -yqq install postgresql-client

COPY src/ tmp/src


RUN set -eux && pip install --upgrade pip && \
      cd /tmp/src/ && pip install -e . 
      cd /tmp/src/ && pip install -e . && \
      pip install pytest pytest-cov


COPY ./test/test.py /test/test.py


CMD ['sh', 'tail', '-f', '/dev/null']
+62 −2
Original line number Diff line number Diff line
# common_package
# Common Package

Code for the Common Python Package to include logging, environment checking, 
and database connections and query. This package contains an extensible 
Database metaclass with a generic query function that is usable out of the box. 
Everything is configurable with environmental variables.

### Installation via pip

Run this command to install version 0.1.10 via pip:

`python3 -m pip --no-cache-dir install common==0.1.10 --index-url https://code.ornl.gov/api/v4/projects/10568/packages/pypi/simple  --trusted-host code.ornl.gov`

This will install latest (not recommended):

`python3 -m pip --no-cache-dir install common --index-url https://code.ornl.gov/api/v4/projects/10568/packages/pypi/simple  --trusted-host code.ornl.gov`

## Usage

A docker image and python package are provided for use as a base image in `docker-compose.yaml`. 

`common_package/sql/` contains the .sql files `create_tables.sql` and `fill_tables.sql` which serve as examples for how to initialize a postgres Database in your project (See below in the Creating an extensible Database Python Class section for details in how to create the Python Class.) The `volumes` statement in the docker-compose files runs these sql files once the container is created.


### Configuration via Environment Variables
Below is a list of environmental variables and what they do:
- DATABASE_TIMEOUT: an integer representing the seconds to wait before deciding a timeout occurred.
- DATABASE_DB: a string representing the database to connect to
- DATABASE_USER: a string representing the user to connect to the database as
- DATABASE_PW: a string representing the password for the DATABASE_USER
- DATABASE_HOST: a string representing the hostname or IP address hosting the database
- DATABASE_PORT: an integer representing the port to connect to the database on
- DATABASE_SCHEMA: a string representing the schema to default to when creating a database connection

These evironmental variables have been assigned default values for the Docker container in the file `envfile`, which is called in `docker-compose.yaml` and `docker-compose.test.yaml`

### Creating an extensible Database Python Class
Some `Database` methods such as `query` and `open` rely on
[python mixins](https://www.python.org/dev/peps/pep-0487/), which allow
abstract classes to interact with different types of databases and provide
additional functionality not provided by the `Database` class. Below is an 
example of how to create a Database class that uses the PostgresMixin:

```
from common.mixins.postgres import PostgresMixin
from common.database import Database


class PostgresDatabase(Database, PostgresMixin):
    """The class that allows Database to interact with psycopg2."""
    # TODO add additional functions for your class here, specific to your needs

with PostgresDatabase() as db:
    db.query('SELECT NOW()')
```

## Testing

Testing for the `common_package` is contained within `/common_package/test/test.py`. This can be accessed by building the test docker compose file with:
`docker-compose -f docker-compose.test.yaml up -d`
and subsequently checking the results in the logs:
`docker-compose -f docker-compose.test.yaml logs package`
Code for the Common Python Package to include logging, environment checking, and database connections and query
 No newline at end of file

build.sh

0 → 100755
+80 −0
Original line number Diff line number Diff line
#!/usr/bin/env bash
# ex: set fdm=marker
# usage {{{1 
#/ Usage: 
#/       ./build.sh [OPTIONS]
#/
#/    -t|--tag)
#/       the tag to assign the docker image
#/
#/    -n|--no-cache)
#/       do not use the cache when building this image
#/
#/    -f|--file)
#/       the Dockerfile to specify during build
#/
#/    -h|-?|--help)
#/       show this help and exit
#/
# 1}}} 
# environment {{{1 
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
PROJECT=${PROJECT:-"Some Project Name in $DIR"}
DOCKER_FILE="Dockerfile"
TAG="latest"
NOCACHED=""
# 1}}} 
# functions {{{1 
banner() { # {{{2
  BANNER=""
  BANNER="$BANNER\n  \033[32mCommon Package Base Image Builder\033[39m"
  echo -e "$BANNER\n\n"
} # 2}}} 
die() { # {{{2 
  echo -e "\033[31mFAILURE:\033[39m $1"
  exit 1
} # 2}}} 
warn() { # {{{2 
  echo -e "\033[33mWARNING:\033[39m $1"
} # 2}}} 
show_help() { # {{{2 
  grep '^#/' "${BASH_SOURCE[0]}" | cut -c4- || \
    die "Failed to display usage information"
} # 2}}} 
# 1}}} 
# arguments {{{1 
while :; do
  case $1 in # check arguments {{{2 
    -t|--tag) # Docker tag {{{3
      TAG=$2
      shift 2
      ;; # 3}}}
    -n|--no-cache) # build without cache {{{3
      NOCACHED="--no-cache"
      shift
      ;; # 3}}}
    -f|--file) # Dockerfile to use {{{3
      DOCKER_FILE=$2
      shift 2
      ;; # 3}}}
    -h|-\?|--help) # help {{{3 
      banner
      show_help
      exit
      ;; # 3}}} 
    -?*) # unknown argument {{{3 
      warn "Unknown option (ignored): $1"
      shift
      ;; # 3}}} 
    *) # default {{{3 
      break # 3}}} 
  esac # 2}}} 
done
# 1}}} 
# logic {{{1 
banner
DOCKER_BUILDKIT=1 docker build -f "$DOCKER_FILE" $NOCACHED  \
  -t "code.ornl.gov:4567/nset-utilities/common-package/common:$TAG" . || \
  die "Image failed to build."
docker push "code.ornl.gov:4567/nset-utilities/common-package/common:$TAG"
# 1}}} 

doc.sh

0 → 100755
+20 −0
Original line number Diff line number Diff line
#!/bin/bash

EXT='.py'

for entry in src/common/*
do
	if [[ $entry == *$EXT* ]]; then
		base=$(basename $entry $EXT)
		pydoc-markdown -I src -m common.$(basename $entry $EXT) > docs/$(basename $entry $EXT).md
	fi
done

for entry in src/common/mixins/*
do

	if [[ $entry == *$EXT* ]]; then
		base=$(basename $entry $EXT)
		pydoc-markdown -I src -m common.mixins.$(basename $entry $EXT) > docs/mixins.$(basename $entry $EXT).md
	fi
done
+9 −9
Original line number Diff line number Diff line
@@ -5,16 +5,17 @@ services:
    build: .
    volumes:
      - ./src/:/tmp/src
    environment:
      - DATABASE_HOST=postgres
      - DATABASE_TIMEOUT=60
      - LOGLEVEL=debug
    command: ["sh", "-c", "python3 /test/test.py"]
      - ./test/:/test/
    env_file:
      #- ./envfile_mssql
      - ./envfile
    #command: ["sh", "-c", "pytest --cov=common /test/test.py"]
    command: ["sh", "-c", "test-db-conn && pytest -v --cov=common /test/test.py --cov-report term-missing"]
    depends_on:
      - postgres

  postgres:
    image: postgres
    image: postgres:14.0
    environment: 
      - POSTGRES_PASSWORD=postgres
      - POSTGRES_USER=postgres
@@ -22,6 +23,5 @@ services:
    volumes:
      - ./sql/create_tables.sql:/docker-entrypoint-initdb.d/create_tables.sql
      - ./sql/fill_tables.sql:/docker-entrypoint-initdb.d/fill_tables.sql

# find what tables already exist in an empty database or initialize a table
# then use that for testing purposes
    ports:
      - "5532:5432" 
Loading