diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..a3da812 Binary files /dev/null and b/.DS_Store differ diff --git a/.gitignore b/.gitignore index 68bc17f..41a6c14 100644 --- a/.gitignore +++ b/.gitignore @@ -48,7 +48,7 @@ coverage.xml *.cover *.py,cover .hypothesis/ -.pytest_cache/ +.pytest_cache cover/ # Translations @@ -158,3 +158,9 @@ cython_debug/ # and can be added to the global gitignore or merged into this file. For a more nuclear # option (not recommended) you can uncomment the following to ignore the entire idea folder. #.idea/ + +# macOS +.DS_Store + +# Visual Studio Code +.vscode/ \ No newline at end of file diff --git a/README.md b/README.md index 2ebc258..470b991 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,45 @@ # liftwing-python -This project involves building a python package that can act as a model registry for the machine learning models deployed on Lift Wing.
A model registry acts as the source of truth for the deployed models and their versions offering two main benefits: -* Versioning and tracking of models: this allows an easier access to model version and tracking -* Collaboration and reproducibility: in order to download a model the user only needs to interact with the registry. -Implementation Proposal
A python package that allows that has different install options according to the model as each model server has different package requirements. The user, after installing the package, will be able to load a Lift Wing model and make predictions.
Taking into consideration the short duration of the internship as well as the fact that we want the person to get to know the Wikimedia community, our way of working as well as get the chance to study and dive into technical topics, the package will first deal with 1-2 models in order to create a complete proof of concept for this work. Also, to avoid blocking this work by other systems/factors or permissions it will be based on our public interfaces:
The python package will have a repository on GitHub with CI/CD setup using Github Actions that will automatically upload the python package to the PyPI repository.
Models for the packages will be fetched by the public analytics repository https://analytics.wikimedia.org/published/wmf-ml-models/ -There will be two modes of operation for each model: -* Offline: the user can download and load the model and start making predictions with it. This is particularly useful for experimentation or in the case when someone wants to make a big number of batch requests that would otherwise fail due to rate limiting. -* Online: The user can make requests to the public APIs (Lift Wing API Gateway) using the package as a client. -Notes/Considerations: -* We would have to figure out a (nice) way to integrate this with the deployment charts repo in order to get the model version we need to deploy. -* Model’s python dependencies: Each model has been developed separately and may require different python libraries and versions. This means that the python package should have different installation options which will reflect the dependencies of a specific model. +This is a Python package that acts as a client and allows users to make requests to the LiftWing API. +Its purpose is to allow users to interact with the API by writing python code instead of manipulating HTTP requests. + +Below is an example of how to make a request. This specific request is being made to the revert_risk API + +import json +import requests + +def revert_risk_api_request(language: str, revision_id: int): + """ + This function makes a request to the RevertRisk API. It takes in two parameters, language and revision_id. Language is the language of the wiki article. + revision_id is the specific version of the article. + """ + if language is None or revision_id is None: + raise ValueError("Both 'language' and 'revision_id' parameters are required.") # this checks if there is a language and rev_id, if not an error is thrown + + + use_auth = False + inference_url = f"https://api.wikimedia.org/service/lw/inference/v1/models/{language}-reverted:predict" # this is the API endpoint + if use_auth: + headers = { + 'Authorization': f'Bearer {access_token}', + 'User-Agent': user_agent, + 'Content-type': 'application/json' + } # headers is a dictionary used to make a HTTP request + else: + headers = {} + + data = {"rev_id": revision_id} + response = requests.post(inference_url, headers=headers, data=json.dumps(data)) # POST request is being made + if response.status_code == 200: + return response.json() # request was successful so return the response + else: + response.status_code == 400 + raise ValueError(f"Unexpected error occurred: {response.status_code}") + + +language = "viwiki" # language has to be in this format, enwiki, arwiki etc... +revision_id = 12345 # rev_id has to be a valid integer, different rev_id gives different response + +response = revert_risk_api_request(language, revision_id) + +print(response) \ No newline at end of file diff --git a/examples/__init__.py b/examples/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/examples/revertrisk_examples.py b/examples/revertrisk_examples.py new file mode 100644 index 0000000..1ca1380 --- /dev/null +++ b/examples/revertrisk_examples.py @@ -0,0 +1,38 @@ +import json +import requests + +def revert_risk_api_request(language: str, revision_id: int): + """ + This function makes a request to the RevertRisk API. It takes in two parameters, language and revision_id. Language is the language of the wiki article. + revision_id is the specific version of the article. + """ + if language is None or revision_id is None: + raise ValueError("Both 'language' and 'revision_id' parameters are required.") # this checks if there is a language and rev_id, if not an error is thrown + + + use_auth = False + inference_url = f"https://api.wikimedia.org/service/lw/inference/v1/models/{language}-reverted:predict" # this is the API endpoint + if use_auth: + headers = { + 'Authorization': f'Bearer {access_token}', + 'User-Agent': user_agent, + 'Content-type': 'application/json' + } # headers is a dictionary used to make a HTTP request + else: + headers = {} + + data = {"rev_id": revision_id} + response = requests.post(inference_url, headers=headers, data=json.dumps(data)) # POST request is being made + if response.status_code == 200: + return response.json() # request was successful so return the response + else: + response.status_code == 400 + raise ValueError(f"Unexpected error occurred: {response.status_code}") + + +language = "viwiki" # language has to be in this format, enwiki, arwiki etc... +revision_id = 12345 # rev_id has to be a valid integer, different rev_id gives different response + +response = revert_risk_api_request(language, revision_id) + +print(response) \ No newline at end of file diff --git a/liftwing/models/draftTopic.py b/liftwing/models/draftTopic.py new file mode 100644 index 0000000..95de264 --- /dev/null +++ b/liftwing/models/draftTopic.py @@ -0,0 +1,45 @@ +import requests +import json +from liftwing_model import LiftwingModel +from typing import Any, Dict + +class DraftTopicModel(LiftwingModel): + def __init__(self, base_url="https://api.wikimedia.org/service/lw/inference/v1/models/{language}-drafttopic:predict"): + super().__init__(base_url) + # base url is super because every class that inherits this from the base model will be using it + + def request(self, payload: Dict[str, Any], method: str = "POST", headers: Dict[str, str] = None) -> Dict[str, Any]: + """ + This function makes a POST request to https://api.wikimedia.org/service/lw/inference/v1/models/enwiki-drafttopic:predict + using the language parameter and returns a JSON + language is for the different wiki languages, rev_id is the specific revisions + """ + if revision_id is None: + raise ValueError("'revision_id' parameter required.") + + use_auth = False + inference_url = f"https://api.wikimedia.org/service/lw/inference/v1/models/enwiki-drafttopic:predict" + + if use_auth: + headers = { + 'Authorization': f'Bearer {self.access_token}', # Assuming access_token is an attribute of class + 'User-Agent': self.user_agent, # Assuming user_agent is an attribute of class + 'Content-type': 'application/json' + } + else: + headers = {} + + data = {"rev_id": revision_id} + response = requests.post(inference_url, headers=headers, data=json.dumps(data)) + + if response.status_code == 200: + return response.json() + else: + response.status_code == 400 + raise ValueError(f"Unexpected error occurred: {response.status_code}") + +draftTopic = DraftTopicModel() + +jsonresponse = draftTopic.request(revision_id=12345) + +print(jsonresponse) \ No newline at end of file diff --git a/liftwing/models/readability.py b/liftwing/models/readability.py new file mode 100644 index 0000000..95a7ca3 --- /dev/null +++ b/liftwing/models/readability.py @@ -0,0 +1,27 @@ +import requests +from .liftwing_model import LiftwingModel +from typing import Any, Dict + + +class ReadabilityAPIModel(LiftwingModel): + def __init__(self, base_url="https://api.wikimedia.org/service/lw/inference/v1/models/readability:predict"): + super().__init__(base_url) + + def request(self, payload: Dict[str, Any], method: str = "POST", headers: Dict[str, str] = None) -> Dict[str, Any]: + """ + This function makes a POST request to https://api.wikimedia.org/service/lw/inference/v1/models/readability:predict + using the language parameter and returns a JSON + language is for the different wiki languages, rev_id is the specific revisions + """ + language = payload.get("lang") + if language is None: + raise ValueError("'lang' parameter is required in the payload.") + rev_id = payload.get("rev_id") + if rev_id is None: + raise ValueError("rev_id is none, add revision id to continue") + + if headers is None: + headers = {} + + response = requests.post(self.base_url, json=payload, headers=headers) + return response.json() diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..342703b --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,16 @@ +[project] +name = "liftwing-python" +version = "0.1.0" +authors = [ + {name = "Mercelis Vaughan", email = "mercelisvaughan@gmail.com"}, +] +description = "Users will be able to retrieve JSON responses from their respective wiki APIs" +readme = "README.md" +requires-python = ">=3.8" +classifiers = [ + "Programming Language :: Python :: 3", +] +dependencies = [ + "requests", +] +dynamic = ["version"] \ No newline at end of file diff --git a/src/liftwing_api/__init__.py b/src/liftwing_api/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/liftwing_api/models/__init__.py b/src/liftwing_api/models/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/liftwing_api/models/articletopic.py b/src/liftwing_api/models/articletopic.py new file mode 100644 index 0000000..df5dd3f --- /dev/null +++ b/src/liftwing_api/models/articletopic.py @@ -0,0 +1,30 @@ +import json +import requests +from liftwing_api.models.liftwing_model import LiftwingModel +from typing import Any, Dict + +class ArticleTopic(LiftwingModel): + + def __init__(self, base_url="https://api.wikimedia.org/service/lw/inference/v1/models/outlink-topic-model:predict"): + super().__init__(base_url) + # base url is super because every class that inherits this from the base model will be using it + + def request(self, method: str = "POST", headers: Dict[str, str] = None) -> Dict[str, Any]: + """ + This function makes a POST request to https://api.wikimedia.org/service/lw/inference/v1/models/langid:predict + using the language parameter and returns a JSON. + The language parameter is for the different wiki languages, and rev_id is for specific revisions. + """ + url = "https://api.wikimedia.org/service/lw/inference/v1/models/langid:predict" + + if headers is None: + headers = {} + + data = {"text": "Some sample text in any language that we want to identify"} + + response = requests.post(url, headers=headers, data=json.dumps(data)) + + if response.status_code == 200: + return response.json() + else: + raise ValueError(f"Unexpected error occurred: {response.status_code}") \ No newline at end of file diff --git a/src/liftwing_api/models/draftQuality.py b/src/liftwing_api/models/draftQuality.py new file mode 100644 index 0000000..6f0535c --- /dev/null +++ b/src/liftwing_api/models/draftQuality.py @@ -0,0 +1,35 @@ +import json +import requests +from liftwing_api.models.liftwing_model import LiftwingModel +from typing import Any, Dict + +class DraftQuality(LiftwingModel): + def __init__(self, base_url="https://api.wikimedia.org/service/lw/inference/v1/models/enwiki-draftquality:predict"): + super().__init__(base_url) + + def request(self, revision_id: int, headers: Dict[str, str] = None) -> Dict[str, Any]: + """ + This function makes a POST request to https://api.wikimedia.org/service/lw/inference/v1/models/enwiki-draftquality:predict + using the revision_id parameter and returns a JSON. + + How to use: + rev = DraftQuality() + jsonresponse = rev.request(revision_id=12345) + print(jsonresponse) + + """ + if headers is None: + headers = {} + + data = {"rev_id": revision_id} + + response = requests.post(self.base_url, headers=headers, data=json.dumps(data)) + + if response.status_code == 200: + return response.json() + else: + raise ValueError(f"Unexpected error occurred: {response.status_code}") + +rev = DraftQuality() +jsonresponse = rev.request(revision_id=12345) +print(jsonresponse) \ No newline at end of file diff --git a/src/liftwing_api/models/draftTopic.py b/src/liftwing_api/models/draftTopic.py new file mode 100644 index 0000000..e016e59 --- /dev/null +++ b/src/liftwing_api/models/draftTopic.py @@ -0,0 +1,38 @@ +import json +import requests +from liftwing_api.models.liftwing_model import LiftwingModel +from typing import Any, Dict + + +class DraftTopicModel(LiftwingModel): + def __init__(self, language: str = "enwiki", base_url: str = "https://api.wikimedia.org/service/lw/inference/v1/models/{language}-drafttopic:predict"): + super().__init__(base_url.format(language=language)) + self.language = language + + def request(self, revision_id: int, headers: Dict[str, str] = None) -> Dict[str, Any]: + """ + This function makes a POST request to https://api.wikimedia.org/service/lw/inference/v1/models/{language}-drafttopic:predict + using the revision_id parameter and returns a JSON. + + Example: + + draftTopic = DraftTopicModel() + jsonresponse = draftTopic.request(revision_id=12345) + print(jsonresponse) + + + """ + if revision_id is None: + raise ValueError("'revision_id' parameter required.") + + if headers is None: + headers = {} + + data = {"rev_id": revision_id} + + response = requests.post(self.base_url, headers=headers, data=json.dumps(data)) + + if response.status_code == 200: + return response.json() + else: + raise ValueError(f"Unexpected error occurred: {response.status_code}") \ No newline at end of file diff --git a/src/liftwing_api/models/langid.py b/src/liftwing_api/models/langid.py new file mode 100644 index 0000000..14f9606 --- /dev/null +++ b/src/liftwing_api/models/langid.py @@ -0,0 +1,31 @@ +import requests +from liftwing_api.models.liftwing_model import LiftwingModel +from typing import Any, Dict +import json + +class LanguageAPIModel(LiftwingModel): + def __init__(self, base_url="https://api.wikimedia.org/service/lw/inference/v1/models/langid:predict"): + super().__init__(base_url) + + def request(self, text: str, headers: Dict[str, str] = None) -> Dict[str, Any]: + """ + This function makes a POST request to https://api.wikimedia.org/service/lw/inference/v1/models/langid:predict + using the provided text parameter and returns a JSON. + """ + if headers is None: + headers = {} + + data = {"text": text} + + response = requests.post(self.base_url, headers=headers, data=json.dumps(data)) + + if response.status_code == 200: + return response.json() + else: + raise ValueError(f"Unexpected error occurred: {response.status_code}") + +lang = LanguageAPIModel() + +jsonresponse = lang.request("Some sample text in any language that we want to identify") + +print(jsonresponse) \ No newline at end of file diff --git a/src/liftwing_api/models/liftwing_model.py b/src/liftwing_api/models/liftwing_model.py new file mode 100644 index 0000000..8af1f77 --- /dev/null +++ b/src/liftwing_api/models/liftwing_model.py @@ -0,0 +1,38 @@ +import requests +import json + +class LiftwingModel: + def __init__(self, base_url): + self.base_url = base_url + # bare url + + def request(self, endpoint_url: str, revision_id: int): + """ + Makes a POST request to the specified endpoint URL using the given revision ID. + """ + if revision_id is None: + raise ValueError("revision_id parameter required.") + + use_auth = False + + if use_auth: + headers = { + 'Authorization': f'Bearer {self.access_token}', + 'User-Agent': self.user_agent, + 'Content-type': 'application/json' + } + else: + headers = {} + + data = {"rev_id": revision_id} + response = requests.post(endpoint_url, headers=headers, data=json.dumps(data)) + + if response.status_code == 200: + try: + json_response = response.json() + except json.JSONDecodeError: + raise ValueError("Response content is not in JSON format.") + + return json_response + else: + raise ValueError(f"Unexpected error occurred: {response.status_code}") diff --git a/src/liftwing_api/models/readability.py b/src/liftwing_api/models/readability.py new file mode 100644 index 0000000..535e887 --- /dev/null +++ b/src/liftwing_api/models/readability.py @@ -0,0 +1,33 @@ +import requests +import json +from liftwing_api.models.liftwing_model import LiftwingModel +from typing import Any, Dict + +class ReadabilityModel(LiftwingModel): + def __init__(self, language: str, base_url="https://api.wikimedia.org/service/lw/inference/v1/models/enwiki-readability:predict"): + super().__init__(base_url.format(language=language)) + self.language = language + + def request(self, revision_id: int, headers: Dict[str, str] = None) -> Dict[str, Any]: + """ + This function makes a POST request to https://api.wikimedia.org/service/lw/inference/v1/models/{language}readability:predict + using the provided revision_id parameter and returns a JSON. + """ + if revision_id is None: + raise ValueError("'revision_id' parameter required.") + + if headers is None: + headers = {} + + data = {"rev_id": revision_id} + + response = requests.post(self.base_url, headers=headers, data=json.dumps(data)) + + if response.status_code == 200: + return response.json() + else: + raise ValueError(f"Unexpected error occurred: {response.status_code}") + +readability_model = ReadabilityModel(language="enwiki") +json_response = readability_model.request(revision_id=12345) +print(json_response) \ No newline at end of file diff --git a/src/liftwing_api/models/revScoreGoodfaith.py b/src/liftwing_api/models/revScoreGoodfaith.py new file mode 100644 index 0000000..9ebeeef --- /dev/null +++ b/src/liftwing_api/models/revScoreGoodfaith.py @@ -0,0 +1,35 @@ +import requests +from liftwing_api.models.liftwing_model import LiftwingModel +from typing import Any, Dict +import json + +class RevScoreGoodFaith(LiftwingModel): + def __init__(self, base_url="https://api.wikimedia.org/service/lw/inference/v1/models/enwiki-goodfaith:predict"): + super().__init__(base_url) + + def request(self, revision_id: int, headers: Dict[str, str] = None) -> Dict[str, Any]: + """ + This function makes a POST request to https://api.wikimedia.org/service/lw/inference/v1/models/enwiki-goodfaith:predict + using the provided revision_id parameter and returns a JSON. + + Example: + rev = RevScoreGoodFaith() + jsonresponse = rev.request(revision_id=12345) + print(jsonresponse) + + """ + if revision_id is None: + raise ValueError("'revision_id' parameter required.") + + if headers is None: + headers = {} + + data = {"rev_id": revision_id} + + response = requests.post(self.base_url, headers=headers, data=json.dumps(data)) + + if response.status_code == 200: + return response.json() + else: + raise ValueError(f"Unexpected error occurred: {response.status_code}") + \ No newline at end of file diff --git a/src/liftwing_api/models/revertRiskMultilingual.py b/src/liftwing_api/models/revertRiskMultilingual.py new file mode 100644 index 0000000..500f0f6 --- /dev/null +++ b/src/liftwing_api/models/revertRiskMultilingual.py @@ -0,0 +1,34 @@ +import json +import requests +from liftwing_api.models.liftwing_model import LiftwingModel +from typing import Any, Dict + +class RevertRiskMultilingual(LiftwingModel): + def __init__(self, base_url="https://api.wikimedia.org/service/lw/inference/v1/models/revertrisk-multilingual:predict"): + super().__init__(base_url) + + def request(self, text: str, headers: Dict[str, str] = None) -> Dict[str, Any]: + """ + This function makes a POST request to https://api.wikimedia.org/service/lw/inference/v1/models/revertrisk-multilingual:predict + using the provided text parameter and returns a JSON. + """ + if not text: + raise ValueError("'text' parameter required.") + + if headers is None: + headers = {} + + data = {"text": text} + + response = requests.post(self.base_url, headers=headers, data=json.dumps(data)) + + if response.status_code == 200: + return response.json() + else: + # Print the response content for debugging + print(f"Error response content: {response.content.decode('utf-8')}") + raise ValueError(f"Unexpected error occurred: {response.status_code}") + +revert_risk_multilingual = RevertRiskMultilingual() +json_response = revert_risk_multilingual.request(text="Some sample text in any language that we want to analyze for revert risk.") +print(json_response) \ No newline at end of file diff --git a/src/liftwing_api/models/revertrisk.py b/src/liftwing_api/models/revertrisk.py new file mode 100644 index 0000000..01ba2a2 --- /dev/null +++ b/src/liftwing_api/models/revertrisk.py @@ -0,0 +1,28 @@ +import requests +from .liftwing_model import LiftwingModel +from typing import Any, Dict + + +class RevertRiskAPIModel(LiftwingModel): + def __init__(self, base_url="https://api.wikimedia.org/service/lw/inference/v1/models/revertrisk-language-agnostic:predict"): + super().__init__(base_url) + + def request(self, payload: Dict[str, Any], method: str = "POST", headers: Dict[str, str] = None) -> Dict[str, Any]: + """ + This function makes a POST request to https://api.wikimedia.org/service/lw/inference/v1/models/revertrisk-language-agnostic:predict + using the language parameter and returns a JSON + language is for the different wiki languages, rev_id is the specific revisions + """ + language = payload.get("lang") + if language is None: + raise ValueError("'lang' parameter is required in the payload.") + rev_id = payload.get("rev_id") + if rev_id is None: + raise ValueError("rev_id is none, add revision id to continue") + + if headers is None: + headers = {} + + response = requests.post(self.base_url, json=payload, headers=headers) + + return response.json() \ No newline at end of file diff --git a/src/liftwing_api/models/revscoredamaging.py b/src/liftwing_api/models/revscoredamaging.py new file mode 100644 index 0000000..5224131 --- /dev/null +++ b/src/liftwing_api/models/revscoredamaging.py @@ -0,0 +1,36 @@ +from liftwing_api.models.liftwing_model import LiftwingModel +from typing import Any, Dict +import json +import requests + +class RevScoreDamaging(LiftwingModel): + def __init__(self, base_url="https://api.wikimedia.org/service/lw/inference/v1/models/enwiki-damaging:predict"): + super().__init__(base_url) + + def request(self, revision_id: int, headers: Dict[str, str] = None) -> Dict[str, Any]: + """ + This function makes a POST request to https://api.wikimedia.org/service/lw/inference/v1/models/enwiki-damaging:predict + using the provided revision_id parameter and returns a JSON. + + Example: + + rev_score_damaging = RevScoreDamaging() + json_response = rev_score_damaging.request(revision_id=12345) + print(json_response) + + """ + if revision_id is None: + raise ValueError("'revision_id' parameter required.") + + if headers is None: + headers = {} + + data = {"rev_id": revision_id} + + response = requests.post(self.base_url, headers=headers, data=json.dumps(data)) + + if response.status_code == 200: + return response.json() + else: + raise ValueError(f"Unexpected error occurred: {response.status_code}") + \ No newline at end of file diff --git a/src/liftwing_api/models/revscoring.py b/src/liftwing_api/models/revscoring.py new file mode 100644 index 0000000..1410896 --- /dev/null +++ b/src/liftwing_api/models/revscoring.py @@ -0,0 +1,35 @@ +import json +import requests +from liftwing_api.models.liftwing_model import LiftwingModel +from typing import Any, Dict + +class Revscoring(LiftwingModel): + def __init__(self, language: str, base_url="https://api.wikimedia.org/service/lw/inference/v1/models/enwiki-reverted:predict"): + super().__init__(base_url.format(language=language)) + self.language = language + + def request(self, revision_id: int, headers: Dict[str, str] = None) -> Dict[str, Any]: + """ + This function makes a POST request to https://api.wikimedia.org/service/lw/inference/v1/models/{language}-goodfaith:predict + using the provided revision_id parameter and returns a JSON. + """ + if revision_id is None: + raise ValueError("'revision_id' parameter required.") + + if headers is None: + headers = {} + + data = {"rev_id": revision_id} + + response = requests.post(self.base_url, headers=headers, data=json.dumps(data)) + + if response.status_code == 200: + return response.json() + else: + raise ValueError(f"Unexpected error occurred: {response.status_code}") + +rev = Revscoring(language="enwiki") + +jsonresponse = rev.request(revision_id=12345) + +print(jsonresponse) \ No newline at end of file diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/models/revertriskTest.py b/tests/models/revertriskTest.py new file mode 100644 index 0000000..f263424 --- /dev/null +++ b/tests/models/revertriskTest.py @@ -0,0 +1,12 @@ +import unittest +from unittest.mock import patch +from src.liftwing_api.models import revertrisk + +@patch('examples.revertrisk_examples.requests.post') +def test_revert_risk_example_test_200(self, mock_post): + mock_post.return_value.status_code = 200 + mock_post.return_value.json.return_value = {'key': 'value'} + + expectedResult = ("enwiki", 12345) + + self.assertEqual(expectedResult, {'key': 'value'}) \ No newline at end of file diff --git a/tests/revertrisk_examplestest.py b/tests/revertrisk_examplestest.py new file mode 100644 index 0000000..5b8ebdf --- /dev/null +++ b/tests/revertrisk_examplestest.py @@ -0,0 +1,36 @@ +import unittest +from unittest.mock import patch +from examples.revertrisk_examples import revert_risk_api_request + + +class RevertRisk_ExamplesTest(unittest.TestCase): + + @patch('examples.revertrisk_examples.requests.post') + def test_revert_risk_example_test_200(self, mock_post): + mock_post.return_value.status_code = 200 + mock_post.return_value.json.return_value = {'key': 'value'} + + expectedResult = revert_risk_api_request("en", 12345) + + self.assertEqual(expectedResult, {'key': 'value'}) + + @patch('examples.revertrisk_examples.requests.post') + def test_revert_risk_api_request_failure(self, mock_post): + mock_post.return_value.status_code = 400 + + with self.assertRaises(ValueError): + revert_risk_api_request("en", 12345) + + @patch('examples.revertrisk_examples.requests.post') + def test_revert_risk_api_request_empty_response(self, mock_post): + # mocks a 200 response + mock_post.return_value.status_code = 200 + # mocks an empty response + mock_post.return_value.json.return_value = {} + # result is the json response + result = revert_risk_api_request("en", 12345) + #check if response is empty + self.assertEqual(result, {}) + +if __name__ == '__main__': + unittest.main()