python-alist


Namepython-alist JSON
Version 0.0.13.6 PyPI version JSON
download
home_pagehttps://github.com/ChenyangGao/web-mount-packs/tree/main/python-alist-client
SummaryPython wrapper for alist.
upload_time2024-11-30 13:41:06
maintainerNone
docs_urlNone
authorChenyangGao
requires_python<4.0,>=3.11
licenseMIT
keywords alist client
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Alist web API 的 Python 封装

![PyPI - Python Version](https://img.shields.io/pypi/pyversions/python-alist)
![PyPI - Version](https://img.shields.io/pypi/v/python-alist)
![PyPI - Downloads](https://img.shields.io/pypi/dm/python-alist)
![PyPI - Format](https://img.shields.io/pypi/format/python-alist)
![PyPI - Status](https://img.shields.io/pypi/status/python-alist)

- [AList web API 官方文档](https://alist.nn.ci/guide/api/)
- [AList web API 在线工具](https://alist-v3.apifox.cn)

## 安装

通过 [pypi](https://pypi.org/project/python-alist/)

```console
pip install -U python-alist
```

## 入门介绍

### 1. 导入模块和创建实例

**导入模块**

```python
from alist import AlistClient, AlistFileSystem
```

**创建客户端对象,登录 <kbd>AList</kbd>:此处,后台服务地址: `"http://localhost:5244"`,用户名: `"admin"`,密码: `"123456"`**

> 请确保 <kbd>AList</kbd> 已经启动,并且可通过 <kbd>http://localhost:5244</kbd> 访问

```python
client = AlistClient("http://localhost:5244", "admin", "123456")
```

绝大部分 <kbd>AlistClient</kbd> 的方法带有 `async_` 参数,意味着它支持异步 IO。

```python
>>> import asyncio
>>> loop = asyncio.get_event_loop()

>>> from alist import AlistClient, AlistFileSystem
>>> client = AlistClient("http://localhost:5244", "admin", "123456")

>>> client.fs_get(dict(path="/"))
{'code': 200,
 'message': 'success',
 'data': {'name': '115',
  'size': 0,
  'is_dir': True,
  'modified': '2023-12-26T12:23:59.259218+08:00',
  'created': '2023-12-26T12:23:59.259218+08:00',
  'sign': '',
  'thumb': '',
  'type': 0,
  'hashinfo': 'null',
  'hash_info': None,
  'raw_url': '',
  'readme': '',
  'header': '',
  'provider': '115 Cloud',
  'related': None}}

>>> client.fs_get(dict(path="/"), async_=True)
<coroutine object AlistClient._async_request.<locals>.request at 0x1055f0d60>
>>> loop.run_until_complete(client.fs_get(dict(path="/"), async_=True))
{'code': 200,
 'message': 'success',
 'data': {'name': 'root',
  'size': 0,
  'is_dir': True,
  'modified': '0001-01-01T00:00:00Z',
  'created': '0001-01-01T00:00:00Z',
  'sign': '',
  'thumb': '',
  'type': 0,
  'hashinfo': 'null',
  'hash_info': None,
  'raw_url': '',
  'readme': '',
  'header': '',
  'provider': 'unknown',
  'related': None}}
```

**创建文件系统对象**

```python
fs = AlistFileSystem(client)
```

或者直接在 <kbd>client</kbd> 上就可获取文件系统对象

```python
fs = client.fs
```

或者直接用 <kbd>AlistFileSystem</kbd> 登录

```python
fs = AlistFileSystem.login("http://localhost:5244", "admin", "123456")
```

### 2. 操作网盘使用 Python 式的文件系统方法

文件系统对象的方法,设计和行为参考了 <kbd>[os](https://docs.python.org/3/library/os.html)</kbd>、<kbd>[posixpath](https://docs.python.org/3/library/os.path.html)</kbd>、<kbd>[pathlib.Path](https://docs.python.org/3/library/pathlib.html)</kbd> 和 <kbd>[shutil](https://docs.python.org/3/library/shutil.html)</kbd> 等模块。

<kbd>alist.AlistFileSystem</kbd> 实现了读写的文件系统方法。

<kbd>alist.AlistPath</kbd> 实现了二次封装,从路径的角度来进行操作。

**使用** <kbd>getcwd</kbd> **方法,获取当前工作目录的路径,参考** <kbd>os.getcwd</kbd>

```python
>>> fs.getcwd()
'/'
```

**使用** <kbd>listdir</kbd> **方法,罗列当前目录的文件名,参考** <kbd>os.listdir</kbd>

```python
>>> fs.listdir()
['115', '阿里云盘']
```

**使用** <kbd>chdir</kbd> **方法,切换当前工作目录,参考** <kbd>os.chdir</kbd>

```python
>>> fs.chdir("/115")
```

**使用** <kbd>listdir_attr</kbd> **方法,罗列当前目录时,还可以获取属性**

```python
>>> fs.listdir_attr()
[{'name': '云下载',
  'size': 0,
  'is_dir': True,
  'modified': '2023-12-16T21:58:22+08:00',
  'created': '2023-03-18T18:52:54+08:00',
  'sign': '',
  'thumb': '',
  'type': 1,
  'hashinfo': '{"sha1":""}',
  'hash_info': {'sha1': ''},
  'path': '/115/云下载',
  'lastest_update': datetime.datetime(2023, 12, 29, 15, 50, 50, 828853)},
 {'name': '000阅读·乱七八糟',
  'size': 0,
  'is_dir': True,
  'modified': '2023-12-14T14:54:20+08:00',
  'created': '2023-03-18T14:45:45+08:00',
  'sign': '',
  'thumb': '',
  'type': 1,
  'hashinfo': '{"sha1":""}',
  'hash_info': {'sha1': ''},
  'path': '/115/000阅读·乱七八糟',
  'lastest_update': datetime.datetime(2023, 12, 29, 15, 50, 50, 828853)},
 {'name': '电视剧',
  'size': 0,
  'is_dir': True,
  'modified': '2023-12-23T22:26:17+08:00',
  'created': '2023-04-16T18:30:33+08:00',
  'sign': '',
  'thumb': '',
  'type': 1,
  'hashinfo': '{"sha1":""}',
  'hash_info': {'sha1': ''},
  'path': '/115/电视剧',
  'lastest_update': datetime.datetime(2023, 12, 29, 15, 50, 50, 828853)},
 {'name': '电影',
  'size': 0,
  'is_dir': True,
  'modified': '2023-12-14T14:54:20+08:00',
  'created': '2023-03-01T12:46:07+08:00',
  'sign': '',
  'thumb': '',
  'type': 1,
  'hashinfo': '{"sha1":""}',
  'hash_info': {'sha1': ''},
  'path': '/115/电影',
  'lastest_update': datetime.datetime(2023, 12, 29, 15, 50, 50, 828853)},
 {'name': '纪录片',
  'size': 0,
  'is_dir': True,
  'modified': '2023-12-18T18:49:29+08:00',
  'created': '2023-02-24T11:40:45+08:00',
  'sign': '',
  'thumb': '',
  'type': 1,
  'hashinfo': '{"sha1":""}',
  'hash_info': {'sha1': ''},
  'path': '/115/纪录片',
  'lastest_update': datetime.datetime(2023, 12, 29, 15, 50, 50, 828853)},
 {'name': 'libgen',
  'size': 0,
  'is_dir': True,
  'modified': '2023-12-14T14:54:20+08:00',
  'created': '2023-05-28T22:05:06+08:00',
  'sign': '',
  'thumb': '',
  'type': 1,
  'hashinfo': '{"sha1":""}',
  'hash_info': {'sha1': ''},
  'path': '/115/libgen',
  'lastest_update': datetime.datetime(2023, 12, 29, 15, 50, 50, 828853)},
 {'name': '👾0号:重要资源',
  'size': 0,
  'is_dir': True,
  'modified': '2023-12-14T14:54:20+08:00',
  'created': '2023-02-28T21:40:32+08:00',
  'sign': '',
  'thumb': '',
  'type': 1,
  'hashinfo': '{"sha1":""}',
  'hash_info': {'sha1': ''},
  'path': '/115/👾0号:重要资源',
  'lastest_update': datetime.datetime(2023, 12, 29, 15, 50, 50, 828853)},
 {'name': '📚1号:书籍大礼包',
  'size': 0,
  'is_dir': True,
  'modified': '2023-12-14T14:54:20+08:00',
  'created': '2023-03-01T01:29:12+08:00',
  'sign': '',
  'thumb': '',
  'type': 1,
  'hashinfo': '{"sha1":""}',
  'hash_info': {'sha1': ''},
  'path': '/115/📚1号:书籍大礼包',
  'lastest_update': datetime.datetime(2023, 12, 29, 15, 50, 50, 828853)},
 {'name': '📼资料备份',
  'size': 0,
  'is_dir': True,
  'modified': '2023-12-14T14:54:20+08:00',
  'created': '2023-07-07T15:13:12+08:00',
  'sign': '',
  'thumb': '',
  'type': 1,
  'hashinfo': '{"sha1":""}',
  'hash_info': {'sha1': ''},
  'path': '/115/📼资料备份',
  'lastest_update': datetime.datetime(2023, 12, 29, 15, 50, 50, 828853)}]
```

**使用** <kbd>listdir_path</kbd> **方法,罗列当前目录时,还可以获取** <kbd>alist.AlistPath</kbd> **对象**

```python
>>> fs.listdir_path()
[<alist.AlistPath(name='云下载', size=0, is_dir=True, modified='2023-12-16T21:58:22+08:00', created='2023-03-18T18:52:54+08:00', sign='', thumb='', type=1, hashinfo='{"sha1":""}', hash_info={'sha1': ''}, lastest_update=datetime.datetime(2023, 12, 29, 15, 51, 11, 817697), fs=alist.AlistFileSystem(client=alist.AlistClient(origin='http://localhost:5244', username='admin', password='******'), path='/115', refresh=False, request_kwargs={}), path='/115/云下载', password='')>,
 <alist.AlistPath(name='000阅读·乱七八糟', size=0, is_dir=True, modified='2023-12-14T14:54:20+08:00', created='2023-03-18T14:45:45+08:00', sign='', thumb='', type=1, hashinfo='{"sha1":""}', hash_info={'sha1': ''}, lastest_update=datetime.datetime(2023, 12, 29, 15, 51, 11, 817697), fs=alist.AlistFileSystem(client=alist.AlistClient(origin='http://localhost:5244', username='admin', password='******'), path='/115', refresh=False, request_kwargs={}), path='/115/000阅读·乱七八糟', password='')>,
 <alist.AlistPath(name='电视剧', size=0, is_dir=True, modified='2023-12-23T22:26:17+08:00', created='2023-04-16T18:30:33+08:00', sign='', thumb='', type=1, hashinfo='{"sha1":""}', hash_info={'sha1': ''}, lastest_update=datetime.datetime(2023, 12, 29, 15, 51, 11, 817697), fs=alist.AlistFileSystem(client=alist.AlistClient(origin='http://localhost:5244', username='admin', password='******'), path='/115', refresh=False, request_kwargs={}), path='/115/电视剧', password='')>,
 <alist.AlistPath(name='电影', size=0, is_dir=True, modified='2023-12-14T14:54:20+08:00', created='2023-03-01T12:46:07+08:00', sign='', thumb='', type=1, hashinfo='{"sha1":""}', hash_info={'sha1': ''}, lastest_update=datetime.datetime(2023, 12, 29, 15, 51, 11, 817697), fs=alist.AlistFileSystem(client=alist.AlistClient(origin='http://localhost:5244', username='admin', password='******'), path='/115', refresh=False, request_kwargs={}), path='/115/电影', password='')>,
 <alist.AlistPath(name='纪录片', size=0, is_dir=True, modified='2023-12-18T18:49:29+08:00', created='2023-02-24T11:40:45+08:00', sign='', thumb='', type=1, hashinfo='{"sha1":""}', hash_info={'sha1': ''}, lastest_update=datetime.datetime(2023, 12, 29, 15, 51, 11, 817697), fs=alist.AlistFileSystem(client=alist.AlistClient(origin='http://localhost:5244', username='admin', password='******'), path='/115', refresh=False, request_kwargs={}), path='/115/纪录片', password='')>,
 <alist.AlistPath(name='libgen', size=0, is_dir=True, modified='2023-12-14T14:54:20+08:00', created='2023-05-28T22:05:06+08:00', sign='', thumb='', type=1, hashinfo='{"sha1":""}', hash_info={'sha1': ''}, lastest_update=datetime.datetime(2023, 12, 29, 15, 51, 11, 817697), fs=alist.AlistFileSystem(client=alist.AlistClient(origin='http://localhost:5244', username='admin', password='******'), path='/115', refresh=False, request_kwargs={}), path='/115/libgen', password='')>,
 <alist.AlistPath(name='👾0号:重要资源', size=0, is_dir=True, modified='2023-12-14T14:54:20+08:00', created='2023-02-28T21:40:32+08:00', sign='', thumb='', type=1, hashinfo='{"sha1":""}', hash_info={'sha1': ''}, lastest_update=datetime.datetime(2023, 12, 29, 15, 51, 11, 817697), fs=alist.AlistFileSystem(client=alist.AlistClient(origin='http://localhost:5244', username='admin', password='******'), path='/115', refresh=False, request_kwargs={}), path='/115/👾0号:重要资源', password='')>,
 <alist.AlistPath(name='📚1号:书籍大礼包', size=0, is_dir=True, modified='2023-12-14T14:54:20+08:00', created='2023-03-01T01:29:12+08:00', sign='', thumb='', type=1, hashinfo='{"sha1":""}', hash_info={'sha1': ''}, lastest_update=datetime.datetime(2023, 12, 29, 15, 51, 11, 817697), fs=alist.AlistFileSystem(client=alist.AlistClient(origin='http://localhost:5244', username='admin', password='******'), path='/115', refresh=False, request_kwargs={}), path='/115/📚1号:书籍大礼包', password='')>,
 <alist.AlistPath(name='📼资料备份', size=0, is_dir=True, modified='2023-12-14T14:54:20+08:00', created='2023-07-07T15:13:12+08:00', sign='', thumb='', type=1, hashinfo='{"sha1":""}', hash_info={'sha1': ''}, lastest_update=datetime.datetime(2023, 12, 29, 15, 51, 11, 817697), fs=alist.AlistFileSystem(client=alist.AlistClient(origin='http://localhost:5244', username='admin', password='******'), path='/115', refresh=False, request_kwargs={}), path='/115/📼资料备份', password='')>]
```

**再次使用** <kbd>chdir</kbd> **,进入一些目录**

```python
>>> fs.chdir("电视剧/欧美剧/A")
>>> fs.getcwd()
'/115/电视剧/欧美剧/A'
>>> fs.listdir()
['A《爱、死亡和机器人》(Love.Death.and.Robot)[tt9561862]']
>>> fs.chdir("A《爱、死亡和机器人》(Love.Death.and.Robot)[tt9561862]/爱、死亡和机器人S01.Love.Death.and.Robots.1080p.NF.WEB-DL.DDP5.1.x264-NTG(18集)")
>>> fs.listdir()
['Love.Death.and.Robots.S01E01.Sonnies.Edge.1080p.NF.WEB-DL.DDP5.1.x264-NTG.简体&英文.ass', 'Love.Death.and.Robots.S01E01.Sonnies.Edge.1080p.NF.WEB-DL.DDP5.1.x264-NTG.mkv']
```

**使用** <kbd>attr</kbd> **方法,获取文件或文件夹的属性** 

```python
>>> fs.attr("Love.Death.and.Robots.S01E01.Sonnies.Edge.1080p.NF.WEB-DL.DDP5.1.x264-NTG.mkv")
{'name': 'Love.Death.and.Robots.S01E01.Sonnies.Edge.1080p.NF.WEB-DL.DDP5.1.x264-NTG.mkv',
 'size': 924544482,
 'is_dir': False,
 'modified': '2023-02-24T11:42:00+08:00',
 'created': '2023-02-24T11:42:51+08:00',
 'sign': '',
 'thumb': '',
 'type': 2,
 'hashinfo': '{"sha1":"7F4121B68A4E467ABF30A84627E20A8978895A4E"}',
 'hash_info': {'sha1': '7F4121B68A4E467ABF30A84627E20A8978895A4E'},
 'raw_url': 'http://localhost:5244/p/115/%E7%94%B5%E8%A7%86%E5%89%A7/%E6%AC%A7%E7%BE%8E%E5%89%A7/A/A%E3%80%8A%E7%88%B1%E3%80%81%E6%AD%BB%E4%BA%A1%E5%92%8C%E6%9C%BA%E5%99%A8%E4%BA%BA%E3%80%8B%28Love.Death.and.Robot%29%5Btt9561862%5D/%E7%88%B1%E3%80%81%E6%AD%BB%E4%BA%A1%E5%92%8C%E6%9C%BA%E5%99%A8%E4%BA%BAS01.Love.Death.and.Robots.1080p.NF.WEB-DL.DDP5.1.x264-NTG%EF%BC%8818%E9%9B%86%EF%BC%89/Love.Death.and.Robots.S01E01.Sonnies.Edge.1080p.NF.WEB-DL.DDP5.1.x264-NTG.mkv',
 'readme': '',
 'header': '',
 'provider': '115 Cloud',
 'related': [{'name': 'Love.Death.and.Robots.S01E01.Sonnies.Edge.1080p.NF.WEB-DL.DDP5.1.x264-NTG.简体&英文.ass',
   'size': 48910,
   'is_dir': False,
   'modified': '2023-03-23T22:09:00+08:00',
   'created': '2023-03-23T22:09:09+08:00',
   'sign': '',
   'thumb': '',
   'type': 4,
   'hashinfo': '{"sha1":"30AB3A1A376DE83049B35F135A774980F5C7C558"}',
   'hash_info': {'sha1': '30AB3A1A376DE83049B35F135A774980F5C7C558'}}],
 'path': '/115/电视剧/欧美剧/A/A《爱、死亡和机器人》(Love.Death.and.Robot)[tt9561862]/爱、死亡和机器人S01.Love.Death.and.Robots.1080p.NF.WEB-DL.DDP5.1.x264-NTG(18集)/Love.Death.and.Robots.S01E01.Sonnies.Edge.1080p.NF.WEB-DL.DDP5.1.x264-NTG.mkv',
 'lastest_update': datetime.datetime(2023, 12, 29, 15, 51, 47, 591418)}
```

**使用** <kbd>stat</kbd> **方法,获取文件或文件夹的部分,参考** <kbd>os.stat</kbd>

```python
>>> fs.stat("Love.Death.and.Robots.S01E01.Sonnies.Edge.1080p.NF.WEB-DL.DDP5.1.x264-NTG.mkv")
os.stat_result(st_mode=33279, st_ino=0, st_dev=0, st_nlink=1, st_uid=0, st_gid=0, st_size=924544482, st_atime=1703836333.124217, st_mtime=1677210120.0, st_ctime=1677210171.0)
```

**使用** <kbd>open</kbd> **方法,打开一个文件(目前只支持读取,不支持写入),参考** <kbd>open</kbd>

```python
>>> f = fs.open("Love.Death.and.Robots.S01E01.Sonnies.Edge.1080p.NF.WEB-DL.DDP5.1.x264-NTG.简体&英文.ass", encoding="UTF-16")
>>> f
<_io.TextIOWrapper name='Love.Death.and.Robots.S01E01.Sonnies.Edge.1080p.NF.WEB-DL.DDP5.1.x264-NTG.简体&英文.ass' encoding='UTF-16'>
```

读取此文件的前 100 个字符

```python
>>> f.read(100)
'[Script Info]\n;SrtEdit 6.3.2012.1001\n;Copyright(C) 2005-2012 Yuan Weiguo\n\nTitle: YYeTs\nOriginal Scri'
```

用完后请及时关闭文件(其实不主动关闭也可以,只要文件不被引用,就会自动关闭)

```python
>>> f.close()
```

**以二进制模式打开一个文件,此时** `mode="rb"`

```python
>>> f = fs.open("Love.Death.and.Robots.S01E01.Sonnies.Edge.1080p.NF.WEB-DL.DDP5.1.x264-NTG.mkv", "rb")
>>> f
alist.util.file.HTTPFileReader('http://localhost:5244/d/115/%E7%94%B5%E8%A7%86%E5%89%A7/%E6%AC%A7%E7%BE%8E%E5%89%A7/A/A%E3%80%8A%E7%88%B1%E3%80%81%E6%AD%BB%E4%BA%A1%E5%92%8C%E6%9C%BA%E5%99%A8%E4%BA%BA%E3%80%8B%28Love.Death.and.Robot%29%5Btt9561862%5D/%E7%88%B1%E3%80%81%E6%AD%BB%E4%BA%A1%E5%92%8C%E6%9C%BA%E5%99%A8%E4%BA%BAS01.Love.Death.and.Robots.1080p.NF.WEB-DL.DDP5.1.x264-NTG%EF%BC%8818%E9%9B%86%EF%BC%89/Love.Death.and.Robots.S01E01.Sonnies.Edge.1080p.NF.WEB-DL.DDP5.1.x264-NTG.mkv', urlopen=<function urlopen at 0x105ffb560>, headers=mappingproxy({'Accept-Encoding': 'identity'}))
```

读取前 10 个字节

```python
>>> f.read(10)
b'\x1aE\xdf\xa3\xa3B\x86\x81\x01B'
```

再读取 10 个字节

```python
>>> f.read(10)
b'\xf7\x81\x01B\xf2\x81\x04B\xf3\x81'
```

当前文件偏移位置(从 0 开始计算)

```python
>>> f.tell()
20
```

把读取位置重新变为文件开头

```python
>>> f.seek(0)
0
>>> f.tell()
0
```

再次读取 20 字节,应该等于上面两次结果的拼接

```python
>>> f.read(20)
b'\x1aE\xdf\xa3\xa3B\x86\x81\x01B\xf7\x81\x01B\xf2\x81\x04B\xf3\x81'
>>> f.tell()
20
```

**回到根目录,我们继续其它试验**

```python
>>> fs.chdir("/")
```

**使用** <kbd>walk</kbd> **方法,可以遍历一个目录,参考** <kbd>os.walk</kbd>

```python
>>> next(fs.walk())
('/', ['115', '阿里云盘'], [])
```

**使用** <kbd>walk_path</kbd> **方法,可以遍历一个目录时,获取** <kbd>alist.AlistPath</kbd> 对象

```python
>>> next(fs.walk_path())
('/',
 [<alist.AlistPath(name='115', size=0, is_dir=True, modified='2023-12-26T12:23:59.259218+08:00', created='2023-12-26T12:23:59.259218+08:00', sign='', thumb='', type=1, hashinfo='null', hash_info=None, lastest_update=datetime.datetime(2023, 12, 29, 15, 53, 33, 430767), fs=alist.AlistFileSystem(client=alist.AlistClient(origin='http://localhost:5244', username='admin', password='******'), path='/', refresh=False, request_kwargs={}), path='/115', password='')>,
  <alist.AlistPath(name='阿里云盘', size=0, is_dir=True, modified='2023-10-01T16:26:52.862197+08:00', created='2023-10-01T16:26:52.862197+08:00', sign='', thumb='', type=1, hashinfo='null', hash_info=None, lastest_update=datetime.datetime(2023, 12, 29, 15, 53, 33, 430767), fs=alist.AlistFileSystem(client=alist.AlistClient(origin='http://localhost:5244', username='admin', password='******'), path='/', refresh=False, request_kwargs={}), path='/阿里云盘', password='')>],
 [])
```

**必需在挂载的 `storage` 下才能创建文件,因此进入 `/115` 下,继续做实验**

```python
>>> fs.chdir("/115")
```

**使用** <kbd>mkdir</kbd> **方法,可以创建空文件夹,参考** <kbd>os.mkdir</kbd>

```python
>>> fs.mkdir("test")
'/115/test'
```

**使用** <kbd>rmdir</kbd> **方法,可以删除空文件夹,参考** <kbd>os.rmdir</kbd>

```python
>>> fs.rmdir('test')
>>> fs.listdir()
['云下载',
 '000阅读·乱七八糟',
 '电视剧',
 '电影',
 '纪录片',
 'libgen',
 '👾0号:重要资源',
 '📚1号:书籍大礼包',
 '📼资料备份']
```

**使用** <kbd>makedirs</kbd> **方法,可以创建多级的空目录,参考** <kbd>os.makedirs</kbd>

```python
>>> fs.makedirs("a/b/c/d", exist_ok=True)
'/115/a/b/c/d'
>>> fs.listdir()
['云下载',
 '000阅读·乱七八糟',
 'a',
 '电视剧',
 '电影',
 '纪录片',
 'libgen',
 '👾0号:重要资源',
 '📚1号:书籍大礼包',
 '📼资料备份']
```

**使用** <kbd>removedirs</kbd> **方法,可以(自底向上地)删除多级的空目录,参考** <kbd>os.removedirs</kbd>

```python
>>> fs.removedirs("a/b/c/d")
>>> fs.listdir()
['云下载',
 '000阅读·乱七八糟',
 '电视剧',
 '电影',
 '纪录片',
 'libgen',
 '👾0号:重要资源',
 '📚1号:书籍大礼包',
 '📼资料备份']
```

**使用** <kbd>upload</kbd> **方法上传文件(提示:如果 `as_task=True`(默认为 `False`),则文件只是上传到 <kbd>AList</kbd> 服务器上,至于 <kbd>AList</kbd> 什么时候上传完成,得等待)**

**说明** 暂时,<kbd>AList</kbd> 新增文件后,并不更新缓存(但删除和改名会更新),需要强制刷新一下。

```python
>>> from io import BytesIO
>>> fs.upload(BytesIO(b"123"), "test.txt")
'/115/test.txt'
>>> _ = fs.listdir(refresh=True)
>>> fs.read_text("test.txt")
'123'
>>> fs.upload("file.py")
'/115/file.py'
>>> fs.listdir(refresh=True)
['云下载',
 '000阅读·乱七八糟',
 '电视剧',
 '电影',
 '纪录片',
 'libgen',
 '👾0号:重要资源',
 '📚1号:书籍大礼包',
 '📼资料备份',
 'file.py',
 'test.txt']
```

**使用** <kbd>remove</kbd> **方法可以删除文件,参考** <kbd>os.remove</kbd>

```python
>>> fs.remove("test.txt")
>>> fs.remove("file.py")
>>> fs.listdir()
['云下载',
 '000阅读·乱七八糟',
 '电视剧',
 '电影',
 '纪录片',
 'libgen',
 '👾0号:重要资源',
 '📚1号:书籍大礼包',
 '📼资料备份']
```

**使用** <kbd>rmtree</kbd> **方法可以删除文件或文件夹,并且在删除文件夹时,也删除其中的文件和文件夹,参考** <kbd>shutil.rmtree</kbd>

```python
>>> fs.makedirs("a/b/c/d")
'/115/a/b/c/d'
>>> fs.removedirs("a")
Traceback (most recent call last):
    ...
OSError: [Errno 66] directory not empty: '/115/a'
>>> fs.rmtree("a")
```

**使用** <kbd>rename</kbd> **方法可以对文件或文件夹进行改名或移动,参考** <kbd>os.rename</kbd>

```python
>>> fs.touch("a")
'/115/a'
>>> _ = fs.listdir(refresh=True)
>>> fs.attr("a")
{'name': 'a',
 'size': 0,
 'is_dir': False,
 'modified': '2023-12-29T16:02:00+08:00',
 'created': '2023-12-29T16:02:41+08:00',
 'sign': '',
 'thumb': '',
 'type': 0,
 'hashinfo': '{"sha1":"DA39A3EE5E6B4B0D3255BFEF95601890AFD80709"}',
 'hash_info': {'sha1': 'DA39A3EE5E6B4B0D3255BFEF95601890AFD80709'},
 'raw_url': 'http://localhost:5244/p/115/a',
 'readme': '',
 'header': '',
 'provider': '115 Cloud',
 'related': None,
 'path': '/115/a',
 'lastest_update': datetime.datetime(2023, 12, 29, 16, 3, 31, 166894)}
>>> fs.rename('a', 'b')
'/115/b'
>>> fs.attr("b")
{'name': 'b',
 'size': 0,
 'is_dir': False,
 'modified': '2023-12-29T16:03:00+08:00',
 'created': '2023-12-29T16:02:41+08:00',
 'sign': '',
 'thumb': '',
 'type': 0,
 'hashinfo': '{"sha1":"DA39A3EE5E6B4B0D3255BFEF95601890AFD80709"}',
 'hash_info': {'sha1': 'DA39A3EE5E6B4B0D3255BFEF95601890AFD80709'},
 'raw_url': 'http://localhost:5244/p/115/b',
 'readme': '',
 'header': '',
 'provider': '115 Cloud',
 'related': None,
 'path': '/115/b',
 'lastest_update': datetime.datetime(2023, 12, 29, 16, 3, 47, 200980)}
```

**使用** <kbd>renames</kbd> **方法可以对文件或文件夹进行改名或移动,并且在移动后如果原来所在目录为空,则会删除那个目录,参考** <kbd>os.renames</kbd>

**使用** <kbd>replace</kbd> **方法可以对文件或文件夹进行改名或移动,并且如果原始路径上是文件,目标路径上也存在一个文件,则会先把目标路径上的文件删除,参考** <kbd>os.replace</kbd>

**使用** <kbd>move</kbd> **方法可以对文件或文件夹进行改名或移动,目标路径存在且是一个目录,则把文件移动到其中(但是目录中有同名的文件或文件夹,还是会报错),参考** <kbd>shutil.move</kbd>

### 3. 遍历文件系统和查找文件

#### 1. 获取当前目录下所有 .mkv 文件的 url

**第 1 种方法,使用** <kbd>iter</kbd>,返回 <kbd>alist.AlistPath</kbd> 对象的迭代器

```python
for path in fs.iter(max_depth=-1):
    if path.name.endswith(".mkv"):
        print(path.url)
```

**第 2 种方法,使用** <kbd>glob</kbd>,参考 <kbd>pathlib.Path.glob</kbd> 和 <kbd>glob.iglob</kbd>,使用通配符查找

```python
for path in fs.glob("**/*.mkv"):
    print(path.url)
```

**第 3 种方法,使用** <kbd>rglob</kbd>,参考 <kbd>pathlib.Path.rglob</kbd>

```python
for path in fs.rglob("*.mkv"):
    print(path.url)
```

### 4. 任务列表

<kbd>AList</kbd> 目前支持 `4` 种类型的任务,我分别进行了封装,大部分方法都支持异步调用 (`async_=True`)

- <kbd>alist.AlistCopyTaskList</kbd> 封装了 `复制` 的任务列表。
- <kbd>alist.AlistOfflineDownloadTaskList</kbd> 封装了 `离线下载(到本地)` 的任务列表。
- <kbd>alist.AlistOfflineDownloadTransferTaskList</kbd> 封装了 `离线下载(到存储)` 的任务列表。
- <kbd>alist.AlistUploadTaskList</kbd> 封装了 `上传` 的任务列表。
- <kbd>alist.AlistAria2DownTaskList</kbd> 封装了 `aria2下载` 的任务列表。
- <kbd>alist.AlistAria2TransferTaskList</kbd> 封装了 `aria2转存` 的任务列表。
- <kbd>alist.AlistQbitDownTaskList</kbd> 封装了 `qbit下载` 的任务列表。
- <kbd>alist.AlistQbitTransferTaskList</kbd> 封装了 `qbit转存` 的任务列表。

```python
from alist import AlistClient

client = AlistClient("http://localhost:5244", "admin", "123456")

# 获取各种任务列表
copy_tasklist = client.copy_tasklist
offline_download_tasklist = client.offline_download_tasklist
offline_download_transfer_tasklist = client.offline_download_transfer_tasklist
upload_tasklist = client.upload_tasklist
aria2_down_tasklist = client.aria2_down_tasklist
aria2_transfer_tasklist = client.aria2_transfer_tasklist
qbit_down_tasklist = client.qbit_down_tasklist
qbit_transfer_tasklist = client.qbit_transfer_tasklist

# 或者自己创建实例

# 创建 复制 任务列表实例
from alist import AlistCopyTaskList
copy_tasklist = AlistCopyTaskList(client)

# 创建 离线下载(到本地) 任务列表实例
from alist import AlistOfflineDownloadTaskList
offline_download_tasklist = AlistOfflineDownloadTaskList(client)

# 创建 离线下载(到存储) 任务列表实例
from alist import AlistOfflineDownloadTransferTaskList
offline_download_transfer_tasklist = AlistOfflineDownloadTransferTaskList(client)

# 创建 上传 任务列表实例
from alist import AlistUploadTaskList
upload_tasklist = AlistUploadTaskList(client)

# 创建 上传 任务列表实例
from alist import AlistAria2DownTaskList
aria2_down_tasklist = AlistAria2DownTaskList(client)

# 创建 上传 任务列表实例
from alist import AlistAria2TransferTaskList
aria2_transfer_tasklist = AlistAria2TransferTaskList(client)

# 创建 上传 任务列表实例
from alist import AlistQbitDownTaskList
qbit_down_tasklist = AlistQbitDownTaskList(client)

# 创建 上传 任务列表实例
from alist import AlistQbitTransferTaskList
qbit_transfer_tasklist = AlistQbitTransferTaskList(client)
```

## 文档

> 正在编写中

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/ChenyangGao/web-mount-packs/tree/main/python-alist-client",
    "name": "python-alist",
    "maintainer": null,
    "docs_url": null,
    "requires_python": "<4.0,>=3.11",
    "maintainer_email": null,
    "keywords": "alist, client",
    "author": "ChenyangGao",
    "author_email": "wosiwujm@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/ae/1d/d19392a8dcd2940b4d4eb73606418cf582488196553810e58925f20343b1/python_alist-0.0.13.6.tar.gz",
    "platform": null,
    "description": "# Alist web API \u7684 Python \u5c01\u88c5\n\n![PyPI - Python Version](https://img.shields.io/pypi/pyversions/python-alist)\n![PyPI - Version](https://img.shields.io/pypi/v/python-alist)\n![PyPI - Downloads](https://img.shields.io/pypi/dm/python-alist)\n![PyPI - Format](https://img.shields.io/pypi/format/python-alist)\n![PyPI - Status](https://img.shields.io/pypi/status/python-alist)\n\n- [AList web API \u5b98\u65b9\u6587\u6863](https://alist.nn.ci/guide/api/)\n- [AList web API \u5728\u7ebf\u5de5\u5177](https://alist-v3.apifox.cn)\n\n## \u5b89\u88c5\n\n\u901a\u8fc7 [pypi](https://pypi.org/project/python-alist/)\n\n```console\npip install -U python-alist\n```\n\n## \u5165\u95e8\u4ecb\u7ecd\n\n### 1. \u5bfc\u5165\u6a21\u5757\u548c\u521b\u5efa\u5b9e\u4f8b\n\n**\u5bfc\u5165\u6a21\u5757**\n\n```python\nfrom alist import AlistClient, AlistFileSystem\n```\n\n**\u521b\u5efa\u5ba2\u6237\u7aef\u5bf9\u8c61\uff0c\u767b\u5f55 <kbd>AList</kbd>\uff1a\u6b64\u5904\uff0c\u540e\u53f0\u670d\u52a1\u5730\u5740: `\"http://localhost:5244\"`\uff0c\u7528\u6237\u540d: `\"admin\"`\uff0c\u5bc6\u7801: `\"123456\"`**\n\n> \u8bf7\u786e\u4fdd <kbd>AList</kbd> \u5df2\u7ecf\u542f\u52a8\uff0c\u5e76\u4e14\u53ef\u901a\u8fc7 <kbd>http://localhost:5244</kbd> \u8bbf\u95ee\n\n```python\nclient = AlistClient(\"http://localhost:5244\", \"admin\", \"123456\")\n```\n\n\u7edd\u5927\u90e8\u5206 <kbd>AlistClient</kbd> \u7684\u65b9\u6cd5\u5e26\u6709 `async_` \u53c2\u6570\uff0c\u610f\u5473\u7740\u5b83\u652f\u6301\u5f02\u6b65 IO\u3002\n\n```python\n>>> import asyncio\n>>> loop = asyncio.get_event_loop()\n\n>>> from alist import AlistClient, AlistFileSystem\n>>> client = AlistClient(\"http://localhost:5244\", \"admin\", \"123456\")\n\n>>> client.fs_get(dict(path=\"/\"))\n{'code': 200,\n 'message': 'success',\n 'data': {'name': '115',\n  'size': 0,\n  'is_dir': True,\n  'modified': '2023-12-26T12:23:59.259218+08:00',\n  'created': '2023-12-26T12:23:59.259218+08:00',\n  'sign': '',\n  'thumb': '',\n  'type': 0,\n  'hashinfo': 'null',\n  'hash_info': None,\n  'raw_url': '',\n  'readme': '',\n  'header': '',\n  'provider': '115 Cloud',\n  'related': None}}\n\n>>> client.fs_get(dict(path=\"/\"), async_=True)\n<coroutine object AlistClient._async_request.<locals>.request at 0x1055f0d60>\n>>> loop.run_until_complete(client.fs_get(dict(path=\"/\"), async_=True))\n{'code': 200,\n 'message': 'success',\n 'data': {'name': 'root',\n  'size': 0,\n  'is_dir': True,\n  'modified': '0001-01-01T00:00:00Z',\n  'created': '0001-01-01T00:00:00Z',\n  'sign': '',\n  'thumb': '',\n  'type': 0,\n  'hashinfo': 'null',\n  'hash_info': None,\n  'raw_url': '',\n  'readme': '',\n  'header': '',\n  'provider': 'unknown',\n  'related': None}}\n```\n\n**\u521b\u5efa\u6587\u4ef6\u7cfb\u7edf\u5bf9\u8c61**\n\n```python\nfs = AlistFileSystem(client)\n```\n\n\u6216\u8005\u76f4\u63a5\u5728 <kbd>client</kbd> \u4e0a\u5c31\u53ef\u83b7\u53d6\u6587\u4ef6\u7cfb\u7edf\u5bf9\u8c61\n\n```python\nfs = client.fs\n```\n\n\u6216\u8005\u76f4\u63a5\u7528 <kbd>AlistFileSystem</kbd> \u767b\u5f55\n\n```python\nfs = AlistFileSystem.login(\"http://localhost:5244\", \"admin\", \"123456\")\n```\n\n### 2. \u64cd\u4f5c\u7f51\u76d8\u4f7f\u7528 Python \u5f0f\u7684\u6587\u4ef6\u7cfb\u7edf\u65b9\u6cd5\n\n\u6587\u4ef6\u7cfb\u7edf\u5bf9\u8c61\u7684\u65b9\u6cd5\uff0c\u8bbe\u8ba1\u548c\u884c\u4e3a\u53c2\u8003\u4e86 <kbd>[os](https://docs.python.org/3/library/os.html)</kbd>\u3001<kbd>[posixpath](https://docs.python.org/3/library/os.path.html)</kbd>\u3001<kbd>[pathlib.Path](https://docs.python.org/3/library/pathlib.html)</kbd> \u548c <kbd>[shutil](https://docs.python.org/3/library/shutil.html)</kbd> \u7b49\u6a21\u5757\u3002\n\n<kbd>alist.AlistFileSystem</kbd> \u5b9e\u73b0\u4e86\u8bfb\u5199\u7684\u6587\u4ef6\u7cfb\u7edf\u65b9\u6cd5\u3002\n\n<kbd>alist.AlistPath</kbd> \u5b9e\u73b0\u4e86\u4e8c\u6b21\u5c01\u88c5\uff0c\u4ece\u8def\u5f84\u7684\u89d2\u5ea6\u6765\u8fdb\u884c\u64cd\u4f5c\u3002\n\n**\u4f7f\u7528** <kbd>getcwd</kbd> **\u65b9\u6cd5\uff0c\u83b7\u53d6\u5f53\u524d\u5de5\u4f5c\u76ee\u5f55\u7684\u8def\u5f84\uff0c\u53c2\u8003** <kbd>os.getcwd</kbd>\n\n```python\n>>> fs.getcwd()\n'/'\n```\n\n**\u4f7f\u7528** <kbd>listdir</kbd> **\u65b9\u6cd5\uff0c\u7f57\u5217\u5f53\u524d\u76ee\u5f55\u7684\u6587\u4ef6\u540d\uff0c\u53c2\u8003** <kbd>os.listdir</kbd>\n\n```python\n>>> fs.listdir()\n['115', '\u963f\u91cc\u4e91\u76d8']\n```\n\n**\u4f7f\u7528** <kbd>chdir</kbd> **\u65b9\u6cd5\uff0c\u5207\u6362\u5f53\u524d\u5de5\u4f5c\u76ee\u5f55\uff0c\u53c2\u8003** <kbd>os.chdir</kbd>\n\n```python\n>>> fs.chdir(\"/115\")\n```\n\n**\u4f7f\u7528** <kbd>listdir_attr</kbd> **\u65b9\u6cd5\uff0c\u7f57\u5217\u5f53\u524d\u76ee\u5f55\u65f6\uff0c\u8fd8\u53ef\u4ee5\u83b7\u53d6\u5c5e\u6027**\n\n```python\n>>> fs.listdir_attr()\n[{'name': '\u4e91\u4e0b\u8f7d',\n  'size': 0,\n  'is_dir': True,\n  'modified': '2023-12-16T21:58:22+08:00',\n  'created': '2023-03-18T18:52:54+08:00',\n  'sign': '',\n  'thumb': '',\n  'type': 1,\n  'hashinfo': '{\"sha1\":\"\"}',\n  'hash_info': {'sha1': ''},\n  'path': '/115/\u4e91\u4e0b\u8f7d',\n  'lastest_update': datetime.datetime(2023, 12, 29, 15, 50, 50, 828853)},\n {'name': '000\u9605\u8bfb\u00b7\u4e71\u4e03\u516b\u7cdf',\n  'size': 0,\n  'is_dir': True,\n  'modified': '2023-12-14T14:54:20+08:00',\n  'created': '2023-03-18T14:45:45+08:00',\n  'sign': '',\n  'thumb': '',\n  'type': 1,\n  'hashinfo': '{\"sha1\":\"\"}',\n  'hash_info': {'sha1': ''},\n  'path': '/115/000\u9605\u8bfb\u00b7\u4e71\u4e03\u516b\u7cdf',\n  'lastest_update': datetime.datetime(2023, 12, 29, 15, 50, 50, 828853)},\n {'name': '\u7535\u89c6\u5267',\n  'size': 0,\n  'is_dir': True,\n  'modified': '2023-12-23T22:26:17+08:00',\n  'created': '2023-04-16T18:30:33+08:00',\n  'sign': '',\n  'thumb': '',\n  'type': 1,\n  'hashinfo': '{\"sha1\":\"\"}',\n  'hash_info': {'sha1': ''},\n  'path': '/115/\u7535\u89c6\u5267',\n  'lastest_update': datetime.datetime(2023, 12, 29, 15, 50, 50, 828853)},\n {'name': '\u7535\u5f71',\n  'size': 0,\n  'is_dir': True,\n  'modified': '2023-12-14T14:54:20+08:00',\n  'created': '2023-03-01T12:46:07+08:00',\n  'sign': '',\n  'thumb': '',\n  'type': 1,\n  'hashinfo': '{\"sha1\":\"\"}',\n  'hash_info': {'sha1': ''},\n  'path': '/115/\u7535\u5f71',\n  'lastest_update': datetime.datetime(2023, 12, 29, 15, 50, 50, 828853)},\n {'name': '\u7eaa\u5f55\u7247',\n  'size': 0,\n  'is_dir': True,\n  'modified': '2023-12-18T18:49:29+08:00',\n  'created': '2023-02-24T11:40:45+08:00',\n  'sign': '',\n  'thumb': '',\n  'type': 1,\n  'hashinfo': '{\"sha1\":\"\"}',\n  'hash_info': {'sha1': ''},\n  'path': '/115/\u7eaa\u5f55\u7247',\n  'lastest_update': datetime.datetime(2023, 12, 29, 15, 50, 50, 828853)},\n {'name': 'libgen',\n  'size': 0,\n  'is_dir': True,\n  'modified': '2023-12-14T14:54:20+08:00',\n  'created': '2023-05-28T22:05:06+08:00',\n  'sign': '',\n  'thumb': '',\n  'type': 1,\n  'hashinfo': '{\"sha1\":\"\"}',\n  'hash_info': {'sha1': ''},\n  'path': '/115/libgen',\n  'lastest_update': datetime.datetime(2023, 12, 29, 15, 50, 50, 828853)},\n {'name': '\ud83d\udc7e0\u53f7\uff1a\u91cd\u8981\u8d44\u6e90',\n  'size': 0,\n  'is_dir': True,\n  'modified': '2023-12-14T14:54:20+08:00',\n  'created': '2023-02-28T21:40:32+08:00',\n  'sign': '',\n  'thumb': '',\n  'type': 1,\n  'hashinfo': '{\"sha1\":\"\"}',\n  'hash_info': {'sha1': ''},\n  'path': '/115/\ud83d\udc7e0\u53f7\uff1a\u91cd\u8981\u8d44\u6e90',\n  'lastest_update': datetime.datetime(2023, 12, 29, 15, 50, 50, 828853)},\n {'name': '\ud83d\udcda1\u53f7\uff1a\u4e66\u7c4d\u5927\u793c\u5305',\n  'size': 0,\n  'is_dir': True,\n  'modified': '2023-12-14T14:54:20+08:00',\n  'created': '2023-03-01T01:29:12+08:00',\n  'sign': '',\n  'thumb': '',\n  'type': 1,\n  'hashinfo': '{\"sha1\":\"\"}',\n  'hash_info': {'sha1': ''},\n  'path': '/115/\ud83d\udcda1\u53f7\uff1a\u4e66\u7c4d\u5927\u793c\u5305',\n  'lastest_update': datetime.datetime(2023, 12, 29, 15, 50, 50, 828853)},\n {'name': '\ud83d\udcfc\u8d44\u6599\u5907\u4efd',\n  'size': 0,\n  'is_dir': True,\n  'modified': '2023-12-14T14:54:20+08:00',\n  'created': '2023-07-07T15:13:12+08:00',\n  'sign': '',\n  'thumb': '',\n  'type': 1,\n  'hashinfo': '{\"sha1\":\"\"}',\n  'hash_info': {'sha1': ''},\n  'path': '/115/\ud83d\udcfc\u8d44\u6599\u5907\u4efd',\n  'lastest_update': datetime.datetime(2023, 12, 29, 15, 50, 50, 828853)}]\n```\n\n**\u4f7f\u7528** <kbd>listdir_path</kbd> **\u65b9\u6cd5\uff0c\u7f57\u5217\u5f53\u524d\u76ee\u5f55\u65f6\uff0c\u8fd8\u53ef\u4ee5\u83b7\u53d6** <kbd>alist.AlistPath</kbd> **\u5bf9\u8c61**\n\n```python\n>>> fs.listdir_path()\n[<alist.AlistPath(name='\u4e91\u4e0b\u8f7d', size=0, is_dir=True, modified='2023-12-16T21:58:22+08:00', created='2023-03-18T18:52:54+08:00', sign='', thumb='', type=1, hashinfo='{\"sha1\":\"\"}', hash_info={'sha1': ''}, lastest_update=datetime.datetime(2023, 12, 29, 15, 51, 11, 817697), fs=alist.AlistFileSystem(client=alist.AlistClient(origin='http://localhost:5244', username='admin', password='******'), path='/115', refresh=False, request_kwargs={}), path='/115/\u4e91\u4e0b\u8f7d', password='')>,\n <alist.AlistPath(name='000\u9605\u8bfb\u00b7\u4e71\u4e03\u516b\u7cdf', size=0, is_dir=True, modified='2023-12-14T14:54:20+08:00', created='2023-03-18T14:45:45+08:00', sign='', thumb='', type=1, hashinfo='{\"sha1\":\"\"}', hash_info={'sha1': ''}, lastest_update=datetime.datetime(2023, 12, 29, 15, 51, 11, 817697), fs=alist.AlistFileSystem(client=alist.AlistClient(origin='http://localhost:5244', username='admin', password='******'), path='/115', refresh=False, request_kwargs={}), path='/115/000\u9605\u8bfb\u00b7\u4e71\u4e03\u516b\u7cdf', password='')>,\n <alist.AlistPath(name='\u7535\u89c6\u5267', size=0, is_dir=True, modified='2023-12-23T22:26:17+08:00', created='2023-04-16T18:30:33+08:00', sign='', thumb='', type=1, hashinfo='{\"sha1\":\"\"}', hash_info={'sha1': ''}, lastest_update=datetime.datetime(2023, 12, 29, 15, 51, 11, 817697), fs=alist.AlistFileSystem(client=alist.AlistClient(origin='http://localhost:5244', username='admin', password='******'), path='/115', refresh=False, request_kwargs={}), path='/115/\u7535\u89c6\u5267', password='')>,\n <alist.AlistPath(name='\u7535\u5f71', size=0, is_dir=True, modified='2023-12-14T14:54:20+08:00', created='2023-03-01T12:46:07+08:00', sign='', thumb='', type=1, hashinfo='{\"sha1\":\"\"}', hash_info={'sha1': ''}, lastest_update=datetime.datetime(2023, 12, 29, 15, 51, 11, 817697), fs=alist.AlistFileSystem(client=alist.AlistClient(origin='http://localhost:5244', username='admin', password='******'), path='/115', refresh=False, request_kwargs={}), path='/115/\u7535\u5f71', password='')>,\n <alist.AlistPath(name='\u7eaa\u5f55\u7247', size=0, is_dir=True, modified='2023-12-18T18:49:29+08:00', created='2023-02-24T11:40:45+08:00', sign='', thumb='', type=1, hashinfo='{\"sha1\":\"\"}', hash_info={'sha1': ''}, lastest_update=datetime.datetime(2023, 12, 29, 15, 51, 11, 817697), fs=alist.AlistFileSystem(client=alist.AlistClient(origin='http://localhost:5244', username='admin', password='******'), path='/115', refresh=False, request_kwargs={}), path='/115/\u7eaa\u5f55\u7247', password='')>,\n <alist.AlistPath(name='libgen', size=0, is_dir=True, modified='2023-12-14T14:54:20+08:00', created='2023-05-28T22:05:06+08:00', sign='', thumb='', type=1, hashinfo='{\"sha1\":\"\"}', hash_info={'sha1': ''}, lastest_update=datetime.datetime(2023, 12, 29, 15, 51, 11, 817697), fs=alist.AlistFileSystem(client=alist.AlistClient(origin='http://localhost:5244', username='admin', password='******'), path='/115', refresh=False, request_kwargs={}), path='/115/libgen', password='')>,\n <alist.AlistPath(name='\ud83d\udc7e0\u53f7\uff1a\u91cd\u8981\u8d44\u6e90', size=0, is_dir=True, modified='2023-12-14T14:54:20+08:00', created='2023-02-28T21:40:32+08:00', sign='', thumb='', type=1, hashinfo='{\"sha1\":\"\"}', hash_info={'sha1': ''}, lastest_update=datetime.datetime(2023, 12, 29, 15, 51, 11, 817697), fs=alist.AlistFileSystem(client=alist.AlistClient(origin='http://localhost:5244', username='admin', password='******'), path='/115', refresh=False, request_kwargs={}), path='/115/\ud83d\udc7e0\u53f7\uff1a\u91cd\u8981\u8d44\u6e90', password='')>,\n <alist.AlistPath(name='\ud83d\udcda1\u53f7\uff1a\u4e66\u7c4d\u5927\u793c\u5305', size=0, is_dir=True, modified='2023-12-14T14:54:20+08:00', created='2023-03-01T01:29:12+08:00', sign='', thumb='', type=1, hashinfo='{\"sha1\":\"\"}', hash_info={'sha1': ''}, lastest_update=datetime.datetime(2023, 12, 29, 15, 51, 11, 817697), fs=alist.AlistFileSystem(client=alist.AlistClient(origin='http://localhost:5244', username='admin', password='******'), path='/115', refresh=False, request_kwargs={}), path='/115/\ud83d\udcda1\u53f7\uff1a\u4e66\u7c4d\u5927\u793c\u5305', password='')>,\n <alist.AlistPath(name='\ud83d\udcfc\u8d44\u6599\u5907\u4efd', size=0, is_dir=True, modified='2023-12-14T14:54:20+08:00', created='2023-07-07T15:13:12+08:00', sign='', thumb='', type=1, hashinfo='{\"sha1\":\"\"}', hash_info={'sha1': ''}, lastest_update=datetime.datetime(2023, 12, 29, 15, 51, 11, 817697), fs=alist.AlistFileSystem(client=alist.AlistClient(origin='http://localhost:5244', username='admin', password='******'), path='/115', refresh=False, request_kwargs={}), path='/115/\ud83d\udcfc\u8d44\u6599\u5907\u4efd', password='')>]\n```\n\n**\u518d\u6b21\u4f7f\u7528** <kbd>chdir</kbd> **\uff0c\u8fdb\u5165\u4e00\u4e9b\u76ee\u5f55**\n\n```python\n>>> fs.chdir(\"\u7535\u89c6\u5267/\u6b27\u7f8e\u5267/A\")\n>>> fs.getcwd()\n'/115/\u7535\u89c6\u5267/\u6b27\u7f8e\u5267/A'\n>>> fs.listdir()\n['A\u300a\u7231\u3001\u6b7b\u4ea1\u548c\u673a\u5668\u4eba\u300b(Love.Death.and.Robot)[tt9561862]']\n>>> fs.chdir(\"A\u300a\u7231\u3001\u6b7b\u4ea1\u548c\u673a\u5668\u4eba\u300b(Love.Death.and.Robot)[tt9561862]/\u7231\u3001\u6b7b\u4ea1\u548c\u673a\u5668\u4ebaS01.Love.Death.and.Robots.1080p.NF.WEB-DL.DDP5.1.x264-NTG\uff0818\u96c6\uff09\")\n>>> fs.listdir()\n['Love.Death.and.Robots.S01E01.Sonnies.Edge.1080p.NF.WEB-DL.DDP5.1.x264-NTG.\u7b80\u4f53&\u82f1\u6587.ass', 'Love.Death.and.Robots.S01E01.Sonnies.Edge.1080p.NF.WEB-DL.DDP5.1.x264-NTG.mkv']\n```\n\n**\u4f7f\u7528** <kbd>attr</kbd> **\u65b9\u6cd5\uff0c\u83b7\u53d6\u6587\u4ef6\u6216\u6587\u4ef6\u5939\u7684\u5c5e\u6027** \n\n```python\n>>> fs.attr(\"Love.Death.and.Robots.S01E01.Sonnies.Edge.1080p.NF.WEB-DL.DDP5.1.x264-NTG.mkv\")\n{'name': 'Love.Death.and.Robots.S01E01.Sonnies.Edge.1080p.NF.WEB-DL.DDP5.1.x264-NTG.mkv',\n 'size': 924544482,\n 'is_dir': False,\n 'modified': '2023-02-24T11:42:00+08:00',\n 'created': '2023-02-24T11:42:51+08:00',\n 'sign': '',\n 'thumb': '',\n 'type': 2,\n 'hashinfo': '{\"sha1\":\"7F4121B68A4E467ABF30A84627E20A8978895A4E\"}',\n 'hash_info': {'sha1': '7F4121B68A4E467ABF30A84627E20A8978895A4E'},\n 'raw_url': 'http://localhost:5244/p/115/%E7%94%B5%E8%A7%86%E5%89%A7/%E6%AC%A7%E7%BE%8E%E5%89%A7/A/A%E3%80%8A%E7%88%B1%E3%80%81%E6%AD%BB%E4%BA%A1%E5%92%8C%E6%9C%BA%E5%99%A8%E4%BA%BA%E3%80%8B%28Love.Death.and.Robot%29%5Btt9561862%5D/%E7%88%B1%E3%80%81%E6%AD%BB%E4%BA%A1%E5%92%8C%E6%9C%BA%E5%99%A8%E4%BA%BAS01.Love.Death.and.Robots.1080p.NF.WEB-DL.DDP5.1.x264-NTG%EF%BC%8818%E9%9B%86%EF%BC%89/Love.Death.and.Robots.S01E01.Sonnies.Edge.1080p.NF.WEB-DL.DDP5.1.x264-NTG.mkv',\n 'readme': '',\n 'header': '',\n 'provider': '115 Cloud',\n 'related': [{'name': 'Love.Death.and.Robots.S01E01.Sonnies.Edge.1080p.NF.WEB-DL.DDP5.1.x264-NTG.\u7b80\u4f53&\u82f1\u6587.ass',\n   'size': 48910,\n   'is_dir': False,\n   'modified': '2023-03-23T22:09:00+08:00',\n   'created': '2023-03-23T22:09:09+08:00',\n   'sign': '',\n   'thumb': '',\n   'type': 4,\n   'hashinfo': '{\"sha1\":\"30AB3A1A376DE83049B35F135A774980F5C7C558\"}',\n   'hash_info': {'sha1': '30AB3A1A376DE83049B35F135A774980F5C7C558'}}],\n 'path': '/115/\u7535\u89c6\u5267/\u6b27\u7f8e\u5267/A/A\u300a\u7231\u3001\u6b7b\u4ea1\u548c\u673a\u5668\u4eba\u300b(Love.Death.and.Robot)[tt9561862]/\u7231\u3001\u6b7b\u4ea1\u548c\u673a\u5668\u4ebaS01.Love.Death.and.Robots.1080p.NF.WEB-DL.DDP5.1.x264-NTG\uff0818\u96c6\uff09/Love.Death.and.Robots.S01E01.Sonnies.Edge.1080p.NF.WEB-DL.DDP5.1.x264-NTG.mkv',\n 'lastest_update': datetime.datetime(2023, 12, 29, 15, 51, 47, 591418)}\n```\n\n**\u4f7f\u7528** <kbd>stat</kbd> **\u65b9\u6cd5\uff0c\u83b7\u53d6\u6587\u4ef6\u6216\u6587\u4ef6\u5939\u7684\u90e8\u5206\uff0c\u53c2\u8003** <kbd>os.stat</kbd>\n\n```python\n>>> fs.stat(\"Love.Death.and.Robots.S01E01.Sonnies.Edge.1080p.NF.WEB-DL.DDP5.1.x264-NTG.mkv\")\nos.stat_result(st_mode=33279, st_ino=0, st_dev=0, st_nlink=1, st_uid=0, st_gid=0, st_size=924544482, st_atime=1703836333.124217, st_mtime=1677210120.0, st_ctime=1677210171.0)\n```\n\n**\u4f7f\u7528** <kbd>open</kbd> **\u65b9\u6cd5\uff0c\u6253\u5f00\u4e00\u4e2a\u6587\u4ef6\uff08\u76ee\u524d\u53ea\u652f\u6301\u8bfb\u53d6\uff0c\u4e0d\u652f\u6301\u5199\u5165\uff09\uff0c\u53c2\u8003** <kbd>open</kbd>\n\n```python\n>>> f = fs.open(\"Love.Death.and.Robots.S01E01.Sonnies.Edge.1080p.NF.WEB-DL.DDP5.1.x264-NTG.\u7b80\u4f53&\u82f1\u6587.ass\", encoding=\"UTF-16\")\n>>> f\n<_io.TextIOWrapper name='Love.Death.and.Robots.S01E01.Sonnies.Edge.1080p.NF.WEB-DL.DDP5.1.x264-NTG.\u7b80\u4f53&\u82f1\u6587.ass' encoding='UTF-16'>\n```\n\n\u8bfb\u53d6\u6b64\u6587\u4ef6\u7684\u524d 100 \u4e2a\u5b57\u7b26\n\n```python\n>>> f.read(100)\n'[Script Info]\\n;SrtEdit 6.3.2012.1001\\n;Copyright(C) 2005-2012 Yuan Weiguo\\n\\nTitle: YYeTs\\nOriginal Scri'\n```\n\n\u7528\u5b8c\u540e\u8bf7\u53ca\u65f6\u5173\u95ed\u6587\u4ef6\uff08\u5176\u5b9e\u4e0d\u4e3b\u52a8\u5173\u95ed\u4e5f\u53ef\u4ee5\uff0c\u53ea\u8981\u6587\u4ef6\u4e0d\u88ab\u5f15\u7528\uff0c\u5c31\u4f1a\u81ea\u52a8\u5173\u95ed\uff09\n\n```python\n>>> f.close()\n```\n\n**\u4ee5\u4e8c\u8fdb\u5236\u6a21\u5f0f\u6253\u5f00\u4e00\u4e2a\u6587\u4ef6\uff0c\u6b64\u65f6** `mode=\"rb\"`\n\n```python\n>>> f = fs.open(\"Love.Death.and.Robots.S01E01.Sonnies.Edge.1080p.NF.WEB-DL.DDP5.1.x264-NTG.mkv\", \"rb\")\n>>> f\nalist.util.file.HTTPFileReader('http://localhost:5244/d/115/%E7%94%B5%E8%A7%86%E5%89%A7/%E6%AC%A7%E7%BE%8E%E5%89%A7/A/A%E3%80%8A%E7%88%B1%E3%80%81%E6%AD%BB%E4%BA%A1%E5%92%8C%E6%9C%BA%E5%99%A8%E4%BA%BA%E3%80%8B%28Love.Death.and.Robot%29%5Btt9561862%5D/%E7%88%B1%E3%80%81%E6%AD%BB%E4%BA%A1%E5%92%8C%E6%9C%BA%E5%99%A8%E4%BA%BAS01.Love.Death.and.Robots.1080p.NF.WEB-DL.DDP5.1.x264-NTG%EF%BC%8818%E9%9B%86%EF%BC%89/Love.Death.and.Robots.S01E01.Sonnies.Edge.1080p.NF.WEB-DL.DDP5.1.x264-NTG.mkv', urlopen=<function urlopen at 0x105ffb560>, headers=mappingproxy({'Accept-Encoding': 'identity'}))\n```\n\n\u8bfb\u53d6\u524d 10 \u4e2a\u5b57\u8282\n\n```python\n>>> f.read(10)\nb'\\x1aE\\xdf\\xa3\\xa3B\\x86\\x81\\x01B'\n```\n\n\u518d\u8bfb\u53d6 10 \u4e2a\u5b57\u8282\n\n```python\n>>> f.read(10)\nb'\\xf7\\x81\\x01B\\xf2\\x81\\x04B\\xf3\\x81'\n```\n\n\u5f53\u524d\u6587\u4ef6\u504f\u79fb\u4f4d\u7f6e\uff08\u4ece 0 \u5f00\u59cb\u8ba1\u7b97\uff09\n\n```python\n>>> f.tell()\n20\n```\n\n\u628a\u8bfb\u53d6\u4f4d\u7f6e\u91cd\u65b0\u53d8\u4e3a\u6587\u4ef6\u5f00\u5934\n\n```python\n>>> f.seek(0)\n0\n>>> f.tell()\n0\n```\n\n\u518d\u6b21\u8bfb\u53d6 20 \u5b57\u8282\uff0c\u5e94\u8be5\u7b49\u4e8e\u4e0a\u9762\u4e24\u6b21\u7ed3\u679c\u7684\u62fc\u63a5\n\n```python\n>>> f.read(20)\nb'\\x1aE\\xdf\\xa3\\xa3B\\x86\\x81\\x01B\\xf7\\x81\\x01B\\xf2\\x81\\x04B\\xf3\\x81'\n>>> f.tell()\n20\n```\n\n**\u56de\u5230\u6839\u76ee\u5f55\uff0c\u6211\u4eec\u7ee7\u7eed\u5176\u5b83\u8bd5\u9a8c**\n\n```python\n>>> fs.chdir(\"/\")\n```\n\n**\u4f7f\u7528** <kbd>walk</kbd> **\u65b9\u6cd5\uff0c\u53ef\u4ee5\u904d\u5386\u4e00\u4e2a\u76ee\u5f55\uff0c\u53c2\u8003** <kbd>os.walk</kbd>\n\n```python\n>>> next(fs.walk())\n('/', ['115', '\u963f\u91cc\u4e91\u76d8'], [])\n```\n\n**\u4f7f\u7528** <kbd>walk_path</kbd> **\u65b9\u6cd5\uff0c\u53ef\u4ee5\u904d\u5386\u4e00\u4e2a\u76ee\u5f55\u65f6\uff0c\u83b7\u53d6** <kbd>alist.AlistPath</kbd> \u5bf9\u8c61\n\n```python\n>>> next(fs.walk_path())\n('/',\n [<alist.AlistPath(name='115', size=0, is_dir=True, modified='2023-12-26T12:23:59.259218+08:00', created='2023-12-26T12:23:59.259218+08:00', sign='', thumb='', type=1, hashinfo='null', hash_info=None, lastest_update=datetime.datetime(2023, 12, 29, 15, 53, 33, 430767), fs=alist.AlistFileSystem(client=alist.AlistClient(origin='http://localhost:5244', username='admin', password='******'), path='/', refresh=False, request_kwargs={}), path='/115', password='')>,\n  <alist.AlistPath(name='\u963f\u91cc\u4e91\u76d8', size=0, is_dir=True, modified='2023-10-01T16:26:52.862197+08:00', created='2023-10-01T16:26:52.862197+08:00', sign='', thumb='', type=1, hashinfo='null', hash_info=None, lastest_update=datetime.datetime(2023, 12, 29, 15, 53, 33, 430767), fs=alist.AlistFileSystem(client=alist.AlistClient(origin='http://localhost:5244', username='admin', password='******'), path='/', refresh=False, request_kwargs={}), path='/\u963f\u91cc\u4e91\u76d8', password='')>],\n [])\n```\n\n**\u5fc5\u9700\u5728\u6302\u8f7d\u7684 `storage` \u4e0b\u624d\u80fd\u521b\u5efa\u6587\u4ef6\uff0c\u56e0\u6b64\u8fdb\u5165 `/115` \u4e0b\uff0c\u7ee7\u7eed\u505a\u5b9e\u9a8c**\n\n```python\n>>> fs.chdir(\"/115\")\n```\n\n**\u4f7f\u7528** <kbd>mkdir</kbd> **\u65b9\u6cd5\uff0c\u53ef\u4ee5\u521b\u5efa\u7a7a\u6587\u4ef6\u5939\uff0c\u53c2\u8003** <kbd>os.mkdir</kbd>\n\n```python\n>>> fs.mkdir(\"test\")\n'/115/test'\n```\n\n**\u4f7f\u7528** <kbd>rmdir</kbd> **\u65b9\u6cd5\uff0c\u53ef\u4ee5\u5220\u9664\u7a7a\u6587\u4ef6\u5939\uff0c\u53c2\u8003** <kbd>os.rmdir</kbd>\n\n```python\n>>> fs.rmdir('test')\n>>> fs.listdir()\n['\u4e91\u4e0b\u8f7d',\n '000\u9605\u8bfb\u00b7\u4e71\u4e03\u516b\u7cdf',\n '\u7535\u89c6\u5267',\n '\u7535\u5f71',\n '\u7eaa\u5f55\u7247',\n 'libgen',\n '\ud83d\udc7e0\u53f7\uff1a\u91cd\u8981\u8d44\u6e90',\n '\ud83d\udcda1\u53f7\uff1a\u4e66\u7c4d\u5927\u793c\u5305',\n '\ud83d\udcfc\u8d44\u6599\u5907\u4efd']\n```\n\n**\u4f7f\u7528** <kbd>makedirs</kbd> **\u65b9\u6cd5\uff0c\u53ef\u4ee5\u521b\u5efa\u591a\u7ea7\u7684\u7a7a\u76ee\u5f55\uff0c\u53c2\u8003** <kbd>os.makedirs</kbd>\n\n```python\n>>> fs.makedirs(\"a/b/c/d\", exist_ok=True)\n'/115/a/b/c/d'\n>>> fs.listdir()\n['\u4e91\u4e0b\u8f7d',\n '000\u9605\u8bfb\u00b7\u4e71\u4e03\u516b\u7cdf',\n 'a',\n '\u7535\u89c6\u5267',\n '\u7535\u5f71',\n '\u7eaa\u5f55\u7247',\n 'libgen',\n '\ud83d\udc7e0\u53f7\uff1a\u91cd\u8981\u8d44\u6e90',\n '\ud83d\udcda1\u53f7\uff1a\u4e66\u7c4d\u5927\u793c\u5305',\n '\ud83d\udcfc\u8d44\u6599\u5907\u4efd']\n```\n\n**\u4f7f\u7528** <kbd>removedirs</kbd> **\u65b9\u6cd5\uff0c\u53ef\u4ee5\uff08\u81ea\u5e95\u5411\u4e0a\u5730\uff09\u5220\u9664\u591a\u7ea7\u7684\u7a7a\u76ee\u5f55\uff0c\u53c2\u8003** <kbd>os.removedirs</kbd>\n\n```python\n>>> fs.removedirs(\"a/b/c/d\")\n>>> fs.listdir()\n['\u4e91\u4e0b\u8f7d',\n '000\u9605\u8bfb\u00b7\u4e71\u4e03\u516b\u7cdf',\n '\u7535\u89c6\u5267',\n '\u7535\u5f71',\n '\u7eaa\u5f55\u7247',\n 'libgen',\n '\ud83d\udc7e0\u53f7\uff1a\u91cd\u8981\u8d44\u6e90',\n '\ud83d\udcda1\u53f7\uff1a\u4e66\u7c4d\u5927\u793c\u5305',\n '\ud83d\udcfc\u8d44\u6599\u5907\u4efd']\n```\n\n**\u4f7f\u7528** <kbd>upload</kbd> **\u65b9\u6cd5\u4e0a\u4f20\u6587\u4ef6\uff08\u63d0\u793a\uff1a\u5982\u679c `as_task=True`\uff08\u9ed8\u8ba4\u4e3a `False`\uff09\uff0c\u5219\u6587\u4ef6\u53ea\u662f\u4e0a\u4f20\u5230 <kbd>AList</kbd> \u670d\u52a1\u5668\u4e0a\uff0c\u81f3\u4e8e <kbd>AList</kbd> \u4ec0\u4e48\u65f6\u5019\u4e0a\u4f20\u5b8c\u6210\uff0c\u5f97\u7b49\u5f85\uff09**\n\n**\u8bf4\u660e** \u6682\u65f6\uff0c<kbd>AList</kbd> \u65b0\u589e\u6587\u4ef6\u540e\uff0c\u5e76\u4e0d\u66f4\u65b0\u7f13\u5b58\uff08\u4f46\u5220\u9664\u548c\u6539\u540d\u4f1a\u66f4\u65b0\uff09\uff0c\u9700\u8981\u5f3a\u5236\u5237\u65b0\u4e00\u4e0b\u3002\n\n```python\n>>> from io import BytesIO\n>>> fs.upload(BytesIO(b\"123\"), \"test.txt\")\n'/115/test.txt'\n>>> _ = fs.listdir(refresh=True)\n>>> fs.read_text(\"test.txt\")\n'123'\n>>> fs.upload(\"file.py\")\n'/115/file.py'\n>>> fs.listdir(refresh=True)\n['\u4e91\u4e0b\u8f7d',\n '000\u9605\u8bfb\u00b7\u4e71\u4e03\u516b\u7cdf',\n '\u7535\u89c6\u5267',\n '\u7535\u5f71',\n '\u7eaa\u5f55\u7247',\n 'libgen',\n '\ud83d\udc7e0\u53f7\uff1a\u91cd\u8981\u8d44\u6e90',\n '\ud83d\udcda1\u53f7\uff1a\u4e66\u7c4d\u5927\u793c\u5305',\n '\ud83d\udcfc\u8d44\u6599\u5907\u4efd',\n 'file.py',\n 'test.txt']\n```\n\n**\u4f7f\u7528** <kbd>remove</kbd> **\u65b9\u6cd5\u53ef\u4ee5\u5220\u9664\u6587\u4ef6\uff0c\u53c2\u8003** <kbd>os.remove</kbd>\n\n```python\n>>> fs.remove(\"test.txt\")\n>>> fs.remove(\"file.py\")\n>>> fs.listdir()\n['\u4e91\u4e0b\u8f7d',\n '000\u9605\u8bfb\u00b7\u4e71\u4e03\u516b\u7cdf',\n '\u7535\u89c6\u5267',\n '\u7535\u5f71',\n '\u7eaa\u5f55\u7247',\n 'libgen',\n '\ud83d\udc7e0\u53f7\uff1a\u91cd\u8981\u8d44\u6e90',\n '\ud83d\udcda1\u53f7\uff1a\u4e66\u7c4d\u5927\u793c\u5305',\n '\ud83d\udcfc\u8d44\u6599\u5907\u4efd']\n```\n\n**\u4f7f\u7528** <kbd>rmtree</kbd> **\u65b9\u6cd5\u53ef\u4ee5\u5220\u9664\u6587\u4ef6\u6216\u6587\u4ef6\u5939\uff0c\u5e76\u4e14\u5728\u5220\u9664\u6587\u4ef6\u5939\u65f6\uff0c\u4e5f\u5220\u9664\u5176\u4e2d\u7684\u6587\u4ef6\u548c\u6587\u4ef6\u5939\uff0c\u53c2\u8003** <kbd>shutil.rmtree</kbd>\n\n```python\n>>> fs.makedirs(\"a/b/c/d\")\n'/115/a/b/c/d'\n>>> fs.removedirs(\"a\")\nTraceback (most recent call last):\n    ...\nOSError: [Errno 66] directory not empty: '/115/a'\n>>> fs.rmtree(\"a\")\n```\n\n**\u4f7f\u7528** <kbd>rename</kbd> **\u65b9\u6cd5\u53ef\u4ee5\u5bf9\u6587\u4ef6\u6216\u6587\u4ef6\u5939\u8fdb\u884c\u6539\u540d\u6216\u79fb\u52a8\uff0c\u53c2\u8003** <kbd>os.rename</kbd>\n\n```python\n>>> fs.touch(\"a\")\n'/115/a'\n>>> _ = fs.listdir(refresh=True)\n>>> fs.attr(\"a\")\n{'name': 'a',\n 'size': 0,\n 'is_dir': False,\n 'modified': '2023-12-29T16:02:00+08:00',\n 'created': '2023-12-29T16:02:41+08:00',\n 'sign': '',\n 'thumb': '',\n 'type': 0,\n 'hashinfo': '{\"sha1\":\"DA39A3EE5E6B4B0D3255BFEF95601890AFD80709\"}',\n 'hash_info': {'sha1': 'DA39A3EE5E6B4B0D3255BFEF95601890AFD80709'},\n 'raw_url': 'http://localhost:5244/p/115/a',\n 'readme': '',\n 'header': '',\n 'provider': '115 Cloud',\n 'related': None,\n 'path': '/115/a',\n 'lastest_update': datetime.datetime(2023, 12, 29, 16, 3, 31, 166894)}\n>>> fs.rename('a', 'b')\n'/115/b'\n>>> fs.attr(\"b\")\n{'name': 'b',\n 'size': 0,\n 'is_dir': False,\n 'modified': '2023-12-29T16:03:00+08:00',\n 'created': '2023-12-29T16:02:41+08:00',\n 'sign': '',\n 'thumb': '',\n 'type': 0,\n 'hashinfo': '{\"sha1\":\"DA39A3EE5E6B4B0D3255BFEF95601890AFD80709\"}',\n 'hash_info': {'sha1': 'DA39A3EE5E6B4B0D3255BFEF95601890AFD80709'},\n 'raw_url': 'http://localhost:5244/p/115/b',\n 'readme': '',\n 'header': '',\n 'provider': '115 Cloud',\n 'related': None,\n 'path': '/115/b',\n 'lastest_update': datetime.datetime(2023, 12, 29, 16, 3, 47, 200980)}\n```\n\n**\u4f7f\u7528** <kbd>renames</kbd> **\u65b9\u6cd5\u53ef\u4ee5\u5bf9\u6587\u4ef6\u6216\u6587\u4ef6\u5939\u8fdb\u884c\u6539\u540d\u6216\u79fb\u52a8\uff0c\u5e76\u4e14\u5728\u79fb\u52a8\u540e\u5982\u679c\u539f\u6765\u6240\u5728\u76ee\u5f55\u4e3a\u7a7a\uff0c\u5219\u4f1a\u5220\u9664\u90a3\u4e2a\u76ee\u5f55\uff0c\u53c2\u8003** <kbd>os.renames</kbd>\n\n**\u4f7f\u7528** <kbd>replace</kbd> **\u65b9\u6cd5\u53ef\u4ee5\u5bf9\u6587\u4ef6\u6216\u6587\u4ef6\u5939\u8fdb\u884c\u6539\u540d\u6216\u79fb\u52a8\uff0c\u5e76\u4e14\u5982\u679c\u539f\u59cb\u8def\u5f84\u4e0a\u662f\u6587\u4ef6\uff0c\u76ee\u6807\u8def\u5f84\u4e0a\u4e5f\u5b58\u5728\u4e00\u4e2a\u6587\u4ef6\uff0c\u5219\u4f1a\u5148\u628a\u76ee\u6807\u8def\u5f84\u4e0a\u7684\u6587\u4ef6\u5220\u9664\uff0c\u53c2\u8003** <kbd>os.replace</kbd>\n\n**\u4f7f\u7528** <kbd>move</kbd> **\u65b9\u6cd5\u53ef\u4ee5\u5bf9\u6587\u4ef6\u6216\u6587\u4ef6\u5939\u8fdb\u884c\u6539\u540d\u6216\u79fb\u52a8\uff0c\u76ee\u6807\u8def\u5f84\u5b58\u5728\u4e14\u662f\u4e00\u4e2a\u76ee\u5f55\uff0c\u5219\u628a\u6587\u4ef6\u79fb\u52a8\u5230\u5176\u4e2d\uff08\u4f46\u662f\u76ee\u5f55\u4e2d\u6709\u540c\u540d\u7684\u6587\u4ef6\u6216\u6587\u4ef6\u5939\uff0c\u8fd8\u662f\u4f1a\u62a5\u9519\uff09\uff0c\u53c2\u8003** <kbd>shutil.move</kbd>\n\n### 3. \u904d\u5386\u6587\u4ef6\u7cfb\u7edf\u548c\u67e5\u627e\u6587\u4ef6\n\n#### 1. \u83b7\u53d6\u5f53\u524d\u76ee\u5f55\u4e0b\u6240\u6709 .mkv \u6587\u4ef6\u7684 url\n\n**\u7b2c 1 \u79cd\u65b9\u6cd5\uff0c\u4f7f\u7528** <kbd>iter</kbd>\uff0c\u8fd4\u56de <kbd>alist.AlistPath</kbd> \u5bf9\u8c61\u7684\u8fed\u4ee3\u5668\n\n```python\nfor path in fs.iter(max_depth=-1):\n    if path.name.endswith(\".mkv\"):\n        print(path.url)\n```\n\n**\u7b2c 2 \u79cd\u65b9\u6cd5\uff0c\u4f7f\u7528** <kbd>glob</kbd>\uff0c\u53c2\u8003 <kbd>pathlib.Path.glob</kbd> \u548c <kbd>glob.iglob</kbd>\uff0c\u4f7f\u7528\u901a\u914d\u7b26\u67e5\u627e\n\n```python\nfor path in fs.glob(\"**/*.mkv\"):\n    print(path.url)\n```\n\n**\u7b2c 3 \u79cd\u65b9\u6cd5\uff0c\u4f7f\u7528** <kbd>rglob</kbd>\uff0c\u53c2\u8003 <kbd>pathlib.Path.rglob</kbd>\n\n```python\nfor path in fs.rglob(\"*.mkv\"):\n    print(path.url)\n```\n\n### 4. \u4efb\u52a1\u5217\u8868\n\n<kbd>AList</kbd> \u76ee\u524d\u652f\u6301 `4` \u79cd\u7c7b\u578b\u7684\u4efb\u52a1\uff0c\u6211\u5206\u522b\u8fdb\u884c\u4e86\u5c01\u88c5\uff0c\u5927\u90e8\u5206\u65b9\u6cd5\u90fd\u652f\u6301\u5f02\u6b65\u8c03\u7528 (`async_=True`)\n\n- <kbd>alist.AlistCopyTaskList</kbd> \u5c01\u88c5\u4e86 `\u590d\u5236` \u7684\u4efb\u52a1\u5217\u8868\u3002\n- <kbd>alist.AlistOfflineDownloadTaskList</kbd> \u5c01\u88c5\u4e86 `\u79bb\u7ebf\u4e0b\u8f7d\uff08\u5230\u672c\u5730\uff09` \u7684\u4efb\u52a1\u5217\u8868\u3002\n- <kbd>alist.AlistOfflineDownloadTransferTaskList</kbd> \u5c01\u88c5\u4e86 `\u79bb\u7ebf\u4e0b\u8f7d\uff08\u5230\u5b58\u50a8\uff09` \u7684\u4efb\u52a1\u5217\u8868\u3002\n- <kbd>alist.AlistUploadTaskList</kbd> \u5c01\u88c5\u4e86 `\u4e0a\u4f20` \u7684\u4efb\u52a1\u5217\u8868\u3002\n- <kbd>alist.AlistAria2DownTaskList</kbd> \u5c01\u88c5\u4e86 `aria2\u4e0b\u8f7d` \u7684\u4efb\u52a1\u5217\u8868\u3002\n- <kbd>alist.AlistAria2TransferTaskList</kbd> \u5c01\u88c5\u4e86 `aria2\u8f6c\u5b58` \u7684\u4efb\u52a1\u5217\u8868\u3002\n- <kbd>alist.AlistQbitDownTaskList</kbd> \u5c01\u88c5\u4e86 `qbit\u4e0b\u8f7d` \u7684\u4efb\u52a1\u5217\u8868\u3002\n- <kbd>alist.AlistQbitTransferTaskList</kbd> \u5c01\u88c5\u4e86 `qbit\u8f6c\u5b58` \u7684\u4efb\u52a1\u5217\u8868\u3002\n\n```python\nfrom alist import AlistClient\n\nclient = AlistClient(\"http://localhost:5244\", \"admin\", \"123456\")\n\n# \u83b7\u53d6\u5404\u79cd\u4efb\u52a1\u5217\u8868\ncopy_tasklist = client.copy_tasklist\noffline_download_tasklist = client.offline_download_tasklist\noffline_download_transfer_tasklist = client.offline_download_transfer_tasklist\nupload_tasklist = client.upload_tasklist\naria2_down_tasklist = client.aria2_down_tasklist\naria2_transfer_tasklist = client.aria2_transfer_tasklist\nqbit_down_tasklist = client.qbit_down_tasklist\nqbit_transfer_tasklist = client.qbit_transfer_tasklist\n\n# \u6216\u8005\u81ea\u5df1\u521b\u5efa\u5b9e\u4f8b\n\n# \u521b\u5efa \u590d\u5236 \u4efb\u52a1\u5217\u8868\u5b9e\u4f8b\nfrom alist import AlistCopyTaskList\ncopy_tasklist = AlistCopyTaskList(client)\n\n# \u521b\u5efa \u79bb\u7ebf\u4e0b\u8f7d\uff08\u5230\u672c\u5730\uff09 \u4efb\u52a1\u5217\u8868\u5b9e\u4f8b\nfrom alist import AlistOfflineDownloadTaskList\noffline_download_tasklist = AlistOfflineDownloadTaskList(client)\n\n# \u521b\u5efa \u79bb\u7ebf\u4e0b\u8f7d\uff08\u5230\u5b58\u50a8\uff09 \u4efb\u52a1\u5217\u8868\u5b9e\u4f8b\nfrom alist import AlistOfflineDownloadTransferTaskList\noffline_download_transfer_tasklist = AlistOfflineDownloadTransferTaskList(client)\n\n# \u521b\u5efa \u4e0a\u4f20 \u4efb\u52a1\u5217\u8868\u5b9e\u4f8b\nfrom alist import AlistUploadTaskList\nupload_tasklist = AlistUploadTaskList(client)\n\n# \u521b\u5efa \u4e0a\u4f20 \u4efb\u52a1\u5217\u8868\u5b9e\u4f8b\nfrom alist import AlistAria2DownTaskList\naria2_down_tasklist = AlistAria2DownTaskList(client)\n\n# \u521b\u5efa \u4e0a\u4f20 \u4efb\u52a1\u5217\u8868\u5b9e\u4f8b\nfrom alist import AlistAria2TransferTaskList\naria2_transfer_tasklist = AlistAria2TransferTaskList(client)\n\n# \u521b\u5efa \u4e0a\u4f20 \u4efb\u52a1\u5217\u8868\u5b9e\u4f8b\nfrom alist import AlistQbitDownTaskList\nqbit_down_tasklist = AlistQbitDownTaskList(client)\n\n# \u521b\u5efa \u4e0a\u4f20 \u4efb\u52a1\u5217\u8868\u5b9e\u4f8b\nfrom alist import AlistQbitTransferTaskList\nqbit_transfer_tasklist = AlistQbitTransferTaskList(client)\n```\n\n## \u6587\u6863\n\n> \u6b63\u5728\u7f16\u5199\u4e2d\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Python wrapper for alist.",
    "version": "0.0.13.6",
    "project_urls": {
        "Homepage": "https://github.com/ChenyangGao/web-mount-packs/tree/main/python-alist-client",
        "Repository": "https://github.com/ChenyangGao/web-mount-packs/tree/main/python-alist-client"
    },
    "split_keywords": [
        "alist",
        " client"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "83b61336ded2f934952a1149cfcadac172f5cf5faef53fe1c4f3f5eec8bc9259",
                "md5": "eef90280327afa928fc5d79fbea5ce0c",
                "sha256": "de304ee9c52a23e8e866c2cea67138cf42b72951ffb9c6820c892ad521c3f7cc"
            },
            "downloads": -1,
            "filename": "python_alist-0.0.13.6-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "eef90280327afa928fc5d79fbea5ce0c",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": "<4.0,>=3.11",
            "size": 79668,
            "upload_time": "2024-11-30T13:41:03",
            "upload_time_iso_8601": "2024-11-30T13:41:03.099473Z",
            "url": "https://files.pythonhosted.org/packages/83/b6/1336ded2f934952a1149cfcadac172f5cf5faef53fe1c4f3f5eec8bc9259/python_alist-0.0.13.6-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "ae1dd19392a8dcd2940b4d4eb73606418cf582488196553810e58925f20343b1",
                "md5": "7e4af429ac6c4a16a87452ae79a470ab",
                "sha256": "c3d49779330e0902199215e265f0bcf3752dfeaf28cd365599eb6d4e281c4e67"
            },
            "downloads": -1,
            "filename": "python_alist-0.0.13.6.tar.gz",
            "has_sig": false,
            "md5_digest": "7e4af429ac6c4a16a87452ae79a470ab",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": "<4.0,>=3.11",
            "size": 70176,
            "upload_time": "2024-11-30T13:41:06",
            "upload_time_iso_8601": "2024-11-30T13:41:06.736296Z",
            "url": "https://files.pythonhosted.org/packages/ae/1d/d19392a8dcd2940b4d4eb73606418cf582488196553810e58925f20343b1/python_alist-0.0.13.6.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-11-30 13:41:06",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "ChenyangGao",
    "github_project": "web-mount-packs",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "python-alist"
}
        
Elapsed time: 0.41429s