flask-githubkit 0.1.2__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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 LJFCoding
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,259 @@
1
+ Metadata-Version: 2.4
2
+ Name: flask-githubkit
3
+ Version: 0.1.2
4
+ Summary: Flask extension for GitHub OAuth login, built on GitHubKit. Handles expiring-token refresh and server-side sessions.
5
+ Author: LJFCoding
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/LJFCoding/flask-githubkit
8
+ Project-URL: Repository, https://github.com/LJFCoding/flask-githubkit
9
+ Project-URL: Issues, https://github.com/LJFCoding/flask-githubkit/issues
10
+ Keywords: flask,github,githubkit,oauth,authentication
11
+ Classifier: Framework :: Flask
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Topic :: Internet :: WWW/HTTP :: Session
18
+ Requires-Python: >=3.10
19
+ Description-Content-Type: text/markdown
20
+ License-File: LICENSE
21
+ Requires-Dist: Flask>=3.0
22
+ Requires-Dist: githubkit<1.0,>=0.16.1
23
+ Requires-Dist: httpx<1.0,>=0.23
24
+ Provides-Extra: test
25
+ Requires-Dist: pytest; extra == "test"
26
+ Requires-Dist: coverage; extra == "test"
27
+ Provides-Extra: lint
28
+ Requires-Dist: ruff; extra == "lint"
29
+ Requires-Dist: mypy; extra == "lint"
30
+ Dynamic: license-file
31
+
32
+ # flask-githubkit
33
+
34
+ A Flask extension for GitHub OAuth login, built on
35
+ [GitHubKit](https://github.com/yanyongyu/githubkit). It handles expiring-token
36
+ refresh and stores tokens in `flask.session`.
37
+
38
+ ## Installation
39
+
40
+ Install the release directly from GitHub:
41
+
42
+ ```console
43
+ pip install "flask-githubkit @ git+https://github.com/LJFCoding/flask-githubkit.git@v0.1.2"
44
+ ```
45
+
46
+ It is not published on PyPI yet, so `pip install flask-githubkit` will not
47
+ find it. It requires Python 3.10+ and installs Flask, GitHubKit and httpx.
48
+
49
+ For local development, install the test dependencies with
50
+ `pip install -e ".[test]"`.
51
+
52
+ ## How it works
53
+
54
+ 1. `github.login()` redirects the user to GitHub with a random `state` value
55
+ that is kept in `flask.session`.
56
+ 2. GitHub redirects back to your callback URL with a `code` and the `state`.
57
+ 3. `@github.callback` checks the `state` (blocking login CSRF), exchanges the
58
+ `code` for tokens through GitHubKit, saves them in `flask.session`, and
59
+ calls your view with the access token.
60
+ 4. In any later request, `github.client()` returns a GitHubKit client for that
61
+ user. GitHubKit refreshes an expired access token itself, and the new
62
+ token values are saved back to the session when the request finishes.
63
+
64
+ The names follow [Flask-GitHub](https://github.com/cenkalti/github-flask), but
65
+ the API is smaller and the HTTP calls are made by
66
+ [GitHubKit](https://github.com/yanyongyu/githubkit), so you get its typed
67
+ `rest` methods instead of raw `get`/`post` helpers. Only synchronous Flask
68
+ apps are supported.
69
+
70
+ ## Quick start
71
+
72
+ Register a GitHub OAuth App and set its callback URL to the value of
73
+ `GITHUB_REDIRECT_URI`. Enable **Expire user authorization tokens** in the
74
+ OAuth App settings if you want GitHub to issue refresh tokens.
75
+
76
+ ```python
77
+ import flask
78
+ import flask_githubkit
79
+
80
+ app = flask.Flask(__name__)
81
+ app.config.update(
82
+ SECRET_KEY="load-this-from-a-secret-manager",
83
+ GITHUB_CLIENT_ID="your-client-id",
84
+ GITHUB_CLIENT_SECRET="load-this-from-a-secret-manager",
85
+ GITHUB_REDIRECT_URI="https://example.com/callback",
86
+ GITHUB_SCOPE="read:user",
87
+ )
88
+
89
+ github = flask_githubkit.GitHub(app)
90
+
91
+
92
+ @app.route("/login")
93
+ @github.login
94
+ def login():
95
+ """Replaced by a redirect to GitHub."""
96
+
97
+
98
+ @app.route("/callback")
99
+ @github.callback
100
+ def callback(access_token):
101
+ if access_token is None:
102
+ return flask.jsonify(
103
+ {"message": "GitHub authorization was denied"}
104
+ ), 401
105
+ return flask.jsonify({"message": "Signed in"})
106
+
107
+
108
+ @app.route("/me")
109
+ def me():
110
+ api = github.client()
111
+ if api is None:
112
+ return flask.redirect(flask.url_for("login"))
113
+ user = api.rest.users.get_authenticated().parsed_data
114
+ return flask.jsonify({"login": user.login})
115
+ ```
116
+
117
+ `callback` validates the OAuth `state`, exchanges the authorization
118
+ code, stores the token data, and calls the decorated view with the access token.
119
+ If the user denies access, the view receives `None`. Protect callback handling
120
+ with the decorator as shown; it is responsible for validating `state`.
121
+
122
+ With an application factory, create the extension once and initialize it for
123
+ each app:
124
+
125
+ ```python
126
+ github = flask_githubkit.GitHub()
127
+
128
+
129
+ def create_app():
130
+ app = flask.Flask(__name__)
131
+ app.config.from_mapping(
132
+ SECRET_KEY="load-this-from-a-secret-manager",
133
+ GITHUB_CLIENT_ID="your-client-id",
134
+ GITHUB_CLIENT_SECRET="load-this-from-a-secret-manager",
135
+ GITHUB_REDIRECT_URI="https://example.com/callback",
136
+ GITHUB_SCOPE="read:user",
137
+ )
138
+ github.init_app(app)
139
+ return app
140
+ ```
141
+
142
+ ## Examples
143
+
144
+ Each file in [examples/](examples) is a complete app. They are checked by the
145
+ test suite, which confirms the login route redirects to GitHub.
146
+
147
+ | File | Shows |
148
+ | --- | --- |
149
+ | [single_file.py](examples/single_file.py) | A module-level app with `GitHub(app)` |
150
+ | [factory.py](examples/factory.py) | An app factory with `init_app` and the optional config keys |
151
+ | [blueprint.py](examples/blueprint.py) | Login routes in a blueprint; the `auth.login` endpoint is found from `@github.login` |
152
+ | [routes.py](examples/routes.py) | A `login_required` decorator and a route that calls the GitHub API |
153
+
154
+ Set `GITHUB_CLIENT_ID`, `GITHUB_CLIENT_SECRET` and `SECRET_KEY` in your
155
+ environment, then run one with, for example,
156
+ `flask --app examples/single_file run`.
157
+
158
+ Calling the API goes through GitHubKit, so see its
159
+ [documentation](https://yanyongyu.github.io/githubkit/) for everything
160
+ `client().rest` offers.
161
+
162
+ ## Coming from Flask-GitHub
163
+
164
+ | Flask-GitHub | flask-githubkit |
165
+ | --- | --- |
166
+ | `GitHub(app)` | `GitHub(app)` or `init_app(app)` |
167
+ | `github.authorize()` | `@github.login`, or `github.login()` in a view |
168
+ | `@github.authorized_handler` | `@github.callback` |
169
+ | `@github.access_token_getter` | Not needed: tokens are kept in `flask.session` |
170
+ | `github.get("user")` | `github.client().rest.users.get_authenticated()` |
171
+ | `authorize(scope=..., redirect_uri=...)` | Not supported: use `scope=` in `GitHub(...)` or `GITHUB_SCOPE`, and `GITHUB_REDIRECT_URI` |
172
+
173
+ ## Configuration and API
174
+
175
+ | Flask config key | Required | Purpose |
176
+ | --- | --- | --- |
177
+ | `GITHUB_CLIENT_ID` | Yes | GitHub OAuth App client ID |
178
+ | `GITHUB_CLIENT_SECRET` | Yes | GitHub OAuth App client secret |
179
+ | `GITHUB_REDIRECT_URI` | Yes | Callback URL registered with the OAuth App |
180
+ | `SECRET_KEY` | Yes | Flask session signing key |
181
+ | `GITHUB_SCOPE` | No | Space-separated OAuth scopes to request. Default `read:user`. |
182
+ | `GITHUB_LOGIN_VIEW` | No | Endpoint name users are sent to when their refresh token has expired. Usually not needed: see below. It is an endpoint name such as `auth.login`, not a URL. |
183
+
184
+ `flask_githubkit.GitHub(app=None, *, scope=None, login_view=None)` accepts an
185
+ optional Flask app. Use `init_app(app)` to initialize it later.
186
+
187
+ `scope` and `login_view` are optional. Each one is taken from the constructor
188
+ if you pass it, otherwise from `GITHUB_SCOPE` or `GITHUB_LOGIN_VIEW` in the
189
+ Flask config. If neither is set, the scope is `read:user`. The login view is
190
+ the view you decorated with `@github.login`, with its blueprint prefix
191
+ (`auth.login`), or an endpoint named `login` if there is no decorated view.
192
+ The client ID, client secret, redirect URI and `SECRET_KEY` always come from
193
+ the Flask config.
194
+
195
+ ```python
196
+ github = flask_githubkit.GitHub(
197
+ scope="read:user repo", login_view="auth.login"
198
+ )
199
+ ```
200
+
201
+ - `@github.login` turns a view into a redirect to GitHub that starts the
202
+ OAuth flow. You can also call `github.login()` inside a view and return
203
+ the result, which is useful if you want to run code first. The decorated
204
+ function's body never runs.
205
+ - `@callback` wraps the callback view.
206
+ - `client()` returns the request-cached GitHubKit `GitHub` client, or `None`
207
+ when there is no valid stored token.
208
+ - `logout()` removes the stored GitHub token from the session.
209
+
210
+ The extension registers an `AuthExpiredError` handler that clears the stored
211
+ token and redirects to the login view. GitHubKit also raises
212
+ `AuthExpiredError` when GitHub rejects the authorization code, so a stale or
213
+ reused code sends the user back to login. If GitHub cannot be reached while
214
+ exchanging the code (a timeout, a connection error or a 5xx response), the
215
+ callback returns a `502` JSON error, `Could not reach GitHub.`, and does not
216
+ call your view. If the login view is not a real
217
+ endpoint, the handler raises a `RuntimeError` that says so.
218
+
219
+ `flask_githubkit.Config.from_current_app()` reads the configuration keys above.
220
+ `flask_githubkit.Token` serializes token expiry datetimes as ISO-formatted
221
+ strings in `flask.session`.
222
+
223
+ ## Sessions, token refresh, and limitations
224
+
225
+ The default Flask session is a signed, client-side cookie; it is **not
226
+ encrypted**, so users can read its contents. This package stores OAuth token
227
+ data there, so use a server-side session backend such as Flask-Session with
228
+ Redis in production. The extension only uses `flask.session` and marks the
229
+ session permanent when it saves tokens. Configure your backend and
230
+ `PERMANENT_SESSION_LIFETIME` (for example, 30 days) in your application; sliding
231
+ expiry and TTL behavior depend on that backend and are not provided by this
232
+ package.
233
+
234
+ GitHubKit refreshes expired access tokens when the client is used. The extension
235
+ writes updated token values back to the session after the request. GitHub
236
+ refresh tokens are single-use, so concurrent requests can race while refreshing;
237
+ this package does not provide a distributed lock. Errors raised while your own
238
+ code uses `client()` (for example a network failure during an API call) are not
239
+ caught by the extension.
240
+
241
+ This package supports synchronous Flask apps and GitHub OAuth Apps. It does not
242
+ support GitHub Apps or configure GitHub Enterprise endpoints. Real GitHub code
243
+ exchange and refresh, Redis operation, and Flask-Session TTL behavior require
244
+ integration testing against those services and are not verified by the
245
+ automated tests in this repository.
246
+
247
+ ## Tests
248
+
249
+ ```console
250
+ pip install -e ".[test]"
251
+ pytest
252
+ ```
253
+
254
+ CI also requires 100% line and branch coverage:
255
+
256
+ ```console
257
+ coverage run -m pytest
258
+ coverage report
259
+ ```
@@ -0,0 +1,228 @@
1
+ # flask-githubkit
2
+
3
+ A Flask extension for GitHub OAuth login, built on
4
+ [GitHubKit](https://github.com/yanyongyu/githubkit). It handles expiring-token
5
+ refresh and stores tokens in `flask.session`.
6
+
7
+ ## Installation
8
+
9
+ Install the release directly from GitHub:
10
+
11
+ ```console
12
+ pip install "flask-githubkit @ git+https://github.com/LJFCoding/flask-githubkit.git@v0.1.2"
13
+ ```
14
+
15
+ It is not published on PyPI yet, so `pip install flask-githubkit` will not
16
+ find it. It requires Python 3.10+ and installs Flask, GitHubKit and httpx.
17
+
18
+ For local development, install the test dependencies with
19
+ `pip install -e ".[test]"`.
20
+
21
+ ## How it works
22
+
23
+ 1. `github.login()` redirects the user to GitHub with a random `state` value
24
+ that is kept in `flask.session`.
25
+ 2. GitHub redirects back to your callback URL with a `code` and the `state`.
26
+ 3. `@github.callback` checks the `state` (blocking login CSRF), exchanges the
27
+ `code` for tokens through GitHubKit, saves them in `flask.session`, and
28
+ calls your view with the access token.
29
+ 4. In any later request, `github.client()` returns a GitHubKit client for that
30
+ user. GitHubKit refreshes an expired access token itself, and the new
31
+ token values are saved back to the session when the request finishes.
32
+
33
+ The names follow [Flask-GitHub](https://github.com/cenkalti/github-flask), but
34
+ the API is smaller and the HTTP calls are made by
35
+ [GitHubKit](https://github.com/yanyongyu/githubkit), so you get its typed
36
+ `rest` methods instead of raw `get`/`post` helpers. Only synchronous Flask
37
+ apps are supported.
38
+
39
+ ## Quick start
40
+
41
+ Register a GitHub OAuth App and set its callback URL to the value of
42
+ `GITHUB_REDIRECT_URI`. Enable **Expire user authorization tokens** in the
43
+ OAuth App settings if you want GitHub to issue refresh tokens.
44
+
45
+ ```python
46
+ import flask
47
+ import flask_githubkit
48
+
49
+ app = flask.Flask(__name__)
50
+ app.config.update(
51
+ SECRET_KEY="load-this-from-a-secret-manager",
52
+ GITHUB_CLIENT_ID="your-client-id",
53
+ GITHUB_CLIENT_SECRET="load-this-from-a-secret-manager",
54
+ GITHUB_REDIRECT_URI="https://example.com/callback",
55
+ GITHUB_SCOPE="read:user",
56
+ )
57
+
58
+ github = flask_githubkit.GitHub(app)
59
+
60
+
61
+ @app.route("/login")
62
+ @github.login
63
+ def login():
64
+ """Replaced by a redirect to GitHub."""
65
+
66
+
67
+ @app.route("/callback")
68
+ @github.callback
69
+ def callback(access_token):
70
+ if access_token is None:
71
+ return flask.jsonify(
72
+ {"message": "GitHub authorization was denied"}
73
+ ), 401
74
+ return flask.jsonify({"message": "Signed in"})
75
+
76
+
77
+ @app.route("/me")
78
+ def me():
79
+ api = github.client()
80
+ if api is None:
81
+ return flask.redirect(flask.url_for("login"))
82
+ user = api.rest.users.get_authenticated().parsed_data
83
+ return flask.jsonify({"login": user.login})
84
+ ```
85
+
86
+ `callback` validates the OAuth `state`, exchanges the authorization
87
+ code, stores the token data, and calls the decorated view with the access token.
88
+ If the user denies access, the view receives `None`. Protect callback handling
89
+ with the decorator as shown; it is responsible for validating `state`.
90
+
91
+ With an application factory, create the extension once and initialize it for
92
+ each app:
93
+
94
+ ```python
95
+ github = flask_githubkit.GitHub()
96
+
97
+
98
+ def create_app():
99
+ app = flask.Flask(__name__)
100
+ app.config.from_mapping(
101
+ SECRET_KEY="load-this-from-a-secret-manager",
102
+ GITHUB_CLIENT_ID="your-client-id",
103
+ GITHUB_CLIENT_SECRET="load-this-from-a-secret-manager",
104
+ GITHUB_REDIRECT_URI="https://example.com/callback",
105
+ GITHUB_SCOPE="read:user",
106
+ )
107
+ github.init_app(app)
108
+ return app
109
+ ```
110
+
111
+ ## Examples
112
+
113
+ Each file in [examples/](examples) is a complete app. They are checked by the
114
+ test suite, which confirms the login route redirects to GitHub.
115
+
116
+ | File | Shows |
117
+ | --- | --- |
118
+ | [single_file.py](examples/single_file.py) | A module-level app with `GitHub(app)` |
119
+ | [factory.py](examples/factory.py) | An app factory with `init_app` and the optional config keys |
120
+ | [blueprint.py](examples/blueprint.py) | Login routes in a blueprint; the `auth.login` endpoint is found from `@github.login` |
121
+ | [routes.py](examples/routes.py) | A `login_required` decorator and a route that calls the GitHub API |
122
+
123
+ Set `GITHUB_CLIENT_ID`, `GITHUB_CLIENT_SECRET` and `SECRET_KEY` in your
124
+ environment, then run one with, for example,
125
+ `flask --app examples/single_file run`.
126
+
127
+ Calling the API goes through GitHubKit, so see its
128
+ [documentation](https://yanyongyu.github.io/githubkit/) for everything
129
+ `client().rest` offers.
130
+
131
+ ## Coming from Flask-GitHub
132
+
133
+ | Flask-GitHub | flask-githubkit |
134
+ | --- | --- |
135
+ | `GitHub(app)` | `GitHub(app)` or `init_app(app)` |
136
+ | `github.authorize()` | `@github.login`, or `github.login()` in a view |
137
+ | `@github.authorized_handler` | `@github.callback` |
138
+ | `@github.access_token_getter` | Not needed: tokens are kept in `flask.session` |
139
+ | `github.get("user")` | `github.client().rest.users.get_authenticated()` |
140
+ | `authorize(scope=..., redirect_uri=...)` | Not supported: use `scope=` in `GitHub(...)` or `GITHUB_SCOPE`, and `GITHUB_REDIRECT_URI` |
141
+
142
+ ## Configuration and API
143
+
144
+ | Flask config key | Required | Purpose |
145
+ | --- | --- | --- |
146
+ | `GITHUB_CLIENT_ID` | Yes | GitHub OAuth App client ID |
147
+ | `GITHUB_CLIENT_SECRET` | Yes | GitHub OAuth App client secret |
148
+ | `GITHUB_REDIRECT_URI` | Yes | Callback URL registered with the OAuth App |
149
+ | `SECRET_KEY` | Yes | Flask session signing key |
150
+ | `GITHUB_SCOPE` | No | Space-separated OAuth scopes to request. Default `read:user`. |
151
+ | `GITHUB_LOGIN_VIEW` | No | Endpoint name users are sent to when their refresh token has expired. Usually not needed: see below. It is an endpoint name such as `auth.login`, not a URL. |
152
+
153
+ `flask_githubkit.GitHub(app=None, *, scope=None, login_view=None)` accepts an
154
+ optional Flask app. Use `init_app(app)` to initialize it later.
155
+
156
+ `scope` and `login_view` are optional. Each one is taken from the constructor
157
+ if you pass it, otherwise from `GITHUB_SCOPE` or `GITHUB_LOGIN_VIEW` in the
158
+ Flask config. If neither is set, the scope is `read:user`. The login view is
159
+ the view you decorated with `@github.login`, with its blueprint prefix
160
+ (`auth.login`), or an endpoint named `login` if there is no decorated view.
161
+ The client ID, client secret, redirect URI and `SECRET_KEY` always come from
162
+ the Flask config.
163
+
164
+ ```python
165
+ github = flask_githubkit.GitHub(
166
+ scope="read:user repo", login_view="auth.login"
167
+ )
168
+ ```
169
+
170
+ - `@github.login` turns a view into a redirect to GitHub that starts the
171
+ OAuth flow. You can also call `github.login()` inside a view and return
172
+ the result, which is useful if you want to run code first. The decorated
173
+ function's body never runs.
174
+ - `@callback` wraps the callback view.
175
+ - `client()` returns the request-cached GitHubKit `GitHub` client, or `None`
176
+ when there is no valid stored token.
177
+ - `logout()` removes the stored GitHub token from the session.
178
+
179
+ The extension registers an `AuthExpiredError` handler that clears the stored
180
+ token and redirects to the login view. GitHubKit also raises
181
+ `AuthExpiredError` when GitHub rejects the authorization code, so a stale or
182
+ reused code sends the user back to login. If GitHub cannot be reached while
183
+ exchanging the code (a timeout, a connection error or a 5xx response), the
184
+ callback returns a `502` JSON error, `Could not reach GitHub.`, and does not
185
+ call your view. If the login view is not a real
186
+ endpoint, the handler raises a `RuntimeError` that says so.
187
+
188
+ `flask_githubkit.Config.from_current_app()` reads the configuration keys above.
189
+ `flask_githubkit.Token` serializes token expiry datetimes as ISO-formatted
190
+ strings in `flask.session`.
191
+
192
+ ## Sessions, token refresh, and limitations
193
+
194
+ The default Flask session is a signed, client-side cookie; it is **not
195
+ encrypted**, so users can read its contents. This package stores OAuth token
196
+ data there, so use a server-side session backend such as Flask-Session with
197
+ Redis in production. The extension only uses `flask.session` and marks the
198
+ session permanent when it saves tokens. Configure your backend and
199
+ `PERMANENT_SESSION_LIFETIME` (for example, 30 days) in your application; sliding
200
+ expiry and TTL behavior depend on that backend and are not provided by this
201
+ package.
202
+
203
+ GitHubKit refreshes expired access tokens when the client is used. The extension
204
+ writes updated token values back to the session after the request. GitHub
205
+ refresh tokens are single-use, so concurrent requests can race while refreshing;
206
+ this package does not provide a distributed lock. Errors raised while your own
207
+ code uses `client()` (for example a network failure during an API call) are not
208
+ caught by the extension.
209
+
210
+ This package supports synchronous Flask apps and GitHub OAuth Apps. It does not
211
+ support GitHub Apps or configure GitHub Enterprise endpoints. Real GitHub code
212
+ exchange and refresh, Redis operation, and Flask-Session TTL behavior require
213
+ integration testing against those services and are not verified by the
214
+ automated tests in this repository.
215
+
216
+ ## Tests
217
+
218
+ ```console
219
+ pip install -e ".[test]"
220
+ pytest
221
+ ```
222
+
223
+ CI also requires 100% line and branch coverage:
224
+
225
+ ```console
226
+ coverage run -m pytest
227
+ coverage report
228
+ ```
@@ -0,0 +1,67 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "flask-githubkit"
7
+ version = "0.1.2"
8
+ description = "Flask extension for GitHub OAuth login, built on GitHubKit. Handles expiring-token refresh and server-side sessions."
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = "MIT"
12
+ license-files = ["LICENSE"]
13
+ authors = [{ name = "LJFCoding" }]
14
+ keywords = ["flask", "github", "githubkit", "oauth", "authentication"]
15
+ classifiers = [
16
+ "Framework :: Flask",
17
+ "Intended Audience :: Developers",
18
+ "Programming Language :: Python :: 3",
19
+ "Programming Language :: Python :: 3.10",
20
+ "Programming Language :: Python :: 3.11",
21
+ "Programming Language :: Python :: 3.12",
22
+ "Topic :: Internet :: WWW/HTTP :: Session",
23
+ ]
24
+ dependencies = [
25
+ "Flask>=3.0",
26
+ "githubkit>=0.16.1,<1.0",
27
+ "httpx>=0.23,<1.0",
28
+ ]
29
+
30
+ [project.optional-dependencies]
31
+ test = ["pytest", "coverage"]
32
+ lint = ["ruff", "mypy"]
33
+
34
+ [project.urls]
35
+ Homepage = "https://github.com/LJFCoding/flask-githubkit"
36
+ Repository = "https://github.com/LJFCoding/flask-githubkit"
37
+ Issues = "https://github.com/LJFCoding/flask-githubkit/issues"
38
+
39
+ [tool.setuptools.packages.find]
40
+ where = ["src"]
41
+
42
+ [tool.setuptools.package-data]
43
+ flask_githubkit = ["py.typed"]
44
+
45
+ [tool.pytest.ini_options]
46
+ testpaths = ["tests"]
47
+
48
+ [tool.coverage.run]
49
+ branch = true
50
+ source = ["flask_githubkit"]
51
+
52
+ [tool.coverage.report]
53
+ fail_under = 100
54
+ show_missing = true
55
+
56
+ [tool.mypy]
57
+ strict = true
58
+ files = ["src"]
59
+
60
+ [tool.ruff]
61
+ line-length = 79
62
+
63
+ [tool.ruff.lint]
64
+ extend-select = ["E501", "TID252"]
65
+
66
+ [tool.ruff.lint.flake8-tidy-imports]
67
+ ban-relative-imports = "all"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,11 @@
1
+ """Flask extension for GitHub OAuth login, built on GitHubKit."""
2
+
3
+ import flask_githubkit.auth
4
+ import flask_githubkit.config
5
+ import flask_githubkit.store
6
+
7
+ GitHub = flask_githubkit.auth.GitHub
8
+ Config = flask_githubkit.config.Config
9
+ Token = flask_githubkit.store.Token
10
+
11
+ __all__ = ["Config", "GitHub", "Token"]