SDK
SDK ສຳລັບ Node.js, Python ແລະ Go ເຮັດທຸກຢ່າງດ້ານລຸ່ມໃຫ້ເອງ ທັງການເຊັນ request ການກວດຄວາມຖືກຕ້ອງຂອງຂໍ້ມູນ ການລອງໃໝ່ ແລະ ການອັບໂຫຼດ/ດາວໂຫຼດໄຟລ໌ໃຫຍ່ເປັນສ່ວນໆພ້ອມກັນ ຕິດຕັ້ງຕາມພາສາທີ່ໃຊ້:
| ພາສາ | ຕ້ອງໃຊ້ | ຕິດຕັ້ງ |
|---|---|---|
| Node.js | 18.17+ | npm install @thailandhosting/object-storage |
| Python | 3.9+ | pip install thailandhosting-object-storage |
| Go | 1.23+ | go get github.com/mrzack99s/thailandhosting-object-storage-sdk-go |
ສ້າງ client ດ້ວຍ Endpoint ຂອງ Region ທີ່ Bucket ຢູ່ ແລະ Access key ຈາກ Console ເກັບ Key ໄວ້ໃນ environment variable ບໍ່ແມ່ນໃນໂຄດ ແລະ ໃຊ້ client ໂຕດຽວຕະຫຼອດໂປຣແກຣມ ເພາະມັນເປີດການເຊື່ອມຕໍ່ຄ້າງໄວ້ໃຫ້ໃຊ້ຊ້ຳ
import { Client, NotFoundError } from '@thailandhosting/object-storage';
const client = new Client({
endpoint: 'https://objects.thailandhosting.com/<region>',
accessKeyId: process.env.TH_ACCESS_KEY_ID,
secretAccessKey: process.env.TH_SECRET_ACCESS_KEY,
});
const bucket = client.bucket('my-bucket');
// Any size: large files go up and come down in parallel parts
await bucket.uploadFile('backups/db.dump', '/var/backups/db.dump');
await bucket.downloadFile('backups/db.dump', '/tmp/db.dump');
// Small files
await bucket.put('notes/hello.txt', 'Hello', { contentType: 'text/plain' });
console.log(await bucket.getText('notes/hello.txt'));
// Every file under a folder
for await (const obj of bucket.objects('backups/')) console.log(obj.key, obj.size);
// A link that works without a key for one hour
const link = await bucket.createLink('backups/db.dump', { expiresIn: 3600 });
console.log(link.url);
try {
await bucket.head('missing.txt');
} catch (e) {
if (e instanceof NotFoundError) console.log(e.code); // object_not_found
}import os
from thailandhosting_objectstorage import Client, NotFoundError
client = Client(
endpoint="https://objects.thailandhosting.com/<region>",
access_key_id=os.environ["TH_ACCESS_KEY_ID"],
secret_access_key=os.environ["TH_SECRET_ACCESS_KEY"],
)
bucket = client.bucket("my-bucket")
# Any size: large files go up and come down in parallel parts
bucket.upload_file("backups/db.dump", "/var/backups/db.dump")
bucket.download_file("backups/db.dump", "/tmp/db.dump")
# Small files
bucket.put("notes/hello.txt", "Hello", content_type="text/plain")
print(bucket.get_bytes("notes/hello.txt").decode())
# Every file under a folder
for obj in bucket.iter_objects("backups/"):
print(obj.key, obj.size)
# A link that works without a key for one hour
print(bucket.create_link("backups/db.dump", expires_in=3600).url)
try:
bucket.head("missing.txt")
except NotFoundError as e:
print(e.code) # object_not_foundpackage main
import (
"context"
"fmt"
"log"
"os"
"time"
objectstorage "github.com/mrzack99s/thailandhosting-object-storage-sdk-go"
)
func main() {
client, err := objectstorage.New(objectstorage.Config{
Endpoint: "https://objects.thailandhosting.com/<region>",
AccessKeyID: os.Getenv("TH_ACCESS_KEY_ID"),
SecretAccessKey: os.Getenv("TH_SECRET_ACCESS_KEY"),
})
if err != nil {
log.Fatal(err)
}
ctx := context.Background()
bucket := client.Bucket("my-bucket")
// Any size: large files go up and come down in parallel parts
if _, err := bucket.UploadFile(ctx, "backups/db.dump", "/var/backups/db.dump", nil); err != nil {
log.Fatal(err)
}
if _, err := bucket.DownloadFile(ctx, "backups/db.dump", "/tmp/db.dump"); err != nil {
log.Fatal(err)
}
// Every file under a folder
for obj, err := range bucket.Objects(ctx, "backups/") {
if err != nil {
log.Fatal(err)
}
fmt.Println(obj.Key, obj.Size)
}
// A link that works without a key for one hour
link, err := bucket.CreateLink(ctx, "backups/db.dump", &objectstorage.LinkOptions{Expires: time.Hour})
if err != nil {
log.Fatal(err)
}
fmt.Println(link.URL)
}SDK ຍັງຕັ້ງໂຟນເດີສາທາລະນະ ບອກທີ່ຢູ່ຂອງໄຟລ໌ ແລະ ຂຽນໄຟລ໌ສະເພາະເມື່ອຍັງບໍ່ມີ ຫຼື ເມື່ອຍັງບໍ່ມີໃຜແກ້ຕັ້ງແຕ່ທ່ານອ່ານໄດ້ນຳ:
// Anyone may read images/ without a key (the key must manage buckets)
await bucket.setPublicAccess([{ prefix: 'images/' }]);
console.log(bucket.publicUrl('images/logo.png'));
// Create a file only if it does not exist yet
await bucket.put('locks/job-42', 'me', { ifNoneMatch: '*' });
// Change it only if nobody changed it since you read it
const info = await bucket.head('config.json');
await bucket.put('config.json', next, { ifMatch: info.etag });Request ທີ່ລົ້ມເພາະລະບົບບໍ່ຫວ່າງຊົ່ວຄາວ ຫຼື ເນັດຫຼຸດຈະລອງໃໝ່ໃຫ້ເອງ ທຸກການອັບໂຫຼດກວດກັບ digest ແລະ ການອັບໂຫຼດໄຟລ໌ໃຫຍ່ທີ່ລົ້ມຈະຖືກຍົກເລີກໃຫ້ ສ່ວນທີ່ຄ້າງຈຶ່ງບໍ່ຖືກຄິດເງິນ
ເຄື່ອງມື S3
AWS CLI, rclone ແລະ ແອັບທີ່ຮອງຮັບ S3 ໃຊ້ໄດ້ທັນທີ ພຽງຊີ້ໄປທີ່ Endpoint ໃຊ້ Access key ຂອງທ່ານ ແລະ ຕັ້ງ region ເປັນ Region ຂອງ Bucket
aws configure set aws_access_key_id YOUR_KEY_ID
aws configure set aws_secret_access_key YOUR_SECRET
aws s3 cp backup.tar.gz s3://your-bucket/ --endpoint-url https://objects.thailandhosting.com --region <region>ເອີ້ນ API ໂດຍກົງ
API ເປັນ HTTP ແລະ JSON ທຳມະດາຢູ່ກ້ອງ /v1 ຂອງ Endpoint ແລະ ໃຊ້ມາດຕະຖານຂອງ IETF ແທນຮູບແບບທີ່ຄິດຂຶ້ນເອງ
| ເລື່ອງ | ເຮັດແນວໃດ |
|---|---|
| ການຢືນຢັນຕົວຕົນ | ທຸກ request ເຊັນດ້ວຍ HTTP Message Signatures (RFC 9421) ໂດຍໃຊ້ Secret ຂອງທ່ານ Secret ຈຶ່ງບໍ່ຖືກສົ່ງອອກໄປເລີຍ ເວລາຂອງເຄື່ອງຕ້ອງຫ່າງຈາກຂອງເຮົາບໍ່ເກີນ 5 ນາທີ |
| ຄວາມຖືກຕ້ອງຂອງຂໍ້ມູນ | ການອັບໂຫຼດແນບ Content-Digest (RFC 9530) ເຮົາກວດຂໍ້ມູນກັບຄ່ານີ້ ແລະ ປະຕິເສດຖ້າບໍ່ກົງ ສ່ວນການດາວໂຫຼດຈະໄດ້ Repr-Digest ກັບໄປໃຫ້ກວດໄດ້ຄືກັນ |
| ອັບເດດຢ່າງປອດໄພ | If-None-Match: * ສ້າງໄຟລ໌ສະເພາະເມື່ອຍັງບໍ່ມີ ແລະ If-Match ແກ້ ຫຼື ລຶບໄຟລ໌ສະເພາະເມື່ອຍັງບໍ່ມີໃຜແກ້ຫຼັງຈາກທີ່ທ່ານອ່ານ (RFC 9110) |
| Error | Problem Details (RFC 9457) ເປັນ JSON ທີ່ມີ code ເຊັ່ນ bucket_not_found |
ອັບໂຫຼດຄັ້ງດຽວ ຫຼື ແຕ່ລະສ່ວນໄດ້ບໍ່ເກີນ 5 GB ໄຟລ໌ໃຫຍ່ແບ່ງໄດ້ສູງສຸດ 10,000 ສ່ວນ ແຕ່ລະ Project ມີໄດ້ສູງສຸດ 100 Bucket ແລະ 50 Access key
ຖ້າພົບບັນຫາ
Request ບໍ່ຜ່ານ ແລະ ຂຶ້ນ “invalid_signature” ເວົ້າເຖິງເວລາຂອງເຄື່ອງ
ໂມງຂອງເຄື່ອງຜິດເກີນ 5 ນາທີ ໃຫ້ເປີດຕັ້ງເວລາອັດຕະໂນມັດ (NTP) ແລ້ວລອງໃໝ່
ເຄື່ອງມື S3 ຂຶ້ນ “SignatureDoesNotMatch”
ກວດ Secret ແລະ ຕັ້ງ region ເປັນ Region ຂອງ Bucket ບໍ່ແມ່ນ region ຂອງ cloud ອື່ນ
ອັບໂຫຼດບໍ່ຜ່ານ ຂຶ້ນ 412 “precondition_failed”
ທ່ານຂໍໃຫ້ສ້າງໄຟລ໌ສະເພາະເມື່ອຍັງບໍ່ມີ ຫຼື ແກ້ສະເພາະເມື່ອຍັງບໍ່ຖືກແກ້ ແຕ່ໄຟລ໌ມີຢູ່ແລ້ວ ຫຼື ຖືກແກ້ໄປແລ້ວ ໃຫ້ອ່ານໄຟລ໌ໃໝ່ແລ້ວຕັດສິນໃຈວ່າຈະຂຽນທັບ ຫຼື ບໍ່
ບາງຄັ້ງ request ບໍ່ຜ່ານດ້ວຍ 503 “busy” ຫຼື “SlowDown”
ລະບົບບໍ່ຫວ່າງຊົ່ວຄາວ ໃຫ້ລໍຖ້າຕາມຈຳນວນວິນາທີໃນ header Retry-After ແລ້ວລອງໃໝ່ SDK ແລະ ເຄື່ອງມື S3 ເຮັດໃຫ້ເອງຢູ່ແລ້ວ