From a5ab4272bc729d137c9d3ac59ff706d75da58e86 Mon Sep 17 00:00:00 2001 From: Vadzim Verhasau Date: Tue, 23 Mar 2021 21:18:48 +0300 Subject: [PATCH] Small fixes (#14) * Linted with black * Bump isort from 5.7.0 to 5.8.0 (#12) * Updated cache in workflows * Reusing code for checking user * Added dependabot workflow * Added GitHub actions to dependabot * Added Github QL checking * Added error info in get_response * More info added on JSONDecodeError exception * Updated version --- .github/dependabot.yml | 25 ++++++++++++++ .github/workflows/codeql-analysis.yml | 33 ++++++++++++++++++ .github/workflows/codestyle.yml | 2 -- .github/workflows/publish.yml | 6 ++-- codeforces_api/__init__.py | 2 +- codeforces_api/api_request_maker.py | 9 ++--- codeforces_api/api_requests.py | 10 +++--- codeforces_api/parse_methods.py | 1 + codeforces_api/version.py | 2 +- requirements.txt | 2 +- tests/conftest.py | 26 +++++++++++++++ tests/test_api.py | 48 ++++----------------------- 12 files changed, 108 insertions(+), 58 deletions(-) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/codeql-analysis.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..d99b703 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,25 @@ +version: 2 +updates: + - package-ecosystem: pip + directory: "/" + schedule: + interval: daily + target-branch: develop + reviewers: + - VadVergasov + assignees: + - VadVergasov + allow: + - dependency-type: direct + - dependency-type: indirect + ignore: + - dependency-name: "idna" + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: daily + target-branch: develop + reviewers: + - VadVergasov + assignees: + - VadVergasov diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 0000000..84611e8 --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,33 @@ +name: "CodeQL" + +on: + push: + branches: + - master + - develop + pull_request: + branches: + - master + - develop + schedule: + - cron: "0 0 * * *" + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + language: ["python"] + steps: + - name: Checkout repository + uses: actions/checkout@v2 + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: ${{ matrix.language }} + - name: Autobuild + uses: github/codeql-action/autobuild@v1 + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 diff --git a/.github/workflows/codestyle.yml b/.github/workflows/codestyle.yml index 2bca66f..701c288 100644 --- a/.github/workflows/codestyle.yml +++ b/.github/workflows/codestyle.yml @@ -24,8 +24,6 @@ jobs: with: path: ~/.cache/pip key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }} - restore-keys: | - ${{ runner.os }}-pip- - name: Install dependencies run: | python -m pip install --upgrade pip diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 16cbac6..00eb41e 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -5,6 +5,8 @@ on: branches: - master - develop + tags: + - "*" pull_request: branches: - master @@ -17,6 +19,8 @@ jobs: matrix: python-version: [3.6, 3.7, 3.8, 3.9] steps: + - name: Print Github refs + run: echo ${{github.ref}} - uses: actions/checkout@v2 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v2 @@ -27,8 +31,6 @@ jobs: with: path: ~/.cache/pip key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }} - restore-keys: | - ${{ runner.os }}-pip- - name: Install dependencies run: | python -m pip install --upgrade pip wheel diff --git a/codeforces_api/__init__.py b/codeforces_api/__init__.py index 8d49965..d14a144 100644 --- a/codeforces_api/__init__.py +++ b/codeforces_api/__init__.py @@ -15,7 +15,7 @@ along with this program. If not, see . """ __all__ = ["CodeforcesApi", "CodeforcesApiRequestMaker", "CodeforcesParser"] -from codeforces_api.api_requests import CodeforcesApi from codeforces_api.api_request_maker import CodeforcesApiRequestMaker +from codeforces_api.api_requests import CodeforcesApi from codeforces_api.parse_methods import CodeforcesParser from codeforces_api.types import * diff --git a/codeforces_api/api_request_maker.py b/codeforces_api/api_request_maker.py index bbb0f31..178dae5 100644 --- a/codeforces_api/api_request_maker.py +++ b/codeforces_api/api_request_maker.py @@ -14,11 +14,11 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . """ -import random -import time -import hashlib import collections +import hashlib import json +import random +import time class CodeforcesApiRequestMaker: @@ -116,5 +116,6 @@ def get_response(self, request): return response["result"] except json.decoder.JSONDecodeError as error: raise ValueError( - "A lot of users, try to reduce the number of users in the list" + "A lot of users, try to reduce the number of users in the list.\nError: %s.\nResponse text: %s" + % (str(error), request.text) ) diff --git a/codeforces_api/api_requests.py b/codeforces_api/api_requests.py index a31906c..33e21c9 100644 --- a/codeforces_api/api_requests.py +++ b/codeforces_api/api_requests.py @@ -18,17 +18,17 @@ from codeforces_api.api_request_maker import CodeforcesApiRequestMaker from codeforces_api.types import ( - User, BlogEntry, Comment, - RecentAction, - RatingChange, Contest, + Hack, Problem, ProblemStatistic, - Submission, - Hack, RanklistRow, + RatingChange, + RecentAction, + Submission, + User, ) diff --git a/codeforces_api/parse_methods.py b/codeforces_api/parse_methods.py index d459d71..6a374b5 100644 --- a/codeforces_api/parse_methods.py +++ b/codeforces_api/parse_methods.py @@ -16,6 +16,7 @@ """ import requests from lxml import html + from codeforces_api.api_requests import CodeforcesApi diff --git a/codeforces_api/version.py b/codeforces_api/version.py index ff6ef86..962c851 100644 --- a/codeforces_api/version.py +++ b/codeforces_api/version.py @@ -1 +1 @@ -__version__ = "2.0.6" +__version__ = "2.0.7" diff --git a/requirements.txt b/requirements.txt index 3c08442..a82ce15 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,7 +12,7 @@ docutils==0.16 idna==2.10 importlib-metadata==3.7.3 iniconfig==1.1.1 -isort==5.7.0 +isort==5.8.0 keyring==23.0.0 lazy-object-proxy==1.5.2 lxml==4.6.2 diff --git a/tests/conftest.py b/tests/conftest.py index 57ba6c2..ac13b07 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -27,3 +27,29 @@ def api_key(request): @pytest.fixture def api_secret(request): return request.config.getoption("--api_secret") + + +@pytest.fixture +def check_user(): + def check(user): + assert user.email is None or isinstance(user.email, str) + assert user.open_id is None or isinstance(user.open_id, str) + assert user.first_name is None or isinstance(user.first_name, str) + assert user.last_name is None or isinstance(user.last_name, str) + assert user.country is None or isinstance(user.country, str) + assert user.vk_id is None or isinstance(user.vk_id, str) + assert user.country is None or isinstance(user.country, str) + assert user.city is None or isinstance(user.city, str) + assert user.organization is None or isinstance(user.organization, str) + assert isinstance(user.contribution, int) + assert user.rank is None or isinstance(user.rank, str) + assert user.rating is None or isinstance(user.rating, int) + assert user.max_rank is None or isinstance(user.max_rank, str) + assert user.max_rating is None or isinstance(user.max_rating, int) + assert isinstance(user.last_online, int) + assert isinstance(user.registration_time_seconds, int) + assert isinstance(user.friend_of_count, int) + assert isinstance(user.avatar, str) + assert isinstance(user.title_photo, str) + + return check diff --git a/tests/test_api.py b/tests/test_api.py index 9f015eb..2637d9e 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -270,54 +270,18 @@ def test_user_friends(api_key, api_secret): assert "aropan" in friends or "gepardo" in friends -def test_user_info(api_key, api_secret): +def test_user_info(api_key, api_secret, check_user): api = CodeforcesApi(api_key, api_secret) info = api.user_info(["VadVergasov", "tourist"]) for user in info: - assert user.email is None or isinstance(user.email, str) - assert user.open_id is None or isinstance(user.open_id, str) - assert user.first_name is None or isinstance(user.first_name, str) - assert user.last_name is None or isinstance(user.last_name, str) - assert user.country is None or isinstance(user.country, str) - assert user.vk_id is None or isinstance(user.vk_id, str) - assert user.country is None or isinstance(user.country, str) - assert user.city is None or isinstance(user.city, str) - assert user.organization is None or isinstance(user.organization, str) - assert isinstance(user.contribution, int) - assert user.rank is None or isinstance(user.rank, str) - assert user.rating is None or isinstance(user.rating, int) - assert user.max_rank is None or isinstance(user.max_rank, str) - assert user.max_rating is None or isinstance(user.max_rating, int) - assert isinstance(user.last_online, int) - assert isinstance(user.registration_time_seconds, int) - assert isinstance(user.friend_of_count, int) - assert isinstance(user.avatar, str) - assert isinstance(user.title_photo, str) - - -def test_user_rated_list(): + check_user(user) + + +def test_user_rated_list(check_user): api = CodeforcesApi() users = api.user_rated_list(True) for user in users: - assert user.email is None or isinstance(user.email, str) - assert user.open_id is None or isinstance(user.open_id, str) - assert user.first_name is None or isinstance(user.first_name, str) - assert user.last_name is None or isinstance(user.last_name, str) - assert user.country is None or isinstance(user.country, str) - assert user.vk_id is None or isinstance(user.vk_id, str) - assert user.country is None or isinstance(user.country, str) - assert user.city is None or isinstance(user.city, str) - assert user.organization is None or isinstance(user.organization, str) - assert isinstance(user.contribution, int) - assert user.rank is None or isinstance(user.rank, str) - assert user.rating is None or isinstance(user.rating, int) - assert user.max_rank is None or isinstance(user.max_rank, str) - assert user.max_rating is None or isinstance(user.max_rating, int) - assert isinstance(user.last_online, int) - assert isinstance(user.registration_time_seconds, int) - assert isinstance(user.friend_of_count, int) - assert isinstance(user.avatar, str) - assert isinstance(user.title_photo, str) + check_user(user) def test_user_rating():