客至汲泉烹茶, 抚琴听者知音

用fastapi搭建随机图api(雁陎二次元随机图api开放试用)

这是简单进阶教程系列第五篇,本系列文章主要介绍那些可以很快上手的进阶库。

很久之前就想写一个随机图片api了,但是由于技术不够,加上懒也没有学php,所以一直拖到今天。借着学了fastapi,就尝试着写一个,感觉还挺简单的,大部分时间其实是耗在mongodb上了……

总之这个api先开放给大家用,看看效果怎么样。

调用地址:https://api.yanshu.work/acg

使用说明

虽然fastapi有自动生成的文档https://api.yanshu.work/docshttps://api.yanshu.work/redoc,但是不够清晰,所以我还是说明一下吧。

如果查询不到记录,会返回null值。

t就是标签名,andor就是并列/或查询,如果同时存在tandtor参数,那默认使用tor。标签的想法和实现来自于https://www.sitstars.com/archives/72/https://www.sitstars.com/archives/75/。数据库中有多少标签我也没有统计过,具体有哪些我也不太清楚,你可以尝试着输入英文单词看下有没有返回,或者是在https://danbooru.donmai.us/tags?commit=Search&search%5Bhide_empty%5D=yes&search%5Border%5D=count中找标签名(不过不保证一定存在于我的数据库中)

PS:有时间的话我可能会进行一定的整理

至于宽高比,就是图片宽度/高度,n代表宽高比最小值,m代表宽高比最大值,当然,也可以和tandtor自由组合。

[scode type="yellow"]随机图使用的均是原图,动辄几M甚至十几M,目前不准备进行压缩,大家慎重使用[/scode]

[scode type="green"]有什么bug或者建议请评论区留言,好想法我会尽量实现的[/scode]

代码

阅读代码前请注意:

  • 所使用的知识都包含在https://www.sitstars.com/archives/86/里了,有个RedirectResponse,其实就是重定向。
  • 代码仅供参考,如果你想直接使用的话,那么首先得有一个和我一样数据结构的mongodb数据库
  • 代码十分简单,但是我觉得已经发挥我能力的极限了(主要是数据库部分),也没有什么提升性能的空间和想法了。
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

添加新评论