From ebfc82a511ed678915c088a1dec2f9e4a6bfa58f Mon Sep 17 00:00:00 2001 From: Kilian Lieret Date: Wed, 3 Jul 2024 16:55:58 -0400 Subject: [PATCH 1/3] Fix: Allow to set GH token from env var --- swebench/collect/print_pulls.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/swebench/collect/print_pulls.py b/swebench/collect/print_pulls.py index 3444936c..619a21fc 100755 --- a/swebench/collect/print_pulls.py +++ b/swebench/collect/print_pulls.py @@ -17,7 +17,7 @@ logger = logging.getLogger(__name__) -def log_all_pulls(repo: Repo, output: str): +def log_all_pulls(repo: Repo, output: str) -> None: """ Iterate over all pull requests in a repository and log them to a file @@ -25,10 +25,10 @@ def log_all_pulls(repo: Repo, output: str): repo (Repo): repository object output (str): output file name """ - with open(output, "w") as output: + with open(output, "w") as file: for pull in repo.get_all_pulls(): setattr(pull, "resolved_issues", repo.extract_resolved_issues(pull)) - print(json.dumps(obj2dict(pull)), end="\n", flush=True, file=output) + print(json.dumps(obj2dict(pull)), end="\n", flush=True, file=file) def main(repo_name: str, output: str, token: Optional[str] = None): From 1bc5dfa3dcb015106ab012b43755cca0ca17e6c1 Mon Sep 17 00:00:00 2001 From: Kilian Lieret Date: Wed, 3 Jul 2024 17:06:05 -0400 Subject: [PATCH 2/3] print_pulls: Add tests and some type cleanup --- swebench/collect/print_pulls.py | 15 ++++++++++----- swebench/collect/utils.py | 16 +++++++++------- tests/test_collect_cli.py | 18 ++++++++++++++++++ 3 files changed, 37 insertions(+), 12 deletions(-) create mode 100644 tests/test_collect_cli.py diff --git a/swebench/collect/print_pulls.py b/swebench/collect/print_pulls.py index 619a21fc..dfa6a4e6 100755 --- a/swebench/collect/print_pulls.py +++ b/swebench/collect/print_pulls.py @@ -2,6 +2,8 @@ """Given the `` of a GitHub repo, this script writes the raw information for all the repo's PRs to a single `.jsonl` file.""" +from __future__ import annotations + import argparse import json import logging @@ -17,7 +19,7 @@ logger = logging.getLogger(__name__) -def log_all_pulls(repo: Repo, output: str) -> None: +def log_all_pulls(repo: Repo, output: str, max_pulls: int|None=None) -> None: """ Iterate over all pull requests in a repository and log them to a file @@ -26,12 +28,14 @@ def log_all_pulls(repo: Repo, output: str) -> None: output (str): output file name """ with open(output, "w") as file: - for pull in repo.get_all_pulls(): + for i_pull, pull in enumerate(repo.get_all_pulls()): setattr(pull, "resolved_issues", repo.extract_resolved_issues(pull)) print(json.dumps(obj2dict(pull)), end="\n", flush=True, file=file) + if max_pulls is not None and i_pull >= max_pulls: + break -def main(repo_name: str, output: str, token: Optional[str] = None): +def main(repo_name: str, output: str, token: Optional[str] = None, max_pulls: int|None=None): """ Logic for logging all pull requests in a repository @@ -41,10 +45,10 @@ def main(repo_name: str, output: str, token: Optional[str] = None): token (str, optional): GitHub token """ if token is None: - token = os.environ["GITHUB_TOKEN"] + token = os.environ.get("GITHUB_TOKEN") owner, repo = repo_name.split("/") repo = Repo(owner, repo, token=token) - log_all_pulls(repo, output) + log_all_pulls(repo, output, max_pulls=max_pulls) if __name__ == "__main__": @@ -52,5 +56,6 @@ def main(repo_name: str, output: str, token: Optional[str] = None): parser.add_argument("repo_name", type=str, help="Name of the repository") parser.add_argument("output", type=str, help="Output file name") parser.add_argument("--token", type=str, help="GitHub token") + parser.add_argument("--max-pulls", type=int, help="Maximum number of pulls to log", default=None) args = parser.parse_args() main(**vars(args)) diff --git a/swebench/collect/utils.py b/swebench/collect/utils.py index 57334c21..4b457c32 100644 --- a/swebench/collect/utils.py +++ b/swebench/collect/utils.py @@ -1,3 +1,6 @@ +from __future__ import annotations + + import logging import re import requests @@ -6,7 +9,7 @@ from bs4 import BeautifulSoup from ghapi.core import GhApi from fastcore.net import HTTP404NotFoundError, HTTP403ForbiddenError -from typing import Optional +from typing import Callable, Iterator, Optional logging.basicConfig( level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s" @@ -30,7 +33,7 @@ def __init__(self, owner: str, name: str, token: Optional[str] = None): self.api = GhApi(token=token) self.repo = self.call_api(self.api.repos.get, owner=owner, repo=name) - def call_api(self, func: callable, **kwargs) -> dict: + def call_api(self, func: Callable, **kwargs) -> dict|None: """ API call wrapper with rate limit handling (checks every 5 minutes if rate limit is reset) @@ -103,12 +106,12 @@ def extract_resolved_issues(self, pull: dict) -> list[str]: def get_all_loop( self, - func: callable, + func: Callable, per_page: int = 100, num_pages: Optional[int] = None, quiet: bool = False, **kwargs, - ) -> list: + ) -> Iterator: """ Return all values from a paginated API endpoint. @@ -195,7 +198,7 @@ def get_all_pulls( direction: str = "asc", sort: str = "created", state: str = "closed", - quiet: str = False, + quiet: bool = False, ) -> list: """ Wrapper for API call to get all PRs from repo @@ -347,7 +350,7 @@ def extract_patches(pull: dict, repo: Repo) -> tuple[str, str]: ### MARK: Repo Specific Parsing Functions ### def extract_problem_statement_and_hints_django( pull: dict, repo: Repo -) -> tuple[str, str]: +) -> tuple[str, list[str]]: """ Get problem statement and hints from issues associated with a pull request @@ -390,7 +393,6 @@ def extract_problem_statement_and_hints_django( # Get all comments before first commit comments_html = soup.find("div", {"id": "changelog"}) div_blocks = comments_html.find_all("div", class_="change") - comments = [] # Loop through each div block for div_block in div_blocks: # Find the comment text and timestamp diff --git a/tests/test_collect_cli.py b/tests/test_collect_cli.py new file mode 100644 index 00000000..20efdba9 --- /dev/null +++ b/tests/test_collect_cli.py @@ -0,0 +1,18 @@ +import subprocess + + +def test_collect_smoke_test(): + cmd = ["python", "-m", "swebench.collect.print_pulls", "--help"] + result = subprocess.run(cmd, capture_output=True) + print(result.stdout) + print(result.stderr) + assert result.returncode == 0 + + +def test_collect_one(tmp_path): + cmd = ["python", "-m", "swebench.collect.print_pulls", "pvlib/pvlib-python", str(tmp_path/ "out.txt"), "--max-pulls", "1"] + print(" ".join(cmd)) + result = subprocess.run(cmd, capture_output=True) + print(result.stdout) + print(result.stderr) + assert result.returncode == 0 \ No newline at end of file From 2a03f7d2c696aafe9905e79be4c3d96edb10e33a Mon Sep 17 00:00:00 2001 From: Kilian Lieret Date: Wed, 3 Jul 2024 17:21:18 -0400 Subject: [PATCH 3/3] Add test for build_dataset.py --- swebench/collect/build_dataset.py | 2 +- tests/test_collect_cli.py | 9 +++++++++ tests/test_data/pvlib.jsonl | 1 + 3 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 tests/test_data/pvlib.jsonl diff --git a/swebench/collect/build_dataset.py b/swebench/collect/build_dataset.py index 17d78fc4..82f8b1d8 100755 --- a/swebench/collect/build_dataset.py +++ b/swebench/collect/build_dataset.py @@ -101,7 +101,7 @@ def main(pr_file: str, output: str, token: Optional[str] = None): """ if token is None: # Get GitHub token from environment variable if not provided - token = os.environ["GITHUB_TOKEN"] + token = os.environ.get("GITHUB_TOKEN") def load_repo(repo_name): # Return repo object for a given repo name diff --git a/tests/test_collect_cli.py b/tests/test_collect_cli.py index 20efdba9..71a001b7 100644 --- a/tests/test_collect_cli.py +++ b/tests/test_collect_cli.py @@ -15,4 +15,13 @@ def test_collect_one(tmp_path): result = subprocess.run(cmd, capture_output=True) print(result.stdout) print(result.stderr) + assert result.returncode == 0 + + +def test_collect_ds(tmp_path): + cmd = ["python", "-m", "swebench.collect.build_dataset", "tests/test_data/pvlib.jsonl", str(tmp_path/ "out.jsonl")] + print(" ".join(cmd)) + result = subprocess.run(cmd, capture_output=True) + print(result.stdout) + print(result.stderr) assert result.returncode == 0 \ No newline at end of file diff --git a/tests/test_data/pvlib.jsonl b/tests/test_data/pvlib.jsonl new file mode 100644 index 00000000..5e1b550c --- /dev/null +++ b/tests/test_data/pvlib.jsonl @@ -0,0 +1 @@ +{"url": "https://api.github.com/repos/pvlib/pvlib-python/pulls/1", "id": 29411065, "node_id": "MDExOlB1bGxSZXF1ZXN0Mjk0MTEwNjU=", "html_url": "https://github.com/pvlib/pvlib-python/pull/1", "diff_url": "https://github.com/pvlib/pvlib-python/pull/1.diff", "patch_url": "https://github.com/pvlib/pvlib-python/pull/1.patch", "issue_url": "https://api.github.com/repos/pvlib/pvlib-python/issues/1", "number": 1, "state": "closed", "locked": false, "title": "Update README.md", "user": {"login": "wholmgren", "id": 4383303, "node_id": "MDQ6VXNlcjQzODMzMDM=", "avatar_url": "https://avatars.githubusercontent.com/u/4383303?v=4", "gravatar_id": "", "url": "https://api.github.com/users/wholmgren", "html_url": "https://github.com/wholmgren", "followers_url": "https://api.github.com/users/wholmgren/followers", "following_url": "https://api.github.com/users/wholmgren/following{/other_user}", "gists_url": "https://api.github.com/users/wholmgren/gists{/gist_id}", "starred_url": "https://api.github.com/users/wholmgren/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/wholmgren/subscriptions", "organizations_url": "https://api.github.com/users/wholmgren/orgs", "repos_url": "https://api.github.com/users/wholmgren/repos", "events_url": "https://api.github.com/users/wholmgren/events{/privacy}", "received_events_url": "https://api.github.com/users/wholmgren/received_events", "type": "User", "site_admin": false}, "body": "Removed unneeded \\* in readme.\n", "created_at": "2015-02-17T01:01:06Z", "updated_at": "2015-03-12T07:08:37Z", "closed_at": "2015-02-17T01:02:03Z", "merged_at": "2015-02-17T01:02:03Z", "merge_commit_sha": "c8ea13cd3193897f760c9bbef6899a0cbcbd1a8d", "assignee": null, "assignees": [], "requested_reviewers": [], "requested_teams": [], "labels": [{"id": 186016142, "node_id": "MDU6TGFiZWwxODYwMTYxNDI=", "url": "https://api.github.com/repos/pvlib/pvlib-python/labels/documentation", "name": "documentation", "color": "bfe5bf", "default": true, "description": null}], "milestone": {"url": "https://api.github.com/repos/pvlib/pvlib-python/milestones/1", "html_url": "https://github.com/pvlib/pvlib-python/milestone/1", "labels_url": "https://api.github.com/repos/pvlib/pvlib-python/milestones/1/labels", "id": 1017829, "node_id": "MDk6TWlsZXN0b25lMTAxNzgyOQ==", "number": 1, "title": "0.1", "description": "First release on PyPi", "creator": {"login": "bmu", "id": 1622906, "node_id": "MDQ6VXNlcjE2MjI5MDY=", "avatar_url": "https://avatars.githubusercontent.com/u/1622906?v=4", "gravatar_id": "", "url": "https://api.github.com/users/bmu", "html_url": "https://github.com/bmu", "followers_url": "https://api.github.com/users/bmu/followers", "following_url": "https://api.github.com/users/bmu/following{/other_user}", "gists_url": "https://api.github.com/users/bmu/gists{/gist_id}", "starred_url": "https://api.github.com/users/bmu/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/bmu/subscriptions", "organizations_url": "https://api.github.com/users/bmu/orgs", "repos_url": "https://api.github.com/users/bmu/repos", "events_url": "https://api.github.com/users/bmu/events{/privacy}", "received_events_url": "https://api.github.com/users/bmu/received_events", "type": "User", "site_admin": false}, "open_issues": 0, "closed_issues": 32, "state": "closed", "created_at": "2015-03-12T06:35:09Z", "updated_at": "2023-05-25T15:38:31Z", "due_on": "2015-03-30T07:00:00Z", "closed_at": "2015-06-03T09:33:00Z"}, "draft": false, "commits_url": "https://api.github.com/repos/pvlib/pvlib-python/pulls/1/commits", "review_comments_url": "https://api.github.com/repos/pvlib/pvlib-python/pulls/1/comments", "review_comment_url": "https://api.github.com/repos/pvlib/pvlib-python/pulls/comments{/number}", "comments_url": "https://api.github.com/repos/pvlib/pvlib-python/issues/1/comments", "statuses_url": "https://api.github.com/repos/pvlib/pvlib-python/statuses/b6e190af35b8386093f6f02f4446cf6eacfc6b45", "head": {"label": "wholmgren:master", "ref": "master", "sha": "b6e190af35b8386093f6f02f4446cf6eacfc6b45", "user": {"login": "wholmgren", "id": 4383303, "node_id": "MDQ6VXNlcjQzODMzMDM=", "avatar_url": "https://avatars.githubusercontent.com/u/4383303?v=4", "gravatar_id": "", "url": "https://api.github.com/users/wholmgren", "html_url": "https://github.com/wholmgren", "followers_url": "https://api.github.com/users/wholmgren/followers", "following_url": "https://api.github.com/users/wholmgren/following{/other_user}", "gists_url": "https://api.github.com/users/wholmgren/gists{/gist_id}", "starred_url": "https://api.github.com/users/wholmgren/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/wholmgren/subscriptions", "organizations_url": "https://api.github.com/users/wholmgren/orgs", "repos_url": "https://api.github.com/users/wholmgren/repos", "events_url": "https://api.github.com/users/wholmgren/events{/privacy}", "received_events_url": "https://api.github.com/users/wholmgren/received_events", "type": "User", "site_admin": false}, "repo": {"id": 30896535, "node_id": "MDEwOlJlcG9zaXRvcnkzMDg5NjUzNQ==", "name": "pvlib-python", "full_name": "wholmgren/pvlib-python", "private": false, "owner": {"login": "wholmgren", "id": 4383303, "node_id": "MDQ6VXNlcjQzODMzMDM=", "avatar_url": "https://avatars.githubusercontent.com/u/4383303?v=4", "gravatar_id": "", "url": "https://api.github.com/users/wholmgren", "html_url": "https://github.com/wholmgren", "followers_url": "https://api.github.com/users/wholmgren/followers", "following_url": "https://api.github.com/users/wholmgren/following{/other_user}", "gists_url": "https://api.github.com/users/wholmgren/gists{/gist_id}", "starred_url": "https://api.github.com/users/wholmgren/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/wholmgren/subscriptions", "organizations_url": "https://api.github.com/users/wholmgren/orgs", "repos_url": "https://api.github.com/users/wholmgren/repos", "events_url": "https://api.github.com/users/wholmgren/events{/privacy}", "received_events_url": "https://api.github.com/users/wholmgren/received_events", "type": "User", "site_admin": false}, "html_url": "https://github.com/wholmgren/pvlib-python", "description": "see https://github.com/pvlib/pvlib-python", "fork": true, "url": "https://api.github.com/repos/wholmgren/pvlib-python", "forks_url": "https://api.github.com/repos/wholmgren/pvlib-python/forks", "keys_url": "https://api.github.com/repos/wholmgren/pvlib-python/keys{/key_id}", "collaborators_url": "https://api.github.com/repos/wholmgren/pvlib-python/collaborators{/collaborator}", "teams_url": "https://api.github.com/repos/wholmgren/pvlib-python/teams", "hooks_url": "https://api.github.com/repos/wholmgren/pvlib-python/hooks", "issue_events_url": "https://api.github.com/repos/wholmgren/pvlib-python/issues/events{/number}", "events_url": "https://api.github.com/repos/wholmgren/pvlib-python/events", "assignees_url": "https://api.github.com/repos/wholmgren/pvlib-python/assignees{/user}", "branches_url": "https://api.github.com/repos/wholmgren/pvlib-python/branches{/branch}", "tags_url": "https://api.github.com/repos/wholmgren/pvlib-python/tags", "blobs_url": "https://api.github.com/repos/wholmgren/pvlib-python/git/blobs{/sha}", "git_tags_url": "https://api.github.com/repos/wholmgren/pvlib-python/git/tags{/sha}", "git_refs_url": "https://api.github.com/repos/wholmgren/pvlib-python/git/refs{/sha}", "trees_url": "https://api.github.com/repos/wholmgren/pvlib-python/git/trees{/sha}", "statuses_url": "https://api.github.com/repos/wholmgren/pvlib-python/statuses/{sha}", "languages_url": "https://api.github.com/repos/wholmgren/pvlib-python/languages", "stargazers_url": "https://api.github.com/repos/wholmgren/pvlib-python/stargazers", "contributors_url": "https://api.github.com/repos/wholmgren/pvlib-python/contributors", "subscribers_url": "https://api.github.com/repos/wholmgren/pvlib-python/subscribers", "subscription_url": "https://api.github.com/repos/wholmgren/pvlib-python/subscription", "commits_url": "https://api.github.com/repos/wholmgren/pvlib-python/commits{/sha}", "git_commits_url": "https://api.github.com/repos/wholmgren/pvlib-python/git/commits{/sha}", "comments_url": "https://api.github.com/repos/wholmgren/pvlib-python/comments{/number}", "issue_comment_url": "https://api.github.com/repos/wholmgren/pvlib-python/issues/comments{/number}", "contents_url": "https://api.github.com/repos/wholmgren/pvlib-python/contents/{+path}", "compare_url": "https://api.github.com/repos/wholmgren/pvlib-python/compare/{base}...{head}", "merges_url": "https://api.github.com/repos/wholmgren/pvlib-python/merges", "archive_url": "https://api.github.com/repos/wholmgren/pvlib-python/{archive_format}{/ref}", "downloads_url": "https://api.github.com/repos/wholmgren/pvlib-python/downloads", "issues_url": "https://api.github.com/repos/wholmgren/pvlib-python/issues{/number}", "pulls_url": "https://api.github.com/repos/wholmgren/pvlib-python/pulls{/number}", "milestones_url": "https://api.github.com/repos/wholmgren/pvlib-python/milestones{/number}", "notifications_url": "https://api.github.com/repos/wholmgren/pvlib-python/notifications{?since,all,participating}", "labels_url": "https://api.github.com/repos/wholmgren/pvlib-python/labels{/name}", "releases_url": "https://api.github.com/repos/wholmgren/pvlib-python/releases{/id}", "deployments_url": "https://api.github.com/repos/wholmgren/pvlib-python/deployments", "created_at": "2015-02-17T00:55:18Z", "updated_at": "2022-01-21T20:25:16Z", "pushed_at": "2024-05-31T02:01:32Z", "git_url": "git://github.com/wholmgren/pvlib-python.git", "ssh_url": "git@github.com:wholmgren/pvlib-python.git", "clone_url": "https://github.com/wholmgren/pvlib-python.git", "svn_url": "https://github.com/wholmgren/pvlib-python", "homepage": "", "size": 113209, "stargazers_count": 1, "watchers_count": 1, "language": "Python", "has_issues": false, "has_projects": true, "has_downloads": true, "has_wiki": true, "has_pages": false, "has_discussions": false, "forks_count": 0, "mirror_url": null, "archived": false, "disabled": false, "open_issues_count": 0, "license": {"key": "bsd-3-clause", "name": "BSD 3-Clause \"New\" or \"Revised\" License", "spdx_id": "BSD-3-Clause", "url": "https://api.github.com/licenses/bsd-3-clause", "node_id": "MDc6TGljZW5zZTU="}, "allow_forking": true, "is_template": false, "web_commit_signoff_required": false, "topics": [], "visibility": "public", "forks": 0, "open_issues": 0, "watchers": 1, "default_branch": "master"}}, "base": {"label": "pvlib:master", "ref": "master", "sha": "e8dd1d9bdaff50319fde60397d704061290f19de", "user": {"login": "pvlib", "id": 11037261, "node_id": "MDEyOk9yZ2FuaXphdGlvbjExMDM3MjYx", "avatar_url": "https://avatars.githubusercontent.com/u/11037261?v=4", "gravatar_id": "", "url": "https://api.github.com/users/pvlib", "html_url": "https://github.com/pvlib", "followers_url": "https://api.github.com/users/pvlib/followers", "following_url": "https://api.github.com/users/pvlib/following{/other_user}", "gists_url": "https://api.github.com/users/pvlib/gists{/gist_id}", "starred_url": "https://api.github.com/users/pvlib/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/pvlib/subscriptions", "organizations_url": "https://api.github.com/users/pvlib/orgs", "repos_url": "https://api.github.com/users/pvlib/repos", "events_url": "https://api.github.com/users/pvlib/events{/privacy}", "received_events_url": "https://api.github.com/users/pvlib/received_events", "type": "Organization", "site_admin": false}, "repo": {"id": 30895522, "node_id": "MDEwOlJlcG9zaXRvcnkzMDg5NTUyMg==", "name": "pvlib-python", "full_name": "pvlib/pvlib-python", "private": false, "owner": {"login": "pvlib", "id": 11037261, "node_id": "MDEyOk9yZ2FuaXphdGlvbjExMDM3MjYx", "avatar_url": "https://avatars.githubusercontent.com/u/11037261?v=4", "gravatar_id": "", "url": "https://api.github.com/users/pvlib", "html_url": "https://github.com/pvlib", "followers_url": "https://api.github.com/users/pvlib/followers", "following_url": "https://api.github.com/users/pvlib/following{/other_user}", "gists_url": "https://api.github.com/users/pvlib/gists{/gist_id}", "starred_url": "https://api.github.com/users/pvlib/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/pvlib/subscriptions", "organizations_url": "https://api.github.com/users/pvlib/orgs", "repos_url": "https://api.github.com/users/pvlib/repos", "events_url": "https://api.github.com/users/pvlib/events{/privacy}", "received_events_url": "https://api.github.com/users/pvlib/received_events", "type": "Organization", "site_admin": false}, "html_url": "https://github.com/pvlib/pvlib-python", "description": "A set of documented functions for simulating the performance of photovoltaic energy systems.", "fork": false, "url": "https://api.github.com/repos/pvlib/pvlib-python", "forks_url": "https://api.github.com/repos/pvlib/pvlib-python/forks", "keys_url": "https://api.github.com/repos/pvlib/pvlib-python/keys{/key_id}", "collaborators_url": "https://api.github.com/repos/pvlib/pvlib-python/collaborators{/collaborator}", "teams_url": "https://api.github.com/repos/pvlib/pvlib-python/teams", "hooks_url": "https://api.github.com/repos/pvlib/pvlib-python/hooks", "issue_events_url": "https://api.github.com/repos/pvlib/pvlib-python/issues/events{/number}", "events_url": "https://api.github.com/repos/pvlib/pvlib-python/events", "assignees_url": "https://api.github.com/repos/pvlib/pvlib-python/assignees{/user}", "branches_url": "https://api.github.com/repos/pvlib/pvlib-python/branches{/branch}", "tags_url": "https://api.github.com/repos/pvlib/pvlib-python/tags", "blobs_url": "https://api.github.com/repos/pvlib/pvlib-python/git/blobs{/sha}", "git_tags_url": "https://api.github.com/repos/pvlib/pvlib-python/git/tags{/sha}", "git_refs_url": "https://api.github.com/repos/pvlib/pvlib-python/git/refs{/sha}", "trees_url": "https://api.github.com/repos/pvlib/pvlib-python/git/trees{/sha}", "statuses_url": "https://api.github.com/repos/pvlib/pvlib-python/statuses/{sha}", "languages_url": "https://api.github.com/repos/pvlib/pvlib-python/languages", "stargazers_url": "https://api.github.com/repos/pvlib/pvlib-python/stargazers", "contributors_url": "https://api.github.com/repos/pvlib/pvlib-python/contributors", "subscribers_url": "https://api.github.com/repos/pvlib/pvlib-python/subscribers", "subscription_url": "https://api.github.com/repos/pvlib/pvlib-python/subscription", "commits_url": "https://api.github.com/repos/pvlib/pvlib-python/commits{/sha}", "git_commits_url": "https://api.github.com/repos/pvlib/pvlib-python/git/commits{/sha}", "comments_url": "https://api.github.com/repos/pvlib/pvlib-python/comments{/number}", "issue_comment_url": "https://api.github.com/repos/pvlib/pvlib-python/issues/comments{/number}", "contents_url": "https://api.github.com/repos/pvlib/pvlib-python/contents/{+path}", "compare_url": "https://api.github.com/repos/pvlib/pvlib-python/compare/{base}...{head}", "merges_url": "https://api.github.com/repos/pvlib/pvlib-python/merges", "archive_url": "https://api.github.com/repos/pvlib/pvlib-python/{archive_format}{/ref}", "downloads_url": "https://api.github.com/repos/pvlib/pvlib-python/downloads", "issues_url": "https://api.github.com/repos/pvlib/pvlib-python/issues{/number}", "pulls_url": "https://api.github.com/repos/pvlib/pvlib-python/pulls{/number}", "milestones_url": "https://api.github.com/repos/pvlib/pvlib-python/milestones{/number}", "notifications_url": "https://api.github.com/repos/pvlib/pvlib-python/notifications{?since,all,participating}", "labels_url": "https://api.github.com/repos/pvlib/pvlib-python/labels{/name}", "releases_url": "https://api.github.com/repos/pvlib/pvlib-python/releases{/id}", "deployments_url": "https://api.github.com/repos/pvlib/pvlib-python/deployments", "created_at": "2015-02-17T00:21:33Z", "updated_at": "2024-07-03T19:58:46Z", "pushed_at": "2024-07-03T20:12:57Z", "git_url": "git://github.com/pvlib/pvlib-python.git", "ssh_url": "git@github.com:pvlib/pvlib-python.git", "clone_url": "https://github.com/pvlib/pvlib-python.git", "svn_url": "https://github.com/pvlib/pvlib-python", "homepage": "https://pvlib-python.readthedocs.io", "size": 112782, "stargazers_count": 1120, "watchers_count": 1120, "language": "Python", "has_issues": true, "has_projects": false, "has_downloads": true, "has_wiki": true, "has_pages": false, "has_discussions": true, "forks_count": 949, "mirror_url": null, "archived": false, "disabled": false, "open_issues_count": 229, "license": {"key": "bsd-3-clause", "name": "BSD 3-Clause \"New\" or \"Revised\" License", "spdx_id": "BSD-3-Clause", "url": "https://api.github.com/licenses/bsd-3-clause", "node_id": "MDc6TGljZW5zZTU="}, "allow_forking": true, "is_template": false, "web_commit_signoff_required": false, "topics": ["photovoltaic", "python", "renewable-energy", "renewables", "solar-energy"], "visibility": "public", "forks": 949, "open_issues": 229, "watchers": 1120, "default_branch": "main"}}, "_links": {"self": {"href": "https://api.github.com/repos/pvlib/pvlib-python/pulls/1"}, "html": {"href": "https://github.com/pvlib/pvlib-python/pull/1"}, "issue": {"href": "https://api.github.com/repos/pvlib/pvlib-python/issues/1"}, "comments": {"href": "https://api.github.com/repos/pvlib/pvlib-python/issues/1/comments"}, "review_comments": {"href": "https://api.github.com/repos/pvlib/pvlib-python/pulls/1/comments"}, "review_comment": {"href": "https://api.github.com/repos/pvlib/pvlib-python/pulls/comments{/number}"}, "commits": {"href": "https://api.github.com/repos/pvlib/pvlib-python/pulls/1/commits"}, "statuses": {"href": "https://api.github.com/repos/pvlib/pvlib-python/statuses/b6e190af35b8386093f6f02f4446cf6eacfc6b45"}}, "author_association": "MEMBER", "auto_merge": null, "active_lock_reason": null, "resolved_issues": []}