华为云OBS批量下载工具

部署运行你感兴趣的模型镜像

之前开发中遇到数据迁移的需求,但是华为OBS对象存储不支持批到导出某个通的文件,于是自己用python写了这个工具,通过GUI界面简化了OBS文件下载流程,特别适合需要批量操作的技术人员使用。


一、工具核心功能亮点

  1. 可视化操作界面​:使用Tkinter构建的直观GUI
  2. 多线程下载​:后台线程处理避免界面卡顿
  3. 实时进度监控​:下载速度、当前文件、进度条三重反馈
  4. 智能路径处理​:自动根据华为云通路径创建本地目录结构
  5. 安全凭证管理​:Secret Key以掩码形式显示

三、使用到的关键库

库名称作用版本要求
tkinterGUI界面构建Python标准库
obs华为云OBS官方SDKpip install obs
requestsHTTP请求处理pip install requests
pathlib路径操作Python标准库

四、使用示例

  1. 填写AK/SK凭证
  2. 设置区域端点(默认西南区)
  3. 输入桶名称
  4. 选择桶内文件夹路径
  5. 保存到本地目录路径
  6. 点击"获取并下载"启动任务


 

总结

通过Python的Tkinter与华为OBS SDK结合,实现了:

  • ✅ 图形化批量下载操作
  • ✅ 实时进度反馈
  • ✅ 智能路径处理
  • ✅ 安全凭证管理

欢迎在评论区交流使用体验和改进建议!对于需要处理华为云OBS文件的技术人员,这个工具能极大提升工作效率。

附上完整源码,可自行编译运行。  
  
如需直接获取可执行文件,欢迎私信联系获取.exe安装包。  


六、完整源码

import os
import tkinter as tk
from tkinter import ttk, filedialog, messagebox, scrolledtext
import requests
import threading
import time
from pathlib import Path
from obs import ObsClient, Object


class ObsAutoDownloader:
    def __init__(self, master):
        self.master = master
        master.title("华为云OBS自动下载工具")
        master.geometry("900x700")

        # 初始化状态
        self.is_downloading = False
        self.obs_client = None
        self.file_list = []
        self.current_file = ""

        # 创建UI组件
        self.create_widgets()

    def create_widgets(self):
        """界面布局"""
        main_frame = ttk.Frame(self.master, padding=20)
        main_frame.pack(fill=tk.BOTH, expand=True)

        # 配置区域
        config_frame = ttk.LabelFrame(main_frame, text="OBS配置")
        config_frame.pack(fill=tk.X, pady=5)

        # 凭证输入
        ttk.Label(config_frame, text="Access Key:").grid(row=0, column=0, sticky=tk.W)
        self.ak_entry = ttk.Entry(config_frame)
        self.ak_entry.grid(row=0, column=1, padx=5, pady=2)

        ttk.Label(config_frame, text="Secret Key:").grid(row=0, column=2, sticky=tk.W)
        self.sk_entry = ttk.Entry(config_frame, show="*")
        self.sk_entry.grid(row=0, column=3, padx=5, pady=2)

        # 区域和桶配置
        ttk.Label(config_frame, text="区域端点:").grid(row=1, column=0, sticky=tk.W)
        self.endpoint_entry = ttk.Entry(config_frame)
        self.endpoint_entry.grid(row=1, column=1, padx=5, pady=2)
        self.endpoint_entry.insert(0, "obs.cn-southwest-2.myhuaweicloud.com")

        ttk.Label(config_frame, text="桶名称:").grid(row=1, column=2, sticky=tk.W)
        self.bucket_entry = ttk.Entry(config_frame)
        self.bucket_entry.grid(row=1, column=3, padx=5, pady=2)

        ttk.Label(config_frame, text="文件夹路径:").grid(row=2, column=0, sticky=tk.W)
        self.prefix_entry = ttk.Entry(config_frame)
        self.prefix_entry.grid(row=2, column=1, columnspan=3, sticky=tk.EW, padx=5, pady=2)
        self.prefix_entry.insert(0, "")

        # 保存路径
        ttk.Label(config_frame, text="保存目录:").grid(row=3, column=0, sticky=tk.W)
        self.save_path = tk.StringVar()
        ttk.Entry(config_frame, textvariable=self.save_path, width=40).grid(row=3, column=1, padx=5)
        ttk.Button(config_frame, text="浏览", command=self.choose_directory).grid(row=3, column=2)

        # 进度区域
        progress_frame = ttk.LabelFrame(main_frame, text="进度")
        progress_frame.pack(fill=tk.X, pady=5)

        self.progress_bar = ttk.Progressbar(progress_frame, mode='determinate')
        self.progress_bar.pack(fill=tk.X, padx=10, pady=5)

        info_frame = ttk.Frame(progress_frame)
        info_frame.pack(fill=tk.X, padx=10)
        ttk.Label(info_frame, text="当前文件:").pack(side=tk.LEFT)
        self.current_file_label = ttk.Label(info_frame, text="等待开始...")
        self.current_file_label.pack(side=tk.LEFT, padx=10)

        ttk.Label(info_frame, text="速度:").pack(side=tk.LEFT)
        self.speed_label = ttk.Label(info_frame, text="0.00 KB/s")
        self.speed_label.pack(side=tk.LEFT, padx=10)

        # 控制按钮
        btn_frame = ttk.Frame(main_frame)
        btn_frame.pack(pady=5)
        self.start_btn = ttk.Button(btn_frame, text="获取并下载", command=self.start_process)
        self.start_btn.pack(side=tk.LEFT, padx=5)
        self.stop_btn = ttk.Button(btn_frame, text="停止", state=tk.DISABLED, command=self.stop_process)
        self.stop_btn.pack(side=tk.LEFT, padx=5)

        # 日志区域
        log_frame = ttk.LabelFrame(main_frame, text="操作日志")
        log_frame.pack(fill=tk.BOTH, expand=True)
        self.log_text = scrolledtext.ScrolledText(log_frame, height=12)
        self.log_text.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)

    def choose_directory(self):
        path = filedialog.askdirectory()
        if path:
            self.save_path.set(path)

    def log(self, message):
        self.log_text.insert(tk.END, f"[{time.strftime('%H:%M:%S')}] {message}\n")
        self.log_text.see(tk.END)

    def validate_config(self):
        """验证配置有效性"""
        required_fields = {
            "AK": self.ak_entry.get().strip(),
            "SK": self.sk_entry.get().strip(),
            "Endpoint": self.endpoint_entry.get().strip(),
            "Bucket": self.bucket_entry.get().strip(),
            "SavePath": self.save_path.get()
        }

        for field, value in required_fields.items():
            if not value:
                messagebox.showerror("错误", f"{field} 不能为空")
                return False

        if not os.path.exists(required_fields["SavePath"]):
            try:
                os.makedirs(required_fields["SavePath"])
            except:
                messagebox.showerror("错误", "无法创建保存目录")
                return False

        return True

    def start_process(self):
        """启动整个流程"""
        if not self.validate_config():
            return

        self.start_btn.config(state=tk.DISABLED)
        self.stop_btn.config(state=tk.NORMAL)
        self.is_downloading = True

        threading.Thread(target=self.full_process, daemon=True).start()

    def full_process(self):
        """完整处理流程"""
        try:
            # 初始化OBS客户端
            self.obs_client = ObsClient(
                access_key_id=self.ak_entry.get().strip(),
                secret_access_key=self.sk_entry.get().strip(),
                server=self.endpoint_entry.get().strip()
            )

            # 获取文件列表
            self.log("正在获取文件列表...")
            self.file_list = self.list_obs_files()
            if not self.file_list:
                self.log("目标文件夹为空")
                return

            self.log(f"找到 {len(self.file_list)} 个文件")

            # 开始下载
            self.download_all_files()

        except Exception as e:
            self.log(f"操作失败: {str(e)}")
        finally:
            self.is_downloading = False
            self.master.after(0, lambda: self.stop_btn.config(state=tk.DISABLED))
            self.master.after(0, lambda: self.start_btn.config(state=tk.NORMAL))

    def list_obs_files(self):
        """获取OBS文件列表"""
        bucket = self.bucket_entry.get().strip()
        prefix = self.prefix_entry.get().strip().rstrip('/') + '/'
        file_list = []
        marker = None

        try:
            while True:
                resp = self.obs_client.listObjects(bucket, prefix=prefix, marker=marker)
                if resp.status < 300:
                    # 过滤文件夹标记对象
                    valid_files = [
                        obj.key for obj in resp.body.contents
                        if not (obj.key.endswith('/') and obj.size == 0)
                    ]
                    file_list.extend(valid_files)

                    if resp.body.is_truncated:
                        marker = resp.body.next_marker
                    else:
                        break
                else:
                    raise Exception(f"列表获取失败: {resp.errorCode}")

            return file_list

        except Exception as e:
            self.log(f"获取文件列表失败: {str(e)}")
            return []

    def download_all_files(self):
        """下载所有文件"""
        total = len(self.file_list)
        success_count = 0
        start_time = time.time()

        for idx, file_key in enumerate(self.file_list, 1):
            if not self.is_downloading:
                break

            self.current_file = file_key
            self.master.after(0, lambda: self.current_file_label.config(
                text=f"{idx}/{total} {os.path.basename(file_key)}"))

            try:
                # 下载文件
                local_path = os.path.join(self.save_path.get(), file_key)
                os.makedirs(os.path.dirname(local_path), exist_ok=True)

                resp = self.obs_client.getObject(
                    self.bucket_entry.get().strip(),
                    file_key,
                    downloadPath=local_path
                )

                if resp.status < 300:
                    success_count += 1
                    self.log(f"下载成功: {file_key}")
                else:
                    self.log(f"下载失败[{resp.status}]: {file_key}")

                # 更新进度
                progress = (idx / total) * 100
                self.master.after(0, lambda: self.progress_bar.configure(value=progress))

                # 计算速度
                time_used = time.time() - start_time
                speed = (idx * 1024) / time_used  # 假设平均每个文件1KB
                self.master.after(0, lambda: self.speed_label.config(text=f"{speed:.2f} 文件/秒"))

            except Exception as e:
                self.log(f"下载异常 {file_key}: {str(e)}")

        self.log(f"下载完成!成功 {success_count}/{total} 个文件")

    def stop_process(self):
        """停止处理"""
        self.is_downloading = False
        self.log("操作已停止")
        if self.obs_client:
            self.obs_client.close()


if __name__ == "__main__":
    root = tk.Tk()
    app = ObsAutoDownloader(root)
    root.mainloop()

 

您可能感兴趣的与本文相关的镜像

Python3.8

Python3.8

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

### 华为云 ECS 与其他服务或功能的对比和关联 #### 1. 华为云 ECS 与 CCE 的对比 华为云 ECS 和 CCE 是两种不同的云计算服务,分别适用于不同的应用场景。ECS 主要用于运行传统应用程序,而 CCE(容器引擎服务)则更适合构建和部署容器化应用[^1]。CCE 提供了更强大的自动探测工具和健康检查功能,对于访问频率较低但稳定性要求较高的服务,CCE 的实例更为可控且稳定[^4]。 #### 2. 华为云 ECS 与阿里云 ECS 的对比 从功能角度来看,华为云 ECS 和阿里云 ECS 在许多方面存在相似之处,但也有一些差异。例如,华为云 ECS 提供了免费的实验环境,用户可以快速上手并测试不同操作系统(如 Windows 和 Linux)[^2]。此外,在市场占有率方面,阿里云占据较大份额,但近年来由于其宕机事故频发,部分企业开始转向华为云以寻求更高的可靠性[^3]。 #### 3. 华为云 ECS 与其他服务的关联 为了实现更高效的业务管理和优化资源利用率,华为云 ECS 可与其他服务协同工作: - **对象存储服务(OBS)**:作为备份存储空间,确保数据安全性和持久性。 - **内容分发网络(CDN)**:加速静态资源加载速度,提升用户体验。 - **负载均衡器(ELB)**:提高系统的可用性和扩展性,保证流量均匀分布至各个 ECS 实例。 #### 4. 华为云 ECS 的优势 华为云 ECS 提供了灵活的资源配置选项,允许用户根据实际需求选择合适的 CPU、内存和存储组合。同时,它还支持高可用性架构设计,通过多区域部署和灾备方案来保障业务连续性[^1]。 ```python # 示例代码:使用 Python SDK 监控 ECS 性能指标 from huaweicloudsdkces.v1 import * def monitor_ecs_metrics(): credentials = BasicCredentials("your_ak", "your_sk") client = CesClient.new_builder() \ .with_credentials(credentials) \ .with_region("region_name") \ .build() request = ListMetricDataRequest( namespace="SYS.ECS", metric_name="cpu_utilization", dimensions=[{"name": "instance_id", "value": "your_instance_id"}], period="300", start_time="startTime", end_time="endTime" ) response = client.list_metric_data(request) print(response) monitor_ecs_metrics() ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值