Python (boto3) i HostArena S3: primeri koda
boto3 je zvanična AWS biblioteka za Python. Radi sa svim S3 kompatibilnim skladištima, pa tako i sa HostArena S3 storage. Uz pravilno podešavanje (adresa servera, region garage i path-style adrese) iz Python skripte možete otpremati, preuzimati, listati i brisati fajlove.
Šta vam je potrebno
| Podatak | Vrednost | Gde ga nalazite |
|---|---|---|
| Endpoint | https://s3.hostarena.rs | Isti za sve korisnike |
| Region | garage | Obavezno tačno ovako |
| Bucket | vas-bucket | HostArena korisnički panel, kod S3 usluge |
| Access Key | VAS_ACCESS_KEY | HostArena korisnički panel, kod S3 usluge |
| Secret Key | VAS_SECRET_KEY | HostArena korisnički panel, kod S3 usluge |
Potreban vam je Python 3. Preporučujemo da biblioteku instalirate u virtuelno okruženje projekta.
Koraci
Napravite virtuelno okruženje i instalirajte boto3 (na Windows-u se okruženje aktivira sa
.venvScriptsactivate):python3 -m venv .venv source .venv/bin/activate pip install boto3Ključeve ne upisujte direktno u kod. Postavite ih kao promenljive okruženja. Na Linux-u i macOS-u:
export AWS_ACCESS_KEY_ID="VAS_ACCESS_KEY" export AWS_SECRET_ACCESS_KEY="VAS_SECRET_KEY"U Windows PowerShell-u:
$env:AWS_ACCESS_KEY_ID="VAS_ACCESS_KEY" $env:AWS_SECRET_ACCESS_KEY="VAS_SECRET_KEY"Ove komande važe za otvoreni terminal. Na serveru ih obično upisujete u podešavanja servisa, u
.envfajl koji se ne objavljuje ili u alat za tajne podatke.Napravite fajl
primer.py. Primer otprema fajl, ispisuje spisak fajlova i preuzima fajl na disk:import os import boto3 from boto3.exceptions import S3UploadFailedError from botocore.config import Config from botocore.exceptions import ClientError BUCKET = "vas-bucket" # Ključevi se čitaju iz promenljivih okruženja # AWS_ACCESS_KEY_ID i AWS_SECRET_ACCESS_KEY. s3 = boto3.client( "s3", endpoint_url="https://s3.hostarena.rs", region_name="garage", aws_access_key_id=os.environ["AWS_ACCESS_KEY_ID"], aws_secret_access_key=os.environ["AWS_SECRET_ACCESS_KEY"], config=Config(signature_version="s3v4", s3={"addressing_style": "path"}), ) def postoji(key): """Vraća True ako fajl postoji, False ako ne postoji.""" try: s3.head_object(Bucket=BUCKET, Key=key) return True except ClientError as e: if e.response["Error"]["Code"] in ("404", "NoSuchKey", "NotFound"): return False raise # druga greška (npr. pogrešan ključ) se ne krije def main(): s3.upload_file("bekap.zip", BUCKET, "bekapi/bekap.zip") print("Otpremljeno") paginator = s3.get_paginator("list_objects_v2") for page in paginator.paginate(Bucket=BUCKET): for obj in page.get("Contents", []): print(obj["Key"], obj["Size"], "bajtova") if postoji("bekapi/bekap.zip"): s3.download_file(BUCKET, "bekapi/bekap.zip", "vraceno.zip") print("Snimljeno: vraceno.zip") if __name__ == "__main__": try: main() except ClientError as e: print("Greška:", e.response["Error"]["Code"], "-", e.response["Error"].get("Message", "")) except S3UploadFailedError as e: print("Otpremanje nije uspelo:", e)Bitna podešavanja su
endpoint_url="https://s3.hostarena.rs",region_name="garage"iaddressing_stylepostavljen napath. Greške se hvataju prekoClientError, a ne golimexcept:, jer bi goliexcept:sakrio i pogrešne ključeve i prekid veze, pa biste dobili „fajl ne postoji” i kada je problem sasvim drugi. Neuspelo otpremanje prekoupload_filejavlja se kaoS3UploadFailedError, pa se i on hvata posebno.Pokrenite primer (u istom terminalu u kom ste postavili ključeve):
python primer.py
Ostale česte operacije
Upis teksta, čitanje u promenljivu, privremeni link i brisanje (koristi isti s3 klijent i BUCKET iz primera):
# Upis teksta direktno iz memorije
s3.put_object(Bucket=BUCKET, Key="pozdrav.txt", Body="Pozdrav sa HostArena S3!".encode("utf-8"))
# Čitanje sadržaja u promenljivu
odgovor = s3.get_object(Bucket=BUCKET, Key="pozdrav.txt")
print(odgovor["Body"].read().decode("utf-8"))
# Privremeni link koji važi jedan sat
link = s3.generate_presigned_url(
"get_object",
Params={"Bucket": BUCKET, "Key": "pozdrav.txt"},
ExpiresIn=3600,
)
print(link)
# Brisanje fajla
s3.delete_object(Bucket=BUCKET, Key="pozdrav.txt")Pažnja: delete_object trajno briše fajl i ne pita za potvrdu. Obrisani fajl se ne može vratiti.
Funkcije upload_file i download_file same dele velike fajlove na delove i prenose ih paralelno, pa su bolji izbor za velike fajlove od put_object i get_object.
Provera da radi
Stavite mali fajl bekap.zip pored skripte i pokrenite je. Ispravan ispis je „Otpremljeno”, spisak fajlova i „Snimljeno: vraceno.zip”. Ako skripta prijavi KeyError: 'AWS_ACCESS_KEY_ID', promenljive okruženja nisu postavljene u tom terminalu.
Najčešći problemi
AuthorizationHeaderMalformed
Region nije dobar. Mora biti tačno garage. Sa us-east-1 ili bilo kojim drugim AWS regionom server odbija zahtev.
InvalidAccessKeyId, AccessDenied ili SignatureDoesNotMatch
Proverite da li su promenljive okruženja postavljene u istom terminalu ili servisu u kom pokrećete program i da ključevi nemaju razmak na početku ili kraju. Ključeve proverite u HostArena korisničkom panelu, kod S3 usluge.
NoSuchBucket
Naziv bucketa nije tačan. Prepišite ga iz HostArena korisničkog panela. Endpoint ostaje https://s3.hostarena.rs, bez naziva bucketa u adresi.
Greška vezana za checksum pri otpremanju
Novije verzije AWS SDK-a same dodaju kontrolni zbir (checksum) svakom otpremanju. Ako dobijete grešku koja pominje checksum, dodajte u Config sledeće dve opcije (ključevi se ovde čitaju automatski iz promenljivih okruženja):
s3 = boto3.client(
"s3",
endpoint_url="https://s3.hostarena.rs",
region_name="garage",
config=Config(
signature_version="s3v4",
s3={"addressing_style": "path"},
request_checksum_calculation="when_required",
response_checksum_validation="when_required",
),
)Zaključak
Isti princip važi i za druge jezike: PHP, Node.js i Go. Tehnički detalji o adresama i potpisivanju zahteva nalaze se u uputstvu HostArena S3 API: adrese, potpisivanje i kompatibilnost. Nemate S3 uslugu? Pogledajte pakete na stranici HostArena S3 storage. Ako zapne, otvorite tiket u korisničkom panelu.
