将文件附加到Kinto记录
项目描述
将文件附加到 Kinto记录。
安装
pip install kinto-attachment
设置
在Kinto项目设置中
kinto.includes = kinto_attachment
kinto.attachment.base_url = http://cdn.service.org/files/
本地文件存储
本地存储文件
kinto.attachment.base_path = /tmp
S3文件存储
存储在Amazon S3上
kinto.attachment.aws.access_key = <AWS access key>
kinto.attachment.aws.secret_key = <AWS secret key>
kinto.attachment.aws.bucket_name = <bucket name>
kinto.attachment.aws.acl = <AWS ACL permissions|public-read>
参阅Pyramid存储。
Google云存储
kinto.attachment.gcloud.credentials = <Path to the Service Accounts credentials JSON file>
kinto.attachment.gcloud.bucket_name = <bucket name>
kinto.attachment.gcloud.acl = publicRead
文件夹选项
使用此选项,文件将存储在子文件夹中。
使用{bucket_id}和{collection_id}占位符按桶或集合组织文件。
kinto.attachment.folder = {bucket_id}/{collection_id}
或仅针对特定桶
kinto.attachment.resources.blog.folder = blog-assets
或特定集合
kinto.attachment.resources.blog.articles.folder = articles-images
keep_old_files选项
当设置为true时,文件在关联记录被删除或附件被替换时不会从磁盘/S3删除。
kinto.attachment.keep_old_files = true
或仅针对特定桶
kinto.attachment.resources.blog.keep_old_files = false
或特定集合
kinto.attachment.resources.blog.articles.keep_old_files = true
gzipped选项
如果您希望存储时上传的文件被gzip压缩(默认:False)
kinto.attachment.gzipped = true
或仅针对特定桶
kinto.attachment.resources.blog.gzipped = true
或特定集合
kinto.attachment.resources.blog.articles.gzipped = true
randomize选项
如果您希望上传的文件以随机名称存储(默认:True)
kinto.attachment.randomize = true
或仅针对特定桶
kinto.attachment.resources.blog.randomize = true
或特定集合
kinto.attachment.resources.blog.articles.randomize = true
extensions选项
如果您想上传不属于默认允许扩展名的文件(请参阅Pyramid扩展组(默认:default))
kinto.attachment.extensions = default+video
mimetypes选项
默认情况下,使用Python标准mimetypes模块从文件名猜测mimetype。
如果您想添加或覆盖mimetype,请使用以下设置和相关语法
kinto.attachment.mimetypes = .ftl:application/vnd.fluent;.db:application/vnd.sqlite3
默认存储桶
为了在默认存储桶上上传文件,应先启用内置的默认存储桶插件,然后再启用kinto_attachment插件。
在配置中,这意味着明确将其添加到includes中
kinto.includes = kinto.plugins.default_bucket
kinto_attachment
生产
确保base_url可以访问(如果文件存储在本地,则指向base_path)
调整上传文件的最大大小(例如,NGinx中的client_max_body_size 10m;)
例如,使用NGinx
server { listen 80; location /v1 { ... } location /files { root /var/www/kinto; } }
API
POST /{record-url}/attachment
如果不存在,将创建底层记录。
必需
attachment:单个multipart编码文件
可选
data:设置在记录上的属性(序列化JSON)
permissions:设置在记录上的权限(序列化JSON)
DELETE /{record-url}/attachment
从记录中删除附件。
属性
当文件被附加时,相关的记录会被赋予一个包含以下字段的attachment属性
filename:原始文件名
hash:SHA-256十六进制摘要
location:附件的URL
mimetype:文件的媒体类型
size:字节数量
{
"data": {
"attachment": {
"filename": "IMG_20150219_174559.jpg",
"hash": "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad",
"location": "http://cdn.service.org/files/ffa9c7b9-7561-406b-b7f9-e00ac94644ff.jpg",
"mimetype": "image/jpeg",
"size": 1481798
},
"id": "c2ce1975-0e52-4b2f-a5db-80166aeca688",
"last_modified": 1447834938251,
"theme": "orange",
"type": "wallpaper"
},
"permissions": {
"write": ["basicauth:6de355038fd943a2dc91405063b91018bb5dd97a08d1beb95713d23c2909748f"]
}
}
如果文件被服务器gzip压缩,则会在attachment键中添加一个original键,包含在gzip之前文件的详细信息。在这种情况下,attachment键指的是压缩后的文件
{
"data": {
"attachment": {
"filename": "IMG_20150219_174559.jpg.gz",
"hash": "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad",
"location": "http://cdn.service.org/files/ffa9c7b9-7561-406b-b7f9-e00ac94644ff.jpg.gz",
"mimetype": "application/x-gzip",
"size": 14818,
"original": {
"filename": "IMG_20150219_174559.jpg",
"hash": "hPME6i9avCf/LFaznYr+sHtwQEX7mXYHSu+vgtygpM8=",
"mimetype": "image/jpeg",
"size": 1481798
}
},
"id": "c2ce1975-0e52-4b2f-a5db-80166aeca688",
"last_modified": 1447834938251,
"theme": "orange",
"type": "wallpaper"
},
"permissions": {
"write": ["basicauth:6de355038fd943a2dc91405063b91018bb5dd97a08d1beb95713d23c2909748f"]
}
}
使用方法
使用HTTPie
http --auth alice:passwd --form POST http://localhost:8888/v1/buckets/website/collections/assets/records/c2ce1975-0e52-4b2f-a5db-80166aeca689/attachment data='{"type": "wallpaper", "theme": "orange"}' "attachment@~/Pictures/background.jpg"
HTTP/1.1 201 Created
Access-Control-Expose-Headers: Retry-After, Content-Length, Alert, Backoff
Content-Length: 209
Content-Type: application/json; charset=UTF-8
Date: Wed, 18 Nov 2015 08:22:18 GMT
Etag: "1447834938251"
Last-Modified: Wed, 18 Nov 2015 08:22:18 GMT
Location: http://localhost:8888/v1/buckets/website/collections/font/assets/c2ce1975-0e52-4b2f-a5db-80166aeca689
Server: waitress
{
"filename": "IMG_20150219_174559.jpg",
"hash": "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad",
"location": "http://cdn.service.org/files/ffa9c7b9-7561-406b-b7f9-e00ac94644ff.jpg",
"mimetype": "image/jpeg",
"size": 1481798
}
使用Python requests
auth = ("alice", "passwd")
attributes = {"type": "wallpaper", "theme": "orange"}
perms = {"read": ["system.Everyone"]}
files = [("attachment", ("background.jpg", open("Pictures/background.jpg", "rb"), "image/jpeg"))]
payload = {"data": json.dumps(attributes), "permissions": json.dumps(perms)}
response = requests.post(SERVER_URL + endpoint, data=payload, files=files, auth=auth)
response.raise_for_status()
使用JavaScript
var headers = {Authorization: "Basic " + btoa("alice:passwd")};
var attributes = {"type": "wallpaper", "theme": "orange"};
var perms = {"read": ["system.Everyone"]};
// File object from input field
var file = form.elements.attachment.files[0];
// Build form data
var payload = new FormData();
// Multipart attachment
payload.append('attachment', file, "background.jpg");
// Record attributes and permissions JSON encoded
payload.append('data', JSON.stringify(attributes));
payload.append('permissions', JSON.stringify(perms));
// Post form using GlobalFetch API
var url = `${server}/buckets/${bucket}/collections/${collection}/records/${record}/attachment`;
fetch(url, {method: "POST", body: payload, headers: headers})
.then(function (result) {
console.log(result);
});
脚本
本存储库中提供了两个脚本。
它们依赖于kinto-client Python包,该包可以安装在一个虚拟环境中
$ virtualenv env --python=python3 $ source env/bin/activate $ pip install kinto-client
或者在系统上全局安装(不建议)
$ sudo pip install kinto-client
上传文件
upload.py接受一个文件列表,并将它们上传到指定的服务器、存储桶和集合
$ python3 scripts/upload.py --server=$SERVER --bucket=$BUCKET --collection=$COLLECTION --auth "token:mysecret" README.rst pictures/*
如果传递了--gzip选项,则在上传之前将文件gzip压缩。由于attachment属性包含压缩文件的元数据,原始文件的元数据将存储在original属性中。
有关选项的更多信息,请参阅python3 scripts/upload.py --help
下载文件
download.py从指定的服务器、存储桶和集合下载附件,并将它们存储在磁盘上
$ python3 scripts/download.py --server=$SERVER --bucket=$BUCKET --collection=$COLLECTION --auth "token:mysecret"
如果记录具有original属性,则脚本在下载后解压缩附件。
默认情况下,文件存储在当前文件夹中。有关选项的更多信息,请参阅python3 scripts/download.py --help
已知限制
不支持分块上传(#10)
当服务器使用POST /v1/__flush__清除时,文件不会被删除
记录中的相对URL(解决方法)
目前,记录中返回的是完整URL。这对于API消费者来说非常方便,他们只需使用location属性中的值即可访问附加的文件。
然而,它的实现方式有一个限制:完整URL直接存储在每个记录中。这很烦人,因为更改base_url设置实际上不会更改现有记录上的location属性。
作为解决方法,可以将kinto.attachment.base_url设置为空值。现在,记录中的location属性将包含一个relative URL。
通过另一个设置kinto.attachment.extra.base_url,可以通知客户端可以预先附加的基URL以获取完整的附件URL。如果指定,它将暴露在根URL端点的功能中。
运行测试
在另一个终端运行一个模拟的Amazon S3服务器
make run-moto
运行测试套件
make tests
发布
在https://github.com/Kinto/kinto-attachment/releases/new上创建一个GitHub发布
创建一个新标签X.Y.Z(此标签将在发布此版本时从目标创建。)
生成发布说明
发布版本
注意
项目详情
下载文件
下载适用于您的平台的文件。如果您不确定选择哪一个,请了解更多关于 安装包 的信息。