From bfa47882552179869d7b7932c7d1a41cd385a4f8 Mon Sep 17 00:00:00 2001 From: Alireza Parvaresh <89921883+parvvaresh@users.noreply.github.com> Date: Mon, 18 Dec 2023 14:40:50 +0330 Subject: [PATCH 1/7] Create api.py --- api.py | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 api.py diff --git a/api.py b/api.py new file mode 100644 index 00000000..34e441fe --- /dev/null +++ b/api.py @@ -0,0 +1,39 @@ +import requests as req +import json + +URL = "Https://targoman.ir/API" + + +def translate(word: str = "سلام", fromLang: str = "fa", toLang: str = "en") -> dict: + payload = { + "jsonrpc": "2.0", + "method": "Targoman::translate", + "id": 1, + "params": [ + "sSTargomanWUI", + word, + "%s2%s" % (fromLang.lower().strip(), toLang.lower().strip()), + "127.0.0.10", + "NMT", + True, + True, + True, + None, + "formal", + ], + } + + data = req.post(URL, json=payload) + data = json.loads(data.text) + return data + + +def Translate(word: str, fromLang: str, toLang: str) -> str: + if fromLang == "fa" and toLang == "en": + return translate(word, toLang=toLang, fromLang=fromLang)["result"]["tr"][ + "base" + ][0][1] + if fromLang == "en" and toLang == "fa": + return translate(word, toLang=toLang, fromLang=fromLang)["result"]["tr"][ + "base" + ][0][1] From b1e3ed40752f563034f962a86cdbc333d5a5eda7 Mon Sep 17 00:00:00 2001 From: alireza parvaresh Date: Sat, 13 Sep 2025 23:55:26 +0330 Subject: [PATCH 2/7] refactor --- .github/workflows/github.yml | 37 ++++++++++++++ Dockerfile | 13 +++++ __pycache__/api.cpython-312.pyc | Bin 0 -> 1530 bytes ...est_translate.cpython-312-pytest-8.4.1.pyc | Bin 0 -> 2506 bytes requirements.txt | 2 + test_translate.py | 45 ++++++++++++++++++ 6 files changed, 97 insertions(+) create mode 100644 .github/workflows/github.yml create mode 100644 Dockerfile create mode 100644 __pycache__/api.cpython-312.pyc create mode 100644 __pycache__/test_translate.cpython-312-pytest-8.4.1.pyc create mode 100644 requirements.txt create mode 100644 test_translate.py diff --git a/.github/workflows/github.yml b/.github/workflows/github.yml new file mode 100644 index 00000000..f0d78d15 --- /dev/null +++ b/.github/workflows/github.yml @@ -0,0 +1,37 @@ +name: Trgoman API CI + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + test: + 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.11" + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + + - name: Run lint + run: pip install flake8 && flake8 play.py + + - name: Run tests + run: pytest -v + + - name: Build Docker image + run: docker build -t translate-app . + + - name: Run Docker container + run: docker run --rm translate-app diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..79159af3 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,13 @@ +FROM python:3.11-slim + +WORKDIR /app + +# Install dependencies +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +# Copy project files +COPY . . + +# Default command: run tests +CMD ["pytest", "api"] diff --git a/__pycache__/api.cpython-312.pyc b/__pycache__/api.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..16b405011a4e40180a665b069ced799662e8f589 GIT binary patch literal 1530 zcmbtTO>7%Q6rSDLKmTRjCXIudkO(Tu3N?;HC8`J^P+R&#u_~OZl5b09o!Ho3Gdosm z%c(3B4!zJ+LQ2Gs6mdZ)Jp}boj=dluxWqK5+i4G$IQ8ZzJ@v$!wYPyB>Fmz?-n@D9 z_Pu%E{*g#T5scqEzbaaSkF5p380unIAdT&$;l9Y%{Fi~2lC6&N(aBL0?rGLj5*uuSUC8D>Of;esC>S0@B8yQH{Z3iNObxRsX`!}{%n0=sz7yM&`>SPz#X@^29%}p8Qc6Sn zt5Dkm|>v(%J&oDh^w6373n6Yc-qN70;5mBDO7qt7Z3^L%HfP zTC8zQozJ;ab3MlKl}|3wL*l#OViS)m%(>1im5QcNpdq5-s<>XW8^VDr#Adc9Y*S)9 zpGYsc6(>!drkxJ+2I8dcT5-D8;E@;A(Q!DV!}PuY(MH|jG5_#!f5_~{kNWYXpPF2| zar?%D)bWR@6P?tFzf$R~(R<@RkKcXuVdiWnb9N_lZaaS7kB|BBL&AUm9qAp34M%q) zNmFZ|dv*-P&0D8#p8ERq`r=OPjrN%*G4s~k&AC;wR=iz&5SwbB@ndHDqdmw1{fEDz zsDQsefU*XxCDLba!Ueq6f*&lpi4o&xJDhXUS?colq;XwoxkzHY9b{8LY@f4D)u$v!d1)<-r9Ti18Y_wSE&%!|LB z?3kDR_~BhFC!^hHY*&?&iEd&@V6ungNV2CPBl(gcFq(L4TTjsmNXf!=QI~)B(Te}$ zqc5q*l}?EbgB!r|y5ljAjtHwDIUNPTG5iI<{A MfM4)40l`QA0Y%1I@&Et; literal 0 HcmV?d00001 diff --git a/__pycache__/test_translate.cpython-312-pytest-8.4.1.pyc b/__pycache__/test_translate.cpython-312-pytest-8.4.1.pyc new file mode 100644 index 0000000000000000000000000000000000000000..538c312ef79b2e2e2d963aab6a23392b9f18ba47 GIT binary patch literal 2506 zcmeHJ%WoS+7@wJ4zrD_@c{I2Yl9l`8FJwehYKyZbOR>o$oT z5onM&`c@(J5Kbk^5s3qLPF#{ERotl%2Pz?MjslmQm~Yp+b_)Fm5NrE4-)m;R`S$z1 z@z08qM&ijo{%N@?A@mzC;S=i;$3F<-0Wy$*Eu><9B(_v07}>HK!+|EQ#(hmfO^A_L zNjs&cy1KNQ7Bb1o*jY7eE2<*ovJo?2Mq-I9;i~^pbCERJCmkTjOc|*i9Qb3TH_=Yl zHFfX>U8YYrw2F(_Kfv;45%XAG_sYvf!c(`X?l4RDOrG*0GEPm_uslvY%H>6!nLKvg zv@G|pq?q6S{^@4>(bKQi6l#9fFqy|nb(eYNu1CHz34tPl==et=eSo}3S0ldu6nJvT zhNo(xT0E5XMlG`QGNIJK1~H@^*h@U?*pSyr6F1478No?SiGAZKfexWsE~I*+5o<~n zY{X$sh3s^9FcRKSXj2;wsooey{4Qdnee0j;S%g#*hi9VwmSds5H})(YEcWkt{cpA; zT-8WEBx@p8>#~tD(oMOFeJ5lFR&32rpe0L$|{p0cs>=+#L-G1hs zfC<*P+|OKP5T_~sIhmPTc5QQxnrr&pEuAj8w(cx^dSlK%V^ou+`YInkErLLKu80+# z6{{7*kKGrrf&Pr6^KU(x{dV@?;!u^Jm_oCn(4G7Wr>_8&2RH}tDgdN6 zodS3bU>e}OfWAtiMZy20NW>1JNW>;3p%u3RVqXZ@K+mV&d})c?+mg48edPj_NMTnl zh!RovGKE7KzE1)^U?SWDX~6CGNKtYvHL{6_$8v#Q5MC6Ac`|HO{#p51Eog3~pr43_ zQ=;ZQT7~;L67fV==0}RhgDE^2-p5>NI8_gtMG0CJh1=181zghW)gZ?3e}+x~Tm*m) z;zwv3`JVZ)JW0N9yGFw@KcMdkJzV1Kp@5ErG5!^yO>|#*h6a8?g=Z-9J9@p7Mlq$G z%(k<`?V;h;$E|EfBBQyEBoCxJQhXrZk&@$N7makrP8ojE8hDA}(HJ6$jnDV-_z{WW ZbH@@Q6CI$A273w_Px*=?A}HVczX3It7xe%D literal 0 HcmV?d00001 diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000..2001f3e2 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +requests +pytest diff --git a/test_translate.py b/test_translate.py new file mode 100644 index 00000000..5f538041 --- /dev/null +++ b/test_translate.py @@ -0,0 +1,45 @@ +import pytest +import requests +from unittest.mock import patch +import json + +from api import Translate, translate + + +# Mock response data +mock_response_fa_en = { + "result": { + "tr": { + "base": [ + [0, "Hello"] + ] + } + } +} + +mock_response_en_fa = { + "result": { + "tr": { + "base": [ + [0, "سلام"] + ] + } + } +} + + +@patch("requests.post") +def test_translate_fa_to_en(mock_post): + # Mock the requests.post response + mock_post.return_value.text = json.dumps(mock_response_fa_en) + + result = Translate("سلام", "fa", "en") + assert result == "Hello" + + +@patch("requests.post") +def test_translate_en_to_fa(mock_post): + mock_post.return_value.text = json.dumps(mock_response_en_fa) + + result = Translate("Hello", "en", "fa") + assert result == "سلام" From 797229072e88c0d1624763e0368ccb97ec080b70 Mon Sep 17 00:00:00 2001 From: alireza parvaresh Date: Sat, 13 Sep 2025 23:56:18 +0330 Subject: [PATCH 3/7] apply black --- test_translate.py | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/test_translate.py b/test_translate.py index 5f538041..9d129ddd 100644 --- a/test_translate.py +++ b/test_translate.py @@ -7,25 +7,9 @@ # Mock response data -mock_response_fa_en = { - "result": { - "tr": { - "base": [ - [0, "Hello"] - ] - } - } -} - -mock_response_en_fa = { - "result": { - "tr": { - "base": [ - [0, "سلام"] - ] - } - } -} +mock_response_fa_en = {"result": {"tr": {"base": [[0, "Hello"]]}}} + +mock_response_en_fa = {"result": {"tr": {"base": [[0, "سلام"]]}}} @patch("requests.post") From 179280b586f008a27f2ebe1af4ac00bf5507589f Mon Sep 17 00:00:00 2001 From: alireza parvaresh Date: Sat, 13 Sep 2025 23:57:32 +0330 Subject: [PATCH 4/7] fix bugs --- .github/workflows/github.yml | 2 +- test_translate.py | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/github.yml b/.github/workflows/github.yml index f0d78d15..b10a50d8 100644 --- a/.github/workflows/github.yml +++ b/.github/workflows/github.yml @@ -25,7 +25,7 @@ jobs: pip install -r requirements.txt - name: Run lint - run: pip install flake8 && flake8 play.py + run: pip install flake8 && flake8 api.py - name: Run tests run: pytest -v diff --git a/test_translate.py b/test_translate.py index 9d129ddd..f223717c 100644 --- a/test_translate.py +++ b/test_translate.py @@ -1,9 +1,7 @@ -import pytest -import requests from unittest.mock import patch import json -from api import Translate, translate +from api import Translate # Mock response data From c0d6494dbea367491190b349144c913d2aed8f92 Mon Sep 17 00:00:00 2001 From: alireza parvaresh Date: Sun, 14 Sep 2025 00:09:16 +0330 Subject: [PATCH 5/7] Add igore for long line --- .github/workflows/github.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github.yml b/.github/workflows/github.yml index b10a50d8..99943e20 100644 --- a/.github/workflows/github.yml +++ b/.github/workflows/github.yml @@ -25,7 +25,7 @@ jobs: pip install -r requirements.txt - name: Run lint - run: pip install flake8 && flake8 api.py + run: pip install flake8 && flake8 --ignore=E501 api.py - name: Run tests run: pytest -v From a20fcba45f596df9492cd3339c1583bcaa7a16f6 Mon Sep 17 00:00:00 2001 From: alireza parvaresh Date: Sun, 14 Sep 2025 00:12:50 +0330 Subject: [PATCH 6/7] fix Docker file for test --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 79159af3..7bbad788 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,4 +10,4 @@ RUN pip install --no-cache-dir -r requirements.txt COPY . . # Default command: run tests -CMD ["pytest", "api"] +CMD ["pytest", "-v"] From ab3ad361d73f918e012676552473bc878da87aa6 Mon Sep 17 00:00:00 2001 From: alireza parvaresh Date: Sun, 14 Sep 2025 00:14:37 +0330 Subject: [PATCH 7/7] add readme file --- README.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..cb704552 --- /dev/null +++ b/README.md @@ -0,0 +1,35 @@ +# 🐍 Python Translator with CI/CD 🚀 + +This project is a simple **Python translator client** for the [Targoman API](https://targoman.ir), fully containerized with Docker and tested automatically using **GitHub Actions (CI/CD)**. + +--- + +## 📂 Project Structure +- `api.py` → Main code for translation +- `test_translate.py` → Unit tests (with pytest & mock) +- `Dockerfile` → Container setup +- `.github/workflows/ci.yml` → CI/CD pipeline + +--- + +## ⚡ Features +- ✅ Translation (fa → en / en → fa) +- ✅ Unit tests with `pytest` +- ✅ Linting with `flake8` +- ✅ Dockerized environment +- ✅ GitHub Actions CI/CD + +--- + +## 🔧 Run Locally + +```bash +# Create venv +python -m venv .venv +source .venv/bin/activate + +# Install dependencies +pip install -r requirements.txt + +# Run tests +pytest -v