Azure ML在线部署处理Multipart表单数据(图片)技术问询
Azure ML托管在线部署处理Multipart表单数据解决方案
1. 配置run(data)处理multipart表单数据的正确方式
你之前导入input_schema的包路径错误,正确的装饰器来自inference-schema库,需先在环境依赖中添加该包(比如在conda.yml里声明)。
正确代码示例:
from inference_schema.schema_decorators import input_schema from inference_schema.parameter_types.bytes_parameter_type import BytesParameterType from werkzeug.formparser import parse_form_data from io import BytesIO @input_schema('data', BytesParameterType(content_type='multipart/form-data')) def run(data): # 构造WSGI环境以解析multipart数据 environ = { 'CONTENT_TYPE': 'multipart/form-data', 'CONTENT_LENGTH': str(len(data)), 'wsgi.input': BytesIO(data) } form, files = parse_form_data(environ) # 提取上传的图片文件 image_file = files.get('image') if image_file: image_content = image_file.read() # 这里替换为你的图片处理/推理逻辑 return {"status": "success", "image_size": len(image_content)} else: return {"error": "未找到图片文件"}
部署时需确保环境包含依赖,conda.yml示例:
dependencies: - python=3.8 - pip: - azureml-defaults - inference-schema - werkzeug
2. @input_schema装饰器的状态及替代方案
你之前使用的azureml_inference_server_http中的input_schema已被弃用,当前Azure ML推荐使用inference-schema库中的同名装饰器,也就是上述示例中的用法。
如果不想使用装饰器,也可以直接在run函数中处理原始请求字节,无需额外装饰:
from werkzeug.formparser import parse_form_data from io import BytesIO def run(data): environ = { 'CONTENT_TYPE': 'multipart/form-data', 'CONTENT_LENGTH': str(len(data)), 'wsgi.input': BytesIO(data) } form, files = parse_form_data(environ) # 后续处理逻辑...
3. 自定义Flask推理服务器的可行性与集成方式
如果你的场景需要更灵活的请求处理(比如支持多路由、同时兼容JSON和multipart输入),切换到自定义Flask应用是更合适的方案。
可以和原有run()方法集成,无需完全手动处理所有路由,示例如下:
- 保留业务逻辑在
score.py的run()函数中:
def run(image_content): # 替换为你的图片推理/处理逻辑 return {"prediction": "sample_result", "image_size": len(image_content)}
- 创建
app.py作为自定义Flask服务:
from flask import Flask, request import score app = Flask(__name__) @app.route('/score', methods=['POST']) def score_endpoint(): if request.content_type.startswith('multipart/form-data'): image_file = request.files.get('image') if not image_file: return {"error": "未提供图片文件"}, 400 image_content = image_file.read() return score.run(image_content) elif request.content_type == 'application/json': # 兼容原有JSON输入场景 data = request.get_json() import base64 image_content = base64.b64decode(data['image']) return score.run(image_content) else: return {"error": "不支持的Content-Type"}, 415 if __name__ == '__main__': app.run(host='0.0.0.0', port=5000)
- 在部署配置
deployment.yml中启用自定义应用:
code_configuration: code: ./ scoring_script: app.py environment: name: custom-flask-env conda_file: conda.yml deployment_settings: online: instance_type: Standard_DS3_v2 instance_count: 1 app_insights_enabled: true use_custom_app: true
这种方式既保留了原有业务逻辑,又通过Flask实现了灵活的请求处理。
内容的提问来源于stack exchange,提问作者cduguet
相关产品推荐
相关产品推荐

