侧边栏壁纸
博主头像

我依旧在追寻自由的路上

  • 累计撰写 123 篇文章
  • 累计创建 9 个分类
  • 累计创建 32 个标签

目 录CONTENT

文章目录

随机图API-Ultra

柚子
原创 / 2024-12-03 / 0 评论 / 0 点赞 / 61 阅读 / 0 字
温馨提示:
部分素材来自网络,若不小心影响您的利益,请联系 站长 删除。

前言

相关文章

随机图API

随机图API-Pro

随机图API-ProMax

代码

from flask import Flask, send_file, jsonify
import os
import random
import redis
import logging

app = Flask(__name__)

# 配置日志
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

# 连接 Redis,使用环境变量
redis_client = redis.StrictRedis(
    host=os.getenv('REDIS_HOST', 'localhost'),
    port=int(os.getenv('REDIS_PORT', 6379)),
    db=int(os.getenv('REDIS_DB', 0)),
    password=os.getenv('REDIS_PASSWORD', None),  # 可选,如果没有密码则为 None
    decode_responses=True
)

# 从环境变量获取 API 路径
STATS_PATH = os.getenv('STATS_PATH', '/images/stats')
IMAGE_PATH = os.getenv('IMAGE_PATH', '/images/<image_type>')


# 获取 API 调用统计信息
@app.route(STATS_PATH, methods=['GET'])
def get_stats():
    stats = {key: redis_client.get(key) or 0 for key in IMAGE_DIRS.keys()}
    logger.info(f'API调用统计信息: {stats}')
    return jsonify(stats)

# 读取并配置图片文件夹路径
image_dirs_env = os.getenv('IMAGE_DIRS')
IMAGE_DIRS = {image_type: dir_path for image_type, dir_path in (item.split('=') for item in image_dirs_env.split(','))}

# 读取支持的图片扩展名
image_extensions_env = os.getenv('IMAGE_EXTENSIONS', '.jpg,.jpeg,.png,.webp')
IMAGE_EXTENSIONS = tuple(image_extensions_env.split(','))  # 转换为元组以便使用

# 更新 API 调用计数
def update_api_call_count(api_name):
    redis_client.incr(api_name)
    logger.info(f'API调用计数更新: {api_name}')

# 获取随机图片
def get_random_image(images_dir):
    try:
        # 使用环境变量中的扩展名筛选图片
        images = [f for f in os.listdir(images_dir) if f.endswith(IMAGE_EXTENSIONS)]
        
        if not images:
            logger.warning(f'没有找到图片在目录: {images_dir}')
            return jsonify({'error': '没有找到图片'}), 404

        random_image = random.choice(images)
        logger.info(f'随机选择的图片: {random_image}')
        return send_file(os.path.join(images_dir, random_image), mimetype='image/jpeg')
    except Exception as e:
        logger.error(f'获取随机图片时发生错误: {str(e)}')
        return jsonify({'error': str(e)}), 500

# 处理获取随机图片的请求
@app.route(IMAGE_PATH, methods=['GET'])
def random_image(image_type):
    logger.info(f'接收到请求获取图片类型: {image_type}')
    
    if image_type not in IMAGE_DIRS:
        logger.warning(f'无效的图片类型请求: {image_type}')
        return jsonify({'error': '无效的图片类型'}), 400

    update_api_call_count(image_type)
    response = get_random_image(IMAGE_DIRS[image_type])
    response.headers['Cache-Control'] = 'no-store'  # 禁用缓存
    return response

@app.after_request
def add_no_cache_headers(response):
    response.cache_control.no_store = True  # 禁用缓存
    return response

# 提供 favicon.ico
@app.route('/favicon.ico')
def favicon():
    return send_file(os.path.join(app.root_path, 'favicon', 'favicon.ico'), mimetype='image/vnd.microsoft.icon')

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

体验地址

PC随机图

PE随机图

PIXIV随机图

查看调用次数

仅用作测试,没做整理、图片不多。

制作镜像

相关依赖

创建一个app.py 文件

from flask import Flask, send_file, jsonify
import os
import random
import redis
import logging

app = Flask(__name__)

# 配置日志
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

# 连接 Redis,使用环境变量
redis_client = redis.StrictRedis(
    host=os.getenv('REDIS_HOST', 'localhost'),
    port=int(os.getenv('REDIS_PORT', 6379)),
    db=int(os.getenv('REDIS_DB', 0)),
    password=os.getenv('REDIS_PASSWORD', None),  # 可选,如果没有密码则为 None
    decode_responses=True
)

# 从环境变量获取 API 路径
STATS_PATH = os.getenv('STATS_PATH', '/images/stats')
IMAGE_PATH = os.getenv('IMAGE_PATH', '/images/<image_type>')


# 获取 API 调用统计信息
@app.route(STATS_PATH, methods=['GET'])
def get_stats():
    stats = {key: redis_client.get(key) or 0 for key in IMAGE_DIRS.keys()}
    logger.info(f'API调用统计信息: {stats}')
    return jsonify(stats)

# 读取并配置图片文件夹路径
image_dirs_env = os.getenv('IMAGE_DIRS')
IMAGE_DIRS = {image_type: dir_path for image_type, dir_path in (item.split('=') for item in image_dirs_env.split(','))}

# 读取支持的图片扩展名
image_extensions_env = os.getenv('IMAGE_EXTENSIONS', '.jpg,.jpeg,.png,.webp')
IMAGE_EXTENSIONS = tuple(image_extensions_env.split(','))  # 转换为元组以便使用

# 更新 API 调用计数
def update_api_call_count(api_name):
    redis_client.incr(api_name)
    logger.info(f'API调用计数更新: {api_name}')

# 获取随机图片
def get_random_image(images_dir):
    try:
        # 使用环境变量中的扩展名筛选图片
        images = [f for f in os.listdir(images_dir) if f.endswith(IMAGE_EXTENSIONS)]
        
        if not images:
            logger.warning(f'没有找到图片在目录: {images_dir}')
            return jsonify({'error': '没有找到图片'}), 404

        random_image = random.choice(images)
        logger.info(f'随机选择的图片: {random_image}')
        return send_file(os.path.join(images_dir, random_image), mimetype='image/jpeg')
    except Exception as e:
        logger.error(f'获取随机图片时发生错误: {str(e)}')
        return jsonify({'error': str(e)}), 500

# 处理获取随机图片的请求
@app.route(IMAGE_PATH, methods=['GET'])
def random_image(image_type):
    logger.info(f'接收到请求获取图片类型: {image_type}')
    
    if image_type not in IMAGE_DIRS:
        logger.warning(f'无效的图片类型请求: {image_type}')
        return jsonify({'error': '无效的图片类型'}), 400

    update_api_call_count(image_type)
    response = get_random_image(IMAGE_DIRS[image_type])
    response.headers['Cache-Control'] = 'no-store'  # 禁用缓存
    return response

@app.after_request
def add_no_cache_headers(response):
    response.cache_control.no_store = True  # 禁用缓存
    return response

# 提供 favicon.ico
@app.route('/favicon.ico')
def favicon():
    return send_file(os.path.join(app.root_path, 'favicon', 'favicon.ico'), mimetype='image/vnd.microsoft.icon')

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

创建一个rely.txt文件,添加下面内容

Flask>=2.0.3
Werkzeug>=2.0.3
redis>=4.0.2
gunicorn

创建一个favicon文件夹,将favicon.ico放进去

mkdir favicon

创建dockerfile文件

# 使用官方 Python 镜像
FROM python:3.9-slim

# 设置工作目录
WORKDIR /usr/src/app

# 复制项目文件
COPY . .

# 安装依赖
RUN pip install --no-cache-dir --timeout=300 -r requirements.txt

# 设置时区
ENV TZ=Asia/Shanghai

# 设置环境变量(可不填,构建容器写入即可。)
ENV REDIS_HOST=
ENV REDIS_PORT=
ENV REDIS_DB=0
ENV REDIS_PASSWORD=

# 暴露端口
EXPOSE 5000

# 启动应用
CMD ["gunicorn", "-b", "0.0.0.0:5000", "app:app"]

构建镜像

docker build -t random-image-api .

构建容器

参数

IMAGE_DIRS:分类=容器文件路径(必有参数)

例:IMAGE_DIRS=pixiv=images/pixiv

REDIS_HOST:redis地址(可选参数,默认:localhost

例:REDIS_HOST=127.0.0.1

REDIS_PORT:redis端口(可选参数,默认:6379

例:REDIS_PORT=6379

REDIS_DB:redis号库(可选参数,默认0号库)

例:REDIS_DB=2

REDIS_PASSWORD:redis密码(可选参数,默认:None

例:REDIS_PASSWORD=REDIS_PASSWORD

IMAGE_EXTENSIONS:图片类型(可选参数,默认:.jpg,.jpeg,.png,.webp

例:IMAGE_EXTENSIONS=.jpg,.jpeg,.png,.webp,.gif,.bmp

STATS_PATH:统计API访问路径(可选参数,默认:/images/stats

例:STATS_PATH=/images/stats

访问路径:域名/images/stats

IMAGE_PATH:随机图API访问路径(可选参数,默认:/images/<image_type>,其中<image_type>为必须携带参数且在末尾)

例:IMAGE_PATH=/images/<image_type>

访问路径:域名/images/pixiv,此处的<image_type>IMAGE_DIRS=pixiv=images/pixiv中左侧的pixiv

docker run \
  -p 5000:5000 \
  -v /images-path/pixiv:/usr/src/app/images/pixiv \
  -e IMAGE_DIRS=pixiv=images/pixiv \
  random-image-api

问题

目前统计会出现图片只出现一次,但后台统计多次的情况。

实测虽然前台只请求一次,但实际请求多次,暂无法解决。

评论区