Python (boto3) i HostArena S3: primeri koda

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

PodatakVrednostGde ga nalazite
Endpointhttps://s3.hostarena.rsIsti za sve korisnike
RegiongarageObavezno tačno ovako
Bucketvas-bucketHostArena korisnički panel, kod S3 usluge
Access KeyVAS_ACCESS_KEYHostArena korisnički panel, kod S3 usluge
Secret KeyVAS_SECRET_KEYHostArena korisnički panel, kod S3 usluge

Potreban vam je Python 3. Preporučujemo da biblioteku instalirate u virtuelno okruženje projekta.

Koraci

  1. 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 boto3
  2. Ključ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 .env fajl koji se ne objavljuje ili u alat za tajne podatke.

  3. 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" i addressing_style postavljen na path. Greške se hvataju preko ClientError, a ne golim except:, jer bi goli except: sakrio i pogrešne ključeve i prekid veze, pa biste dobili „fajl ne postoji” i kada je problem sasvim drugi. Neuspelo otpremanje preko upload_file javlja se kao S3UploadFailedError, pa se i on hvata posebno.

  4. 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.

Tags: , , ,