Jak uzyskać dostęp do object storage z NSIS za pomocą boto3
W tym artykule dowiesz się, jak uzyskać dostęp do object storage z NSIS przy użyciu biblioteki Python boto3.
Wymagania wstępne
Nr 1 Konto
Potrzebne jest konto hostingowe NSIS z dostępem do interfejsu Horizon: https://horizon.cloudferro.com.
Nr 2 Generowane poświadczenia EC2
Musisz wygenerować poświadczenia EC2. Dowiedz się więcej tutaj: Jak wygenerować poświadczenia EC2 i zarządzać nimi na NSIS Cloud
Nr 3 Komputer z systemem Linux lub Windows lub maszyna wirtualna
Nr 3 Komputer z systemem Linux lub maszyna wirtualna
Ten artykuł został napisany dla Ubuntu 22.04. Inne systemy operacyjne mogą działać, ale są poza zakresem tego artykułu i mogą wymagać dostosowania dostarczonych tutaj poleceń.
Z tego artykułu można korzystać zarówno na maszynach wirtualnych z systemem Linux lub Windows, jak i na komputerze lokalnym z jednym z tych systemów operacyjnych.
Aby zbudować nową maszynę wirtualną hostowaną w chmurze NSIS, pomocny może być jeden z poniższych artykułów:
Nr 4 Dodatkowe biblioteki Pythona
Będziemy używać dwóch bibliotek Pythona do wypychania plików na serwer S3 w NSIS:
- requests
Powszechnie używany do dostępu HTTP.
- requests_aws4auth
Biblioteka potrzebna do podpisywania przesyłanych plików na serwer S3. Zainstaluj je za pomocą
pip install requests
pip install requests-aws4auth
i import za pomocą poleceń Pythona
import boto3
import requests
from requests_aws4auth import AWS4Auth
Terminologia: kontener i bucket
Terminy kontener (używany przez pulpit nawigacyjny Horizon) i bucket (używany przez boto3) są tutaj używane zamiennie, aby opisać to samo.
Przygotowanie środowiska
Aby wykonać przykłady przedstawione w tym artykule, będziesz potrzebować działającej instalacji Pythona 3 i biblioteki boto3. Dokładna metoda instalacji będzie zależeć od twoich celów i nawyków pracy z Pythonem.
Ubuntu 22.04
Metoda 1: Korzystanie z virtualenvwrapper i pip
Jeśli jesteś doświadczonym użytkownikiem Pythona i pracujesz nad wieloma projektami, z pewnością korzystasz z wirtualnych środowisk Pythona. Zaleca się utworzenie nowego wirtualnego środowiska dla boto3, a oto jeden ze sposobów, aby to zrobić: Jak zainstalować Python virtualenv lub virtualenvwrapper na NSIS Cloud.
Jak wspomniano w tym artykule, użyj polecenia workon, aby wejść do środowiska wirtualnego. Na przykład, jeśli twoje środowisko nazywa się managing-files wykonaj:
workon managing-files
Po aktywacji środowiska zainstaluj boto3:
pip3 install boto3
Metoda 2: Korzystanie z apt
Jeśli jednak nie potrzebujesz takiego środowiska i chcesz udostępnić boto3 globalnie pod Ubuntu, użyj apt. Poniższe polecenie zainstaluje zarówno Python3 jak i bibliotekę boto3:
sudo apt install python3 python3-boto3
Windows Server 2022
Jeśli korzystasz z systemu Windows, postępuj zgodnie z tym artykułem, aby dowiedzieć się, jak zainstalować boto3: Jak zainstalować Boto3 w Windows na NSIS.
Jak korzystać z podanych przykładów?
Każdy z podanych przykładów może służyć jako samodzielny kod. Powinieneś być w stanie
wprowadzić kod w edytorze tekstu,
określić odpowiednią zawartość dla dostarczonych zmiennych,
zapisać go jako plik i
uruchomić go.
Przykłady te można również wykorzystać jako punkt wyjścia dla własnego kodu.
Każdy przykład składa się z trzech części:
- niebieski prostokąt Zaimportuj niezbędne biblioteki
Standardową praktyką Pythona jest importowanie wszystkich bibliotek potrzebnych później do kodu. W tym przypadku, najpierw zaimportuj bibliotekę boto3, jak również inne, jeśli takie są.
- czerwony prostokąt Definiowanie parametrów wejściowych
Typowe wywołanie w bibliotece boto3 będzie wyglądać następująco:
s3=boto3.resource('s3',
aws_access_key_id=access_key,
aws_secret_access_key=secret_key,
endpoint_url=endpoint_url,
region_name=region_name)
For each call, several variables must be present:
* **aws_access_key_id** -- from Prerequisite No. 2
* **aws_secret_access_key** -- also from Prerequisite No. 2
* **endpoint_url** -- s3.waw4-1.cloudferro.com
* **region_name** -- US
Inne zmienne mogą być potrzebne w zależności od przypadku:
name,
path
i ewentualnie inne. Pamiętaj, aby wprowadzić wartości wszystkich tych dodatkowych zmiennych przed uruchomieniem przykładów.
- zielony prostokąt boto3 call
Większość kodu przygotowawczego pozostaje taka sama od pliku do pliku, a ta ostatnia część jest miejscem, w którym mają miejsce różne działania. Czasami będzie to tylko jedna linia kodu, czasami kilka, zwykle pętla.
Uruchamianie kodu Python
Po wprowadzeniu wszystkich wartości do odpowiednich zmiennych, można zapisać plik z rozszerzeniem .py. Jednym ze sposobów uruchamiania skryptów Pythona jest użycie wiersza poleceń. Aby uruchomić taki skrypt, należy najpierw przejść do folderu, w którym znajduje się skrypt. Następnie wykonaj poniższe polecenie, ale zastąp script.py nazwą skryptu, który chcesz uruchomić.
python3 script.py
python script.py
Upewnij się, że nazwa i/lub lokalizacja pliku jest poprawnie przekazywana do powłoki - uważaj na spacje i inne znaki specjalne.
Ważne
W tych przykładach, nawet w przypadku potencjalnie destrukcyjnych operacji, nie zostaniesz poproszony o potwierdzenie. Jeśli na przykład skrypt zapisuje plik, a plik już istnieje pod wskazaną nazwą i lokalizacją, prawdopodobnie zostanie nadpisany. Przed uruchomieniem skryptu upewnij się, że tego właśnie chcesz, lub rozszerz kod o sprawdzanie, czy plik już istnieje.
We wszystkich poniższych przykładach zakładamy, że odpowiednie pliki i buckety już istnieją. Dodawanie kodu do sprawdzania tego rodzaju jest poza zakresem tego artykułu.
Tworzenie kontenera
Aby utworzyć nowy kontener, najpierw wybierz nazwę dla swojego bucketu i wprowadź ją w zmiennej name. W chmurze NSIS należy używać tylko liter, cyfr i myślników.
boto3_create_bucket.py
import boto3 access_key = '' secret_key = '' name = 'boto3' endpoint_url='https://s3.waw4-1.cloudferro.com' region_name='US' try: s3=boto3.resource('s3', aws_access_key_id=access_key, aws_secret_access_key=secret_key, endpoint_url=endpoint_url, region_name=region_name) s3.Bucket(name).create() except Exception as issue: print("The following error occurred:") print(issue)
Pomyślne wykonanie tego kodu nie powinno dać żadnych wyników.
Aby sprawdzić, czy bucket został utworzony, można między innymi wyświetlić listę bucketów zgodnie z opisem w sekcji Wyświetlanie bucketów poniżej.
Rozwiązywanie problemów z tworzeniem kontenera
Bucket już istnieje
Jeśli otrzymasz następujące dane wyjściowe:
The following error occurred:
An error occurred (BucketAlreadyExists) when calling the CreateBucket operation: Unknown
oznacza to, że nie można wybrać tej nazwy dla bucketu, ponieważ bucket o tej nazwie już istnieje. Wybierz inną nazwę i spróbuj ponownie.
Użyto nieprawidłowych znaków
Jeśli w nazwie kontenera użyto nieprawidłowych znaków, powinien pojawić się błąd podobny do tego:
Invalid bucket name "this container should not exist": Bucket name must match the regex "^[a-zA-Z0-9.\-_]{1,255}$" or be an ARN matching the regex "^arn:(aws).*:(s3|s3-object-lambda):[a-z\-0-9]*:[0-9]{12}:accesspoint[/:][a-zA-Z0-9\-.]{1,63}$|^arn:(aws).*:s3-outposts:[a-z\-0-9]+:[0-9]{12}:outpost[/:][a-zA-Z0-9\-]{1,63}[/:]accesspoint[/:][a-zA-Z0-9\-]{1,63}$"
Aby rozwiązać problem, wybierz inną nazwę - w chmurze NSIS używaj tylko liter, cyfr i myślników.
Wylistowanie bucketów
Ten kod umożliwia wyświetlenie listy bucketów.
boto3_list_buckets.py
import boto3 access_key = '' secret_key = '' name = 'boto3' endpoint_url='https://s3.waw4-1.cloudferro.com' region_name='US' try: s3=boto3.client('s3', aws_access_key_id=access_key, aws_secret_access_key=secret_key, endpoint_url=endpoint_url, region_name=region_name) print(s3.list_buckets()['Buckets']) except Exception as issue: print("The following error occurred:") print(issue)
Wynikiem powinna być lista słowników, z których każdy zawiera informacje dotyczące określonego bucketu, zaczynając od jego nazwy. Jeśli istnieją już dwa buckety, moje-pliki i moje-inne-pliki, wynik może być podobny do tego:
[{'Name': 'boto3', 'CreationDate': datetime.datetime(2025, 4, 30, 8, 52, 30, 658000, tzinfo=tzutc())}, {'Name': 'mapsrv', 'CreationDate': datetime.datetime(2025, 1, 7, 12, 43, 50, 522000, tzinfo=tzutc())}, {'Name': 'mapsrv-rasters', 'CreationDate': datetime.datetime(2025, 1, 7, 12, 44, 23, 39000, tzinfo=tzutc())}, {'Name': 's2ffb', 'CreationDate': datetime.datetime(2025, 1, 7, 13, 1, 37, 806000, tzinfo=tzutc())}, {'Name': 's2ffb82', 'CreationDate': datetime.datetime(2025, 1, 7, 13, 1, 45, 124000, tzinfo=tzutc())}, {'Name': 's2landkreise', 'CreationDate': datetime.datetime(2025, 1, 7, 13, 2, 6, 887000, tzinfo=tzutc())}, {'Name': 's2lkffb', 'CreationDate': datetime.datetime(2025, 1, 7, 13, 2, 20, 140000, tzinfo=tzutc())}, {'Name': 'yy-1', 'CreationDate': datetime.datetime(2025, 2, 20, 15, 38, 40, 454000, tzinfo=tzutc())}]
Aby uprościć dane wyjściowe, użyj pętli for z instrukcją print, aby wyświetlić tylko nazwy bucketów, po jednym bucket w wierszu:
boto3_list_one_by_one.py
import boto3 access_key = '' secret_key = '' name = 'boto3' endpoint_url='https://s3.waw4-1.cloudferro.com' region_name='US' try: s3=boto3.client('s3', aws_access_key_id=access_key, aws_secret_access_key=secret_key, endpoint_url=endpoint_url, region_name=region_name) for i in s3.list_buckets()['Buckets']: print(i['Name']) except Exception as issue: print("The following error occurred:") print(issue)
Przykładowy wynik dla tego kodu może wyglądać następująco:
boto3
mapsrv
mapsrv-rasters
Jeśli nie masz żadnych bucketów, dane wyjściowe powinny być puste.
Sprawdzanie, kiedy bucket został utworzony
Użyj tego kodu, aby sprawdzić datę utworzenia bucketu. Wprowadź nazwę tego bucketu w zmiennej name.
boto3_check_date.py
import boto3 access_key = '' secret_key = '' name = 'boto3' endpoint_url='https://s3.waw4-1.cloudferro.com' region_name='US' try: s3=boto3.resource('s3', aws_access_key_id=access_key, aws_secret_access_key=secret_key, endpoint_url=endpoint_url, region_name=region_name) print(s3.Bucket(name).creation_date) except Exception as issue: print("The following error occurred:") print(issue)
Dane wyjściowe powinny zawierać datę utworzenia bucketu w formacie obiektu Python datetime:
2024-01-23 14:21:03.070000+00:00
Wyświetlanie plików w bucket
Aby wyświetlić listę plików znajdujących się w bucket, należy podać nazwę bucketu w zmiennej name.
boto3_list_files_in_bucket.py
import boto3 access_key = '' secret_key = '' name = 'boto3' endpoint_url='https://s3.waw4-1.cloudferro.com' region_name='US' try: s3=boto3.resource('s3', aws_access_key_id=access_key, aws_secret_access_key=secret_key, endpoint_url=endpoint_url, region_name=region_name) bucket=s3.Bucket(name) for obj in bucket.objects.filter(): print(obj) except Exception as issue: print("The following error occurred:") print(issue)
Dane wyjściowe powinny zawierać listę plików, jak poniżej:
s3.ObjectSummary(bucket_name='my-files', key='some-directory/')
s3.ObjectSummary(bucket_name='my-files', key='some-directory/another-file.txt')
s2.ObjectSummary(bucket_name='my-files', key='some-directory/first-file.txt')
s3.ObjectSummary(bucket_name='my-files', key='some-directory/some-other-directory/')
s3.ObjectSummary(bucket_name='my-files', key='some-directory/some-other-directory/some-other-file.txt')
s3.ObjectSummary(bucket_name='my-files', key='some-directory/some-other-directory/yet-another-file.txt')
s3.ObjectSummary(bucket_name='my-files', key='text-file.txt')
Jeśli w bucket nie ma żadnych plików, dane wyjściowe powinny być puste.
Rozwiązywanie problemów z listowaniem plików w bucket
Brak dostępu do bucketu
Jeśli para kluczy nie ma dostępu do wybranego bucketu, powinien pojawić się następujący błąd:
botocore.exceptions.ClientError: An error occurred (AccessDenied) when calling the ListObjects operation: Unknown
W takim przypadku należy wybrać inny bucket lub inną parę kluczy, jeśli masz taką, która może uzyskać do niego dostęp.
Bucket nie istnieje
Jeśli wybrany bucket nie istnieje, błąd może wyglądać następująco:
botocore.errorfactory.NoSuchBucket: An error occurred (NoSuchBucket) when calling the ListObjects operation: Unknown
Jeśli potrzebujesz bucketa, który używa tej nazwy, spróbuj go utworzyć zgodnie z opisem w sekcji Tworzenie kontenera powyżej.
Wyświetlanie plików z określonej ścieżki w bucket
Ten przykład wyświetli tylko obiekty z określonej ścieżki. Istnieją dwie zasady, których należy przestrzegać dla zmiennej ścieżka:
Zakończ ukośnikiem
Nie zaczynaj od ukośnika.
Jak zawsze, dodaj nazwę bucketu do zmiennej name.
boto3_list_files_from_path
import boto3 access_key = '' secret_key = '' name = 'boto3' endpoint_url='https://s3.waw4-1.cloudferro.com' region_name='US' path = '' try: s3=boto3.resource('s3', aws_access_key_id=access_key, aws_secret_access_key=secret_key, endpoint_url=endpoint_url, region_name=region_name) bucket=s3.Bucket(name) for obj in bucket.objects.filter(Prefix=path): print(obj) except Exception as issue: print("The following error occurred:") print(issue)
Standardowe wyjście powinno zostać wygenerowane, ale jeśli nie ma plików pod wybraną ścieżką, wyjście będzie puste.
Przesyłanie pliku do bucketu
Aby przesłać plik do kontenera, dodaj następującą zawartość do zmiennych:
Nazwa zmiennej |
Co powinna zawierać |
bucket_name |
Nazwa bucketu, do którego zostanie wysłany plik. |
source_file |
Lokalizacja pliku, który chcesz przesłać w swoim lokalnym systemie plików. |
destination_file |
Ścieżka docelowa w kontenerze dla przesyłanego pliku. Powinna zawierać wyłącznie litery, cyfry, myślniki i ukośniki. |
Dwa zastrzeżenia dotyczące zmiennej destination:
Zakończ ją nazwą przesyłanego pliku i
Nie zaczynaj ani nie kończ go ukośnikiem.
To jest kod:
boto3_upload_files.py
import boto3 import requests from requests_aws4auth import AWS4Auth access_key = '' secret_key = '' bucket_name = 'boto3' source_file = 'onefile.txt' destination_file = 'onefile.txt' import requests from requests_aws4auth import AWS4Auth def upload_file_to_object_storage(bucket_name, source_path, destination_path, access_key, secret_key): """ Upload a file to a CloudFerro S3 bucket. Args: bucket_name (str): Name of the destination S3 bucket. source_path (str): Local path to the file to upload. destination_path (str): Destination path in the bucket. access_key (str): AWS access key. secret_key (str): AWS secret key. Returns: response (requests.Response): The HTTP response object. """ region = 'RegionOne' service = 's3' endpoint = 'https://s3.waw4-1.cloudferro.com' auth = AWS4Auth(access_key, secret_key, region, service) with open(source_path, 'rb') as file_data: file_content = file_data.read() headers = { 'Content-Length': str(len(file_content)), } url = f'{endpoint}/{bucket_name}/{destination_path}' response = żądania.put(url, data=file_content, headers=headers, auth=auth) return response #demo response = upload_file_to_object_storage(bucket_name, source_file, destination_file, access_key, secret_key) jeśli response.status_code == 200: print(f "Uploaded {source_file} successfully to {bucket_name}/{destination_file}") inaczej: print(f "Upload failed with status {response.status_code}: {response.text}")
Spowoduje to przesłanie pliku onefile.txt z lokalnego folderu do bucketu o nazwie boto3; przesłany plik będzie również nazywał się onefile.txt. Sama funkcja, upload_file_to_object_storage, jest wielokrotnego użytku i może być używana w różnych kontekstach; tutaj główny program po prostu drukuje jednowierszowy raport o tym, co się stało. Można również wykonać funkcję
zgłasza wyjątek w przypadku błędu przesyłania,
ponawia próbę automatycznie,
przesłać wiele plików w partii lub
rejestrowanie sukcesu/porażki w pliku
ale to wykracza poza zakres tego artykułu.
Rozwiązywanie problemów z przesyłaniem pliku do bucketu
Plik, który chcesz przesłać nie istnieje
Jeśli podałeś nieistniejący plik w zmiennej source, powinieneś otrzymać błąd podobny do tego:
The following error occurred:
[Errno 2] No such file or directory: 'here/wrong-file.txt'
Aby rozwiązać problem, podaj prawidłowy plik i spróbuj ponownie.
Pobieranie pliku z bucketu
Aby zapisać plik z bucketu na lokalnym dysku twardym, wprowadź wartości poniższych zmiennych i uruchom poniższy kod:
Nazwa zmiennej |
Co powinna zawierać |
name |
Nazwa bucketu, z którego chcesz pobrać plik. |
source |
Ścieżka w kontenerze, z której chcesz pobrać swój plik. |
destination |
Ścieżka w twoim lokalnym systemie plików, pod którą chcesz zapisać swój plik. |
Nie zaczynaj ani nie kończ zmiennej source ukośnikiem.
boto3_download_file.py
import boto3 access_key = '' secret_key = '' name = 'boto3' endpoint_url='https://s3.waw4-1.cloudferro.com' region_name='US' source='onefile.txt' destination='onefile2.txt' try: s3=boto3.resource('s3', aws_access_key_id=access_key, aws_secret_access_key=secret_key, endpoint_url=endpoint_url, region_name=region_name) bucket=s3.Bucket(name) bucket.download_file(source, destination) except Exception as issue: print("The following error occurred:") print(issue)
Pomyślne wykonanie tego kodu nie powinno dać żadnych wyników.
Rozwiązywanie problemów z przesyłaniem pliku do bucketu
Plik nie istnieje w bucket.
Jeśli wybrany plik nie istnieje w bucket, powinien pojawić się następujący błąd:
The following error occurred:
An error occurred (404) when calling the HeadObject operation: Not Found
Aby rozwiązać ten problem, należy upewnić się, że podano prawidłowy plik.
Usuwanie pliku z bucketu
Aby usunąć plik ze swojego bucketu, podaj nazwę bucketu w zmiennej name, a jego pełną ścieżkę w zmiennej ścieżka.
boto3_remove_file_from_bucket.py
import boto3 access_key = '' secret_key = '' name = 'boto3' endpoint_url='https://s3.waw4-1.cloudferro.com' region_name='US' path = 'onefile.txt' try: s3=boto3.resource('s3', aws_access_key_id=access_key, aws_secret_access_key=secret_key, endpoint_url=endpoint_url, region_name=region_name) s3.Object(name, path).delete() except Exception as issue: print("The following error occurred:") print(issue)
Pomyślne wykonanie tego kodu nie powinno dać żadnych wyników.
Usuwanie bucketu
Aby usunąć bucket, należy najpierw usunąć z niego wszystkie obiekty. Gdy bucket będzie pusty, zdefiniuj zmienną name dla bucketu, który chcesz usunąć i wykonaj poniższy kod:
boto3_remove_bucket.py
import boto3 access_key = '' secret_key = '' name = 'boto3' endpoint_url='https://s3.waw4-1.cloudferro.com' region_name='US' try: s3=boto3.resource('s3', aws_access_key_id=access_key, aws_secret_access_key=secret_key, endpoint_url=endpoint_url, region_name=region_name) s3.Bucket(name).delete() except Exception as issue: print("The following error occurred:") print(issue)
Pomyślne wykonanie tego kodu nie powinno dać żadnych wyników.
Rozwiązywanie problemów z usuwaniem bucketu
Bucket nie istnieje lub jest niedostępny dla twojej pary kluczy.
Jeśli bucket nie istnieje lub jest niedostępny dla twojej pary kluczy, powinieneś otrzymać następujące dane wyjściowe:
The following error occurred:
An error occurred (NoSuchBucket) when calling the DeleteBucket operation: Unknown
Bucket nie jest pusty
Jeśli bucket nie jest pusty, nie można go usunąć. Zostanie wyświetlony komunikat:
The following error occurred:
An error occurred (BucketNotEmpty) when calling the DeleteBucket operation: Unknown
Aby rozwiązać ten problem, usuń wszystkie obiekty z bucketu i spróbuj ponownie.
Ogólne rozwiązywanie problemów
Brak połączenia z punktem końcowym
Jeśli nie masz połączenia z punktem końcowym (na przykład z powodu utraty połączenia z Internetem), powinieneś otrzymać wynik podobny do tego:
The following error occurred: Could not connect to the endpoint URL: "https://s3.waw4-1.cloudferro.com/"
Jeśli tak jest, upewnij się, że masz połączenie z Internetem. Jeśli masz pewność, że masz połączenie z Internetem i nie ogłoszono przestoju dla NSIS Cloud object storage, skontaktuj się z obsługą klienta NSIS Cloud: Helpdesk i wsparcie
Błędne dane uwierzytelniające
Jeśli klucze access i/lub secret są nieprawidłowe, wyświetlony zostanie następujący komunikat:
The following error occurred:
An error occurred (InvalidAccessKeyId) when calling the ListBuckets operation: Unknown
Aby dowiedzieć się, jak uzyskać ważne dane uwierzytelniające, patrz Warunek wstępny nr 2.
Bucket nie istnieje lub jest niedostępny dla twojej pary kluczy.
Jeśli bucket wybrany dla tego kodu nie istnieje lub jest niedostępny dla pary kluczy, można uzyskać różne wyniki w zależności od wykonywanego polecenia. Poniżej znajdują się dwa takie przykłady:
None
The following error occurred:
An error occurred (NoSuchBucket) when calling the DeleteObject operation: Unknown
Co można zrobić dalej
boto3 może być również używane do uzyskiwania dostępu do repozytorium EODATA na maszynach wirtualnych hostowanych w chmurze NSIS Cloud. Dowiedz się więcej tutaj: Jak uzyskać dostęp do EODATA za pomocą boto3 na NSIS
Innym narzędziem do uzyskiwania dostępu do przechowywania obiektów w chmurze jest s3cmd: Jak uzyskać dostęp do object storage z NSIS za pomocą s3cmd.