Name | autocrud JSON |
Version |
0.4.3
JSON |
| download |
home_page | None |
Summary | 自動產生 CRUD API 的 Python 函式庫 |
upload_time | 2025-09-08 00:33:24 |
maintainer | None |
docs_url | None |
author | None |
requires_python | >=3.11 |
license | MIT License
Copyright (c) 2025 HYChou0515
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. |
keywords |
api
automation
crud
fastapi
rest
|
VCS |
 |
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# AutoCRUD
🚀 **自動生成 CRUD API 的 Python 庫** - 支持多種數據類型,零配置快速構建 REST API
[](https://www.python.org/downloads/)
[](https://fastapi.tiangolo.com/)
[](LICENSE)
## ✨ 特色功能
- 🎯 **多數據類型支持**: TypedDict、dataclass、msgspec.Struct
- ⚡ **零配置**: 一行代碼生成完整 CRUD API
- 🔧 **高度可定制**: 靈活的路由模板和命名約定
- 📚 **自動文檔**: 集成 Swagger/OpenAPI 文檔
- 🏎️ **高性能**: 基於 FastAPI 和 msgspec
- 🔒 **類型安全**: 完整的 TypeScript 風格類型檢查
## 🚀 快速開始
### 安裝
```bash
pip install autocrud
# 或使用 uv
uv add autocrud
```
### 5 分鐘創建 API
```python
from msgspec import Struct
from fastapi import FastAPI, APIRouter
from autocrud.crud.core import (
AutoCRUD, CreateRouteTemplate, ReadRouteTemplate,
UpdateRouteTemplate, DeleteRouteTemplate, ListRouteTemplate
)
# 定義數據模型
class User(Struct):
name: str
email: str
age: int = 0
# 創建 AutoCRUD 實例
crud = AutoCRUD(model_naming="kebab")
# 添加 CRUD 操作
crud.add_route_template(CreateRouteTemplate())
crud.add_route_template(ReadRouteTemplate())
crud.add_route_template(UpdateRouteTemplate())
crud.add_route_template(DeleteRouteTemplate())
crud.add_route_template(ListRouteTemplate())
# 註冊模型 - 就這麼簡單!
crud.add_model(User)
# 集成到 FastAPI
app = FastAPI(title="User API")
router = APIRouter()
crud.apply(router)
app.include_router(router)
# 運行: uvicorn main:app --reload
```
**🎉 完成!** 現在你有了一個完整的 CRUD API:
- `POST /user` - 創建用戶
- `GET /user/{id}` - 獲取用戶
- `PUT /user/{id}` - 更新用戶
- `DELETE /user/{id}` - 刪除用戶
- `GET /user` - 列出所有用戶
## 📊 多數據類型支持
AutoCRUD 支持 Python 主流數據類型,你可以選擇最適合的:
```python
from typing import TypedDict, Optional
from dataclasses import dataclass
import msgspec
# 1. TypedDict - 輕量級
class Product(TypedDict):
name: str
price: float
in_stock: bool
# 2. msgspec.Struct - 高性能
class User(msgspec.Struct):
username: str
email: str
age: Optional[int] = 0
# 3. dataclass - 原生支持
@dataclass
class Order:
customer_id: str
items: list
total: float = 0.0
# 4. msgspec - 靈活數據
class Event(msgspec.Struct):
type: str
data: dict
timestamp: float
# 一次註冊所有類型
crud.add_model(Product) # /product
crud.add_model(User) # /user
crud.add_model(Order) # /order
crud.add_model(Event) # /event
```
## 🎯 實際示例
### 博客 API
```python
from dataclasses import dataclass
from msgspec import Struct
from typing import List, Optional
class Author(Struct):
name: str
email: str
bio: Optional[str] = ""
@dataclass
class BlogPost:
title: str
content: str
author_id: str
tags: List[str] = None
published: bool = False
# 創建完整博客 API
crud = AutoCRUD(model_naming="kebab")
# ... 添加路由模板
crud.add_model(Author) # /author
crud.add_model(BlogPost) # /blog-post
```
### 電商系統
```python
from decimal import Decimal
from enum import Enum
from msgspec import Struct
class OrderStatus(str, Enum):
PENDING = "pending"
SHIPPED = "shipped"
DELIVERED = "delivered"
class Product(Struct):
name: str
price: Decimal
stock: int
category: str
class Order(Struct):
customer_id: str
items: List[dict]
status: OrderStatus = OrderStatus.PENDING
total: Decimal
# 完整電商 CRUD
crud.add_model(Product) # /product
crud.add_model(Order) # /order
```
## ⚙️ 配置選項
### 命名約定
```python
# kebab-case (推薦)
crud = AutoCRUD(model_naming="kebab")
# UserProfile -> /user-profile
# snake_case
crud = AutoCRUD(model_naming="snake")
# UserProfile -> /user_profile
# 自定義
def custom_naming(model_type):
return f"api_{model_type.__name__.lower()}"
crud = AutoCRUD(model_naming=custom_naming)
```
### 選擇性 CRUD 操作
```python
# 只讀 API
crud.add_route_template(ReadRouteTemplate())
crud.add_route_template(ListRouteTemplate())
# 基本 CRUD
crud.add_route_template(CreateRouteTemplate())
crud.add_route_template(ReadRouteTemplate())
crud.add_route_template(UpdateRouteTemplate())
crud.add_route_template(DeleteRouteTemplate())
# 高級功能
crud.add_route_template(PatchRouteTemplate()) # 部分更新
crud.add_route_template(SwitchRevisionRouteTemplate()) # 版本控制
crud.add_route_template(RestoreRouteTemplate()) # 恢復刪除
```
## 📖 文檔
- 📚 [完整文檔](docs/source/index.md)
- 🚀 [快速開始](docs/source/quickstart_new.md)
- 📖 [用戶指南](docs/source/user_guide_new.md)
- 💡 [示例集合](docs/source/examples_new.md)
- 🔧 [API 參考](docs/source/api_reference.md)
## 🏃♂️ 運行示例
克隆倉庫並運行示例:
```bash
git clone https://github.com/HYChou0515/autocrud.git
cd autocrud
# 博客 API 示例
python examples/blog_api_example.py
# 電商 API 示例
python examples/ecommerce_api_example.py
# 多數據類型示例
python examples/simple_quickstart.py
```
然後訪問 http://localhost:8000/docs 查看 API 文檔。
## 🧪 測試
```bash
# 安裝依賴
uv install
# 運行測試
uv run pytest
# 運行特定測試
uv run pytest tests/test_multiple_data_types.py -v
```
## 🤝 貢獻
歡迎貢獻!請查看 [貢獻指南](docs/source/contributing.md)。
## 📄 許可證
MIT License - 詳見 [LICENSE](LICENSE) 文件。
## 🌟 為什麼選擇 AutoCRUD?
### 傳統方式 😫
```python
# 需要手寫大量樣板代碼
@app.post("/users")
async def create_user(user: UserCreate):
# 驗證邏輯
# 業務邏輯
# 數據庫操作
# 錯誤處理
# 響應格式化
pass
@app.get("/users/{user_id}")
async def get_user(user_id: str):
# 更多樣板代碼...
pass
# ... 重複 5+ 個端點
```
### AutoCRUD 方式 😎
```python
# 一行代碼,完整 CRUD API
crud.add_model(User)
```
**節省 90% 的開發時間!** 🎯
Raw data
{
"_id": null,
"home_page": null,
"name": "autocrud",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.11",
"maintainer_email": null,
"keywords": "api, automation, crud, fastapi, rest",
"author": null,
"author_email": "HYChou0515 <hychou.svm@example.com>",
"download_url": "https://files.pythonhosted.org/packages/98/e6/4f17237e16edba3d5c7becbf67e17f27e080835db3c68b89882d1f8e7a7c/autocrud-0.4.3.tar.gz",
"platform": null,
"description": "# AutoCRUD\n\n\ud83d\ude80 **\u81ea\u52d5\u751f\u6210 CRUD API \u7684 Python \u5eab** - \u652f\u6301\u591a\u7a2e\u6578\u64da\u985e\u578b\uff0c\u96f6\u914d\u7f6e\u5feb\u901f\u69cb\u5efa REST API\n\n[](https://www.python.org/downloads/)\n[](https://fastapi.tiangolo.com/)\n[](LICENSE)\n\n## \u2728 \u7279\u8272\u529f\u80fd\n\n- \ud83c\udfaf **\u591a\u6578\u64da\u985e\u578b\u652f\u6301**: TypedDict\u3001dataclass\u3001msgspec.Struct\n- \u26a1 **\u96f6\u914d\u7f6e**: \u4e00\u884c\u4ee3\u78bc\u751f\u6210\u5b8c\u6574 CRUD API\n- \ud83d\udd27 **\u9ad8\u5ea6\u53ef\u5b9a\u5236**: \u9748\u6d3b\u7684\u8def\u7531\u6a21\u677f\u548c\u547d\u540d\u7d04\u5b9a\n- \ud83d\udcda **\u81ea\u52d5\u6587\u6a94**: \u96c6\u6210 Swagger/OpenAPI \u6587\u6a94\n- \ud83c\udfce\ufe0f **\u9ad8\u6027\u80fd**: \u57fa\u65bc FastAPI \u548c msgspec\n- \ud83d\udd12 **\u985e\u578b\u5b89\u5168**: \u5b8c\u6574\u7684 TypeScript \u98a8\u683c\u985e\u578b\u6aa2\u67e5\n\n## \ud83d\ude80 \u5feb\u901f\u958b\u59cb\n\n### \u5b89\u88dd\n\n```bash\npip install autocrud\n# \u6216\u4f7f\u7528 uv\nuv add autocrud\n```\n\n### 5 \u5206\u9418\u5275\u5efa API\n\n```python\nfrom msgspec import Struct\nfrom fastapi import FastAPI, APIRouter\nfrom autocrud.crud.core import (\n AutoCRUD, CreateRouteTemplate, ReadRouteTemplate,\n UpdateRouteTemplate, DeleteRouteTemplate, ListRouteTemplate\n)\n\n# \u5b9a\u7fa9\u6578\u64da\u6a21\u578b\nclass User(Struct):\n name: str\n email: str\n age: int = 0\n\n# \u5275\u5efa AutoCRUD \u5be6\u4f8b\ncrud = AutoCRUD(model_naming=\"kebab\")\n\n# \u6dfb\u52a0 CRUD \u64cd\u4f5c\ncrud.add_route_template(CreateRouteTemplate())\ncrud.add_route_template(ReadRouteTemplate())\ncrud.add_route_template(UpdateRouteTemplate())\ncrud.add_route_template(DeleteRouteTemplate())\ncrud.add_route_template(ListRouteTemplate())\n\n# \u8a3b\u518a\u6a21\u578b - \u5c31\u9019\u9ebc\u7c21\u55ae\uff01\ncrud.add_model(User)\n\n# \u96c6\u6210\u5230 FastAPI\napp = FastAPI(title=\"User API\")\nrouter = APIRouter()\ncrud.apply(router)\napp.include_router(router)\n\n# \u904b\u884c: uvicorn main:app --reload\n```\n\n**\ud83c\udf89 \u5b8c\u6210\uff01** \u73fe\u5728\u4f60\u6709\u4e86\u4e00\u500b\u5b8c\u6574\u7684 CRUD API\uff1a\n\n- `POST /user` - \u5275\u5efa\u7528\u6236\n- `GET /user/{id}` - \u7372\u53d6\u7528\u6236\n- `PUT /user/{id}` - \u66f4\u65b0\u7528\u6236\n- `DELETE /user/{id}` - \u522a\u9664\u7528\u6236\n- `GET /user` - \u5217\u51fa\u6240\u6709\u7528\u6236\n\n## \ud83d\udcca \u591a\u6578\u64da\u985e\u578b\u652f\u6301\n\nAutoCRUD \u652f\u6301 Python \u4e3b\u6d41\u6578\u64da\u985e\u578b\uff0c\u4f60\u53ef\u4ee5\u9078\u64c7\u6700\u9069\u5408\u7684\uff1a\n\n```python\nfrom typing import TypedDict, Optional\nfrom dataclasses import dataclass\nimport msgspec\n\n# 1. TypedDict - \u8f15\u91cf\u7d1a\nclass Product(TypedDict):\n name: str\n price: float\n in_stock: bool\n\n# 2. msgspec.Struct - \u9ad8\u6027\u80fd\nclass User(msgspec.Struct):\n username: str\n email: str\n age: Optional[int] = 0\n\n# 3. dataclass - \u539f\u751f\u652f\u6301\n@dataclass\nclass Order:\n customer_id: str\n items: list\n total: float = 0.0\n\n# 4. msgspec - \u9748\u6d3b\u6578\u64da\nclass Event(msgspec.Struct):\n type: str\n data: dict\n timestamp: float\n\n# \u4e00\u6b21\u8a3b\u518a\u6240\u6709\u985e\u578b\ncrud.add_model(Product) # /product\ncrud.add_model(User) # /user \ncrud.add_model(Order) # /order\ncrud.add_model(Event) # /event\n```\n\n## \ud83c\udfaf \u5be6\u969b\u793a\u4f8b\n\n### \u535a\u5ba2 API\n\n```python\nfrom dataclasses import dataclass\nfrom msgspec import Struct\nfrom typing import List, Optional\n\nclass Author(Struct):\n name: str\n email: str\n bio: Optional[str] = \"\"\n\n@dataclass\nclass BlogPost:\n title: str\n content: str\n author_id: str\n tags: List[str] = None\n published: bool = False\n\n# \u5275\u5efa\u5b8c\u6574\u535a\u5ba2 API\ncrud = AutoCRUD(model_naming=\"kebab\")\n# ... \u6dfb\u52a0\u8def\u7531\u6a21\u677f\ncrud.add_model(Author) # /author\ncrud.add_model(BlogPost) # /blog-post\n```\n\n### \u96fb\u5546\u7cfb\u7d71\n\n```python\nfrom decimal import Decimal\nfrom enum import Enum\nfrom msgspec import Struct\n\nclass OrderStatus(str, Enum):\n PENDING = \"pending\"\n SHIPPED = \"shipped\"\n DELIVERED = \"delivered\"\n\nclass Product(Struct):\n name: str\n price: Decimal\n stock: int\n category: str\n\nclass Order(Struct):\n customer_id: str\n items: List[dict]\n status: OrderStatus = OrderStatus.PENDING\n total: Decimal\n\n# \u5b8c\u6574\u96fb\u5546 CRUD\ncrud.add_model(Product) # /product\ncrud.add_model(Order) # /order\n```\n\n## \u2699\ufe0f \u914d\u7f6e\u9078\u9805\n\n### \u547d\u540d\u7d04\u5b9a\n\n```python\n# kebab-case (\u63a8\u85a6)\ncrud = AutoCRUD(model_naming=\"kebab\")\n# UserProfile -> /user-profile\n\n# snake_case\ncrud = AutoCRUD(model_naming=\"snake\") \n# UserProfile -> /user_profile\n\n# \u81ea\u5b9a\u7fa9\ndef custom_naming(model_type):\n return f\"api_{model_type.__name__.lower()}\"\ncrud = AutoCRUD(model_naming=custom_naming)\n```\n\n### \u9078\u64c7\u6027 CRUD \u64cd\u4f5c\n\n```python\n# \u53ea\u8b80 API\ncrud.add_route_template(ReadRouteTemplate())\ncrud.add_route_template(ListRouteTemplate())\n\n# \u57fa\u672c CRUD\ncrud.add_route_template(CreateRouteTemplate())\ncrud.add_route_template(ReadRouteTemplate()) \ncrud.add_route_template(UpdateRouteTemplate())\ncrud.add_route_template(DeleteRouteTemplate())\n\n# \u9ad8\u7d1a\u529f\u80fd\ncrud.add_route_template(PatchRouteTemplate()) # \u90e8\u5206\u66f4\u65b0\ncrud.add_route_template(SwitchRevisionRouteTemplate()) # \u7248\u672c\u63a7\u5236\ncrud.add_route_template(RestoreRouteTemplate()) # \u6062\u5fa9\u522a\u9664\n```\n\n## \ud83d\udcd6 \u6587\u6a94\n\n- \ud83d\udcda [\u5b8c\u6574\u6587\u6a94](docs/source/index.md)\n- \ud83d\ude80 [\u5feb\u901f\u958b\u59cb](docs/source/quickstart_new.md)\n- \ud83d\udcd6 [\u7528\u6236\u6307\u5357](docs/source/user_guide_new.md)\n- \ud83d\udca1 [\u793a\u4f8b\u96c6\u5408](docs/source/examples_new.md)\n- \ud83d\udd27 [API \u53c3\u8003](docs/source/api_reference.md)\n\n## \ud83c\udfc3\u200d\u2642\ufe0f \u904b\u884c\u793a\u4f8b\n\n\u514b\u9686\u5009\u5eab\u4e26\u904b\u884c\u793a\u4f8b\uff1a\n\n```bash\ngit clone https://github.com/HYChou0515/autocrud.git\ncd autocrud\n\n# \u535a\u5ba2 API \u793a\u4f8b\npython examples/blog_api_example.py\n\n# \u96fb\u5546 API \u793a\u4f8b \npython examples/ecommerce_api_example.py\n\n# \u591a\u6578\u64da\u985e\u578b\u793a\u4f8b\npython examples/simple_quickstart.py\n```\n\n\u7136\u5f8c\u8a2a\u554f http://localhost:8000/docs \u67e5\u770b API \u6587\u6a94\u3002\n\n## \ud83e\uddea \u6e2c\u8a66\n\n```bash\n# \u5b89\u88dd\u4f9d\u8cf4\nuv install\n\n# \u904b\u884c\u6e2c\u8a66\nuv run pytest\n\n# \u904b\u884c\u7279\u5b9a\u6e2c\u8a66\nuv run pytest tests/test_multiple_data_types.py -v\n```\n\n## \ud83e\udd1d \u8ca2\u737b\n\n\u6b61\u8fce\u8ca2\u737b\uff01\u8acb\u67e5\u770b [\u8ca2\u737b\u6307\u5357](docs/source/contributing.md)\u3002\n\n## \ud83d\udcc4 \u8a31\u53ef\u8b49\n\nMIT License - \u8a73\u898b [LICENSE](LICENSE) \u6587\u4ef6\u3002\n\n## \ud83c\udf1f \u70ba\u4ec0\u9ebc\u9078\u64c7 AutoCRUD\uff1f\n\n### \u50b3\u7d71\u65b9\u5f0f \ud83d\ude2b\n```python\n# \u9700\u8981\u624b\u5beb\u5927\u91cf\u6a23\u677f\u4ee3\u78bc\n@app.post(\"/users\")\nasync def create_user(user: UserCreate):\n # \u9a57\u8b49\u908f\u8f2f\n # \u696d\u52d9\u908f\u8f2f \n # \u6578\u64da\u5eab\u64cd\u4f5c\n # \u932f\u8aa4\u8655\u7406\n # \u97ff\u61c9\u683c\u5f0f\u5316\n pass\n\n@app.get(\"/users/{user_id}\")\nasync def get_user(user_id: str):\n # \u66f4\u591a\u6a23\u677f\u4ee3\u78bc...\n pass\n\n# ... \u91cd\u8907 5+ \u500b\u7aef\u9ede\n```\n\n### AutoCRUD \u65b9\u5f0f \ud83d\ude0e\n```python\n# \u4e00\u884c\u4ee3\u78bc\uff0c\u5b8c\u6574 CRUD API\ncrud.add_model(User)\n```\n\n**\u7bc0\u7701 90% \u7684\u958b\u767c\u6642\u9593\uff01** \ud83c\udfaf\n",
"bugtrack_url": null,
"license": "MIT License\n \n Copyright (c) 2025 HYChou0515\n \n Permission is hereby granted, free of charge, to any person obtaining a copy\n of this software and associated documentation files (the \"Software\"), to deal\n in the Software without restriction, including without limitation the rights\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the Software is\n furnished to do so, subject to the following conditions:\n \n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n \n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n SOFTWARE.",
"summary": "\u81ea\u52d5\u7522\u751f CRUD API \u7684 Python \u51fd\u5f0f\u5eab",
"version": "0.4.3",
"project_urls": {
"Documentation": "https://HYChou0515.github.io/autocrud/",
"Homepage": "https://github.com/HYChou0515/autocrud",
"Issues": "https://github.com/HYChou0515/autocrud/issues",
"Repository": "https://github.com/HYChou0515/autocrud.git"
},
"split_keywords": [
"api",
" automation",
" crud",
" fastapi",
" rest"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "fec137afaaa9e463ab633ac03af34eee0c52cda767bb0d0c9a5dd719a1f7b7ea",
"md5": "2ecebcca01815e42cb5631548ee76a46",
"sha256": "5064cfbd340e8ca5bac8aa1bf83d47740c17471694b40576af20f0c6e0c1d79a"
},
"downloads": -1,
"filename": "autocrud-0.4.3-py3-none-any.whl",
"has_sig": false,
"md5_digest": "2ecebcca01815e42cb5631548ee76a46",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.11",
"size": 82040,
"upload_time": "2025-09-08T00:33:23",
"upload_time_iso_8601": "2025-09-08T00:33:23.326723Z",
"url": "https://files.pythonhosted.org/packages/fe/c1/37afaaa9e463ab633ac03af34eee0c52cda767bb0d0c9a5dd719a1f7b7ea/autocrud-0.4.3-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "98e64f17237e16edba3d5c7becbf67e17f27e080835db3c68b89882d1f8e7a7c",
"md5": "2714372d7cb1e70e4f194204e271b139",
"sha256": "a61c53358c8ce5e91c59521fcf53db8078e3f50d4547278a6ac1f9468bf0bfc8"
},
"downloads": -1,
"filename": "autocrud-0.4.3.tar.gz",
"has_sig": false,
"md5_digest": "2714372d7cb1e70e4f194204e271b139",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.11",
"size": 238469,
"upload_time": "2025-09-08T00:33:24",
"upload_time_iso_8601": "2025-09-08T00:33:24.936084Z",
"url": "https://files.pythonhosted.org/packages/98/e6/4f17237e16edba3d5c7becbf67e17f27e080835db3c68b89882d1f8e7a7c/autocrud-0.4.3.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-09-08 00:33:24",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "HYChou0515",
"github_project": "autocrud",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "autocrud"
}