From 27009c6141236b6b2a3a4103733ac202f2868b24 Mon Sep 17 00:00:00 2001 From: Ivan Ogasawara Date: Sat, 12 Aug 2023 10:55:27 -0400 Subject: [PATCH] fix issues pointed by the linter --- .pre-commit-config.yaml | 10 +------ pyproject.toml | 6 ++++ src/cf_warning/__init__.py | 3 +- src/cf_warning/main.py | 11 ++----- src/cf_warning/reader.py | 59 +++++++------------------------------- src/cf_warning/report.py | 20 +++++++------ tests/test_cf_warning.py | 3 +- 7 files changed, 36 insertions(+), 76 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a3356cf9..7e653597 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -8,14 +8,6 @@ repos: - repo: local hooks: - # NOTE: This is a total unnecessary check, just used as part of the - # template. Remove this after creating the template. - - id: check-python - name: check-python - entry: python --version - language: system - pass_filenames: no - - id: black name: black entry: black @@ -75,7 +67,7 @@ repos: - id: vulture name: vulture - entry: vulture + entry: vulture --min-confidence 80 language: system files: "./" description: Find unused Python code. diff --git a/pyproject.toml b/pyproject.toml index 09f24f17..54c0eb19 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -98,3 +98,9 @@ convention = "numpy" [tool.mypy] no_strict_optional = false + +[[tool.mypy.overrides]] +module = [ + "pandas", +] +ignore_missing_imports = true diff --git a/src/cf_warning/__init__.py b/src/cf_warning/__init__.py index 01c23441..4513cb12 100644 --- a/src/cf_warning/__init__.py +++ b/src/cf_warning/__init__.py @@ -1 +1,2 @@ -from .report import CondaForgeWarning +"""Conda-Forge Warning package.""" +from .report import CondaForgeWarning # noqa: F401 diff --git a/src/cf_warning/main.py b/src/cf_warning/main.py index 6fdfef94..ee297c0b 100755 --- a/src/cf_warning/main.py +++ b/src/cf_warning/main.py @@ -1,17 +1,12 @@ -#!/usr/bin/env python -""" -Read information from Github API using GraphQL GitHubAPI. -""" -import asyncio - +"""Read information from Github API using GraphQL GitHubAPI.""" from public import public from cf_warning.report import CondaForgeWarning -from cf_warning.cli import parse_cli -from cf_warning.config import ArgsCLI +@public def main() -> None: + """Generate the Conda-Forge Warning report.""" report = CondaForgeWarning() report.run() diff --git a/src/cf_warning/reader.py b/src/cf_warning/reader.py index 98494d55..421404f9 100644 --- a/src/cf_warning/reader.py +++ b/src/cf_warning/reader.py @@ -6,15 +6,9 @@ """ from __future__ import annotations -import dataclasses -import re - -from abc import ABC, abstractclassmethod -from pathlib import Path -from typing import Any, Dict, List, Optional, Union, cast +from typing import Dict import pandas as pd - from gql import Client, gql from gql.transport.aiohttp import AIOHTTPTransport from jinja2 import Template @@ -22,10 +16,13 @@ class GitHubGraphQL: + """Store token and the query transport for GitHubGraphQL.""" + token: str transport: AIOHTTPTransport def __init__(self, token): + """Instantiate GitHubGraphQL.""" self.token = token self.transport = AIOHTTPTransport( headers={"Authorization": f"bearer {self.token}"}, @@ -34,17 +31,20 @@ def __init__(self, token): class CondaForgeGitHubSearch: + """Conda-Forge GitHub Search class.""" + ghgql: GitHubGraphQL def __init__(self, token: str) -> None: + """Instantiate CondaForgeGitHubSearch.""" self.ghgql = GitHubGraphQL(token) async def pagination( self, gql_tmpl: str, variables: Dict[str, str] ) -> pd.DataFrame: + """Paginate the GitHub GraphQL search.""" has_next_page = True pagination_after = "" - limit = 100 results = [] has_result = False @@ -85,6 +85,7 @@ async def pagination( return results async def search_all_repos_feedstock(self) -> pd.DataFrame: + """Search all feedstock repos.""" search = """ query { search( @@ -133,41 +134,6 @@ async def search_all_repos_feedstock(self) -> pd.DataFrame: return pd.DataFrame(repos) - async def search_repo_stats(self, repo: str) -> dict[str, str]: - search = """ - query () { - repository({{search_query}}) { - pullRequests(states: OPEN) { - totalCount - } - issues(states: OPEN) { - totalCount - } - } - } - """ - - variables = { - f"search_query": "owner:conda-forge name:{repo}", - } - - results = await self.pagination(search, variables) - data = results.get("data", {}).get("repository", {}) - - stats = { - "open_prs": data.get("pullRequests", {}).get("totalCount", 0), - "open_issues": data.get("issues", {}).get("totalCount", 0), - } - return pd.DataFrame(stats) - - async def get_repos_stats(self, repos: pd.DataFrame) -> pd.DataFrame: - repos_stats = [] - - for row_id, row in repos.iterrows(): - repo_stats = self.search_repo_stats(str(row["repo"])) - repos_stats.append(repo_stats) - return pd.DataFrame(repos_stats) - @public class CondaForgeGitHubReader: @@ -176,14 +142,11 @@ class CondaForgeGitHubReader: token: str def __init__(self, token: str) -> None: + """Instantiate CondaForgeGitHubReader.""" self.token = token async def get_data(self) -> pd.DataFrame: - """ - Return all the data used for the report. - """ - results = [] - + """Return all the data used for the report.""" token = self.token if not token: raise Exception("Invalid GitHub token.") diff --git a/src/cf_warning/report.py b/src/cf_warning/report.py index d9e9e591..8e943da4 100644 --- a/src/cf_warning/report.py +++ b/src/cf_warning/report.py @@ -1,29 +1,28 @@ +"""Report module.""" import asyncio -import io -import json import os - from pathlib import Path -from typing import Dict, List, Union, cast +from typing import cast import dotenv import pandas as pd -import yaml - -from dotenv import load_dotenv -from jinja2 import Template from cf_warning.reader import CondaForgeGitHubReader class CondaForgeWarning: + """Conda Forge Warning class.""" + reader: CondaForgeGitHubReader def __init__(self) -> None: + """Instantiate the CondaForgeWarning.""" + self.token = "" self._load_token() self.reader = CondaForgeGitHubReader(self.token) def _load_token(self) -> None: + """Load the GitHub token.""" env_file = ".env" if not env_file: @@ -34,7 +33,7 @@ def _load_token(self) -> None: "`GITHUB_TOKEN` environment variable not found" ) - self.config.gh_token = gh_token + self.token = gh_token return if not env_file.startswith("/"): @@ -56,9 +55,11 @@ def _load_token(self) -> None: self.token = gh_token def run(self) -> None: + """Generate the report.""" asyncio.run(self.run_async()) def apply_criteria(self, df: pd.DataFrame) -> dict[str, pd.DataFrame]: + """Apply criteria to prepare the groups of data for the report.""" criteria = { "critical": (lambda data: data[data["open_prs"] >= 10]), "danger": ( @@ -76,6 +77,7 @@ def apply_criteria(self, df: pd.DataFrame) -> dict[str, pd.DataFrame]: return {level: fn_filter(df) for level, fn_filter in criteria.items()} async def run_async(self): + """Generate the report in async mode.""" data = await self.reader.get_data() index_path = Path(__file__).parent.parent.parent / "docs" / "index.md" diff --git a/tests/test_cf_warning.py b/tests/test_cf_warning.py index c0284a3d..f25cebd1 100644 --- a/tests/test_cf_warning.py +++ b/tests/test_cf_warning.py @@ -1,8 +1,9 @@ -from pathlib import Path +"""Tests for CondaForgeWarning.""" from cf_warning import CondaForgeWarning def test_cfwarning(): + """Test CondaForgeWarning.""" report = CondaForgeWarning() report.run()