apikee 0.0.7__tar.gz → 0.1.2.dev0__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.
Files changed (49) hide show
  1. apikee-0.1.2.dev0/.github/CODEOWNERS +3 -0
  2. apikee-0.1.2.dev0/.github/ISSUE_TEMPLATE/bug_report.yml +41 -0
  3. apikee-0.1.2.dev0/.github/ISSUE_TEMPLATE/config.yml +5 -0
  4. apikee-0.1.2.dev0/.github/ISSUE_TEMPLATE/feature_request.yml +22 -0
  5. apikee-0.1.2.dev0/.github/PULL_REQUEST_TEMPLATE.md +9 -0
  6. apikee-0.1.2.dev0/.github/dependabot.yml +15 -0
  7. apikee-0.1.2.dev0/.github/workflows/release.yml +196 -0
  8. apikee-0.1.2.dev0/.gitignore +32 -0
  9. apikee-0.1.2.dev0/.release-please-manifest.json +3 -0
  10. apikee-0.1.2.dev0/AGENTS.md +64 -0
  11. apikee-0.1.2.dev0/CONTRIBUTING.md +80 -0
  12. apikee-0.1.2.dev0/LICENSE +21 -0
  13. apikee-0.1.2.dev0/PKG-INFO +166 -0
  14. apikee-0.1.2.dev0/README.md +132 -0
  15. apikee-0.1.2.dev0/apikee/__init__.py +33 -0
  16. apikee-0.1.2.dev0/apikee/core.py +269 -0
  17. apikee-0.1.2.dev0/apikee/crypto.py +114 -0
  18. apikee-0.1.2.dev0/apikee/fastapi.py +170 -0
  19. apikee-0.1.2.dev0/apikee/flask.py +138 -0
  20. apikee-0.1.2.dev0/apikee/key.py +287 -0
  21. apikee-0.1.2.dev0/apikee/server.py +232 -0
  22. apikee-0.1.2.dev0/examples/fastapi/README.md +22 -0
  23. apikee-0.1.2.dev0/examples/fastapi/main.py +47 -0
  24. apikee-0.1.2.dev0/examples/flask/README.md +20 -0
  25. apikee-0.1.2.dev0/examples/flask/app.py +47 -0
  26. apikee-0.1.2.dev0/examples/starlette/README.md +12 -0
  27. apikee-0.1.2.dev0/examples/starlette/app.py +41 -0
  28. apikee-0.1.2.dev0/pyproject.toml +40 -0
  29. apikee-0.1.2.dev0/pytest.ini +3 -0
  30. apikee-0.1.2.dev0/release-please-config.json +22 -0
  31. apikee-0.1.2.dev0/tests/smoke.py +87 -0
  32. apikee-0.1.2.dev0/tests/test_apikee.py +206 -0
  33. apikee-0.0.7/PKG-INFO +0 -140
  34. apikee-0.0.7/README.md +0 -130
  35. apikee-0.0.7/apikee/__init__.py +0 -4
  36. apikee-0.0.7/apikee/config.py +0 -30
  37. apikee-0.0.7/apikee/middleware.py +0 -42
  38. apikee-0.0.7/apikee/security.py +0 -56
  39. apikee-0.0.7/apikee/server/client.py +0 -113
  40. apikee-0.0.7/apikee/server/error.py +0 -19
  41. apikee-0.0.7/apikee/server/types.py +0 -42
  42. apikee-0.0.7/apikee/test.py +0 -28
  43. apikee-0.0.7/apikee.egg-info/PKG-INFO +0 -140
  44. apikee-0.0.7/apikee.egg-info/SOURCES.txt +0 -15
  45. apikee-0.0.7/apikee.egg-info/dependency_links.txt +0 -1
  46. apikee-0.0.7/apikee.egg-info/top_level.txt +0 -1
  47. apikee-0.0.7/setup.cfg +0 -4
  48. apikee-0.0.7/setup.py +0 -15
  49. {apikee-0.0.7/apikee/server → apikee-0.1.2.dev0/tests}/__init__.py +0 -0
@@ -0,0 +1,3 @@
1
+ # Default owners for everything in the repo.
2
+ # Required for branch protection's "Require review from Code Owners".
3
+ * @usmhic
@@ -0,0 +1,41 @@
1
+ name: Bug report
2
+ description: Report a problem with the apikee Python package
3
+ labels: [bug]
4
+ body:
5
+ - type: textarea
6
+ id: description
7
+ attributes:
8
+ label: What happened?
9
+ description: A clear description of the bug.
10
+ validations:
11
+ required: true
12
+ - type: textarea
13
+ id: reproduce
14
+ attributes:
15
+ label: Steps to reproduce
16
+ placeholder: |
17
+ 1. ...
18
+ 2. ...
19
+ 3. ...
20
+ validations:
21
+ required: true
22
+ - type: textarea
23
+ id: expected
24
+ attributes:
25
+ label: Expected behavior
26
+ validations:
27
+ required: false
28
+ - type: input
29
+ id: version
30
+ attributes:
31
+ label: Package version
32
+ placeholder: e.g. apikee==0.1.2 (or a .devN pre-release)
33
+ validations:
34
+ required: false
35
+ - type: textarea
36
+ id: env
37
+ attributes:
38
+ label: Environment
39
+ placeholder: Python version, optional extras installed (fast/server/fastapi/all), OS, etc.
40
+ validations:
41
+ required: false
@@ -0,0 +1,5 @@
1
+ blank_issues_enabled: false
2
+ contact_links:
3
+ - name: Questions & discussions
4
+ url: https://github.com/apikee-dev/python/discussions
5
+ about: Ask questions and discuss ideas with the community
@@ -0,0 +1,22 @@
1
+ name: Feature request
2
+ description: Suggest an idea for the apikee Python package
3
+ labels: [enhancement]
4
+ body:
5
+ - type: textarea
6
+ id: problem
7
+ attributes:
8
+ label: What problem does this solve?
9
+ validations:
10
+ required: true
11
+ - type: textarea
12
+ id: solution
13
+ attributes:
14
+ label: Proposed solution
15
+ validations:
16
+ required: false
17
+ - type: textarea
18
+ id: alternatives
19
+ attributes:
20
+ label: Alternatives considered
21
+ validations:
22
+ required: false
@@ -0,0 +1,9 @@
1
+ ## Summary
2
+
3
+ <!-- What does this PR do, and why? -->
4
+
5
+ ## Checklist
6
+
7
+ - [ ] PR title follows [Conventional Commits](https://www.conventionalcommits.org/) (e.g. `feat: ...`, `fix: ...`)
8
+ - [ ] `pytest -q` and `python -m build` pass locally
9
+ - [ ] Documentation updated (README, CONTRIBUTING.md) if needed
@@ -0,0 +1,15 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: pip
4
+ directory: "/"
5
+ schedule:
6
+ interval: weekly
7
+ groups:
8
+ pip-dependencies:
9
+ patterns:
10
+ - "*"
11
+
12
+ - package-ecosystem: github-actions
13
+ directory: "/"
14
+ schedule:
15
+ interval: weekly
@@ -0,0 +1,196 @@
1
+ name: python-cicd
2
+
3
+ on:
4
+ pull_request:
5
+ paths:
6
+ - "apikee/**"
7
+ - "tests/**"
8
+ - "pyproject.toml"
9
+ - ".github/workflows/**"
10
+ push:
11
+ branches:
12
+ - main
13
+ - dev
14
+ workflow_dispatch:
15
+
16
+ permissions:
17
+ contents: read
18
+ id-token: write
19
+
20
+ jobs:
21
+ validate:
22
+ name: Validate, Test, Package
23
+ runs-on: ubuntu-latest
24
+
25
+ steps:
26
+ - name: Checkout
27
+ uses: actions/checkout@v4
28
+
29
+ - name: Setup Python
30
+ uses: actions/setup-python@v5
31
+ with:
32
+ python-version: "3.11"
33
+ cache: pip
34
+ cache-dependency-path: pyproject.toml
35
+
36
+ - name: Install dependencies
37
+ run: |
38
+ python -m pip install --upgrade pip
39
+ pip install -e .[all]
40
+ pip install build twine pytest pytest-asyncio httpx
41
+
42
+ - name: Test
43
+ run: pytest -q
44
+
45
+ - name: Build package
46
+ run: python -m build
47
+
48
+ - name: Check artifacts
49
+ run: twine check dist/*
50
+
51
+ - name: Upload package artifact (PR)
52
+ if: github.event_name == 'pull_request'
53
+ uses: actions/upload-artifact@v4
54
+ with:
55
+ name: python-package-${{ github.event.pull_request.number }}
56
+ path: dist/*
57
+ if-no-files-found: error
58
+
59
+ - name: Dependency review (PR)
60
+ if: github.event_name == 'pull_request'
61
+ uses: actions/dependency-review-action@v4
62
+
63
+ - name: Vulnerability scan (Trivy)
64
+ uses: aquasecurity/trivy-action@v0.36.0
65
+ with:
66
+ scan-type: fs
67
+ scan-ref: .
68
+ format: table
69
+ severity: CRITICAL,HIGH
70
+ ignore-unfixed: true
71
+ exit-code: 1
72
+
73
+ pr-title:
74
+ name: PR Title (Conventional Commits)
75
+ if: github.event_name == 'pull_request'
76
+ runs-on: ubuntu-latest
77
+ permissions:
78
+ pull-requests: read
79
+ steps:
80
+ - uses: amannn/action-semantic-pull-request@v5
81
+ env:
82
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
83
+
84
+ release-please:
85
+ name: Release Please
86
+ if: github.event_name == 'push' && github.ref == 'refs/heads/main'
87
+ runs-on: ubuntu-latest
88
+ permissions:
89
+ contents: write
90
+ pull-requests: write
91
+ outputs:
92
+ release_created: ${{ steps.release.outputs.release_created }}
93
+ tag_name: ${{ steps.release.outputs.tag_name }}
94
+ steps:
95
+ - uses: googleapis/release-please-action@v4
96
+ id: release
97
+ with:
98
+ config-file: release-please-config.json
99
+ manifest-file: .release-please-manifest.json
100
+
101
+ publish-dev:
102
+ name: Publish Dev (dev)
103
+ if: github.event_name == 'push' && github.ref == 'refs/heads/dev'
104
+ needs: validate
105
+ runs-on: ubuntu-latest
106
+
107
+ steps:
108
+ - name: Checkout
109
+ uses: actions/checkout@v4
110
+
111
+ - name: Setup Python
112
+ uses: actions/setup-python@v5
113
+ with:
114
+ python-version: "3.11"
115
+ cache: pip
116
+ cache-dependency-path: pyproject.toml
117
+
118
+ - name: Install build tools
119
+ run: |
120
+ python -m pip install --upgrade pip
121
+ pip install build twine
122
+
123
+ - name: Compute next dev version
124
+ run: |
125
+ python - <<'PY'
126
+ import json, re, pathlib, urllib.request
127
+
128
+ text = pathlib.Path("pyproject.toml").read_text()
129
+ m = re.search(r'^version\s*=\s*"([^"]+)"', text, re.M)
130
+ if not m:
131
+ raise SystemExit("Could not find version in pyproject.toml")
132
+ base = re.sub(r"\.dev\d+$", "", m.group(1))
133
+
134
+ next_num = 0
135
+ try:
136
+ with urllib.request.urlopen("https://pypi.org/pypi/apikee/json", timeout=10) as r:
137
+ releases = json.loads(r.read()).get("releases", {})
138
+ pat = re.compile(r"^" + re.escape(base) + r"\.dev(\d+)$")
139
+ nums = [int(mm.group(1)) for v in releases for mm in [pat.match(v)] if mm]
140
+ if nums:
141
+ next_num = max(nums) + 1
142
+ except Exception:
143
+ pass
144
+
145
+ dev_version = f"{base}.dev{next_num}"
146
+ new_text = re.sub(r'^version\s*=\s*"[^"]+"', f'version = "{dev_version}"', text, count=1, flags=re.M)
147
+ pathlib.Path("pyproject.toml").write_text(new_text)
148
+ print(f"Dev version: {dev_version}")
149
+ PY
150
+
151
+ - name: Build package
152
+ run: python -m build
153
+
154
+ - name: Check artifacts
155
+ run: twine check dist/*
156
+
157
+ - name: Publish dev to PyPI (Trusted Publishing)
158
+ uses: pypa/gh-action-pypi-publish@release/v1
159
+ with:
160
+ packages-dir: dist/
161
+
162
+ publish-release:
163
+ name: Publish Release (main)
164
+ needs: [validate, release-please]
165
+ if: |
166
+ needs.validate.result == 'success' &&
167
+ needs.release-please.result == 'success' &&
168
+ needs.release-please.outputs.release_created == 'true'
169
+ runs-on: ubuntu-latest
170
+
171
+ steps:
172
+ - name: Checkout
173
+ uses: actions/checkout@v4
174
+
175
+ - name: Setup Python
176
+ uses: actions/setup-python@v5
177
+ with:
178
+ python-version: "3.11"
179
+ cache: pip
180
+ cache-dependency-path: pyproject.toml
181
+
182
+ - name: Install build tools
183
+ run: |
184
+ python -m pip install --upgrade pip
185
+ pip install build twine
186
+
187
+ - name: Build package
188
+ run: python -m build
189
+
190
+ - name: Check artifacts
191
+ run: twine check dist/*
192
+
193
+ - name: Publish release to PyPI (Trusted Publishing)
194
+ uses: pypa/gh-action-pypi-publish@release/v1
195
+ with:
196
+ packages-dir: dist/
@@ -0,0 +1,32 @@
1
+ # Python caches
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ .pytest_cache/
6
+ .mypy_cache/
7
+ .ruff_cache/
8
+
9
+ # Virtual environments
10
+ .venv/
11
+ venv/
12
+ env/
13
+
14
+ # Build outputs
15
+ dist/
16
+ build/
17
+ *.egg-info/
18
+
19
+ # Coverage
20
+ .coverage
21
+ coverage.xml
22
+ htmlcov/
23
+
24
+ # Environment
25
+ .env
26
+ .env.*
27
+ !.env.example
28
+
29
+ # Editor / OS
30
+ .DS_Store
31
+ .vscode/
32
+ .idea/
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.1.2"
3
+ }
@@ -0,0 +1,64 @@
1
+ # AGENTS.md — apikee Python
2
+
3
+ This file orients AI coding agents (and humans) working in this repository.
4
+
5
+ ## What this project is
6
+
7
+ `apikee` is an API key creation/validation plugin for Python — local-only by default
8
+ (zero dependencies), with optional integrations for FastAPI, Flask, and Starlette/ASGI.
9
+ It creates and verifies HMAC-signed API keys (`apikee_<claims>.<signature>`) carrying
10
+ tenant, scopes, and expiry, and can optionally talk to a self-hosted Apikee server for
11
+ key rotation, encrypted payloads (X25519 + AES-256-GCM), and RSA-signed requests. See
12
+ [README.md](./README.md) for usage examples and environment variables.
13
+
14
+ ## Build, test, lint
15
+
16
+ ```bash
17
+ python3 -m venv .venv && source .venv/bin/activate
18
+ pip install -e .[all] # all extras: fast (msgpack), server (cryptography), fastapi
19
+ pytest -q
20
+ python -m build # build sdist + wheel
21
+ ```
22
+
23
+ There is no separate lint step configured.
24
+
25
+ ## Source layout
26
+
27
+ ```
28
+ apikee/
29
+ __init__.py Public API surface — Apikee, ApikeeClaims, get_apikee(), etc.
30
+ core.py Apikee class — create()/verify()/protect(), config + env fallbacks
31
+ key.py Local key encode/decode/HMAC verify, RSA request signing (zero I/O)
32
+ crypto.py X25519 ECDH + AES-256-GCM encrypted channel for server mode
33
+ server.py ApikeeServer — HTTP client for a self-hosted Apikee instance
34
+ fastapi.py SecuredFastAPI, ApikeeDepends(), require_scope() for FastAPI
35
+ flask.py init_apikee(), apikee_required, require_scope() for Flask
36
+ tests/
37
+ test_apikee.py Unit tests (pytest)
38
+ smoke.py Smoke test for the installed package
39
+ examples/
40
+ fastapi/ Todo API example using apikee.fastapi
41
+ flask/ Notes API example using apikee.flask
42
+ starlette/ Items API example using Apikee().middleware (ASGI)
43
+ ```
44
+
45
+ ## Conventions
46
+
47
+ - **Local-only mode has zero runtime dependencies.** Optional extras
48
+ (`fast`/`server`/`fastapi`, see `pyproject.toml [project.optional-dependencies]`) are
49
+ required only for msgpack serialisation, the encrypted server channel, and FastAPI
50
+ integration respectively.
51
+ - `Apikee(...)` and `init_apikee()`/`SecuredFastAPI()` are zero-config — all server-mode
52
+ and crypto options fall back to `APIKEE_*` environment variables when not passed
53
+ explicitly (see `core.py`'s module docstring for the full list).
54
+ - Commit messages and PR titles follow [Conventional Commits](https://www.conventionalcommits.org/)
55
+ (`feat:`, `fix:`, `chore:`, `docs:`, `feat!:` for breaking changes).
56
+ - Branching: `dev` is the integration branch; every push queries the PyPI JSON API for the
57
+ latest published `.devN` counter with the same base version, increments it, and publishes.
58
+ `main` is the stable branch. **release-please** owns `version` in `pyproject.toml` and
59
+ `CHANGELOG.md` — never hand-edit either.
60
+
61
+ ## Contribution process
62
+
63
+ For the branch/PR workflow, release process, and required CI secrets and runtime
64
+ environment variables, see [CONTRIBUTING.md](./CONTRIBUTING.md).
@@ -0,0 +1,80 @@
1
+ # Contributing — apikee Python
2
+
3
+ Thanks for contributing! This guide covers the contribution workflow, branch
4
+ and release process, and required secrets/environment variables.
5
+
6
+ For build/test commands, project layout, and coding conventions, see
7
+ [AGENTS.md](./AGENTS.md) — the same reference used by AI coding agents.
8
+
9
+ ## Local setup
10
+
11
+ ```bash
12
+ python3 -m venv .venv && source .venv/bin/activate
13
+ pip install -e .[all]
14
+ pytest -q
15
+ python -m build
16
+ ```
17
+
18
+ ## Branch & PR flow
19
+
20
+ | Branch | Purpose | On push |
21
+ |---|---|---|
22
+ | `dev` | integration branch — branch your work from here | publishes a `.devN` pre-release to PyPI (`pip install --pre apikee`) |
23
+ | `main` | stable branch, protected | release-please opens/updates a release PR; merging it publishes the stable release |
24
+
25
+ 1. Branch from `dev`, naming it after the [Conventional Commits](https://www.conventionalcommits.org/)
26
+ type it corresponds to: `feature/<short-description>` (`feat:`), `fix/<short-description>`
27
+ (`fix:`), `chore/<short-description>` (`chore:`), `docs/<short-description>` (`docs:`).
28
+ 2. Open a PR into `dev` (or `main` for urgent hotfixes). CI runs the test suite, builds the
29
+ package, runs a dependency review, and scans for vulnerabilities (Trivy).
30
+ 3. **PR titles must follow Conventional Commits** (`type(scope?): description`) — a bot
31
+ checks this on open/edit. Examples: `feat: add async client support`, `fix(server):
32
+ correct signature verification`, `feat!: rename ApikeeClient constructor argument`
33
+ (the `!` marks a breaking change and triggers a major version bump).
34
+ 4. `main` and `dev` are protected branches — all changes land via a reviewed PR that
35
+ passes CI.
36
+
37
+ ## Releases
38
+
39
+ Versioning and `CHANGELOG.md` are fully automated by
40
+ [release-please](https://github.com/googleapis/release-please) from Conventional Commits
41
+ PR titles — never hand-edit `version` in `pyproject.toml` or commit dev versions.
42
+
43
+ - **Push to `dev`** → CI queries the PyPI JSON API for the latest published `.devN` version
44
+ with the same base (e.g. `0.1.2`), increments the counter by one, and publishes it to PyPI.
45
+ The first push for a new base starts at `0`. Install with `pip install --pre apikee`.
46
+ - **Merging the release-please PR on `main`** → CI publishes the stable release to PyPI.
47
+ PEP 440 guarantees `1.0.0 > 1.0.0.devN`, so `pip install apikee` always resolves to
48
+ the stable release. No additional deprecation step is needed.
49
+
50
+ ## Secrets & environment
51
+
52
+ ### CI/CD secrets (GitHub Actions)
53
+
54
+ | Secret | Used for | Notes |
55
+ |---|---|---|
56
+ | `GITHUB_TOKEN` | release-please, PR title check | auto-provided by GitHub Actions, no setup needed |
57
+ | *(none)* | PyPI publish | uses PyPI Trusted Publishing (OIDC) via `id-token: write` — no secret to configure, but the `apikee` project on PyPI must have a Trusted Publisher set up for `apikee-dev/python` |
58
+
59
+ ### Runtime environment variables
60
+
61
+ These configure the `apikee` package itself (used by the examples, tests, and any app
62
+ that depends on it):
63
+
64
+ | Variable | Required | Purpose |
65
+ |---|---|---|
66
+ | `APIKEE_SECRET` | yes\* | HMAC signing secret(s) used for local key creation/verification |
67
+ | `APIKEE_BASE_URL` | no | URL of a self-hosted Apikee instance — enables server mode |
68
+ | `APIKEE_SERVER_KEY` | no | API key for the Apikee instance (server mode) |
69
+ | `APIKEE_PROJECT_ENV` | no | project-env slug (server mode) |
70
+ | `APIKEE_SERVER_PUBLIC_KEY` | no | X25519 public key (base64) — enables payload encryption |
71
+ | `APIKEE_PRIVATE_KEY` | no | RSA private key (PEM) — signs server validation requests |
72
+
73
+ \* Not required if you only use server mode (`APIKEE_BASE_URL` + `APIKEE_SERVER_KEY`),
74
+ since the server validates keys remotely.
75
+
76
+ For local development, create a `.env` file (gitignored) with at least:
77
+
78
+ ```env
79
+ APIKEE_SECRET=replace-with-strong-random-secret
80
+ ```
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 apikee
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,166 @@
1
+ Metadata-Version: 2.4
2
+ Name: apikee
3
+ Version: 0.1.2.dev0
4
+ Summary: API key creation, validation & developer platform integration
5
+ Project-URL: Homepage, https://github.com/apikee-dev/python
6
+ Project-URL: Repository, https://github.com/apikee-dev/python
7
+ License: MIT
8
+ License-File: LICENSE
9
+ Keywords: api-key,authentication,middleware,security
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Programming Language :: Python :: 3.14
18
+ Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
19
+ Classifier: Topic :: Security
20
+ Requires-Python: >=3.10
21
+ Provides-Extra: all
22
+ Requires-Dist: cryptography>=41.0; extra == 'all'
23
+ Requires-Dist: fastapi>=0.100; extra == 'all'
24
+ Requires-Dist: msgpack>=1.0; extra == 'all'
25
+ Requires-Dist: starlette>=0.27; extra == 'all'
26
+ Provides-Extra: fast
27
+ Requires-Dist: msgpack>=1.0; extra == 'fast'
28
+ Provides-Extra: fastapi
29
+ Requires-Dist: fastapi>=0.100; extra == 'fastapi'
30
+ Requires-Dist: starlette>=0.27; extra == 'fastapi'
31
+ Provides-Extra: server
32
+ Requires-Dist: cryptography>=41.0; extra == 'server'
33
+ Description-Content-Type: text/markdown
34
+
35
+ # apikee · Python
36
+
37
+ [![PyPI](https://img.shields.io/pypi/v/apikee)](https://pypi.org/project/apikee/)
38
+
39
+ API key plugin for Python — FastAPI, Flask, and Starlette.
40
+
41
+ ## Install
42
+
43
+ ```bash
44
+ pip install apikee # local mode, zero deps
45
+ pip install "apikee[fastapi]" # + FastAPI middleware
46
+ pip install "apikee[server]" # + encrypted server channel
47
+ pip install "apikee[all]" # everything
48
+ pip install --pre apikee # latest dev pre-release
49
+ ```
50
+
51
+ ## Configure
52
+
53
+ ```bash
54
+ export APIKEE_SECRET=$(openssl rand -hex 32)
55
+
56
+ # Optional server mode — point to your self-hosted Apikee instance
57
+ export APIKEE_BASE_URL=https://apikee.example.com/api/v1
58
+ export APIKEE_SERVER_KEY=sk_...
59
+ export APIKEE_PROJECT_ENV=my-api-production
60
+ ```
61
+
62
+ ## FastAPI
63
+
64
+ ```python
65
+ from apikee.fastapi import SecuredFastAPI, ApikeeDepends, require_scope
66
+ from apikee import ApikeeClaims
67
+ from fastapi import Depends
68
+
69
+ app = SecuredFastAPI() # reads APIKEE_SECRET — done
70
+
71
+ @app.post("/keys") # public endpoint — issue keys to customers
72
+ def create_key(tenant: str, scopes: str = "read,write"):
73
+ key = app.apikee.create(tenant, scopes=scopes.split(","))
74
+ return {"key": key} # store it — returned once
75
+
76
+ @app.get("/data")
77
+ def get_data(claims: ApikeeClaims = ApikeeDepends()):
78
+ return {"tenant": claims.tenant, "scopes": claims.scopes}
79
+
80
+ @app.delete("/admin", dependencies=[Depends(require_scope("admin"))])
81
+ def admin_action(): ...
82
+ ```
83
+
84
+ Open `/docs` — every endpoint shows the 🔒 lock. Click **Authorize**, paste a key.
85
+
86
+ ## Flask
87
+
88
+ ```python
89
+ from flask import Flask
90
+ from apikee.flask import init_apikee, apikee_required, require_scope, get_claims
91
+
92
+ app = Flask(__name__)
93
+ init_apikee(app) # reads APIKEE_SECRET — done
94
+
95
+ @app.get("/data")
96
+ @apikee_required
97
+ def data():
98
+ return {"tenant": get_claims().tenant}
99
+
100
+ @app.delete("/admin")
101
+ @require_scope("admin")
102
+ def admin(): ...
103
+ ```
104
+
105
+ ## Any ASGI
106
+
107
+ ```python
108
+ from apikee import Apikee
109
+
110
+ apikee = Apikee()
111
+ app.add_middleware(apikee.middleware) # claims at request.state.apikee
112
+
113
+ # Or inline, no middleware:
114
+ claims = apikee.protect(request.headers.get("x-api-key"))
115
+ ```
116
+
117
+ ## Key rotation (zero downtime)
118
+
119
+ ```bash
120
+ export APIKEE_SECRET=new-secret # new keys signed with this
121
+ # Old keys still validate during the rotation window — pass both to Apikee():
122
+ ```
123
+ ```python
124
+ apikee = Apikee(secrets=["new-secret", "old-secret"])
125
+ ```
126
+
127
+ ## Environment Variables (.env)
128
+
129
+ Python frameworks (FastAPI, Flask, Starlette/ASGI) use the same variables.
130
+
131
+ Required:
132
+
133
+ ```env
134
+ APIKEE_SECRET=replace-with-strong-random-secret
135
+ ```
136
+
137
+ Optional (server mode — requires a running Apikee instance):
138
+
139
+ ```env
140
+ APIKEE_BASE_URL=https://apikee.example.com/api/v1
141
+ APIKEE_SERVER_KEY=sk_...
142
+ APIKEE_PROJECT_ENV=my-api-production
143
+ APIKEE_SERVER_PUBLIC_KEY=base64-x25519-public-key # enables payload encryption
144
+ APIKEE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----..." # enables RSA request signing
145
+ ```
146
+
147
+ ## Project structure
148
+
149
+ ```
150
+ apikee/ Library source — core + framework modules (FastAPI, Flask, server)
151
+ tests/ Test suite
152
+ examples/ Example apps (FastAPI, Flask, Starlette)
153
+ ```
154
+
155
+ ## Contributing
156
+
157
+ See [CONTRIBUTING.md](./CONTRIBUTING.md) for local setup, branch naming
158
+ conventions, and the release process.
159
+
160
+ ## License
161
+
162
+ [MIT](./LICENSE)
163
+
164
+ ## Docs
165
+
166
+ [github.com/apikee-dev](https://github.com/apikee-dev)