You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Python Hook进程或修改程序,将云存储文件注入Slither的Stdin?

问题背景

我使用第三方Python工具包Slither,它仅支持通过本地文件路径调用(比如slither filename.sol)。现在要把它部署在Django API后端,捕获输出返回给用户,但应用运行在仅提供临时存储的Heroku平台上,所以选择Cloudinary存储文件,能获取到文件的Cloudinary URI(比如https://mybucket.cloundary.io/mybucket),但Slither不支持直接传入这类URI。

当前我是先把文件下载到本地./files/目录再调用:

subprocess.run(
    f"slither {'./files/'+filename}",
    stderr=subprocess.STDOUT,
    shell=True,
    timeout=120,
    universal_newlines=True
)

希望实现直接传入Cloudinary URI调用Slither,比如:

subprocess.run(
    f"slither {'https://mybucket.cloundary.io/mybucket'}",
    stderr=subprocess.STDOUT,
    shell=True,
    timeout=120,
    universal_newlines=True
)
可行解决方案

方案1:修改Slither源码添加URI支持

Slither是开源工具,直接修改它的入口逻辑就能添加HTTP/HTTPS URI支持:

  • 找到Slither处理输入参数的核心文件(比如slither/__main__.py)
  • 增加判断逻辑:如果输入是HTTP/HTTPS开头的URI,先用requests下载文件到内存临时文件,再将临时文件路径传给原有处理逻辑
  • 修改完成后重新打包Slither,替换Heroku环境中的依赖包

核心逻辑示例:

import tempfile
import requests
import os
from slither.slither import Slither

def main(target):
    if target.startswith(('http://', 'https://')):
        # 下载文件内容
        resp = requests.get(target)
        resp.raise_for_status()
        # 创建临时文件
        with tempfile.NamedTemporaryFile(suffix='.sol', delete=False) as tmp:
            tmp.write(resp.content)
            tmp_path = tmp.name
        # 用临时文件调用Slither
        slither = Slither(tmp_path)
        # 调用完成后删除临时文件
        os.unlink(tmp_path)
    else:
        slither = Slither(target)
    # 后续输出处理逻辑...

方案2:Hook调用逻辑,自动下载URI到临时目录

不想修改Slither源码的话,可在调用前自行处理URI:

  • 在Django视图中先判断传入的目标是否为Cloudinary URI
  • 如果是,将文件下载到Heroku允许的临时可写目录/tmp
  • 使用本地临时文件路径调用Slither,调用完成后删除临时文件

示例代码:

import os
import requests
import tempfile
import subprocess

def analyze_contract(target):
    local_path = target
    # 判断是否为URI
    if target.startswith(('http://', 'https://')):
        # 下载文件到/tmp临时目录
        resp = requests.get(target)
        resp.raise_for_status()
        with tempfile.NamedTemporaryFile(suffix='.sol', delete=False, dir='/tmp') as tmp:
            tmp.write(resp.content)
            local_path = tmp.name
    
    # 调用Slither
    result = subprocess.run(
        f"slither {local_path}",
        stderr=subprocess.STDOUT,
        shell=True,
        timeout=120,
        universal_newlines=True,
        capture_output=True
    )
    
    # 清理临时文件
    if local_path.startswith('/tmp/'):
        os.unlink(local_path)
    
    return result.stdout

方案3:使用Slither的Python API直接处理内存内容

Slither提供Python API,无需通过subprocess调用,可直接处理内存中的文件内容:

  • 下载Cloudinary文件内容到内存
  • 直接将内容传给Slither API,无需写入本地文件

示例代码:

import requests
from slither.slither import Slither

def analyze_contract_from_uri(uri):
    # 下载文件内容
    resp = requests.get(uri)
    resp.raise_for_status()
    contract_content = resp.text
    
    # 直接用内存内容初始化Slither
    slither = Slither(contracts_content=contract_content)
    
    # 收集分析结果
    analysis_results = []
    for detector in slither.detectors:
        detector.run()
        analysis_results.extend(detector.results)
    
    # 格式化结果返回
    return "\n".join([str(res) for res in analysis_results])

内容的提问来源于stack exchange,提问作者djangonewbie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 00:36:23