<div align="center">
# 🔐 Keymaster HJY
**Zero-config, professional-grade API security manager**
*Elegant authentication, rate limiting, and audit logging for modern Python APIs*
[](https://pypi.org/project/keymaster_hjy/)
[](https://pypi.org/project/keymaster_hjy/)
[](https://github.com/hjy/keymaster_hjy/blob/main/LICENSE)
[](https://pypi.org/project/keymaster_hjy/)
[](https://github.com/psf/black)
[](https://github.com/astral-sh/ruff)
[](https://mypy-lang.org/)
---
**🚀 Zero Configuration** • **🔒 Production Ready** • **⚡ High Performance** • **🎯 Framework Agnostic**
</div>
## ✨ Why Keymaster HJY?
<table>
<tr>
<td width="50%">
### 🎯 **Zero Configuration**
- Automatic environment detection
- Database schema auto-creation
- Intelligent defaults that just work
- No complex setup required
### 🔒 **Production Ready**
- Secure key hashing & storage
- Distributed rate limiting with Redis
- Comprehensive audit logging
- Thread-safe & async-compatible
</td>
<td width="50%">
### ⚡ **High Performance**
- Optimized database queries
- Efficient Redis operations
- Minimal memory footprint
- Sub-millisecond response times
### 🎨 **Developer Experience**
- Intuitive API design
- Complete type hints
- Framework integrations
- Excellent error messages
</td>
</tr>
</table>
## 🚀 Quick Start
### Installation
Choose the installation that matches your needs:
```bash
# For FastAPI projects
pip install keymaster_hjy[fastapi] -i https://pypi.tuna.tsinghua.edu.cn/simple
# For Flask projects
pip install keymaster_hjy[flask] -i https://pypi.tuna.tsinghua.edu.cn/simple
# With CLI tools for easy setup
pip install keymaster_hjy[cli] -i https://pypi.tuna.tsinghua.edu.cn/simple
# Everything included
pip install keymaster_hjy[all] -i https://pypi.tuna.tsinghua.edu.cn/simple
```
### Interactive Setup
The easiest way to get started is with our interactive CLI:
```bash
# Initialize a new project with guided setup
keymaster init
# Or initialize in a specific directory
keymaster init my-secure-api
```
This will:
- ✅ Guide you through database configuration
- ✅ Set up optional Redis for distributed rate limiting
- ✅ Generate framework-specific example applications
- ✅ Create all necessary configuration files
### Manual Configuration
Alternatively, create a `mysql.env` file manually:
```bash
# mysql.env - Database configuration
MYSQL_HOST=your-mysql-host
MYSQL_PORT=3306
MYSQL_USER=your_user
MYSQL_PASSWORD=your_password
MYSQL_DATABASE=your_database
# Optional: Redis for distributed rate limiting
REDIS_HOST=your-redis-host
REDIS_PORT=6379
REDIS_PASSWORD=your_redis_password
```
### Usage Examples
#### FastAPI Integration
```python
from fastapi import FastAPI
from keymaster_hjy.integrations import fastapi_guard
app = FastAPI()
# Basic protection - requires valid API key
@app.get("/api/data", dependencies=[fastapi_guard()])
async def get_data():
return {"message": "Protected data"}
# Scope-based protection
@app.get("/api/users", dependencies=[fastapi_guard("read:users")])
async def get_users():
return {"users": [...]}
@app.post("/api/users", dependencies=[fastapi_guard("write:users")])
async def create_user():
return {"status": "created"}
```
#### Flask Integration
```python
from flask import Flask
from keymaster_hjy.integrations import flask_guard
app = Flask(__name__)
@app.route("/api/data")
@flask_guard() # Basic protection
def get_data():
return {"message": "Protected data"}
@app.route("/api/admin")
@flask_guard("admin:access") # Scope-based protection
def admin_panel():
return {"message": "Admin access granted"}
```
### API Key Management
#### Creating API Keys
```python
from keymaster_hjy import master
# Create a basic API key
key_info = master.keys.create(
description="My application key",
tags=["production"],
scopes=["read:users", "write:data"]
)
print(f"Key ID: {key_info['id']}")
print(f"API Key: {key_info['key']}") # Store this securely!
```
#### Testing Your API
Once you have an API key, test your protected endpoints:
```bash
# Test with curl
curl -H "X-API-Key: your-api-key-here" http://localhost:8000/api/data
# Test with httpx (Python)
import httpx
response = httpx.get(
"http://localhost:8000/api/data",
headers={"X-API-Key": "your-api-key-here"}
)
```
#### Key Management Operations
```python
# Rotate a key (old key expires after transition period)
new_key = master.keys.rotate(key_id=123, transition_period_hours=24)
# Deactivate a key
master.keys.deactivate(key_id=123)
# Manual validation
try:
master.auth.validate_key("your-key", required_scope="read:data")
print("✅ Key is valid and has required scope")
except Exception as e:
print(f"❌ Validation failed: {e}")
```
## 📚 API Reference
### Key Management (`master.keys`)
| Method | Description | Returns |
|--------|-------------|---------|
| `create(description, **opts)` | Create new API key | `{'id': int, 'key': str}` |
| `deactivate(key_id)` | Deactivate a key | `None` |
| `rotate(key_id, transition_period_hours=24)` | Rotate key with grace period | `{'id': int, 'key': str}` |
**Create Options:**
- `rate_limit`: Custom rate limit (e.g., `"100/minute"`)
- `expires_at`: Expiration date (ISO string)
- `tags`: List of tags for organization
- `scopes`: List of permission scopes
### Authentication (`master.auth`)
| Method | Description | Exceptions |
|--------|-------------|------------|
| `validate_key(key, **opts)` | Validate API key | `InvalidKeyError`, `KeyExpiredError`, `RateLimitExceededError`, `ScopeDeniedError` |
**Validation Options:**
- `required_scope`: Required permission scope
- `request_id`: Request tracking ID
- `source_ip`: Client IP address
- `request_method`: HTTP method
- `request_path`: Request path
### Framework Integrations
```python
from keymaster_hjy.integrations import fastapi_guard, flask_guard
# FastAPI
@app.get("/path", dependencies=[fastapi_guard("scope?")])
# Flask
@flask_guard("scope?")
```
## 🔧 Advanced Features
### Custom Rate Limits
```python
# High-frequency API key
key_info = master.keys.create(
description="Batch processing service",
rate_limit="1000/minute" # Custom limit
)
# Different limits for different use cases
analytics_key = master.keys.create(
description="Analytics dashboard",
rate_limit="50/second"
)
```
### Key Organization with Tags
```python
# Organize keys by environment and purpose
prod_key = master.keys.create(
description="Production mobile app",
tags=["production", "mobile", "v2.1"],
scopes=["read:users", "write:analytics"]
)
# Query and manage by tags (future feature)
# keys_by_tag = master.keys.find_by_tags(["production"])
```
### Automatic Key Rotation
```python
# Rotate keys with zero downtime
new_key = master.keys.rotate(
key_id=123,
transition_period_hours=48 # Old key valid for 48h
)
print(f"New key: {new_key['key']}")
print("Update your applications with the new key within 48 hours")
```
## 🚨 Error Handling
Keymaster provides clear, actionable error messages:
```python
from keymaster_hjy.exceptions import (
InvalidKeyError,
KeyDeactivatedError,
KeyExpiredError,
RateLimitExceededError,
ScopeDeniedError
)
try:
master.auth.validate_key("your-key", required_scope="read:data")
except InvalidKeyError:
# Key not found or malformed
return {"error": "Invalid API key provided"}
except KeyExpiredError:
# Key has expired
return {"error": "API key expired, please generate a new one"}
except ScopeDeniedError:
# Missing required permissions
return {"error": "Insufficient permissions for this operation"}
except RateLimitExceededError:
# Too many requests
return {"error": "Rate limit exceeded, please try again later"}
```
### HTTP Status Mapping
| Exception | HTTP Status | Description |
|-----------|-------------|-------------|
| `InvalidKeyError` | 401 Unauthorized | Key not found or invalid format |
| `KeyDeactivatedError` | 401 Unauthorized | Key has been deactivated |
| `KeyExpiredError` | 401 Unauthorized | Key has expired |
| `ScopeDeniedError` | 403 Forbidden | Missing required permissions |
| `RateLimitExceededError` | 429 Too Many Requests | Rate limit exceeded |
## ⚙️ Configuration
### Environment Variables
All configuration is done through the `mysql.env` file:
```bash
# Database (Required)
MYSQL_HOST=your-mysql-host
MYSQL_PORT=3306
MYSQL_USER=your-username
MYSQL_PASSWORD=your-password
MYSQL_DATABASE=your-database
# Redis (Optional - for distributed rate limiting)
REDIS_HOST=your-redis-host
REDIS_PORT=6379
REDIS_PASSWORD=your-redis-password
```
### Default Settings
| Setting | Default Value | Description |
|---------|---------------|-------------|
| Key Prefix | `lingchongtong-` | Prefix for generated keys |
| Rate Limit | `100/minute` | Default rate limit for new keys |
| Config Refresh | `30 seconds` | Settings cache refresh interval |
> 💡 **Pro Tip**: All settings are stored in your database and can be modified at runtime by updating the `keymaster_settings` table.
## 🏗️ Architecture
- **Zero Configuration**: Automatic database schema creation and environment detection
- **Security First**: Keys are hashed using secure algorithms, never stored in plain text
- **Scalable**: Redis-backed rate limiting for multi-instance deployments
- **Framework Agnostic**: Works with FastAPI, Flask, and can be extended to any Python web framework
- **Production Ready**: Thread-safe, async-compatible, and battle-tested
## 📝 License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## 🤝 Contributing
We welcome contributions! Please see [DEVELOPER.md](DEVELOPER.md) for development setup and guidelines.
---
<div align="center">
**Made with ❤️ for the Python community**
*If you find this project useful, please consider giving it a ⭐ on GitHub!*
</div>
Raw data
{
"_id": null,
"home_page": null,
"name": "keymaster-hjy",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": null,
"keywords": "api, authentication, security, rate-limiting, audit-logging, zero-config, fastapi, flask, mysql, redis, async, middleware",
"author": null,
"author_email": "hjy <hjy@example.com>",
"download_url": "https://files.pythonhosted.org/packages/e0/5b/ad11ecaef892f2e9d9a340239c8ea4e9f01c0808951e873bc49168f791d6/keymaster_hjy-0.0.1.tar.gz",
"platform": null,
"description": "<div align=\"center\">\n\n# \ud83d\udd10 Keymaster HJY\n\n**Zero-config, professional-grade API security manager**\n\n*Elegant authentication, rate limiting, and audit logging for modern Python APIs*\n\n[](https://pypi.org/project/keymaster_hjy/)\n[](https://pypi.org/project/keymaster_hjy/)\n[](https://github.com/hjy/keymaster_hjy/blob/main/LICENSE)\n[](https://pypi.org/project/keymaster_hjy/)\n\n[](https://github.com/psf/black)\n[](https://github.com/astral-sh/ruff)\n[](https://mypy-lang.org/)\n\n---\n\n**\ud83d\ude80 Zero Configuration** \u2022 **\ud83d\udd12 Production Ready** \u2022 **\u26a1 High Performance** \u2022 **\ud83c\udfaf Framework Agnostic**\n\n</div>\n\n## \u2728 Why Keymaster HJY?\n\n<table>\n<tr>\n<td width=\"50%\">\n\n### \ud83c\udfaf **Zero Configuration**\n- Automatic environment detection\n- Database schema auto-creation \n- Intelligent defaults that just work\n- No complex setup required\n\n### \ud83d\udd12 **Production Ready**\n- Secure key hashing & storage\n- Distributed rate limiting with Redis\n- Comprehensive audit logging\n- Thread-safe & async-compatible\n\n</td>\n<td width=\"50%\">\n\n### \u26a1 **High Performance**\n- Optimized database queries\n- Efficient Redis operations\n- Minimal memory footprint\n- Sub-millisecond response times\n\n### \ud83c\udfa8 **Developer Experience**\n- Intuitive API design\n- Complete type hints\n- Framework integrations\n- Excellent error messages\n\n</td>\n</tr>\n</table>\n\n## \ud83d\ude80 Quick Start\n\n### Installation\n\nChoose the installation that matches your needs:\n\n```bash\n# For FastAPI projects\npip install keymaster_hjy[fastapi] -i https://pypi.tuna.tsinghua.edu.cn/simple\n\n# For Flask projects \npip install keymaster_hjy[flask] -i https://pypi.tuna.tsinghua.edu.cn/simple\n\n# With CLI tools for easy setup\npip install keymaster_hjy[cli] -i https://pypi.tuna.tsinghua.edu.cn/simple\n\n# Everything included\npip install keymaster_hjy[all] -i https://pypi.tuna.tsinghua.edu.cn/simple\n```\n\n### Interactive Setup\n\nThe easiest way to get started is with our interactive CLI:\n\n```bash\n# Initialize a new project with guided setup\nkeymaster init\n\n# Or initialize in a specific directory\nkeymaster init my-secure-api\n```\n\nThis will:\n- \u2705 Guide you through database configuration\n- \u2705 Set up optional Redis for distributed rate limiting \n- \u2705 Generate framework-specific example applications\n- \u2705 Create all necessary configuration files\n\n### Manual Configuration\n\nAlternatively, create a `mysql.env` file manually:\n\n```bash\n# mysql.env - Database configuration\nMYSQL_HOST=your-mysql-host\nMYSQL_PORT=3306\nMYSQL_USER=your_user\nMYSQL_PASSWORD=your_password\nMYSQL_DATABASE=your_database\n\n# Optional: Redis for distributed rate limiting\nREDIS_HOST=your-redis-host\nREDIS_PORT=6379\nREDIS_PASSWORD=your_redis_password\n```\n\n### Usage Examples\n\n#### FastAPI Integration\n\n```python\nfrom fastapi import FastAPI\nfrom keymaster_hjy.integrations import fastapi_guard\n\napp = FastAPI()\n\n# Basic protection - requires valid API key\n@app.get(\"/api/data\", dependencies=[fastapi_guard()])\nasync def get_data():\n return {\"message\": \"Protected data\"}\n\n# Scope-based protection\n@app.get(\"/api/users\", dependencies=[fastapi_guard(\"read:users\")])\nasync def get_users():\n return {\"users\": [...]}\n\n@app.post(\"/api/users\", dependencies=[fastapi_guard(\"write:users\")])\nasync def create_user():\n return {\"status\": \"created\"}\n```\n\n#### Flask Integration\n\n```python\nfrom flask import Flask\nfrom keymaster_hjy.integrations import flask_guard\n\napp = Flask(__name__)\n\n@app.route(\"/api/data\")\n@flask_guard() # Basic protection\ndef get_data():\n return {\"message\": \"Protected data\"}\n\n@app.route(\"/api/admin\")\n@flask_guard(\"admin:access\") # Scope-based protection\ndef admin_panel():\n return {\"message\": \"Admin access granted\"}\n```\n\n### API Key Management\n\n#### Creating API Keys\n\n```python\nfrom keymaster_hjy import master\n\n# Create a basic API key\nkey_info = master.keys.create(\n description=\"My application key\",\n tags=[\"production\"],\n scopes=[\"read:users\", \"write:data\"]\n)\n\nprint(f\"Key ID: {key_info['id']}\")\nprint(f\"API Key: {key_info['key']}\") # Store this securely!\n```\n\n#### Testing Your API\n\nOnce you have an API key, test your protected endpoints:\n\n```bash\n# Test with curl\ncurl -H \"X-API-Key: your-api-key-here\" http://localhost:8000/api/data\n\n# Test with httpx (Python)\nimport httpx\nresponse = httpx.get(\n \"http://localhost:8000/api/data\",\n headers={\"X-API-Key\": \"your-api-key-here\"}\n)\n```\n\n#### Key Management Operations\n\n```python\n# Rotate a key (old key expires after transition period)\nnew_key = master.keys.rotate(key_id=123, transition_period_hours=24)\n\n# Deactivate a key\nmaster.keys.deactivate(key_id=123)\n\n# Manual validation\ntry:\n master.auth.validate_key(\"your-key\", required_scope=\"read:data\")\n print(\"\u2705 Key is valid and has required scope\")\nexcept Exception as e:\n print(f\"\u274c Validation failed: {e}\")\n```\n\n## \ud83d\udcda API Reference\n\n### Key Management (`master.keys`)\n\n| Method | Description | Returns |\n|--------|-------------|---------|\n| `create(description, **opts)` | Create new API key | `{'id': int, 'key': str}` |\n| `deactivate(key_id)` | Deactivate a key | `None` |\n| `rotate(key_id, transition_period_hours=24)` | Rotate key with grace period | `{'id': int, 'key': str}` |\n\n**Create Options:**\n- `rate_limit`: Custom rate limit (e.g., `\"100/minute\"`)\n- `expires_at`: Expiration date (ISO string) \n- `tags`: List of tags for organization\n- `scopes`: List of permission scopes\n\n### Authentication (`master.auth`)\n\n| Method | Description | Exceptions |\n|--------|-------------|------------|\n| `validate_key(key, **opts)` | Validate API key | `InvalidKeyError`, `KeyExpiredError`, `RateLimitExceededError`, `ScopeDeniedError` |\n\n**Validation Options:**\n- `required_scope`: Required permission scope\n- `request_id`: Request tracking ID\n- `source_ip`: Client IP address\n- `request_method`: HTTP method\n- `request_path`: Request path\n\n### Framework Integrations\n\n```python\nfrom keymaster_hjy.integrations import fastapi_guard, flask_guard\n\n# FastAPI\n@app.get(\"/path\", dependencies=[fastapi_guard(\"scope?\")])\n\n# Flask \n@flask_guard(\"scope?\")\n```\n\n## \ud83d\udd27 Advanced Features\n\n### Custom Rate Limits\n```python\n# High-frequency API key\nkey_info = master.keys.create(\n description=\"Batch processing service\",\n rate_limit=\"1000/minute\" # Custom limit\n)\n\n# Different limits for different use cases\nanalytics_key = master.keys.create(\n description=\"Analytics dashboard\", \n rate_limit=\"50/second\"\n)\n```\n\n### Key Organization with Tags\n```python\n# Organize keys by environment and purpose\nprod_key = master.keys.create(\n description=\"Production mobile app\",\n tags=[\"production\", \"mobile\", \"v2.1\"],\n scopes=[\"read:users\", \"write:analytics\"]\n)\n\n# Query and manage by tags (future feature)\n# keys_by_tag = master.keys.find_by_tags([\"production\"])\n```\n\n### Automatic Key Rotation\n```python\n# Rotate keys with zero downtime\nnew_key = master.keys.rotate(\n key_id=123,\n transition_period_hours=48 # Old key valid for 48h\n)\n\nprint(f\"New key: {new_key['key']}\")\nprint(\"Update your applications with the new key within 48 hours\")\n```\n\n## \ud83d\udea8 Error Handling\n\nKeymaster provides clear, actionable error messages:\n\n```python\nfrom keymaster_hjy.exceptions import (\n InvalidKeyError,\n KeyDeactivatedError, \n KeyExpiredError,\n RateLimitExceededError,\n ScopeDeniedError\n)\n\ntry:\n master.auth.validate_key(\"your-key\", required_scope=\"read:data\")\nexcept InvalidKeyError:\n # Key not found or malformed\n return {\"error\": \"Invalid API key provided\"}\nexcept KeyExpiredError:\n # Key has expired\n return {\"error\": \"API key expired, please generate a new one\"}\nexcept ScopeDeniedError:\n # Missing required permissions\n return {\"error\": \"Insufficient permissions for this operation\"}\nexcept RateLimitExceededError:\n # Too many requests\n return {\"error\": \"Rate limit exceeded, please try again later\"}\n```\n\n### HTTP Status Mapping\n\n| Exception | HTTP Status | Description |\n|-----------|-------------|-------------|\n| `InvalidKeyError` | 401 Unauthorized | Key not found or invalid format |\n| `KeyDeactivatedError` | 401 Unauthorized | Key has been deactivated |\n| `KeyExpiredError` | 401 Unauthorized | Key has expired |\n| `ScopeDeniedError` | 403 Forbidden | Missing required permissions |\n| `RateLimitExceededError` | 429 Too Many Requests | Rate limit exceeded |\n\n## \u2699\ufe0f Configuration\n\n### Environment Variables\n\nAll configuration is done through the `mysql.env` file:\n\n```bash\n# Database (Required)\nMYSQL_HOST=your-mysql-host\nMYSQL_PORT=3306\nMYSQL_USER=your-username\nMYSQL_PASSWORD=your-password\nMYSQL_DATABASE=your-database\n\n# Redis (Optional - for distributed rate limiting)\nREDIS_HOST=your-redis-host\nREDIS_PORT=6379\nREDIS_PASSWORD=your-redis-password\n```\n\n### Default Settings\n\n| Setting | Default Value | Description |\n|---------|---------------|-------------|\n| Key Prefix | `lingchongtong-` | Prefix for generated keys |\n| Rate Limit | `100/minute` | Default rate limit for new keys |\n| Config Refresh | `30 seconds` | Settings cache refresh interval |\n\n> \ud83d\udca1 **Pro Tip**: All settings are stored in your database and can be modified at runtime by updating the `keymaster_settings` table.\n\n## \ud83c\udfd7\ufe0f Architecture\n\n- **Zero Configuration**: Automatic database schema creation and environment detection\n- **Security First**: Keys are hashed using secure algorithms, never stored in plain text\n- **Scalable**: Redis-backed rate limiting for multi-instance deployments\n- **Framework Agnostic**: Works with FastAPI, Flask, and can be extended to any Python web framework\n- **Production Ready**: Thread-safe, async-compatible, and battle-tested\n\n## \ud83d\udcdd License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## \ud83e\udd1d Contributing\n\nWe welcome contributions! Please see [DEVELOPER.md](DEVELOPER.md) for development setup and guidelines.\n\n---\n\n<div align=\"center\">\n\n**Made with \u2764\ufe0f for the Python community**\n\n*If you find this project useful, please consider giving it a \u2b50 on GitHub!*\n\n</div>\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Zero-config, professional-grade API security manager. Elegant authentication, rate limiting, and audit logging for modern Python APIs.",
"version": "0.0.1",
"project_urls": {
"Changelog": "https://github.com/hjy/keymaster_hjy/releases",
"Documentation": "https://github.com/hjy/keymaster_hjy#readme",
"Homepage": "https://github.com/hjy/keymaster_hjy",
"Issues": "https://github.com/hjy/keymaster_hjy/issues",
"Repository": "https://github.com/hjy/keymaster_hjy.git"
},
"split_keywords": [
"api",
" authentication",
" security",
" rate-limiting",
" audit-logging",
" zero-config",
" fastapi",
" flask",
" mysql",
" redis",
" async",
" middleware"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "5263e5c6da4d4a94900a32025bef37ceca9278a797db7d061725966ff94b3f80",
"md5": "76f8ab6d299a66017217d325b9b87f95",
"sha256": "7369a1e0e6f1e9e1dc9e165e5bd55e87e2eec3be2fd211faafc573421cadfbb8"
},
"downloads": -1,
"filename": "keymaster_hjy-0.0.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "76f8ab6d299a66017217d325b9b87f95",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9",
"size": 36062,
"upload_time": "2025-08-15T06:41:26",
"upload_time_iso_8601": "2025-08-15T06:41:26.056014Z",
"url": "https://files.pythonhosted.org/packages/52/63/e5c6da4d4a94900a32025bef37ceca9278a797db7d061725966ff94b3f80/keymaster_hjy-0.0.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "e05bad11ecaef892f2e9d9a340239c8ea4e9f01c0808951e873bc49168f791d6",
"md5": "c2dc7c31974a1d4c96330abdf0515781",
"sha256": "92a3827da76ee715d8c4163e35f8e4a320b8089702593bac6b4d68f523039a5f"
},
"downloads": -1,
"filename": "keymaster_hjy-0.0.1.tar.gz",
"has_sig": false,
"md5_digest": "c2dc7c31974a1d4c96330abdf0515781",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 51542,
"upload_time": "2025-08-15T06:41:27",
"upload_time_iso_8601": "2025-08-15T06:41:27.493729Z",
"url": "https://files.pythonhosted.org/packages/e0/5b/ad11ecaef892f2e9d9a340239c8ea4e9f01c0808951e873bc49168f791d6/keymaster_hjy-0.0.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-15 06:41:27",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "hjy",
"github_project": "keymaster_hjy",
"github_not_found": true,
"lcname": "keymaster-hjy"
}