AutoDL Python实现 自动续签 防止实例过期释放 小脚本 定时任务 apscheduler requests

简介: AutoDL Python实现 自动续签 防止实例过期释放 小脚本 定时任务 apscheduler requests

代码仓库

我把东西都打包到GitHub了,时不时我就去更新一下加点新功能进去。大家需要的话帮忙点个 Star!

https://github.com/turbo-duck/autodl-keeper

背景介绍

平常对模型进行训练、微调的时候,我在 AutoDL 有一台主机。

但是有些主机环境我配置好了,又不想让它过期,可能过段时间还会再用。

我一不留神就会超过15天,导致我的机器给释放了很难受。

所以写了一个Python的小脚本,获取列表、时间快过期了就进行无卡开机、关机,这样便完成续签。


安装依赖

需要的前置依赖大概有这些(有些是系统已经带了)

import os
from dotenv import load_dotenv
import requests
import json
import time
import logging
from datetime import datetime
import pytz
from apscheduler.schedulers.blocking import BlockingScheduler

编写代码

import os
from dotenv import load_dotenv
import requests
import json
import time
import logging
from datetime import datetime
import pytz
from apscheduler.schedulers.blocking import BlockingScheduler


load_dotenv()
authorization = os.getenv('Authorization')
min_day = os.getenv('MIN_DAY')

logging.basicConfig(
    filename='main.log',
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s')

headers = {
    "Authorization": authorization,
    "Content-Type": "application/json;charset=UTF-8",
    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36",
}


def open_machine(instance_uuid: str = None):
    if not instance_uuid:
        return False
    url = "https://www.autodl.com/api/v1/instance/power_on"
    body = {
        "instance_uuid": str(instance_uuid),
        "payload": "non_gpu"
    }

    response = requests.post(url=url, headers=headers, data=json.dumps(body))
    json_data = response.json()
    logging.info(f"uuid: {instance_uuid}, open")
    logging.info(f"{instance_uuid} response: {json_data}")
    if json_data['code'] == "Success":
        return True
    return False


def close_machine(instance_uuid: str = None):
    if not instance_uuid:
        return False
    url = "https://www.autodl.com/api/v1/instance/power_off"
    body = {
        "instance_uuid": str(instance_uuid)
    }
    response = requests.post(url=url, headers=headers, data=json.dumps(body))
    json_data = response.json()
    logging.info(f"uuid: {instance_uuid}, close")
    logging.info(f"{instance_uuid} response: {json_data}")
    if json_data['code'] == "Success":
        return True
    return False


def check_instance(page: int = 1):
    url = "https://www.autodl.com/api/v1/instance"
    body = {
        "date_from": "",
        "date_to": "",
        "page_index": page,
        "page_size": 100,
        "status": [],
        "charge_type": []
    }
    response = requests.post(url=url, headers=headers, data=json.dumps(body))
    json_data = response.json()
    if json_data['code'] == "Success":
        data_list = json_data['data']['list']
        for each_data in data_list:
            uuid = each_data.get('uuid', '')
            if uuid == "":
                return
            machine_alias = each_data.get('machine_alias', '')
            region_name = each_data.get('region_name', '')
            status = each_data.get('status', '')
            status_at = each_data.get('status_at', '')
            phone = each_data.get('phone', '')

            status_at_time = datetime.fromisoformat(status_at)
            current_date = datetime.now(pytz.timezone('Asia/Shanghai'))
            date_difference = current_date - status_at_time
            date_difference_day = date_difference.days
            logging.info(f"now: {current_date.strftime('%Y-%m-%d %H:%M:%S')}, "
                         f"phone: {phone}, name: {region_name} {machine_alias} {uuid}, "
                         f"status: {status}, date_diff: {date_difference_day}天")
            # 小于1天
            if date_difference_day >= int(min_day):
                logging.info(f"准备续费: {uuid}")
                # 续费逻辑
                open_machine(uuid)
                time.sleep(60)
                close_machine(uuid)
                time.sleep(5)
            else:
                logging.info(f"等待下次扫描: {uuid}")
                # 不作操作
                pass
    else:
        return


def main():
    if not authorization:
        logging.error("Authorization is None !")
        exit(-1)
    logging.info(f"now: {datetime.now(pytz.timezone('Asia/Shanghai')).strftime('%Y-%m-%d %H:%M:%S')}")
    check_instance()


if __name__ == "__main__":
    scheduler = BlockingScheduler()
    scheduler.add_job(main, 'interval', hours=1)
    try:
        # 启动调度器
        scheduler.start()
    except (KeyboardInterrupt, SystemExit):
        print("KeyboardInterrupt Or SystemExit")

测试效果

容器部署

首先需要一个Dockerfile

FROM python:3.10-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
COPY . .
RUN touch main.log
ENV ENV_FILE_PATH .env
CMD ["sh", "-c", "if [ -f $ENV_FILE_PATH ]; then export $(cat $ENV_FILE_PATH | xargs); fi && python main.py"]

对其进行打包

docker build -t autodl-keeper .

打包后运行

docker run --env-file .env autodl-keeper
目录
相关文章
|
6月前
|
存储 Web App开发 前端开发
Python + Requests库爬取动态Ajax分页数据
Python + Requests库爬取动态Ajax分页数据
|
6月前
|
Web App开发 安全 数据安全/隐私保护
利用Python+Requests实现抖音无水印视频下载
利用Python+Requests实现抖音无水印视频下载
|
3月前
|
存储 Java 调度
Python定时任务实战:APScheduler从入门到精通
APScheduler是Python强大的定时任务框架,通过触发器、执行器、任务存储和调度器四大组件,灵活实现各类周期性任务。支持内存、数据库、Redis等持久化存储,适用于Web集成、数据抓取、邮件发送等场景,解决传统sleep循环的诸多缺陷,助力构建稳定可靠的自动化系统。(238字)
739 1
|
6月前
|
JSON 网络安全 数据格式
Python网络请求库requests使用详述
总结来说,`requests`库非常适用于需要快速、简易、可靠进行HTTP请求的应用场景,它的简洁性让开发者避免繁琐的网络代码而专注于交互逻辑本身。通过上述方式,你可以利用 `requests`处理大部分常见的HTTP请求需求。
610 51
|
8月前
|
网络协议 API 开发者
分析http.client与requests在Python中的性能差异并优化。
合理地选择 `http.client`和 `requests`库以及在此基础上优化代码,可以帮助你的Python网络编程更加顺利,无论是在性能还是在易用性上。我们通常推荐使用 `requests`库,因为它的易用性。对于需要大量详细控制的任务,或者对性能有严格要求的情况,可以考虑使用 `http.client`库。同时,不断优化并管理员连接、设定合理超时和重试都是提高网络访问效率和稳定性的好方式。
208 19
|
6月前
|
数据采集 API 调度
Python爬虫框架对比:Scrapy vs Requests在API调用中的应用
本文对比了 Python 中 Scrapy 与 Requests 两大爬虫框架在 API 调用中的差异,涵盖架构设计、调用模式、性能优化及适用场景,并提供实战建议,助力开发者根据项目需求选择合适工具。
|
7月前
|
JSON 数据格式 Python
解决Python requests库POST请求参数顺序问题的方法。
总之,想要在Python的requests库里保持POST参数顺序,你要像捋顺头发一样捋顺它们,在向服务器炫耀你那有条不紊的数据前。抓紧手中的 `OrderedDict`与 `json`这两把钥匙,就能向服务端展示你的请求参数就像经过高端配置的快递包裹,里面的商品摆放井井有条,任何时候开箱都是一种享受。
162 10
|
7月前
|
网络协议 API Python
解析http.client与requests在Python中的性能比较和改进策略。
最后,需要明确的是,这两种库各有其优点和适用场景。`http.client` 更适合于基础且并行的请求,`requests` 则因其易用且强大的功能,更适用于复杂的 HTTP 场景。对于哪种更适合你的应用,可能需要你自己进行实际的测试来确定。
207 10
|
7月前
|
XML JSON 安全
分析参数顺序对Python requests库进行POST请求的影响。
最后,尽管理论上参数顺序对POST请求没影响,但编写代码时仍然建议遵循一定的顺序和规范,比如URL总是放在第一位,随后是data或json,最后是headers,这样可以提高代码的可读性和维护性。在处理复杂的请求时,一致的参数顺序有助于调试和团队协作。
231 9

推荐镜像

更多