本文介绍怎么根据 GitHub 为图片存储,经过 API 随机回来可用的图片地址。
前语
常用的桌面壁纸、终端布景图片,亦或是博客布景或文章封面,这些都离不开图片。所以,就想怎么免费办理图片,一起又能轻松同享他人。
在网上找了一些免费的随机图片 API,大部分处于不可用的状况,或者是需要注册登录,创建 API Token。
作为一名老年程序员,天然就想能经过编程完成,完成图片自在。尽管也能够经过类似爬虫的思路完成,但仍是期望都在自己的操控中,万一出现欠好的图片就欠好了。
免费 CDN 加快
我的博客图片一直在用 GitHub 存储,经过 jsdelivr CDN 加快。所以就考虑,如果能获取到 GitHub 存储的文件列表,就能够完成一个图片服务。
简单说下 jsdelivr CDN,它支撑对 GitHub 中文件的加快拜访。如坐落我的库房下的图片,经过对地址转为为 jsdelivr CDN 地址。
如下所示:
-> https://www.6hu.cc/wp-content/uploads/2023/11/221229-wqteW0.webp
现在如果能顺畅获取到库房的图片文件列表,即可将 github 作为咱们的图片图片存储,而无需花钱购买云存储完成。
怎么取得 GitHub 文件列表呢?
查询 GitHub 图片列表
GitHub 支撑接口获取库房文件列表,如下所示,查询 user/repo 下某分支的状况。
https ://api.github.com/repos/{user}/{repo}/branches/{branch}。
JSON 回来体中,经过拜访途径 .commit.commit.tree.url
拿到获取库房文件列表的接口地址。其实主要是获取该分支最近的 commit hash。
演示案例,获取 github.com/poloxue/public_images
经过 httpie
执行恳求,如下所示:
https ://api.github.com/repos/poloxue/public_images/branches/main
{
// ...
"commit": {
"commit": {
"tree": {
"sha": "3859a482b15ed41bfb86ce073d6c500fef36910c",
"url": "https://api.github.com/repos/poloxue/public_images/git/trees/3859a482b15ed41bfb86ce073d6c500fef36910c"
}
}
}
}
经过 jq 解析恳求成果,再次经过 httpie 恳求,指令如下:
https $(https ://api.github.com/repos/poloxue/public_images/branches/main | jq -r '.commit.commit.tree.url+"?recursive=1"') | jq '.tree[].path'
如上的指令中经过 ?recursive=1
完成遍历子目录,经过 ‘.tree[].path’ 回来所有文件和目录。
回来成果如下:
.gitignore
README.md
beauties
beauties/0001.jpeg
beauties/0002.jpeg
beauties/0003.jpeg
beauties/0004.webp
beauties/0005.jpg
beauties/0006.webp
default
default/0001.webp
default/0002.webp
default/0003.webp
scenes
scenes/0001.webp
scenes/0002.webp
scenes/0003.webp
scenes/0004.webp
scenes/0005.webp
特别阐明:接口的回来其实有数量限制,但这个限制并不是很大,个人使用无需忧虑。
图片 API 服务
在了解怎么使用GitHub 的接口后,我经过 aws 的 serverless 的才能,创建了一个简单的 Image Random API,将图片文件在库房中的途径与 jsdelivr CDN 地址结合,随机回来一个图片地址。
接口定义:
- /image/random/{category}
- 输入参数:
- category:str, 图片类型,即 github 库房的子目名称;
- 回来成果:
- image:str,图片地址,指定 category 类型下的一个图片地址;
核心的代码如下所示:
import time
import random
import requests
from collections import defaultdict
class ImageService:
def __init__(self):
self._sha = None
self._images = defaultdict(list)
self._timeout = 60
self._timestamp = 0
def last_sha(self):
last_timestamp = time.time()
if last_timestamp - self._timestamp < self._timeout:
return self._sha
self._timestamp = last_timestamp
data = requests.get(
"https://api.github.com/repos/poloxue/public_images/branches/main"
).json()
return data["commit"]["commit"]["tree"]["sha"]
def get_images(self, category):
last_sha = self.last_sha()
if self._sha == last_sha:
return self._images[category]
self._images[category] = []
self._sha = last_sha
data = requests.get(
f"https://api.github.com/repos/poloxue/public_images/git/trees/{last_sha}?recursive=1"
).json()
for file in data["tree"]:
fpath = file["path"]
subdir = fpath.split("/")[0]
if fpath.lower().endswith((".png", "jpg", "jpeg", "webp")):
self._images[subdir].append(
f"https://cdn.jsdelivr.net/gh/poloxue/public_images@latest/{file['path']}"
)
return self._images[category]
def random_image(self, category):
images = self.get_images(category)
if images:
return random.choice(images)
如上方法,random_image
可供给给接口调用,从 GitHub 库房回来一个随机图片。
恳求示例,如下所示:
https ://api.poloxue.com/image/random/scenes
输出成果:
{
"image": "https://cdn.jsdelivr.net/gh/poloxue/public_images@latest/scenes/0005.webp"
}
这只是服务的最小版别,还能够持续扩展,供给更多接口才能,如根据 Python 完成简单的裁剪缩放,皆是可行。
别的,这个 service 中还完成了简单的根据时间的缓存计划,别的当恳求到分支最终的 hash 变化时才会更新 self._images
。
唯一的惋惜便是,因为要提升同享才能,开发了一个简单的后端服务,没有免费云服务可用。还有便是,没有自动更新图片机制,有机会看看补齐吧
总结
本文介绍了怎么根据 GitHub 完成一个简单的 random image API 服务,主要是了办理我的图片资源,一起完成了编程自在操控图片资源的的方针。
我计划将会利用这个的图片接口才能,自在更新我的桌面、iTerm 乃至是博客的布景图片,自己着手,锦衣玉食。