J'ai une variable qui a l'url aws s3
s3://bucket_name/folder1/folder2/file1.json
Je veux obtenir le bucket_name dans une variable et reposer c'est-à-dire /folder1/folder2/file1.json dans une autre variable. J'ai essayé les expressions régulières et j'ai pu obtenir le bucket_name comme ci-dessous, je ne sais pas s'il y a une meilleure façon.
m = re.search('(?<=s3:\/\/)[^\/]+', 's3://bucket_name/folder1/folder2/file1.json')
print(m.group(0))
Comment puis-je obtenir le reste, c'est-à-dire dossier1/dossier2/fichier1.json?
J'ai vérifié s'il existe une fonctionnalité boto3 pour extraire le bucket_name et la clé de l'URL, mais je ne l'ai pas trouvée.
Comme il ne s'agit que d'une URL normale, vous pouvez utiliser urlparse
pour obtenir toutes les parties de l'URL.
>>> from urlparse import urlparse
>>> o = urlparse('s3://bucket_name/folder1/folder2/file1.json', allow_fragments=False)
>>> o
ParseResult(scheme='s3', netloc='bucket_name', path='/folder1/folder2/file1.json', params='', query='', fragment='')
>>> o.netloc
'bucket_name'
>>> o.path
'/folder1/folder2/file1.json'
Vous devrez peut-être supprimer la barre oblique de début de la clé, comme le suggère la réponse suivante.
o.path.lstrip('/')
Avec Python 3 urlparse
déplacé vers urllib.parse
alors utilisez:
from urllib.parse import urlparse
Voici un cours qui s'occupe de tous les détails.
try:
from urlparse import urlparse
except ImportError:
from urllib.parse import urlparse
class S3Url(object):
"""
>>> s = S3Url("s3://bucket/hello/world")
>>> s.bucket
'bucket'
>>> s.key
'hello/world'
>>> s.url
's3://bucket/hello/world'
>>> s = S3Url("s3://bucket/hello/world?qwe1=3#ddd")
>>> s.bucket
'bucket'
>>> s.key
'hello/world?qwe1=3#ddd'
>>> s.url
's3://bucket/hello/world?qwe1=3#ddd'
>>> s = S3Url("s3://bucket/hello/world#foo?bar=2")
>>> s.key
'hello/world#foo?bar=2'
>>> s.url
's3://bucket/hello/world#foo?bar=2'
"""
def __init__(self, url):
self._parsed = urlparse(url, allow_fragments=False)
@property
def bucket(self):
return self._parsed.netloc
@property
def key(self):
if self._parsed.query:
return self._parsed.path.lstrip('/') + '?' + self._parsed.query
else:
return self._parsed.path.lstrip('/')
@property
def url(self):
return self._parsed.geturl()
Pour ceux qui comme moi essayaient d'utiliser urlparse pour extraire la clé et le bucket afin de créer un objet avec boto3. Il y a un détail important: supprimer la barre oblique du début de la clé
from urlparse import urlparse
o = urlparse('s3://bucket_name/folder1/folder2/file1.json')
bucket = o.netloc
key = o.path
boto3.client('s3')
client.put_object(Body='test', Bucket=bucket, Key=key.lstrip('/'))
Il a fallu un certain temps pour réaliser cela, car boto3 ne lève aucune exception.
Une solution qui fonctionne sans urllib ou re (gère également la barre oblique précédente):
def split_s3_path(s3_path):
path_parts=s3_path.replace("s3://","").split("/")
bucket=path_parts.pop(0)
key="/".join(path_parts)
return bucket, key
Courir:
bucket, key = split_s3_path("s3://my-bucket/some_folder/another_folder/my_file.txt")
Retour:
bucket: my-bucket
key: some_folder/another_folder/my_file.txt
Si vous souhaitez le faire avec des expressions régulières, vous pouvez effectuer les opérations suivantes:
>>> import re
>>> uri = 's3://my-bucket/my-folder/my-object.png'
>>> match = re.match(r's3:\/\/(.+?)\/(.+)', uri)
>>> match.group(1)
'my-bucket'
>>> match.group(2)
'my-folder/my-object.png'
Cela a l'avantage que vous pouvez vérifier le s3
schéma plutôt que d'y autoriser quoi que ce soit.
Ici, c'est comme une ligne à l'aide de regex:
import re
s3_path = "s3://bucket/path/to/key"
bucket, key = re.match(r"s3:\/\/(.+?)\/(.+)", s3_path).groups()