生信人员基本都是半路出家的野路子,大多没有系统学习过IT知识,只是在终端运行一些简单命令。而IT人员往往不懂生物、不懂统计、也不懂生信,因此要开发生物领域的系统和平台往往需要双方通力合作完成。
假设问题
假设你是生信人员,有一个命令行是:vcftools --vcf input.vcf --max-missing 0.8 --maf 0.05 --min-alleles 2 --max-alleles 2 --recode --recode-INFO-all --out output,该如何优雅地用web框架,如fastAPI、flask等写成接口供IT调用?
步骤
以fastAPI为例,要将你的命令行工具 vcftools
封装成 FastAPI 的接口,需要做以下几步:
创建一个 FastAPI 应用。 定义一个 Pydantic 模型来接收请求数据。 创建一个端点来处理请求,并在后端调用 vcftools
命令。处理命令的输出,并将其返回给客户端。
以下是一个简单的示例代码:
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import subprocess
import os
import shutil
app = FastAPI()
class VcftoolsInput(BaseModel):
max_missing: float
maf: float
min_alleles: int
max_alleles: int
@app.post("/analyze")
def analyze(input_data: VcftoolsInput):
# 准备命令行参数
vcf_file = "input.vcf"
output_prefix = "output"
# 构建命令行
command = [
"vcftools",
"--vcf", vcf_file,
"--max-missing", str(input_data.max_missing),
"--maf", str(input_data.maf),
"--min-alleles", str(input_data.min_alleles),
"--max-alleles", str(input_data.max_alleles),
"--recode",
"--recode-INFO-all",
"--out", output_prefix
]
try:
# 调用命令行工具
result = subprocess.run(command, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
# 处理输出文件
output_vcf = f"{output_prefix}.recode.vcf"
output_log = f"{output_prefix}.log"
# 读取输出文件内容
with open(output_vcf, 'r') as f:
vcf_content = f.read()
with open(output_log, 'r') as f:
log_content = f.read()
# 删除临时文件
os.remove(output_vcf)
os.remove(output_log)
# 返回结果
return {
"vcf_content": vcf_content,
"log": log_content
}
except subprocess.CalledProcessError as e:
# 如果命令执行失败,返回错误信息
raise HTTPException(status_code=500, detail=e.stderr)
# 启动FastAPI应用
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
在这个示例中:
我们定义了一个 VcftoolsInput
类来接收输入参数。/analyze
端点接收这些参数,并构建vcftools
命令行。使用 subprocess.run
来执行命令行工具,并捕获输出。读取输出文件的内容,并将其作为响应返回。 如果命令执行失败,捕获异常并返回错误信息。
请注意,这个示例假设 vcftools
已经安装在服务器上,并且服务器有权限执行它。此外,这个示例没有处理上传VCF文件的逻辑,你需要根据实际情况添加文件上传的处理。
要运行这个 FastAPI 应用,你可以使用以下命令:
uvicorn your_script_name:app --reload
将 your_script_name
替换为你的 Python 脚本文件名。
最后,确保你的 IT 团队知道如何调用这个 API,包括端点的 URL、需要的请求体格式以及如何处理响应。
在 FastAPI 接口中添加文件上传功能
要在 FastAPI 接口中添加文件上传功能,你可以使用 UploadFile
类型来接收上传的文件。以下是一个简单的示例,展示了如何创建一个文件上传的端点:
from fastapi import FastAPI, UploadFile, File
from typing import List
app = FastAPI()
@app.post("/upload-vcf/")
async def upload_vcf(file: UploadFile = File(...)):
# 保存文件到临时文件
with open(f"./temp_{file.filename}", "wb") as buffer:
shutil.copyfileobj(file.file, buffer)
# 这里可以添加你的文件处理逻辑,例如调用 vcftools
command = [
"vcftools",
"--vcf", f"./temp_{file.filename}",
"--max-missing", "0.8",
"--maf", "0.05",
"--min-alleles", "2",
"--max-alleles", "2",
"--recode",
"--recode-INFO-all",
"--out", "output"
]
result = subprocess.run(command, capture_output=True, text=True)
if result.stderr:
return {"error": result.stderr}
# 读取输出文件内容
with open(f"./output.recode.vcf", 'r') as f:
vcf_content = f.read()
# 读取日志文件内容
with open(f"./output.log", 'r') as f:
log_content = f.read()
# 删除临时文件和输出文件
os.remove(f"./temp_{file.filename}")
os.remove(f"./output.recode.vcf")
os.remove(f"./output.log")
# 返回结果
return {
"vcf_content": vcf_content,
"log": log_content
}
在这个例子中,我们定义了一个端点 /upload-vcf/
,它接受一个上传的 VCF 文件。文件被保存到服务器的临时文件中,然后使用 vcftools
命令行工具进行分析。分析完成后,输出文件的内容被读取并返回给客户端。
请注意,你需要确保服务器上安装了 vcftools
,并且 Python 进程有足够的权限来执行它。此外,你可能需要根据你的具体需求调整命令行参数和文件处理逻辑。
这个示例展示了如何使用 FastAPI 处理文件上传和命令行工具调用。你可以根据你的具体需求进行调整和扩展。