Label Studio集成Azure Data Lake时预签名URL生成失败求助
问题:Azure Data Lake存储集成无法生成符合Label Studio要求的预签名URL
我正在为Label Studio开发Azure Data Lake存储集成,Django后端的核心逻辑是将云存储对象解析为预签名HTTP地址,实现跨云存储提供商的文件读取。但目前遇到以下问题:
- 调用接口
{django_live_url}/api/projects/{project_pk}/next时,返回的是azure-spi://<path/to/file>格式的地址,而非预期的/tasks/\d+/presign/?fileuri=YX...格式 - 对应的测试用例执行失败,不确定服务主体认证模式下Azure Data Lake是否支持生成HTTP可访问的预签名URI
测试用例代码
- 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
当前实现的代码片段
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): # 处理列表类型的URI if isinstance(uri, list): resolved = [] for item in uri: result = self.resolve_uri(item, task) resolved.append(result if result else item) return resolved # 处理字典类型的URI 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: # 从任务数据中提取URI if self.presign and task is not None: sig = urlparse(uri) if sig.query != '': return uri # 将URI解析为HTTP URL 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
问题排查与修复建议
- 核心逻辑偏差:当前
resolve_uri方法直接生成Azure的SAS URL,但Label Studio预期的是内部预签路由(/tasks/xxx/presign/),而非直接返回云存储的HTTP地址。需要调整逻辑,构造符合平台要求的内部预签路径。 - Azure Data Lake的HTTP URI支持:服务主体认证模式下,Azure Data Lake Storage Gen2完全支持生成带SAS令牌的HTTP可访问URL,技术上不存在障碍,问题出在代码的路由适配逻辑上。
- 修正
resolve_uri方法:当启用预签且存在任务对象时,应生成Label Studio的内部预签地址,而非直接返回Azure的SAS URL。示例修改如下:
elif isinstance(uri, str): try: if self.presign and task is not None: # 构造Label Studio内部预签路由 from django.urls import reverse presign_path = reverse('tasks:presign', kwargs={'task_id': task.id}) # 对原始URI进行URL编码 import urllib.parse encoded_uri = urllib.parse.quote(uri) # 返回符合预期格式的预签地址 return f"{presign_path}?fileuri={encoded_uri}" else: # 非预签场景直接返回Azure的HTTP URL http_url = self.generate_http_url(uri) return http_url except Exception: logger.info(f"Can't resolve URI={uri}", exc_info=True)
- 测试规则验证:确保测试用例中的正则表达式能匹配新生成的预签地址,若路径有调整需同步更新
!re_match的匹配规则。
内容的提问来源于stack exchange,提问作者Manrique Vargas
相关产品推荐
相关产品推荐

