From 62922c5afb8834a92eaee5c4ce4c0f7498c30405 Mon Sep 17 00:00:00 2001 From: rj Date: Fri, 22 Mar 2024 12:37:08 -0500 Subject: [PATCH 1/5] step0: add python dependencies --- api/requirements.txt | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 api/requirements.txt diff --git a/api/requirements.txt b/api/requirements.txt new file mode 100644 index 000000000..d15df981c --- /dev/null +++ b/api/requirements.txt @@ -0,0 +1,25 @@ +attrs==22.1.0 +autopep8==2.0.1 +certifi==2022.12.7 +charset-normalizer==3.1.0 +click==8.1.3 +coverage==6.4.2 +coveralls==3.3.1 +docopt==0.6.2 +Flask==2.2.1 +idna==3.4 +iniconfig==1.1.1 +itsdangerous==2.1.2 +Jinja2==3.1.2 +MarkupSafe==2.1.1 +packaging==21.3 +pluggy==1.0.0 +py==1.11.0 +pycodestyle==2.10.0 +pyparsing==3.0.9 +pytest==7.1.2 +pytest-cov==3.0.0 +requests==2.28.2 +tomli==2.0.1 +urllib3==1.26.15 +Werkzeug==2.2.1 From a13fe3332906871ebe058c80e7145e875267d9cc Mon Sep 17 00:00:00 2001 From: rj Date: Fri, 22 Mar 2024 12:47:05 -0500 Subject: [PATCH 2/5] step1: add calculator backend and tests --- api/app.py | 35 +++++++++++++++++++++++++++++++ api/calculator/__init__.py | 0 api/calculator/calculator.py | 14 +++++++++++++ api/calculator/test_calculator.py | 30 ++++++++++++++++++++++++++ 4 files changed, 79 insertions(+) create mode 100644 api/app.py create mode 100644 api/calculator/__init__.py create mode 100644 api/calculator/calculator.py create mode 100644 api/calculator/test_calculator.py diff --git a/api/app.py b/api/app.py new file mode 100644 index 000000000..d91792d1b --- /dev/null +++ b/api/app.py @@ -0,0 +1,35 @@ +from flask import ( + Flask, + request, +) + +from calculator.calculator import Calculator + +app = Flask(__name__) + +@app.route('/api/add', methods=['POST']) +def add(): + return operation('add', 2) + +@app.route('/api/subtract', methods=['POST']) +def subtract(): + return operation('subtract', 2) + +@app.route('/api/multiply', methods=['POST']) +def multiply(): + return operation('multiply', 2) + +@app.route('/api/divide', methods=['POST']) +def divide(): + return operation('divide', 2) + +def operation(method, num_factors): + factors = [] + if num_factors == 2: + factors.append(float(request.json.get('x'))) + factors.append(float(request.json.get('y'))) + + return str(getattr(Calculator, method)(*factors)) + + +app.run(host='0.0.0.0', port=8080) \ No newline at end of file diff --git a/api/calculator/__init__.py b/api/calculator/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/api/calculator/calculator.py b/api/calculator/calculator.py new file mode 100644 index 000000000..eac4e7acb --- /dev/null +++ b/api/calculator/calculator.py @@ -0,0 +1,14 @@ +class Calculator: + def add(x, y): + return x + y + + def subtract(x, y): + return x - y + + def multiply(x, y): + return x * y + + def divide(x, y): + if y == 0: + return 'Cannot divide by 0' + return x * 1.0 / y \ No newline at end of file diff --git a/api/calculator/test_calculator.py b/api/calculator/test_calculator.py new file mode 100644 index 000000000..deabbae31 --- /dev/null +++ b/api/calculator/test_calculator.py @@ -0,0 +1,30 @@ +from .calculator import Calculator + + +def test_add(): + assert Calculator.add(1, 2) == 3.0 + assert Calculator.add(1.0, 2.0) == 3.0 + assert Calculator.add(0, 2.0) == 2.0 + assert Calculator.add(2.0, 0) == 2.0 + assert Calculator.add(-4, 2.0) == -2.0 + +# def test_subtract(): +# assert Calculator.subtract(1, 2) == -1.0 +# assert Calculator.subtract(2, 1) == 1.0 +# assert Calculator.subtract(1.0, 2.0) == -1.0 +# assert Calculator.subtract(0, 2.0) == -2.0 +# assert Calculator.subtract(2.0, 0.0) == 2.0 +# assert Calculator.subtract(-4, 2.0) == -6.0 + +# def test_multiply(): +# assert Calculator.multiply(1, 2) == 2.0 +# assert Calculator.multiply(1.0, 2.0) == 2.0 +# assert Calculator.multiply(0, 2.0) == 0.0 +# assert Calculator.multiply(2.0, 0.0) == 0.0 +# assert Calculator.multiply(-4, 2.0) == -8.0 + +# def test_divide(): +# assert Calculator.divide(1, 2) == 0.5 +# assert Calculator.divide(1.0, 2.0) == 0.5 +# assert Calculator.divide(0, 2.0) == 0 +# assert Calculator.divide(-4, 2.0) == -2.0 \ No newline at end of file From 1f3ca16c44b641eee32498e7f285e694d4f8a1aa Mon Sep 17 00:00:00 2001 From: rj Date: Fri, 22 Mar 2024 13:03:32 -0500 Subject: [PATCH 3/5] upload coverage reports to Codecov --- .github/workflows/api.yml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 .github/workflows/api.yml diff --git a/.github/workflows/api.yml b/.github/workflows/api.yml new file mode 100644 index 000000000..9cc12b4fa --- /dev/null +++ b/.github/workflows/api.yml @@ -0,0 +1,21 @@ +name: API workflow + +on: [push, pull_request] + +jobs: + build: + runs-on: ubuntu-latest + name: Test python API + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.11' + - name: Install requirements + run: pip install -r api/requirements.txt + - name: Run tests and collect coverage + run: pytest --cov=api.calculator --cov-report=xml + - name: Upload coverage reports to Codecov with GitHub Action + uses: codecov/codecov-action@v4 + with: + token: ${{ secrets.CODECOV_TOKEN }} \ No newline at end of file From 6baa487d6ad39adad2764f6131241f919e2679d1 Mon Sep 17 00:00:00 2001 From: rj Date: Fri, 22 Mar 2024 13:36:20 -0500 Subject: [PATCH 4/5] added codecov yml for status checks and ignore --- codecov.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 codecov.yml diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 000000000..9bfcf9d0e --- /dev/null +++ b/codecov.yml @@ -0,0 +1,14 @@ +coverage: + status: + project: + default: + target: 80% + threshold: 1% + informational: true + patch: + default: + target: 80% + threshold: 1% + informational: true +ignore: + - "**/test_*.py" \ No newline at end of file From 98cf9b8a6bb3d3bcea34cb035069a52d2609db7f Mon Sep 17 00:00:00 2001 From: rj Date: Fri, 22 Mar 2024 13:52:30 -0500 Subject: [PATCH 5/5] divide by zero case added --- api/calculator/test_calculator.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/api/calculator/test_calculator.py b/api/calculator/test_calculator.py index deabbae31..7b888250c 100644 --- a/api/calculator/test_calculator.py +++ b/api/calculator/test_calculator.py @@ -27,4 +27,7 @@ def test_add(): # assert Calculator.divide(1, 2) == 0.5 # assert Calculator.divide(1.0, 2.0) == 0.5 # assert Calculator.divide(0, 2.0) == 0 -# assert Calculator.divide(-4, 2.0) == -2.0 \ No newline at end of file +# assert Calculator.divide(-4, 2.0) == -2.0 + +def test_divide_by_0(): + assert Calculator.divide(2.0, 0) == 'Cannot divide by 0' \ No newline at end of file