Skip to main content

Python SDK

在一些权限受限的环境中(如非特权容器和大部分 Serverless 环境),由于无法使用 FUSE 模块,挂载文件系统会受到限制。为了解决这些限制并更好地支持 AI 场景,JuiceFS 企业版在 5.1 版本中推出了 Python SDK,允许应用程序在进程内直接访问 JuiceFS。

注意

JuiceFS Python SDK 尚处于 Beta 公测阶段,必须谨慎使用,并且在投入生产环境使用前进行充分测试。使用过程中如果遇到问题,请及时联系 Juicedata 工程师协助解决。

安装

确保安装了 Python 3.8 及以上版本,然后通过 pip 安装 JuiceFS Python SDK:

pip install https://static.juicefs.com/misc/juicefs-5.2.15.20250930-py3-none-any.whl

如果要安装 Ceph 版本的 JuiceFS Python SDK,请使用以下命令:

pip install https://static.juicefs.com/misc/juicefs-5.2.9.202605220801-py3-none-any.whl

初始化 JuiceFS 客户端

在 Python SDK 中,需要初始化一个 juicefs.Client 对象,并通过他来访问 JuiceFS 文件系统。如果此前使用云服务客户端挂载过文件系统,也就是说在当前用户的 ~/.juicefs 目录下已经存在文件系统的 *.conf 配置文件,那么在初始化 Client 对象时只需指定文件系统名称:

import juicefs

# 使用名为 myjfs 的文件系统初始化客户端对象
jfs = juicefs.Client("myjfs")

如果没有,则需要提供 JuiceFS 的认证信息,包括文件系统名称、token、对象存储的访问密钥等:

import os
import juicefs

# 从环境变量中获取配置信息,也可以直接填写。
volume = os.getenv("VOLUME_NAME")
jfs_token = os.getenv("TOKEN")
ak = os.getenv("ACCESS_KEY")
sk = os.getenv("SECRET_KEY")

# 初始化 JuiceFS 客户端
jfs = juicefs.Client(volume, # 文件系统名称
token=jfs_token, # JuiceFS 控制台获取的文件系统 token
access_key=ak, # 对象存储的 Access Key
secret_key=sk) # 对象存储的 Secret Key

基本文件操作

为了便于用户快速上手使用,JuiceFS Python SDK 在设计上参考了 Python 的内置函数和 os 包中的部分函数。以下是一些基本的文件操作示例。

列出目录中的文件

使用 listdir() 方法列出指定目录中的文件:

jfs.listdir('/')

创建目录

你可以使用 makedirs() 方法创建目录:

jfs.makedirs("/files")

检查文件或目录是否存在

使用 exists() 方法检查文件或目录是否存在:

if jfs.exists("/files/hello.txt"):
print("File exists")
else:
print("File does not exist")

写入文件

使用 open() 方法打开文件并使用 write() 方法写入内容:

with jfs.open("/files/hello.txt", "w") as f:
f.write("hello")

追加内容

使用 open() 方法以追加模式打开文件并写入内容:

with jfs.open("/files/hello.txt", "a+") as f:
f.write(" world")

读取文件

使用 open 方法打开文件并使用 read() 方法读取内容:

with jfs.open("/files/hello.txt") as f:
data = f.read()
print(data)

删除文件

使用 remove() 方法删除文件:

jfs.remove("/files/hello.txt")

高级操作

修改文件权限

使用 chmod() 方法修改文件权限,权限参数为八进制数

jfs.chmod("/files/hello.txt", 0o777)

使用 symlink() 方法创建符号链接:

jfs.symlink("/files/hello.txt", "/files/link")

使用 readlink() 方法读取符号链接的目标文件:

link_target = jfs.readlink("/files/link")
print(link_target)

使用 unlink() 方法删除符号链接:

jfs.unlink("/files/link")

设置和获取扩展属性

使用 setxattr()getxattr() 方法设置和获取文件的扩展属性:

jfs.setxattr("/files/hello.txt", "user.key", b"value\0")
xx = jfs.getxattr("/files/hello.txt", "user.key")
print(xx)

和 Ray 集成

JuiceFS Python SDK 可以通过 fsspec 接口与 Ray 集成,示例如下:

import fsspec
import ray

# 这个 import 语句会自动调用 fsspec.register_implementation()
from juicefs.spec import JuiceFS

# 初始化 JuiceFS 文件系统客户端
jfs = fsspec.filesystem("juicefs", name="<volume-name>",
conf_dir="/root/.juicefs", cache_group="CACHEGROUP",
cache_size="20480", cache_dir="/dev/shm/cache",
no_sharing=True)

# 读取数据
ds = ray.data.read_csv("example.csv", filesystem=jfs)
ds.count()
ds.schema()

API 索引

Client

Client 类是 JuiceFS 云服务的客户端类,用于与 JuiceFS 进行交互。

初始化方法

SDK 初始化的过程,完成了客户端认证(获取配置文件),以及连接元数据、建立客户端会话。过程十分类似在使用 JuiceFS 客户端的时候,需要先 authmount,因此需要传入的参数也可以参考 juicefs authjuicefs mount 命令的选项说明。

需要特别注意:

  • 因为使用场景有很大区别,SDK 的特定选项的默认值和 FUSE 客户端不同,以更好适配 SDK 的常见使用场景,例如:
    • cache_dir 的默认值是 memory
    • cache_size 的默认值是 100M
    • put_timeout 的默认值是 60sget_timeout 的默认值是 5s
  • console_url 只有在私有部署环境下才需要修改,改成集群实际的 Web 控制台访问地址。
class Client(name, *, token="", conf_dir="", console_url="https://juicefs.com",
bucket=None, access_key=None, secret_key=None, session_token=None, shards=0, storage_class=None,
bucket2=None, access_key2=None, secret_key2=None, session_token2=None, shards2=0, storage_class2=None,
rsa_key_path="", rsa_passphrase=None, internal=False, external=False,
max_uploads=20, max_downloads=200, prefetch=1, put_timeout="60s", get_timeout="5s",
upload_limit='', download_limit='', writeback=False, writeback_threshold_size="0",
metacache=True, max_cached_inodes=500000, opencache=False,
attr_cache="1s", entry_cache="0s", dir_entry_cache="1s",
buffer_size="300M", cache_size="100M", cache_items=0, free_space_ratio=0.1, cache_dir="memory",
cache_evict="2-random", cache_expire="0s", cache_scan_interval="3600s", verify_cache_checksum="extend",
cache_group="", group_ip="", group_weight=100, group_weight_unit="0M", group_port=0, no_sharing=False,
second_group="", cache_partial_only=False, cache_large_write=False, cache_try_dio=True,
fill_group_cache=False, cache_priority=0,
mount_point="/jfs", access_log="", debug=False, flip=False, no_bgjob=False, log="", read_only=False)

open()

Client.open(path, mode='r', buffering=-1, encoding=None, errors=None)

参数说明:

  • path (str):文件路径
  • mode (str):文件打开模式。支持 rwaxb/t+ 的组合,其中 rwax 必须且只能指定一个
  • buffering (int):缓冲区大小,默认为 -1(使用默认缓冲)
  • encoding (str):文件编码,二进制模式不支持该参数
  • errors (str):错误处理策略,二进制模式不支持该参数

返回值:

  • 返回一个 File 对象

makedirs()

Client.makedirs(path, mode=0o777, exist_ok=False)

参数说明:

  • path (str):目录路径
  • mode (int):目录权限
  • exist_ok (bool):如果目录已存在,是否忽略错误

返回值:

  • 无返回值

exists()

Client.exists(path)

参数说明:

  • path (str):文件或目录路径

返回值:

  • 返回一个布尔值,表示文件或目录是否存在

remove()

Client.remove(path)

参数说明:

  • path (str):文件路径

返回值:

  • 无返回值

chmod()

Client.chmod(path, mode)

参数说明:

  • path (str):文件路径
  • mode (int):文件权限

返回值:

  • 无返回值
Client.symlink(src, dst)

参数说明:

  • src (str):源文件路径
  • dst (str):目标符号链接路径

返回值:

  • 无返回值
Client.readlink(path)

参数说明:

  • path (str):符号链接路径

返回值:

  • 返回符号链接的目标路径
Client.unlink(path)

参数说明:

  • path (str):符号链接路径

返回值:

  • 无返回值

setxattr()

Client.setxattr(path, name, value, flags=0)

参数说明:

  • path (str):文件路径
  • name (str):扩展属性名称
  • value (bytes):扩展属性值
  • flags (int):扩展属性标志

返回值:

  • 无返回值

getxattr()

Client.getxattr(path, name)

参数说明:

  • path (str):文件路径
  • name (str):扩展属性名称

返回值:

  • 返回扩展属性值

listdir()

Client.listdir(path, detail=False)

参数说明:

  • path (str):目录路径
  • detail (bool):是否返回包含文件详细信息的列表,默认为 False,只返回文件名列表

返回值:

  • 返回一个包含目录中文件名的列表;如果 detail=True,返回 (文件名, stat 结果) 元组的列表

stat()

Client.stat(path)

参数说明:

  • path (str):文件或目录路径

返回值:

lstat()

Client.lstat(path)

参数说明:

  • path (str):文件或目录路径

返回值:

  • stat() 类似,但不跟随符号链接

mkdir()

Client.mkdir(path, mode=0o777)

参数说明:

  • path (str):目录路径
  • mode (int):目录权限

返回值:

  • 无返回值

rmdir()

Client.rmdir(path)

参数说明:

  • path (str):目录路径,目录必须为空

返回值:

  • 无返回值

rename()

Client.rename(old, new)

参数说明:

  • old (str):原文件或目录路径
  • new (str):新的文件或目录路径

返回值:

  • 无返回值

truncate()

Client.truncate(path, size)

参数说明:

  • path (str):文件路径
  • size (int):截断后的文件大小

返回值:

  • 无返回值

chown()

Client.chown(path, uid, gid)

参数说明:

  • path (str):文件路径
  • uid (int):新的文件所有者 UID
  • gid (int):新的文件所属组 GID

返回值:

  • 无返回值
Client.link(src, dst)

参数说明:

  • src (str):源文件路径
  • dst (str):目标硬链接路径

返回值:

  • 无返回值

rmr()

Client.rmr(path)

参数说明:

  • path (str):要递归删除的文件或目录路径

返回值:

  • 无返回值

utime()

Client.utime(path, times=None)

参数说明:

  • path (str):文件路径
  • times (tuple):(atime, mtime) 时间戳元组,默认为 None,表示使用当前时间

返回值:

  • 无返回值

listxattr()

Client.listxattr(path)

参数说明:

  • path (str):文件路径

返回值:

  • 返回一个包含文件所有扩展属性名称的列表

removexattr()

Client.removexattr(path, name)

参数说明:

  • path (str):文件路径
  • name (str):要删除的扩展属性名称

返回值:

  • 无返回值

summary()

Client.summary(path, depth=0, entries=1)

获取目录的汇总信息,包括目录及子目录内的文件数、目录数、总大小等。

参数说明:

  • path (str):目录路径
  • depth (int):汇总统计的目录深度,默认为 0,表示统计全部
  • entries (int):返回的子目录条目数上限,默认为 1

返回值:

  • 返回一个字典,包含目录汇总信息,例如 Files(文件数)、Dirs(目录数)、Size(数据大小)、Entries(子目录明细)等字段

clone()

Client.clone(src, dst, preserve=False, follow_link=True)

克隆文件或目录。与 juicefs clone 命令类似,克隆只拷贝元数据,并不会实际复制对象存储数据,因此速度非常快。

参数说明:

  • src (str):源文件或目录路径
  • dst (str):目标路径
  • preserve (bool):是否保留源文件的元数据(mode、UID、GID、atime、mtime),默认为 False
  • follow_link (bool):为 True 时符号链接作为普通文件被克隆,为 False 时按符号链接本身克隆,默认为 True

返回值:

  • 无返回值

set_quota()

Client.set_quota(path, capacity=0, inodes=0, create=False, strict=False)

设置目录的配额。配额的管理方式可参考 「容量和配额」

参数说明:

  • path (str):目录路径
  • capacity (int):容量配额(字节数),默认为 0
  • inodes (int):文件数配额,默认为 0
  • create (bool):如果目录不存在,是否自动创建,默认为 False
  • strict (bool):预留参数

返回值:

  • 无返回值

get_quota()

Client.get_quota(path)

获取目录的配额信息。

参数说明:

  • path (str):目录路径

返回值:

  • 返回一个字典,包含目录的配额信息,例如 MaxSpace(容量配额)、MaxInodes(文件数配额)等字段

del_quota()

Client.del_quota(path)

删除目录的配额。

参数说明:

  • path (str):目录路径

返回值:

  • 无返回值

list_quota()

Client.list_quota()

列出文件系统中所有目录的配额。

返回值:

  • 返回一个字典,包含所有已设置配额的目录及其配额信息

merge()

Client.merge(dest, sources, overwrite=False, append=False)

将多个源文件合并到一个目标文件。

参数说明:

  • dest (str):目标文件路径
  • sources (str 或 list):源文件路径,可以是单个路径或路径列表
  • overwrite (bool):目标文件已存在时是否覆盖,默认为 False
  • append (bool):目标文件已存在且不是普通文件时,是否追加写入,默认为 False

返回值:

  • 返回操作结果

info()

Client.info(path, inode=0, recursive=False)

获取文件或目录的详细信息。

参数说明:

  • path (str):文件或目录路径
  • inode (int):文件的 inode 号,默认为 0,此时根据 path 查询
  • recursive (bool):是否递归获取目录的详细信息,默认为 False

返回值:

  • 返回一个字典,包含文件或目录的详细信息

warmup()

Client.warmup(paths, threads=10, priority=0, retry=3, max_failure=0, evict=False, follow_link=False, check=False, background=False, samples=0, expand=0)

预热缓存。与 juicefs warmup 命令类似,将文件提前下载到缓存,提升后续访问速度。

参数说明:

  • paths (str):要预热的文件或目录路径
  • threads (int):下载并发度,默认为 10
  • priority (int):缓存块的优先级,可选值为 0123,数字越大优先级越高,默认为 0
  • retry (int):下载单个数据块的最大失败重试次数,默认为 3
  • max_failure (int):允许的最大失败数据块数,默认为 0
  • evict (bool):主动删除给定路径的缓存内容,默认为 False
  • follow_link (bool):是否跟随符号链接,默认为 False
  • check (bool):检查给定路径是否已被缓存,默认为 False
  • background (bool):是否后台运行,默认为 False
  • samples (int):抽样预热的数据块数量,默认为 0,表示全部预热
  • expand (int):预热时额外扩展预热的范围,默认为 0

返回值:

  • 返回一个字典,包含预热结果

trash()

Client.trash(cursor=0, limit=100, query="", mode=1, startTs=0, endTs=0)

列出回收站中的文件。

参数说明:

  • cursor (int):分页游标,默认为 0
  • limit (int):单次返回的文件数量上限,默认为 100
  • query (str):查询关键字,默认为空字符串
  • mode (int):查询模式,默认为 1
  • startTs (int):起始时间戳,默认为 0
  • endTs (int):结束时间戳,默认为 0

返回值:

  • 返回 (文件列表, 下一个游标) 元组,其中文件列表中的每个元素为 (文件名, stat 结果) 元组

status()

Client.status()

获取文件系统的状态。

返回值:

  • 返回一个字典,包含文件系统的状态信息

File

File 类是 JuiceFS 文件操作的类,用于读写文件。

初始化方法

通常使用 Client.open() 方法来初始化 File 对象,不会直接创建。

fileno()

File.fileno()

返回值:

  • 返回文件描述符

isatty()

File.isatty()

返回值:

  • 返回一个布尔值,表示文件是否为 TTY

read()

File.read(size=-1)

参数说明:

  • size (int):读取的字节数,默认为 -1,表示读取整个文件

返回值:

  • 返回读取的字节数据

write()

File.write(data)

参数说明:

  • data (bytes):要写入的数据

返回值:

  • 返回写入的字节数

readline()

File.readline()

读取一行,直到换行符或文件末尾。

返回值:

  • 返回读取的一行数据

close()

File.close()

返回值:

  • 无返回值

flush()

File.flush()

返回值:

  • 无返回值

fsync()

File.fsync()

强制将文件数据写入后端存储。

返回值:

  • 无返回值

readlines()

File.readlines(hint=-1)

参数说明:

  • hint (int):读取的行数,默认为 -1,表示读取所有行

返回值:

  • 返回一个包含文件行的列表

writelines()

File.writelines(lines)

参数说明:

  • lines (list):要写入的行列表

返回值:

  • 无返回值

seek()

File.seek(offset, whence=0)

参数说明:

  • offset (int):偏移量
  • whence (int):偏移基准,0 表示从文件开头,1 表示从当前位置,2 表示从文件末尾

返回值:

  • 返回新的文件指针位置

tell()

File.tell()

返回值:

  • 返回当前文件指针位置

truncate()

File.truncate(size=None)

参数说明:

  • size (int):截断后的文件大小,默认为当前文件指针位置

返回值:

  • 返回截断后的文件大小

readable()

File.readable()

返回值:

  • 返回一个布尔值,表示文件是否可读

writable()

File.writable()

返回值:

  • 返回一个布尔值,表示文件是否可写

seekable()

File.seekable()

返回值:

  • 返回一个布尔值,表示文件是否可寻址