Разрешите http URI для озера данных azure
Я создаю интеграцию с хранилищем Azure Data Lake для Label Studio. Бэкенд Django работает следующим образом: он разрешает интеграцию облачных хранилищ таким образом, что они могут быть разрешены в http-адреса для предварительно подписанных объектов, таких как изображения. Это позволяет бэкенду читать все файлы, несмотря на провайдера облачного хранилища. Однако мне не удается успешно создать предварительно подписанные урлы для Azure data lake, какие-нибудь предложения?
Тест, который должен пройти успешно, показан ниже:
- name: stage
request:
method: GET
url: '{django_live_url}/api/projects/{project_pk}/next'
response:
json:
data:
image_url: !re_match "/tasks/\\d+/presign/\\?fileuri=YXp1cmUtYmxvYjovL3B5dGVzdC1henVyZS1pbWFnZXMvYWJj"
status_code: 200
Этот тест выше не работает, конечная точка возвращает "azure-spi://<path/to/file>" вместо "/tasks/\d+/presign/?fileuri=YX..."
Это означает, что я не разрешаю uri так, как ожидает бэкэнд. Проблема в том, что я не знаю, поддерживаются ли http uri в Azure Data Lake с аутентификацией принципала службы. Посмотрите функцию resolve_uri, которую я пытаюсь использовать в классе ниже:
class AzureServicePrincipalImportStorageBase(AzureServicePrincipalStorageMixin, ImportStorage):
url_scheme = 'azure_spi'
presign = models.BooleanField(_('presign'), default=True, help_text='Generate presigned URLs')
presign_ttl = models.PositiveSmallIntegerField(
_('presign_ttl'), default=1, help_text='Presigned URLs TTL (in minutes)'
)
(…)
def generate_http_url(self, url):
match = re.match(AZURE_URL_PATTERN, url)
if match:
match_dict = match.groupdict()
sas_token = self.get_sas_token(match_dict['blob_name'])
url = f"{self.get_account_url()}/{self.container}/{match_dict['blob_name']}?{sas_token}"
return url
(…)
def resolve_uri(self, uri, task=None):
# list of objects
if isinstance(uri, list):
resolved = []
for item in uri:
result = self.resolve_uri(item, task)
resolved.append(result if result else item)
return resolved
# dict of objects
elif isinstance(uri, dict):
resolved = {}
for key in uri.keys():
result = self.resolve_uri(uri[key], task)
resolved[key] = result if result else uri[key]
return resolved
elif isinstance(uri, str):
try:
# extract uri first from task data
if self.presign and task is not None:
sig = urlparse(uri)
if sig.query != '':
return uri
# resolve uri to url using storages
http_url = self.generate_http_url(uri)
return http_url
except Exception:
logger.info(f"Can't resolve URI={uri}", exc_info=True)
class Meta:
abstract = True
Чтобы разрешить HTTP URI для Azure Data Lake в интеграции Label Studio с помощью Django, вам нужно убедиться, что вы правильно генерируете предварительно подписанные URL с токенами SAS для файлов, хранящихся в Azure Data Lake. Выполните следующие шаги :
Настройка Azure Data Lake Client путем создания клиентского класса для взаимодействия с Azure Data Lake с помощью Python
class AzureDataLakeClient:
def __init__(self, account_name, credential):
self.service_client = DataLakeServiceClient(account_url=f"https://{account_name}.dfs.core.windows.net", credential=credential)
def get_file_url(self, file_system_name, file_path):
file_system_client = self.service_client.get_file_system_client(file_system_name)
file_client = file_system_client.get_file_client(file_path)
return file_client.url # This will return the URL of the file
def generate_sas_token(self, file_system_name, file_path, permission="read", expiry=None)://add required permission
file_system_client = self.service_client.get_file_system_client(file_system_name)
file_client = file_system_client.get_file_client(file_path)
sas_token = file_client.generate_shared_access_signature(
permission=permission,
expiry=expiry
)
return f"{file_client.url}?{sas_token}"
Интегрируйте клиент Azure Data Lake в модель Django
def resolve_uri(self, uri, task=None):
if isinstance(uri, list):
resolved = []
for item in uri:
result = self.resolve_uri(item, task)
resolved.append(result if result else item)
return resolved
elif isinstance(uri, dict):
resolved = {}
for key in uri.keys():
result = self.resolve_uri(uri[key], task)
resolved[key] = result if result else uri[key]
return resolved
elif isinstance(uri, str):
try:
if self.presign and task is not None:
sig = urlparse(uri)
if sig.query != '':
return uri
http_url = self.generate_http_url(uri)
return http_url
except Exception as e:
logger.info(f"Can't resolve URI={uri}", exc_info=True)