用fastapi搭建随机图api(雁陎二次元随机图api开放试用)
雁陎 • 2020 年 04 月 28 日
Loading...
> 这是简单进阶教程系列第五篇,本系列文章主要介绍那些可以很快上手的进阶库。
很久之前就想写一个随机图片api了,但是由于技术不够,加上懒也没有学php,所以一直拖到今天。借着学了fastapi,就尝试着写一个,感觉还挺简单的,大部分时间其实是耗在mongodb上了……
总之这个api先开放给大家用,看看效果怎么样。
调用地址:[https://api.yanshu.work/acg](https://api.yanshu.work/acg)
## 使用说明
虽然fastapi有自动生成的文档[https://api.yanshu.work/docs](https://api.yanshu.work/docs)和[https://api.yanshu.work/redoc](https://api.yanshu.work/redoc),但是不够清晰,所以我还是说明一下吧。
* 返回一张随机图:[https://api.yanshu.work/acg](https://api.yanshu.work/acg)
* 返回一张有天空或树元素的随机图片:[https://api.yanshu.work/acg/?tor=sky&tor=tree](https://api.yanshu.work/acg/?tor=sky&tor=tree)
* 返回一张有天空且有一个女孩的随机图片:[https://api.yanshu.work/acg/?tand=sky&tand=1girl](https://api.yanshu.work/acg/?tand=sky&tand=1girl)
* 返回一张宽长比大于等于1的随机图片:[https://api.yanshu.work/acg/?n=1](https://api.yanshu.work/acg/?n=1)
* 返回一张宽长比大于等于1小于等于2的随机图片:[https://api.yanshu.work/acg/?n=1&m=3](https://api.yanshu.work/acg/?n=1&m=3)
* 返回一张宽长比等于1的随机图片:[https://api.yanshu.work/acg/?n=1&m=1](https://api.yanshu.work/acg/?n=1&m=1)
如果查询不到记录,会返回`null`值。
`t`就是标签名,`and`和`or`就是并列/或查询,如果同时存在`tand`和`tor`参数,那默认使用`tor`。标签的想法和实现来自于[https://www.sitstars.com/archives/72/](https://www.sitstars.com/archives/72/)和[https://www.sitstars.com/archives/75/](https://www.sitstars.com/archives/75/)。数据库中有多少标签我也没有统计过,具体有哪些我也不太清楚,你可以尝试着输入英文单词看下有没有返回,或者是在[https://danbooru.donmai.us/tags?commit=Search&search%5Bhide_empty%5D=yes&search%5Border%5D=count](https://danbooru.donmai.us/tags?commit=Search&search%5Bhide_empty%5D=yes&search%5Border%5D=count)中找标签名(不过不保证一定存在于我的数据库中)
> PS:有时间的话我可能会进行一定的整理
至于宽高比,就是图片宽度/高度,`n`代表宽高比最小值,`m`代表宽高比最大值,当然,也可以和`tand`和`tor`自由组合。
## 代码
阅读代码前请注意:
* 所使用的知识都包含在[https://www.sitstars.com/archives/86/](https://www.sitstars.com/archives/86/)里了,有个`RedirectResponse`,其实就是重定向。
* 代码仅供参考,如果你想直接使用的话,那么首先得有一个和我一样数据结构的mongodb数据库
* 代码十分简单,但是我觉得已经发挥我能力的极限了(主要是数据库部分),也没有什么提升性能的空间和想法了。
```python
from typing import List
from fastapi import FastAPI, Query
from fastapi.responses import RedirectResponse
import pymongo
myclient = pymongo.MongoClient("mongodb://localhost:27017/") # 连接数据库
mydb = myclient["mdpicture"] # 创建数据库
mycol = mydb["acg"]
app = FastAPI()
@app.get("/")
async def root():
return {"欢迎使用雁陎API,目前有:\n随机图片API,使用说明见https://sitstars.com"}
@app.get("/acg/")
def read_acg(tand: List[str] = Query(None),tor: List[str] = Query(None),
m: float = None,n:float=None,seed=None):
condition=[]
if tand and tor:
tand = None
if tand:
condition.append({'tag': {"$all": tand}})
if tor:
condition.append({'tag': {"$in": tor}})
if n:
condition.append({'size.wh': {"$gte": n}})
if m:
condition.append({'size.wh': {"$lte": m}})
try:
result = randomp(condition)
response = RedirectResponse(url=result)
except:
response = 'null'
return response
def randomp(condition):
if condition:
pipeline = [{'$match':{'$and':[]}},{'$sample': { 'size': 1 }}]
pipeline[0]['$match']['$and'].extend(condition)
else:
pipeline = [{'$sample': { 'size': 1 }}]
data = mycol.aggregate(pipeline)
for i in data:
res = i['url']['distribute']+'.jpg'
return res
```
版权属于:雁陎
本文链接:https://www.sitstars.com/archives/87/
转载时须注明出处及本声明