Skip to content

Commit

Permalink
Merge pull request #1 from TogetherCrew/WIP-create-python-library-tem…
Browse files Browse the repository at this point in the history
…plate-repository

Added dockerfiles with code & tests!
  • Loading branch information
cyri113 authored Aug 8, 2023
2 parents addce68 + a641082 commit bc9bf35
Show file tree
Hide file tree
Showing 17 changed files with 354 additions and 0 deletions.
8 changes: 8 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.github/

.coverage/
.coverage
coverage

venv/
.env
35 changes: 35 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Staging CI/CD Pipeline

on: pull_request

jobs:
ci:
uses: TogetherCrew/operations/.github/workflows/ci.yml@main
secrets:
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
package_publish:
needs: ci
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.10"]
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: |
python -m pip install --upgrade pip setuptools wheel twine
- name: Build package
run: |
python setup.py sdist bdist_wheel
- name: Publish package to PyPI
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
run: |
python -m twine upload dist/*
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
coverage/*
.DS_store
.env
12 changes: 12 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
FROM python:3.10-bullseye AS base
WORKDIR /project
COPY . .
RUN pip install .

FROM base as test
RUN chmod +x docker-entrypoint.sh
CMD ["./docker-entrypoint.sh"]


FROM test as prod
RUN echo "prod passed"
71 changes: 71 additions & 0 deletions docker-compose.test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
version: "3.9"

services:
app:
build:
context: .
target: test
dockerfile: Dockerfile
environment:
- PORT=3000
- SAMPLE_ENV=sample_env
- DB_HOST=mongo
- DB_PORT=27017
- DB_USER=root
- DB_NAME=RnDAO
- DB_PASSWORD=pass
- RABBIT_HOST=rabbitmq
- RABBIT_PORT=5672
- RABBIT_USER=root
- RABBIT_PASSWORD=pass
- NEO4J_PROTOCOL=bolt
- NEO4J_HOST=neo4j
- NEO4J_PORT=7687
- NEO4J_USER=neo4j
- NEO4J_PASSWORD=password
- NEO4J_DB=neo4j
- SENTRY_DSN=sample_dsn
- SENTRY_ENV=local
volumes:
- ./coverage:/project/coverage
depends_on:
mongo:
condition: service_healthy
neo4j:
condition: service_healthy
rabbitmq:
condition: service_healthy
mongo:
image: "mongo:6.0.8"
environment:
- MONGO_INITDB_ROOT_USERNAME=root
- MONGO_INITDB_ROOT_PASSWORD=pass
healthcheck:
test: echo 'db.stats().ok' | mongosh localhost:27017/test --quiet
interval: 60s
timeout: 10s
retries: 2
start_period: 40s
neo4j:
image: "neo4j:5.9.0"
environment:
- NEO4J_AUTH=neo4j/password
- NEO4J_PLUGINS=["apoc", "graph-data-science"]
- NEO4J_dbms_security_procedures_unrestricted=apoc.*,gds.*
healthcheck:
test: ["CMD" ,"wget", "http://localhost:7474"]
interval: 1m30s
timeout: 10s
retries: 2
start_period: 40s
rabbitmq:
image: "rabbitmq:3-management-alpine"
environment:
- RABBITMQ_DEFAULT_USER=root
- RABBITMQ_DEFAULT_PASS=pass
healthcheck:
test: rabbitmq-diagnostics -q ping
interval: 30s
timeout: 30s
retries: 2
start_period: 40s
3 changes: 3 additions & 0 deletions docker-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env bash
python3 -m coverage run --omit=tests/* -m pytest tests
python3 -m coverage lcov -o coverage/lcov.info
2 changes: 2 additions & 0 deletions python_library/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# flake8: noqa
from .sample import Sample
47 changes: 47 additions & 0 deletions python_library/sample.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import os

import numpy as np
from dotenv import load_dotenv


class Sample:
def __init__(self) -> None:
pass

def sample_compute(self, max_value: int = 50) -> int:
"""
Do a random sample computations
Parameters:
------------
max_value : int
a maximum value for generating randome number
default is set to 50
Returns:
--------
computation_results : int
the result of computations
"""
a = np.random.randint(0, max_value)
b = np.random.randint(0, max_value)

computation_results = a + b

return computation_results

def sample_get_env(self) -> str | None:
"""
getting an env for example
the env name is `SAMPLE_ENV`
Returns:
---------
env_value : str
the value that was set to env
"""
load_dotenv()

env_value = os.getenv("SAMPLE_ENV")

return env_value
8 changes: 8 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
numpy==1.24.1
pytest==7.2.0
pytest-cov==4.0.0
coverage==7.2.5
python-dotenv==0.21.1
tc_messageBroker==1.4.0
pymongo==4.3.3
neo4j==5.8.0
17 changes: 17 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from setuptools import find_packages, setup

with open("requirements.txt") as f:
requirements = f.read().splitlines()


setup(
name="python-lib-template",
version="1.0.0",
author="Mohammad Amin Dadgar, TogetherCrew",
maintainer="Mohammad Amin Dadgar",
maintainer_email="[email protected]",
packages=find_packages(),
description="A python library template for future togethercrew python repos",
long_description=open("README.md").read(),
install_requires=requirements,
)
Empty file added tests/__init__.py
Empty file.
Empty file added tests/integration/__init__.py
Empty file.
39 changes: 39 additions & 0 deletions tests/integration/test_mongo_connection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import os

from dotenv import load_dotenv
from pymongo import MongoClient


def test_mongo_env_variables():
"""
test if the environment variables are loaded correctly
"""
load_dotenv()

host = os.getenv("DB_HOST")
port = os.getenv("DB_PORT")
user = os.getenv("DB_USER")
password = os.getenv("DB_PASSWORD")
db_name = os.getenv("DB_NAME")

assert host is not None
assert port is not None
assert user is not None
assert password is not None
assert db_name is not None


def test_mongo_connection():
"""
test connecting to mongodb
"""
load_dotenv()

host = os.getenv("DB_HOST")
port = os.getenv("DB_PORT")
user = os.getenv("DB_USER")
password = os.getenv("DB_PASSWORD")
db_name = os.getenv("DB_NAME")

mongodb_connection = f"mongodb://{user}:{password}@{host}:{port}/{db_name}"
_ = MongoClient(host=mongodb_connection)
42 changes: 42 additions & 0 deletions tests/integration/test_neo4j_connection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import os

from dotenv import load_dotenv
from neo4j import GraphDatabase


def test_neo4j_env_variables():
"""
test if the environment variables are loaded correctly
"""
load_dotenv()

protocol = os.getenv("NEO4J_PROTOCOL")
host = os.getenv("NEO4J_HOST")
port = os.getenv("NEO4J_PORT")
db_name = os.getenv("NEO4J_DB")

user = os.getenv("NEO4J_USER")
password = os.getenv("NEO4J_PASSWORD")

assert protocol is not None
assert host is not None
assert port is not None
assert db_name is not None
assert protocol is not None
assert user is not None
assert password is not None


def test_neo4j_connection():
load_dotenv()

protocol = os.getenv("NEO4J_PROTOCOL")
host = os.getenv("NEO4J_HOST")
port = os.getenv("NEO4J_PORT")

url = f"{protocol}://{host}:{port}"
user = os.getenv("NEO4J_USER")
password = os.getenv("NEO4J_PASSWORD")

with GraphDatabase.driver(url, auth=(user, password)) as driver:
driver.verify_connectivity()
34 changes: 34 additions & 0 deletions tests/integration/test_rabbitmq_connection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import os

from tc_messageBroker import RabbitMQ


def test_rabbitmq_env_variables():
"""
test if the environment variables are loaded correctly
"""
broker_url = os.getenv("RABBIT_HOST")
port = os.getenv("RABBIT_PORT")
username = os.getenv("RABBIT_USER")
password = os.getenv("RABBIT_PASSWORD")

assert broker_url is not None
assert port is not None
assert username is not None
assert password is not None


def test_tc_message_broker_connection():
"""
test connecting to rabbitMQ and defining a queue for that
"""
broker_url = os.getenv("RABBIT_HOST")
port = os.getenv("RABBIT_PORT")
username = os.getenv("RABBIT_USER")
password = os.getenv("RABBIT_PASSWORD")

messageBroker = RabbitMQ(
broker_url=broker_url, port=port, username=username, password=password
)

_ = messageBroker.connect(queue_name="test_queue")
12 changes: 12 additions & 0 deletions tests/unit/test_env_load.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from python_library import Sample


def test_env_load():
"""
test whether the env is loaded correctly
"""
sample = Sample()

env_value = sample.sample_get_env()

assert env_value is not None
21 changes: 21 additions & 0 deletions tests/unit/test_return_results.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from python_library import Sample


def test_random_computations_have_results():
"""
test if the random copmutations results is not None
"""
sample = Sample()
result = sample.sample_compute()

assert result is not None


def test_random_computations_integer_results():
"""
test if the random computation result is integer
"""
sample = Sample()
result = sample.sample_compute()

assert type(result) is int

0 comments on commit bc9bf35

Please sign in to comment.