token共享/缓存 后端代码(丐版)

一个后端代码

  • 这个代码有以下目的

  • 利用一些平台为新用户提供的免费token额度,支持用户自发获取平台的免费token并共享到后端

  • 后端实时更新可用token并且弃用额度耗尽token

  • 减少API的调用量,设置对短时间内相同的请求调用之前的响应内容

  • 总的来说,目的很单纯,就是白嫖

GPT完成了日志输出的补充

代码实现

from flask import Flask, jsonify, request
from datetime import datetime
import requests
import time
import logging

app = Flask(__name__)
API_URL = "https://api.caiyunapp.com/v2.6/{}/{}/realtime"

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

# 从文件中读取API tokens
try:
    with open("tokens.txt", 'r') as f:
        tokens = [i.strip() for i in f.readlines()]
except Exception as e:
    logger.error("Error reading tokens: %s", e)
    tokens = []

# 历史天气获取数据,如果有请求对于同一个position在5min内提出相同的请求,那么直接返回历史数据
# 格式为 {position : {time:,info:}}  
history = {}

# 天气条件的映射
weather_conditions = {
    "CLEAR_NIGHT": "晴(夜间)",
    "PARTLY_CLOUDY_DAY": "多云(白天)",
    "PARTLY_CLOUDY_NIGHT": "多云(夜间)",
    "CLOUDY": "阴",
    "LIGHT_HAZE": "轻度雾霾",
    "MODERATE_HAZE": "中度雾霾",
    "HEAVY_HAZE": "重度雾霾",
    "LIGHT_RAIN": "小雨",
    "MODERATE_RAIN": "中雨",
    "HEAVY_RAIN": "大雨",
    "STORM_RAIN": "暴雨",
    "FOG": "雾",
    "LIGHT_SNOW": "小雪",
    "MODERATE_SNOW": "中雪",
    "HEAVY_SNOW": "大雪",
    "STORM_SNOW": "暴雪",
    "DUST": "浮尘",
    "SAND": "沙尘",
    "WIND": "大风"
}

def fetch_weather_data(token: str, position: str):
    """Fetch weather data from the API."""
    try:
        logger.debug("Fetching weather data for position: %s using token: %s", position, token)
        response = requests.get(API_URL.format(token, position))
        response.raise_for_status()
        data = response.json()
        
        if data.get("status") != "ok":
            logger.warning("API returned status 'no' for position: %s", position)
            return {"status": "no"}
        
        realtime = data.get("result", {}).get("realtime", {})
        temperature = realtime.get("temperature")
        wind_speed = realtime.get("wind", {}).get("speed")
        skycon = realtime.get("skycon")
        weather_condition = determine_weather_condition(skycon)
        
        logger.info("Weather data fetched successfully for %s: Temperature: %s, Wind Speed: %s, Condition: %s",
                    position, temperature, wind_speed, weather_condition)
        
        return {
            "status": 'ok',
            "temperature": temperature,
            "wind": wind_speed,
            "condition": weather_condition
        }
    except requests.exceptions.RequestException as e:
        logger.error("Request error for token %s: %s", token, e)
        return {"error": str(e)}
    except Exception as e:
        logger.error("Error processing weather data: %s", e)
        return {"error": "An error occurred while processing the weather data."}

def determine_weather_condition(skycon):
    """Determine the weather condition from the skycon."""
    condition = weather_conditions.get(skycon, "未知天气")
    logger.debug("Determined weather condition for skycon %s: %s", skycon, condition)
    return condition

@app.route('/weather', methods=['GET'])
def get_weather():
    position = request.args.get('position')
    if not position:
        logger.error("No position parameter provided in request.")
        return jsonify({"error": "Position parameter is required."}), 400
    
    timestamp = time.time()
    if position in history and (timestamp - history[position]['time'] <= 300):
        logger.info("Returning cached weather data for position: %s", position)
        return jsonify(history[position]['info'])
    
    if not tokens:
        logger.error("No available tokens to make a request.")
        return jsonify({"error": "No available tokens."}), 500
    
    to_remove_token = []
    for token in tokens:
        logger.info("Using token: %s at %s", token, datetime.now())
        info = fetch_weather_data(token, position)
        
        if 'error' in info:
            logger.warning("Failed with token %s: %s", token, info['error'])
            with open("stale_token.txt", 'a') as f:
                f.write(token + "\n")
            to_remove_token.append(token)
            continue
        
        if info['status'] == "no":
            logger.warning("API call unsuccessful for token: %s", token)
            to_remove_token.append(token)
            continue
        
        logger.info("Successful response received.")
        history[position] = {
            "time": time.time(),
            "info": info
        }
        return jsonify(info)

    for token in to_remove_token:
        tokens.remove(token)
        logger.info("Removing stale token: %s", token)

    logger.error("All tokens failed for position: %s", position)
    return jsonify({"error": "All tokens failed."}), 500

if __name__ == '__main__':
    app.run(debug=True)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值