github-to-sqlite 2.9__tar.gz → 2.9.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {github-to-sqlite-2.9 → github_to_sqlite-2.9.1}/PKG-INFO +11 -11
- {github-to-sqlite-2.9 → github_to_sqlite-2.9.1}/github_to_sqlite/cli.py +7 -4
- {github-to-sqlite-2.9 → github_to_sqlite-2.9.1}/github_to_sqlite/utils.py +9 -4
- github_to_sqlite-2.9.1/pyproject.toml +39 -0
- github_to_sqlite-2.9.1/pyproject.toml.orig +37 -0
- github-to-sqlite-2.9/github_to_sqlite.egg-info/PKG-INFO +0 -277
- github-to-sqlite-2.9/github_to_sqlite.egg-info/SOURCES.txt +0 -25
- github-to-sqlite-2.9/github_to_sqlite.egg-info/dependency_links.txt +0 -1
- github-to-sqlite-2.9/github_to_sqlite.egg-info/entry_points.txt +0 -2
- github-to-sqlite-2.9/github_to_sqlite.egg-info/requires.txt +0 -8
- github-to-sqlite-2.9/github_to_sqlite.egg-info/top_level.txt +0 -1
- github-to-sqlite-2.9/setup.cfg +0 -4
- github-to-sqlite-2.9/setup.py +0 -32
- github-to-sqlite-2.9/tests/test_auth.py +0 -46
- github-to-sqlite-2.9/tests/test_commits.py +0 -89
- github-to-sqlite-2.9/tests/test_get.py +0 -127
- github-to-sqlite-2.9/tests/test_issue_comments.py +0 -134
- github-to-sqlite-2.9/tests/test_issues.py +0 -152
- github-to-sqlite-2.9/tests/test_pull_requests.py +0 -140
- github-to-sqlite-2.9/tests/test_releases.py +0 -199
- github-to-sqlite-2.9/tests/test_repos.py +0 -110
- github-to-sqlite-2.9/tests/test_scrape_dependents.py +0 -83
- github-to-sqlite-2.9/tests/test_stargazers.py +0 -33
- github-to-sqlite-2.9/tests/test_starred.py +0 -241
- github-to-sqlite-2.9/tests/test_tags.py +0 -47
- github-to-sqlite-2.9/tests/test_workflows.py +0 -207
- {github-to-sqlite-2.9 → github_to_sqlite-2.9.1}/LICENSE +0 -0
- {github-to-sqlite-2.9 → github_to_sqlite-2.9.1}/README.md +0 -0
- {github-to-sqlite-2.9 → github_to_sqlite-2.9.1}/github_to_sqlite/__init__.py +0 -0
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: github-to-sqlite
|
|
3
|
-
Version: 2.9
|
|
3
|
+
Version: 2.9.1
|
|
4
4
|
Summary: Save data from GitHub to a SQLite database
|
|
5
|
-
Home-page: https://github.com/dogsheep/github-to-sqlite
|
|
6
5
|
Author: Simon Willison
|
|
7
|
-
License: Apache
|
|
8
|
-
Description-Content-Type: text/markdown
|
|
6
|
+
License-Expression: Apache-2.0
|
|
9
7
|
License-File: LICENSE
|
|
10
|
-
Requires-Dist: sqlite-utils
|
|
8
|
+
Requires-Dist: sqlite-utils>4
|
|
11
9
|
Requires-Dist: requests
|
|
12
|
-
Requires-Dist:
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
10
|
+
Requires-Dist: pyyaml
|
|
11
|
+
Requires-Python: >=3.10
|
|
12
|
+
Project-URL: Homepage, https://github.com/dogsheep/github-to-sqlite
|
|
13
|
+
Project-URL: Changelog, https://github.com/dogsheep/github-to-sqlite/releases
|
|
14
|
+
Project-URL: Issues, https://github.com/dogsheep/github-to-sqlite/issues
|
|
15
|
+
Project-URL: CI, https://github.com/dogsheep/github-to-sqlite/actions
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
17
|
|
|
18
18
|
# github-to-sqlite
|
|
19
19
|
|
|
@@ -142,15 +142,16 @@ def pull_requests(db_path, repo, pull_request_ids, auth, load, orgs, state, sear
|
|
|
142
142
|
else:
|
|
143
143
|
if orgs:
|
|
144
144
|
repos = itertools.chain.from_iterable(
|
|
145
|
-
utils.fetch_all_repos(token=token, org=org)
|
|
146
|
-
for org in orgs
|
|
145
|
+
utils.fetch_all_repos(token=token, org=org) for org in orgs
|
|
147
146
|
)
|
|
148
147
|
else:
|
|
149
148
|
repos = [utils.fetch_repo(repo, token)]
|
|
150
149
|
for repo_full in repos:
|
|
151
150
|
utils.save_repo(db, repo_full)
|
|
152
151
|
repo = repo_full["full_name"]
|
|
153
|
-
pull_requests = utils.fetch_pull_requests(
|
|
152
|
+
pull_requests = utils.fetch_pull_requests(
|
|
153
|
+
repo, state, token, pull_request_ids
|
|
154
|
+
)
|
|
154
155
|
utils.save_pull_requests(db, pull_requests, repo_full)
|
|
155
156
|
utils.ensure_db_shape(db)
|
|
156
157
|
|
|
@@ -499,7 +500,9 @@ def scrape_dependents(db_path, repos, auth, verbose):
|
|
|
499
500
|
{
|
|
500
501
|
"repo": repo_full["id"],
|
|
501
502
|
"dependent": dependent_id,
|
|
502
|
-
"first_seen_utc": datetime.datetime.
|
|
503
|
+
"first_seen_utc": datetime.datetime.now(datetime.timezone.utc)
|
|
504
|
+
.replace(tzinfo=None)
|
|
505
|
+
.isoformat(),
|
|
503
506
|
},
|
|
504
507
|
pk=("repo", "dependent"),
|
|
505
508
|
foreign_keys=(
|
|
@@ -229,11 +229,11 @@ def save_pull_requests(db, pull_requests, repo):
|
|
|
229
229
|
|
|
230
230
|
|
|
231
231
|
def save_user(db, user):
|
|
232
|
-
# Under some conditions, GitHub caches removed repositories with
|
|
232
|
+
# Under some conditions, GitHub caches removed repositories with
|
|
233
233
|
# stars and ends up leaving dangling `None` user references.
|
|
234
234
|
if user is None:
|
|
235
235
|
return None
|
|
236
|
-
|
|
236
|
+
|
|
237
237
|
# Remove all url fields except avatar_url and html_url
|
|
238
238
|
to_save = {
|
|
239
239
|
key: value
|
|
@@ -461,7 +461,9 @@ def fetch_stargazers(repo, token=None):
|
|
|
461
461
|
|
|
462
462
|
|
|
463
463
|
def fetch_all_repos(username=None, token=None, org=None):
|
|
464
|
-
assert
|
|
464
|
+
assert (
|
|
465
|
+
username or token or org
|
|
466
|
+
), "Must provide username= or token= or org= or a combination"
|
|
465
467
|
headers = make_headers(token)
|
|
466
468
|
# Get topics for each repo:
|
|
467
469
|
headers["Accept"] = "application/vnd.github.mercy-preview+json"
|
|
@@ -695,7 +697,10 @@ def ensure_foreign_keys(db):
|
|
|
695
697
|
for expected_foreign_key in FOREIGN_KEYS:
|
|
696
698
|
table, column, table2, column2 = expected_foreign_key
|
|
697
699
|
if (
|
|
698
|
-
expected_foreign_key not in
|
|
700
|
+
expected_foreign_key not in {
|
|
701
|
+
(fk.table, fk.column, fk.other_table, fk.other_column)
|
|
702
|
+
for fk in db[table].foreign_keys
|
|
703
|
+
}
|
|
699
704
|
and
|
|
700
705
|
# Ensure all tables and columns exist
|
|
701
706
|
db[table].exists()
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "github-to-sqlite"
|
|
3
|
+
version = "2.9.1"
|
|
4
|
+
description = "Save data from GitHub to a SQLite database"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.10"
|
|
7
|
+
license = "Apache-2.0"
|
|
8
|
+
license-files = ["LICENSE"]
|
|
9
|
+
dependencies = [
|
|
10
|
+
"sqlite-utils>4",
|
|
11
|
+
"requests",
|
|
12
|
+
"PyYAML",
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
[[project.authors]]
|
|
16
|
+
name = "Simon Willison"
|
|
17
|
+
|
|
18
|
+
[project.urls]
|
|
19
|
+
Homepage = "https://github.com/dogsheep/github-to-sqlite"
|
|
20
|
+
Changelog = "https://github.com/dogsheep/github-to-sqlite/releases"
|
|
21
|
+
Issues = "https://github.com/dogsheep/github-to-sqlite/issues"
|
|
22
|
+
CI = "https://github.com/dogsheep/github-to-sqlite/actions"
|
|
23
|
+
|
|
24
|
+
[project.scripts]
|
|
25
|
+
github-to-sqlite = "github_to_sqlite.cli:cli"
|
|
26
|
+
|
|
27
|
+
[dependency-groups]
|
|
28
|
+
dev = [
|
|
29
|
+
"pytest",
|
|
30
|
+
"requests-mock",
|
|
31
|
+
"bs4",
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
[build-system]
|
|
35
|
+
requires = ["uv_build>=0.9.18,<0.12.0"]
|
|
36
|
+
build-backend = "uv_build"
|
|
37
|
+
|
|
38
|
+
[tool.uv.build-backend]
|
|
39
|
+
module-root = ""
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "github-to-sqlite"
|
|
3
|
+
version = "2.9.1"
|
|
4
|
+
description = "Save data from GitHub to a SQLite database"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.10"
|
|
7
|
+
authors = [{name = "Simon Willison"}]
|
|
8
|
+
license = "Apache-2.0"
|
|
9
|
+
license-files = ["LICENSE"]
|
|
10
|
+
dependencies = [
|
|
11
|
+
"sqlite-utils>4",
|
|
12
|
+
"requests",
|
|
13
|
+
"PyYAML",
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
[project.urls]
|
|
17
|
+
Homepage = "https://github.com/dogsheep/github-to-sqlite"
|
|
18
|
+
Changelog = "https://github.com/dogsheep/github-to-sqlite/releases"
|
|
19
|
+
Issues = "https://github.com/dogsheep/github-to-sqlite/issues"
|
|
20
|
+
CI = "https://github.com/dogsheep/github-to-sqlite/actions"
|
|
21
|
+
|
|
22
|
+
[project.scripts]
|
|
23
|
+
github-to-sqlite = "github_to_sqlite.cli:cli"
|
|
24
|
+
|
|
25
|
+
[dependency-groups]
|
|
26
|
+
dev = [
|
|
27
|
+
"pytest",
|
|
28
|
+
"requests-mock",
|
|
29
|
+
"bs4",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
[build-system]
|
|
33
|
+
requires = ["uv_build>=0.9.18,<0.12.0"]
|
|
34
|
+
build-backend = "uv_build"
|
|
35
|
+
|
|
36
|
+
[tool.uv.build-backend]
|
|
37
|
+
module-root = ""
|
|
@@ -1,277 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.1
|
|
2
|
-
Name: github-to-sqlite
|
|
3
|
-
Version: 2.9
|
|
4
|
-
Summary: Save data from GitHub to a SQLite database
|
|
5
|
-
Home-page: https://github.com/dogsheep/github-to-sqlite
|
|
6
|
-
Author: Simon Willison
|
|
7
|
-
License: Apache License, Version 2.0
|
|
8
|
-
Description-Content-Type: text/markdown
|
|
9
|
-
License-File: LICENSE
|
|
10
|
-
Requires-Dist: sqlite-utils>=2.7.2
|
|
11
|
-
Requires-Dist: requests
|
|
12
|
-
Requires-Dist: PyYAML
|
|
13
|
-
Provides-Extra: test
|
|
14
|
-
Requires-Dist: pytest; extra == "test"
|
|
15
|
-
Requires-Dist: requests-mock; extra == "test"
|
|
16
|
-
Requires-Dist: bs4; extra == "test"
|
|
17
|
-
|
|
18
|
-
# github-to-sqlite
|
|
19
|
-
|
|
20
|
-
[](https://pypi.org/project/github-to-sqlite/)
|
|
21
|
-
[](https://github.com/dogsheep/github-to-sqlite/releases)
|
|
22
|
-
[](https://github.com/dogsheep/github-to-sqlite/actions?query=workflow%3ATest)
|
|
23
|
-
[](https://github.com/dogsheep/github-to-sqlite/blob/main/LICENSE)
|
|
24
|
-
|
|
25
|
-
Save data from GitHub to a SQLite database.
|
|
26
|
-
|
|
27
|
-
<!-- toc -->
|
|
28
|
-
|
|
29
|
-
- [Demo](#demo)
|
|
30
|
-
- [How to install](#how-to-install)
|
|
31
|
-
- [Authentication](#authentication)
|
|
32
|
-
- [Fetching issues for a repository](#fetching-issues-for-a-repository)
|
|
33
|
-
- [Fetching pull requests for a repository](#fetching-pull-requests-for-a-repository)
|
|
34
|
-
- [Fetching issue comments for a repository](#fetching-issue-comments-for-a-repository)
|
|
35
|
-
- [Fetching commits for a repository](#fetching-commits-for-a-repository)
|
|
36
|
-
- [Fetching releases for a repository](#fetching-releases-for-a-repository)
|
|
37
|
-
- [Fetching tags for a repository](#fetching-tags-for-a-repository)
|
|
38
|
-
- [Fetching contributors to a repository](#fetching-contributors-to-a-repository)
|
|
39
|
-
- [Fetching repos belonging to a user or organization](#fetching-repos-belonging-to-a-user-or-organization)
|
|
40
|
-
- [Fetching specific repositories](#fetching-specific-repositories)
|
|
41
|
-
- [Fetching repos that have been starred by a user](#fetching-repos-that-have-been-starred-by-a-user)
|
|
42
|
-
- [Fetching users that have starred specific repos](#fetching-users-that-have-starred-specific-repos)
|
|
43
|
-
- [Fetching GitHub Actions workflows](#fetching-github-actions-workflows)
|
|
44
|
-
- [Scraping dependents for a repository](#scraping-dependents-for-a-repository)
|
|
45
|
-
- [Fetching emojis](#fetching-emojis)
|
|
46
|
-
- [Making authenticated API calls](#making-authenticated-api-calls)
|
|
47
|
-
|
|
48
|
-
<!-- tocstop -->
|
|
49
|
-
|
|
50
|
-
## Demo
|
|
51
|
-
|
|
52
|
-
https://github-to-sqlite.dogsheep.net/ hosts a [Datasette](https://datasette.io/) demo of a database created by [running this tool](https://github.com/dogsheep/github-to-sqlite/blob/main/.github/workflows/deploy-demo.yml#L40-L60) against all of the repositories in the [Dogsheep GitHub organization](https://github.com/dogsheep), plus the [datasette](https://github.com/simonw/datasette) and [sqlite-utils](https://github.com/simonw/sqlite-utils) repositories.
|
|
53
|
-
|
|
54
|
-
## How to install
|
|
55
|
-
|
|
56
|
-
$ pip install github-to-sqlite
|
|
57
|
-
|
|
58
|
-
## Authentication
|
|
59
|
-
|
|
60
|
-
Create a GitHub personal access token: https://github.com/settings/tokens
|
|
61
|
-
|
|
62
|
-
Run this command and paste in your new token:
|
|
63
|
-
|
|
64
|
-
$ github-to-sqlite auth
|
|
65
|
-
|
|
66
|
-
This will create a file called `auth.json` in your current directory containing the required value. To save the file at a different path or filename, use the `--auth=myauth.json` option.
|
|
67
|
-
|
|
68
|
-
As an alternative to using an `auth.json` file you can add your access token to an environment variable called `GITHUB_TOKEN`.
|
|
69
|
-
|
|
70
|
-
## Fetching issues for a repository
|
|
71
|
-
|
|
72
|
-
The `issues` command retrieves all of the issues belonging to a specified repository.
|
|
73
|
-
|
|
74
|
-
$ github-to-sqlite issues github.db simonw/datasette
|
|
75
|
-
|
|
76
|
-
If an `auth.json` file is present it will use the token from that file. It works without authentication for public repositories but you should be aware that GitHub have strict IP-based rate limits for unauthenticated requests.
|
|
77
|
-
|
|
78
|
-
You can point to a different location of `auth.json` using `-a`:
|
|
79
|
-
|
|
80
|
-
$ github-to-sqlite issues github.db simonw/datasette -a /path/to/auth.json
|
|
81
|
-
|
|
82
|
-
You can use the `--issue` option one or more times to load specific issues:
|
|
83
|
-
|
|
84
|
-
$ github-to-sqlite issues github.db simonw/datasette --issue=1
|
|
85
|
-
|
|
86
|
-
Example: [issues table](https://github-to-sqlite.dogsheep.net/github/issues)
|
|
87
|
-
|
|
88
|
-
## Fetching pull requests for a repository
|
|
89
|
-
|
|
90
|
-
While pull requests are a type of issue, you will get more information on pull requests by pulling them separately. For example, whether a pull request has been merged and when.
|
|
91
|
-
|
|
92
|
-
Following the API of issues, the `pull-requests` command retrieves all of the pull requests belonging to a specified repository.
|
|
93
|
-
|
|
94
|
-
$ github-to-sqlite pull-requests github.db simonw/datasette
|
|
95
|
-
|
|
96
|
-
You can use the `--pull-request` option one or more times to load specific pull request:
|
|
97
|
-
|
|
98
|
-
$ github-to-sqlite pull-requests github.db simonw/datasette --pull-request=81
|
|
99
|
-
|
|
100
|
-
Note that the `merged_by` column on the `pull_requests` table will only be populated for pull requests that are loaded using the `--pull-request` option - the GitHub API does not return this field for pull requests that are loaded in bulk.
|
|
101
|
-
|
|
102
|
-
You can load only pull requests in a certain state with the `--state` option:
|
|
103
|
-
|
|
104
|
-
$ github-to-sqlite pull-requests --state=open github.db simonw/datasette
|
|
105
|
-
|
|
106
|
-
Pull requests across an entire organization (or more than one) can be loaded with `--org`:
|
|
107
|
-
|
|
108
|
-
$ github-to-sqlite pull-requests --state=open --org=psf --org=python github.db
|
|
109
|
-
|
|
110
|
-
You can use a search query to find pull requests. Note that no more than 1000 will be loaded (this is a GitHub API limitation), and some data will be missing (base and head SHAs). When using searches, other filters are ignored; put all criteria into the search itself:
|
|
111
|
-
|
|
112
|
-
$ github-to-sqlite pull-requests --search='org:python defaultdict state:closed created:<2023-09-01' github.db
|
|
113
|
-
|
|
114
|
-
Example: [pull_requests table](https://github-to-sqlite.dogsheep.net/github/pull_requests)
|
|
115
|
-
|
|
116
|
-
## Fetching issue comments for a repository
|
|
117
|
-
|
|
118
|
-
The `issue-comments` command retrieves all of the comments on all of the issues in a repository.
|
|
119
|
-
|
|
120
|
-
It is recommended you run `issues` first, so that each imported comment can have a foreign key pointing to its issue.
|
|
121
|
-
|
|
122
|
-
$ github-to-sqlite issues github.db simonw/datasette
|
|
123
|
-
$ github-to-sqlite issue-comments github.db simonw/datasette
|
|
124
|
-
|
|
125
|
-
You can use the `--issue` option to only load comments for a specific issue within that repository, for example:
|
|
126
|
-
|
|
127
|
-
$ github-to-sqlite issue-comments github.db simonw/datasette --issue=1
|
|
128
|
-
|
|
129
|
-
Example: [issue_comments table](https://github-to-sqlite.dogsheep.net/github/issue_comments)
|
|
130
|
-
|
|
131
|
-
## Fetching commits for a repository
|
|
132
|
-
|
|
133
|
-
The `commits` command retrieves details of all of the commits for one or more repositories. It currently fetches the SHA, commit message and author and committer details; it does not retrieve the full commit body.
|
|
134
|
-
|
|
135
|
-
$ github-to-sqlite commits github.db simonw/datasette simonw/sqlite-utils
|
|
136
|
-
|
|
137
|
-
The command accepts one or more repositories.
|
|
138
|
-
|
|
139
|
-
By default it will stop as soon as it sees a commit that has previously been retrieved. You can force it to retrieve all commits (including those that have been previously inserted) using `--all`.
|
|
140
|
-
|
|
141
|
-
Example: [commits table](https://github-to-sqlite.dogsheep.net/github/commits)
|
|
142
|
-
|
|
143
|
-
## Fetching releases for a repository
|
|
144
|
-
|
|
145
|
-
The `releases` command retrieves the releases for one or more repositories.
|
|
146
|
-
|
|
147
|
-
$ github-to-sqlite releases github.db simonw/datasette simonw/sqlite-utils
|
|
148
|
-
|
|
149
|
-
The command accepts one or more repositories.
|
|
150
|
-
|
|
151
|
-
Example: [releases table](https://github-to-sqlite.dogsheep.net/github/releases)
|
|
152
|
-
|
|
153
|
-
## Fetching tags for a repository
|
|
154
|
-
|
|
155
|
-
The `tags` command retrieves all of the tags for one or more repositories.
|
|
156
|
-
|
|
157
|
-
$ github-to-sqlite tags github.db simonw/datasette simonw/sqlite-utils
|
|
158
|
-
|
|
159
|
-
Example: [tags table](https://github-to-sqlite.dogsheep.net/github/tags)
|
|
160
|
-
|
|
161
|
-
## Fetching contributors to a repository
|
|
162
|
-
|
|
163
|
-
The `contributors` command retrieves details of all of the contributors for one or more repositories.
|
|
164
|
-
|
|
165
|
-
$ github-to-sqlite contributors github.db simonw/datasette simonw/sqlite-utils
|
|
166
|
-
|
|
167
|
-
The command accepts one or more repositories. It populates a `contributors` table, with foreign keys to `repos` and `users` and a `contributions` table listing the number of commits to that repository for each contributor.
|
|
168
|
-
|
|
169
|
-
Example: [contributors table](https://github-to-sqlite.dogsheep.net/github/contributors)
|
|
170
|
-
|
|
171
|
-
## Fetching repos belonging to a user or organization
|
|
172
|
-
|
|
173
|
-
The `repos` command fetches repos belonging to a user or organization.
|
|
174
|
-
|
|
175
|
-
Without any other arguments, this command will fetch all repos that the currently authenticated user owns, collaborates on or can access via one of their organizations:
|
|
176
|
-
|
|
177
|
-
$ github-to-sqlite repos github.db
|
|
178
|
-
|
|
179
|
-
To fetch repos belonging to a specific user or organization, provide their username as an argument:
|
|
180
|
-
|
|
181
|
-
$ github-to-sqlite repos github.db dogsheep # organization
|
|
182
|
-
$ github-to-sqlite repos github.db simonw # user
|
|
183
|
-
|
|
184
|
-
You can pass more than one username to fetch for multiple users or organizations at once:
|
|
185
|
-
|
|
186
|
-
$ github-to-sqlite repos github.db simonw dogsheep
|
|
187
|
-
|
|
188
|
-
Add the `--readme` option to save the README for the repo in a column called `readme`. Add `--readme-html` to save the HTML rendered version of the README into a column called `readme_html`.
|
|
189
|
-
|
|
190
|
-
Example: [repos table](https://github-to-sqlite.dogsheep.net/github/repos)
|
|
191
|
-
|
|
192
|
-
## Fetching specific repositories
|
|
193
|
-
|
|
194
|
-
You can use `-r` with the `repos` command one or more times to fetch just specific repositories.
|
|
195
|
-
|
|
196
|
-
$ github-to-sqlite repos github.db -r simonw/datasette -r dogsheep/github-to-sqlite
|
|
197
|
-
|
|
198
|
-
## Fetching repos that have been starred by a user
|
|
199
|
-
|
|
200
|
-
The `starred` command fetches the repos that have been starred by a user.
|
|
201
|
-
|
|
202
|
-
$ github-to-sqlite starred github.db simonw
|
|
203
|
-
|
|
204
|
-
If you are using an `auth.json` file you can omit the username to retrieve the starred repos for the authenticated user.
|
|
205
|
-
|
|
206
|
-
Example: [stars table](https://github-to-sqlite.dogsheep.net/github/stars)
|
|
207
|
-
|
|
208
|
-
## Fetching users that have starred specific repos
|
|
209
|
-
|
|
210
|
-
The `stargazers` command fetches the users that have starred the specified repos.
|
|
211
|
-
|
|
212
|
-
$ github-to-sqlite stargazers github.db simonw/datasette dogsheep/github-to-sqlite
|
|
213
|
-
|
|
214
|
-
You can specify one or more repository using `owner/repo` syntax.
|
|
215
|
-
|
|
216
|
-
Users fetched using this command will be inserted into the `users` table. Many-to-many records showing which repository they starred will be added to the `stars` table.
|
|
217
|
-
|
|
218
|
-
## Fetching GitHub Actions workflows
|
|
219
|
-
|
|
220
|
-
The `workflows` command fetches the YAML workflow configurations from each repository's `.github/workflows` directory and parses them to populate `workflows`, `jobs` and `steps` tables.
|
|
221
|
-
|
|
222
|
-
$ github-to-sqlite workflows github.db simonw/datasette dogsheep/github-to-sqlite
|
|
223
|
-
|
|
224
|
-
You can specify one or more repository using `owner/repo` syntax.
|
|
225
|
-
|
|
226
|
-
Example: [workflows table](https://github-to-sqlite.dogsheep.net/github/workflows), [jobs table](https://github-to-sqlite.dogsheep.net/github/jobs), [steps table](https://github-to-sqlite.dogsheep.net/github/steps)
|
|
227
|
-
|
|
228
|
-
## Scraping dependents for a repository
|
|
229
|
-
|
|
230
|
-
The GitHub dependency graph can show other GitHub projects that depend on a specific repo, for example [simonw/datasette/network/dependents](https://github.com/simonw/datasette/network/dependents).
|
|
231
|
-
|
|
232
|
-
This data is not yet available through the GitHub API. The `scrape-dependents` command scrapes those pages and uses the GitHub API to load full versions of the dependent repositories.
|
|
233
|
-
|
|
234
|
-
$ github-to-sqlite scrape-dependents github.db simonw/datasette
|
|
235
|
-
|
|
236
|
-
The command accepts one or more repositories.
|
|
237
|
-
|
|
238
|
-
Add `-v` for verbose output.
|
|
239
|
-
|
|
240
|
-
Example: [dependents table](https://github-to-sqlite.dogsheep.net/github/dependents?_sort_desc=first_seen_utc)
|
|
241
|
-
|
|
242
|
-
## Fetching emojis
|
|
243
|
-
|
|
244
|
-
You can fetch a list of every emoji supported by GitHub using the `emojis` command:
|
|
245
|
-
|
|
246
|
-
$ github-to-sqlite emojis github.db
|
|
247
|
-
|
|
248
|
-
This will create a table called `emojis` with a primary key `name` and a `url` column.
|
|
249
|
-
|
|
250
|
-
If you add the `--fetch` option the command will also fetch the binary content of the images and place them in an `image` column:
|
|
251
|
-
|
|
252
|
-
$ github-to-sqlite emojis emojis.db -f
|
|
253
|
-
[########----------------------------] 397/1799 22% 00:03:43
|
|
254
|
-
|
|
255
|
-
You can then use the [datasette-render-images](https://github.com/simonw/datasette-render-images) plugin to browse them visually.
|
|
256
|
-
|
|
257
|
-
Example: [emojis table](https://github-to-sqlite.dogsheep.net/github/emojis)
|
|
258
|
-
|
|
259
|
-
## Making authenticated API calls
|
|
260
|
-
|
|
261
|
-
The `github-to-sqlite get` command provides a convenient shortcut for making authenticated calls to the API. Once you have created your `auth.json` file (or set a `GITHUB_TOKEN` environment variable) you can use it like this:
|
|
262
|
-
|
|
263
|
-
$ github-to-sqlite get https://api.github.com/gists
|
|
264
|
-
|
|
265
|
-
This will make an authenticated call to the URL you provide and pretty-print the resulting JSON to the console.
|
|
266
|
-
|
|
267
|
-
You can omit the `https://api.github.com/` prefix, for example:
|
|
268
|
-
|
|
269
|
-
$ github-to-sqlite get /gists
|
|
270
|
-
|
|
271
|
-
Many GitHub APIs are [paginated using the HTTP Link header](https://docs.github.com/en/rest/guides/traversing-with-pagination). You can follow this pagination and output a list of all of the resulting items using `--paginate`:
|
|
272
|
-
|
|
273
|
-
$ github-to-sqlite get /users/simonw/repos --paginate
|
|
274
|
-
|
|
275
|
-
You can outline newline-delimited JSON for each item using `--nl`. This can be useful for streaming items into another tool.
|
|
276
|
-
|
|
277
|
-
$ github-to-sqlite get /users/simonw/repos --nl
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
LICENSE
|
|
2
|
-
README.md
|
|
3
|
-
setup.py
|
|
4
|
-
github_to_sqlite/__init__.py
|
|
5
|
-
github_to_sqlite/cli.py
|
|
6
|
-
github_to_sqlite/utils.py
|
|
7
|
-
github_to_sqlite.egg-info/PKG-INFO
|
|
8
|
-
github_to_sqlite.egg-info/SOURCES.txt
|
|
9
|
-
github_to_sqlite.egg-info/dependency_links.txt
|
|
10
|
-
github_to_sqlite.egg-info/entry_points.txt
|
|
11
|
-
github_to_sqlite.egg-info/requires.txt
|
|
12
|
-
github_to_sqlite.egg-info/top_level.txt
|
|
13
|
-
tests/test_auth.py
|
|
14
|
-
tests/test_commits.py
|
|
15
|
-
tests/test_get.py
|
|
16
|
-
tests/test_issue_comments.py
|
|
17
|
-
tests/test_issues.py
|
|
18
|
-
tests/test_pull_requests.py
|
|
19
|
-
tests/test_releases.py
|
|
20
|
-
tests/test_repos.py
|
|
21
|
-
tests/test_scrape_dependents.py
|
|
22
|
-
tests/test_stargazers.py
|
|
23
|
-
tests/test_starred.py
|
|
24
|
-
tests/test_tags.py
|
|
25
|
-
tests/test_workflows.py
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
github_to_sqlite
|
github-to-sqlite-2.9/setup.cfg
DELETED
github-to-sqlite-2.9/setup.py
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
from setuptools import setup
|
|
2
|
-
import os
|
|
3
|
-
|
|
4
|
-
VERSION = "2.9"
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
def get_long_description():
|
|
8
|
-
with open(
|
|
9
|
-
os.path.join(os.path.dirname(os.path.abspath(__file__)), "README.md"),
|
|
10
|
-
encoding="utf8",
|
|
11
|
-
) as fp:
|
|
12
|
-
return fp.read()
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
setup(
|
|
16
|
-
name="github-to-sqlite",
|
|
17
|
-
description="Save data from GitHub to a SQLite database",
|
|
18
|
-
long_description=get_long_description(),
|
|
19
|
-
long_description_content_type="text/markdown",
|
|
20
|
-
author="Simon Willison",
|
|
21
|
-
url="https://github.com/dogsheep/github-to-sqlite",
|
|
22
|
-
license="Apache License, Version 2.0",
|
|
23
|
-
version=VERSION,
|
|
24
|
-
packages=["github_to_sqlite"],
|
|
25
|
-
entry_points="""
|
|
26
|
-
[console_scripts]
|
|
27
|
-
github-to-sqlite=github_to_sqlite.cli:cli
|
|
28
|
-
""",
|
|
29
|
-
install_requires=["sqlite-utils>=2.7.2", "requests", "PyYAML"],
|
|
30
|
-
extras_require={"test": ["pytest", "requests-mock", "bs4"]},
|
|
31
|
-
tests_require=["github-to-sqlite[test]"],
|
|
32
|
-
)
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
from click.testing import CliRunner
|
|
2
|
-
from github_to_sqlite import cli
|
|
3
|
-
import json
|
|
4
|
-
import os
|
|
5
|
-
import pytest
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
@pytest.fixture
|
|
9
|
-
def mocked_starred(requests_mock):
|
|
10
|
-
requests_mock.get("https://api.github.com/user", json={"id": 1, "login": "test"})
|
|
11
|
-
m = requests_mock.get("https://api.github.com/user/starred", json=[])
|
|
12
|
-
return m
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
def test_auth_command():
|
|
16
|
-
runner = CliRunner()
|
|
17
|
-
with runner.isolated_filesystem():
|
|
18
|
-
assert [] == os.listdir(".")
|
|
19
|
-
result = runner.invoke(cli.cli, ["auth"], input="zzz")
|
|
20
|
-
assert 0 == result.exit_code
|
|
21
|
-
assert ["auth.json"] == os.listdir(".")
|
|
22
|
-
assert {"github_personal_token": "zzz"} == json.load(open("auth.json"))
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
def test_auth_file(mocked_starred):
|
|
26
|
-
runner = CliRunner()
|
|
27
|
-
with runner.isolated_filesystem():
|
|
28
|
-
open("auth.json", "w").write(json.dumps({"github_personal_token": "xxx"}))
|
|
29
|
-
result = runner.invoke(
|
|
30
|
-
cli.cli, ["starred", "starred.db"], catch_exceptions=False
|
|
31
|
-
)
|
|
32
|
-
assert 0 == result.exit_code
|
|
33
|
-
assert mocked_starred.called
|
|
34
|
-
assert "token xxx" == mocked_starred.last_request.headers["authorization"]
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
def test_auth_environment_variable(mocked_starred, monkeypatch):
|
|
38
|
-
monkeypatch.setenv("GITHUB_TOKEN", "xyz")
|
|
39
|
-
runner = CliRunner()
|
|
40
|
-
with runner.isolated_filesystem():
|
|
41
|
-
result = runner.invoke(
|
|
42
|
-
cli.cli, ["starred", "starred.db"], catch_exceptions=False
|
|
43
|
-
)
|
|
44
|
-
assert 0 == result.exit_code
|
|
45
|
-
assert mocked_starred.called
|
|
46
|
-
assert "token xyz" == mocked_starred.last_request.headers["authorization"]
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
from github_to_sqlite import utils
|
|
2
|
-
import pytest
|
|
3
|
-
import pathlib
|
|
4
|
-
import sqlite_utils
|
|
5
|
-
from sqlite_utils.db import ForeignKey
|
|
6
|
-
import json
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
@pytest.fixture
|
|
10
|
-
def commits():
|
|
11
|
-
return json.load(open(pathlib.Path(__file__).parent / "commits.json"))
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
@pytest.fixture
|
|
15
|
-
def repo():
|
|
16
|
-
return json.load(open(pathlib.Path(__file__).parent / "repo.json"))
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
@pytest.fixture
|
|
20
|
-
def db(commits, repo):
|
|
21
|
-
db = sqlite_utils.Database(memory=True)
|
|
22
|
-
utils.save_repo(db, repo)
|
|
23
|
-
utils.save_commits(db, commits, repo["id"])
|
|
24
|
-
return db
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
def test_tables(db):
|
|
28
|
-
assert {"users", "commits", "raw_authors", "licenses", "repos"} == set(
|
|
29
|
-
db.table_names()
|
|
30
|
-
)
|
|
31
|
-
assert {
|
|
32
|
-
ForeignKey(
|
|
33
|
-
table="commits", column="committer", other_table="users", other_column="id"
|
|
34
|
-
),
|
|
35
|
-
ForeignKey(
|
|
36
|
-
table="commits", column="author", other_table="users", other_column="id"
|
|
37
|
-
),
|
|
38
|
-
ForeignKey(
|
|
39
|
-
table="commits",
|
|
40
|
-
column="raw_committer",
|
|
41
|
-
other_table="raw_authors",
|
|
42
|
-
other_column="id",
|
|
43
|
-
),
|
|
44
|
-
ForeignKey(
|
|
45
|
-
table="commits",
|
|
46
|
-
column="raw_author",
|
|
47
|
-
other_table="raw_authors",
|
|
48
|
-
other_column="id",
|
|
49
|
-
),
|
|
50
|
-
ForeignKey(
|
|
51
|
-
table="commits", column="repo", other_table="repos", other_column="id"
|
|
52
|
-
),
|
|
53
|
-
} == set(db["commits"].foreign_keys)
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
def test_commits(db):
|
|
57
|
-
commit_rows = list(db["commits"].rows)
|
|
58
|
-
raw_author_rows = list(db["raw_authors"].rows)
|
|
59
|
-
assert [
|
|
60
|
-
{
|
|
61
|
-
"sha": "9eb737090fafd0e5a7e314be48402374d99e9828",
|
|
62
|
-
"message": "Release 0.6",
|
|
63
|
-
"author_date": "2019-11-11T05:31:46Z",
|
|
64
|
-
"committer_date": "2019-11-11T05:31:46Z",
|
|
65
|
-
"raw_author": "13ae486343ea6454a93114c6f558ffea2f2c6874",
|
|
66
|
-
"raw_committer": "13ae486343ea6454a93114c6f558ffea2f2c6874",
|
|
67
|
-
"repo": 207052882,
|
|
68
|
-
"author": None,
|
|
69
|
-
"committer": None,
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
"sha": "1e6995a362e5b8f23331aafb84e631392eb81492",
|
|
73
|
-
"message": "--auth is now optional, closes #9",
|
|
74
|
-
"author_date": "2019-11-11T05:30:41Z",
|
|
75
|
-
"committer_date": "2019-11-11T05:30:41Z",
|
|
76
|
-
"raw_author": "13ae486343ea6454a93114c6f558ffea2f2c6874",
|
|
77
|
-
"raw_committer": "13ae486343ea6454a93114c6f558ffea2f2c6874",
|
|
78
|
-
"repo": 207052882,
|
|
79
|
-
"author": 9599,
|
|
80
|
-
"committer": 9599,
|
|
81
|
-
},
|
|
82
|
-
] == commit_rows
|
|
83
|
-
assert [
|
|
84
|
-
{
|
|
85
|
-
"id": "13ae486343ea6454a93114c6f558ffea2f2c6874",
|
|
86
|
-
"name": "Simon Willison",
|
|
87
|
-
"email": "swillison@gmail.com",
|
|
88
|
-
}
|
|
89
|
-
] == raw_author_rows
|