无法找到Action Storage附件的Action Job出现错误:Errno::ENOENT(找不到文件或目录 @ rb_sysopen)

我有一个Rails 7.0.4应用程序,其中有一个简单的TranscriptionController,当提交包含标题、描述和音频文件的表单后,会启动一个Action Job来使用openai gem处理音频转录。尽管生成的URL指向我想转码的音频文件,我仍然不断收到此错误:Errno::ENOENT (No such file or directory @ rb_sysopen

这是Transcription模型:

    class Transcription < ApplicationRecord    has_one_attached :audio_file    def audio_file_url        Rails.application.routes.url_helpers.url_for(audio_file) if audio_file.attached?    end end

这是TranscriptionController中的create操作:

def create    @transcription = Transcription.new(transcription_params)    respond_to do |format|      if @transcription.save        # 使用OpenAI的Whisper API处理音频文件        TranscriptionJob.perform_later(@transcription)        format.html { redirect_to transcription_url(@transcription), notice: "转录已成功创建。稍后查看转录文本。" }        format.json { render :show, status: :created, location: @transcription }              else        format.html { render :new, status: :unprocessable_entity }        format.json { render json: @transcription.errors, status: :unprocessable_entity }      end    end  end

这是最重要的部分,即名为transcription_job.rb的Active Job:

class TranscriptionJob < ApplicationJob  queue_as :default  require 'openai'  def perform(transcription)    # 稍后执行某些操作    client = OpenAI::Client.new(access_token:  Rails.application.credentials.dig(:openai, :api_key))    logger.info "SMC DEBUG: OpenAI Key set"    file_path = transcription.audio_file_url    logger.info "SMC DEBUG: Audio file path is: #{file_path}"        response = client.transcribe(        parameters: {            model: "whisper-1",            file: File.open(file_path, "rb")        })    logger.info "SMC DEBUG: transcription sent"    # 使用返回的文本更新转录对象    transcription.transcriptionresult = response['text']    logger.info "SMC DEBUG: TranscriptionResult is: #{transcription.transcriptionresult}"        # 保存更新后的转录对象    transcription.save  endend

这是Action Job相关的Rails日志反馈:

15:21:58 web.1  | [ActiveJob] Enqueued ActiveStorage::AnalyzeJob (Job ID: 7b3600ec-ee85-4be6-8faa-18f467fc719a) to Async(default) with arguments: #<GlobalID:0x00000001073c6880 @uri=#<URI::GID gid://transcriptionservice/ActiveStorage::Blob/59>>15:21:58 web.1  | [ActiveJob] Enqueued TranscriptionJob (Job ID: 974566f7-7d83-48ee-b3ae-d6f02a006efb) to Async(default) with arguments: #<GlobalID:0x00000001073d7ba8 @uri=#<URI::GID gid://transcriptionservice/Transcription/61>>15:21:58 web.1  | Redirected to http://localhost:3000/transcriptions/6115:21:58 web.1  | Completed 302 Found in 60ms (ActiveRecord: 13.1ms | Allocations: 24625)15:21:58 web.1  | 15:21:58 web.1  | 15:21:58 web.1  | Started GET "/transcriptions/61" for ::1 at 2023-05-14 15:21:58 -040015:21:58 web.1  | [ActiveJob] [ActiveStorage::AnalyzeJob] [7b3600ec-ee85-4be6-8faa-18f467fc719a]   ActiveStorage::Blob Load (2.2ms)  SELECT "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = $1 LIMIT $2  [["id", 59], ["LIMIT", 1]]15:21:58 web.1  | [ActiveJob] [ActiveStorage::AnalyzeJob] [7b3600ec-ee85-4be6-8faa-18f467fc719a] Performing ActiveStorage::AnalyzeJob (Job ID: 7b3600ec-ee85-4be6-8faa-18f467fc719a) from Async(default) enqueued at 2023-05-14T19:21:58Z with arguments: #<GlobalID:0x0000000107426ac8 @uri=#<URI::GID gid://transcriptionservice/ActiveStorage::Blob/59>>15:21:58 web.1  | [ActiveJob] [ActiveStorage::AnalyzeJob] [7b3600ec-ee85-4be6-8faa-18f467fc719a]   Disk Storage (0.6ms) Downloaded file from key: 49zqmrx6g54pk1pzuc3y2uyvtiyx15:21:58 web.1  | [ActiveJob] [TranscriptionJob] [974566f7-7d83-48ee-b3ae-d6f02a006efb]   Transcription Load (0.3ms)  SELECT "transcriptions".* FROM "transcriptions" WHERE "transcriptions"."id" = $1 LIMIT $2  [["id", 61], ["LIMIT", 1]]15:21:58 web.1  | [ActiveJob] [TranscriptionJob] [974566f7-7d83-48ee-b3ae-d6f02a006efb] Performing TranscriptionJob (Job ID: 974566f7-7d83-48ee-b3ae-d6f02a006efb) from Async(default) enqueued at 2023-05-14T19:21:58Z with arguments: #<GlobalID:0x000000010743ca80 @uri=#<URI::GID gid://transcriptionservice/Transcription/61>>15:21:58 web.1  | [ActiveJob] [TranscriptionJob] [974566f7-7d83-48ee-b3ae-d6f02a006efb] SMC DEBUG: OpenAI Key set15:21:58 web.1  | Processing by TranscriptionsController#show as TURBO_STREAM15:21:58 web.1  |   Parameters: {"id"=>"61"}15:21:58 web.1  | [ActiveJob] [TranscriptionJob] [974566f7-7d83-48ee-b3ae-d6f02a006efb]   ActiveStorage::Attachment Load (7.0ms)  SELECT "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_id" = $1 AND "active_storage_attachments"."record_type" = $2 AND "active_storage_attachments"."name" = $3 LIMIT $4  [["record_id", 61], ["record_type", "Transcription"], ["name", "audio_file"], ["LIMIT", 1]]15:21:58 web.1  | [ActiveJob] [TranscriptionJob] [974566f7-7d83-48ee-b3ae-d6f02a006efb]   ↳ app/models/transcription.rb:5:in `audio_file_url'15:21:58 web.1  |   Transcription Load (1.7ms)  SELECT "transcriptions".* FROM "transcriptions" WHERE "transcriptions"."id" = $1 LIMIT $2  [["id", 61], ["LIMIT", 1]]15:21:58 web.1  |   ↳ app/controllers/transcriptions_controller.rb:83:in `set_transcription'15:21:58 web.1  |   Rendering layout layouts/application.html.erb15:21:58 web.1  |   Rendering transcriptions/show.html.erb within layouts/application15:21:58 web.1  |   Rendered transcriptions/_transcription.html.erb (Duration: 0.0ms | Allocations: 25)15:21:58 web.1  | [ActiveJob] [TranscriptionJob] [974566f7-7d83-48ee-b3ae-d6f02a006efb]   ActiveStorage::Blob Load (1.4ms)  SELECT "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = $1 LIMIT $2  [["id", 59], ["LIMIT", 1]]15:21:58 web.1  |   Rendered transcriptions/show.html.erb within layouts/application (Duration: 1.1ms | Allocations: 843)15:21:58 web.1  | [ActiveJob] [TranscriptionJob] [974566f7-7d83-48ee-b3ae-d6f02a006efb]   ↳ app/models/transcription.rb:5:in `audio_file_url'15:21:58 web.1  | [ActiveJob] [TranscriptionJob] [974566f7-7d83-48ee-b3ae-d6f02a006efb] SMC DEBUG: Audio file path is: http://localhost:3000/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBRQT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--495ff1b4e7c2001a5ca50886bfd85e2ad6847c7b/test_audio.mp315:21:58 web.1  | [ActiveJob] [TranscriptionJob] [974566f7-7d83-48ee-b3ae-d6f02a006efb] Error performing TranscriptionJob (Job ID: 974566f7-7d83-48ee-b3ae-d6f02a006efb) from Async(default) in 25.03ms: Errno::ENOENT (No such file or directory @ rb_sysopen - http://localhost:3000/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBRQT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--495ff1b4e7c2001a5ca50886bfd85e2ad6847c7b/test_audio.mp3):

当我在浏览器中输入该URL时,它会下载正确的文件。

我尝试使用以下代码来引用路径而不是URL:

file_path = Rails.application.routes.url_helpers.rails_blob_path(transcription.audio_file, only_path: true)

但这会导致类似的错误,指向路径而不是URL:

15:38:35 web.1  | [ActiveJob] [TranscriptionJob] [854d3393-ed0b-41b7-8f5f-7d6469feb8a1] Error performing TranscriptionJob (Job ID: 854d3393-ed0b-41b7-8f5f-7d6469feb8a1) from Async(default) in 134.93ms: Errno::ENOENT (No such file or directory @ rb_sysopen - /rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBRUT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--f6270379699bf876802dd28de4cb4414cc7f96ba/test_audio.mp3):

我不知道如何解决这个问题。我希望能从智囊团中找到答案。


回答:

感谢@Chiperific 指引我查阅这篇边缘指南:https://edgeguides.rubyonrails.org/active_storage_overview.html#downloading-files 这帮助我重写了代码如下。关键是要先将文件下载到系统的临时文件位置,然后在openai API中指向该本地路径。

class TranscriptionJob < ApplicationJob  queue_as :default  require 'openai'  def perform(transcription)    # 提供openai API密钥并初始化openai客户端实例    client = OpenAI::Client.new(access_token:  Rails.application.credentials.dig(:openai, :api_key))    # 初始化transcriptionresult变量    transcription.transcriptionresult = ''        # 必须先将文件下载到临时存储位置,然后再使用openai API提交。    transcription.audio_file.open do |file|      # 我在应用程序根目录下创建了一个名为“transcribe”的文件夹/tmp      system '/tmp/transcribe', file.path            response = client.transcribe(        parameters: {            model: "whisper-1",            file: File.open(file.path, "rb")        })      # 将transcriptionresult设置为openai转录生成的response['text']。      transcription.transcriptionresult = response['text']            # 保存更新后的转录对象      transcription.save    end  endend

Related Posts

Keras Dense层输入未被展平

这是我的测试代码: from keras import…

无法将分类变量输入随机森林

我有10个分类变量和3个数值变量。我在分割后直接将它们…

如何在Keras中对每个输出应用Sigmoid函数?

这是我代码的一部分。 model = Sequenti…

如何选择类概率的最佳阈值?

我的神经网络输出是一个用于多标签分类的预测类概率表: …

在Keras中使用深度学习得到不同的结果

我按照一个教程使用Keras中的深度神经网络进行文本分…

‘MatMul’操作的输入’b’类型为float32,与参数’a’的类型float64不匹配

我写了一个简单的TensorFlow代码,但不断遇到T…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注