Action Job can't seem to find an Action Storage attachment with error: Errno::ENOENT (No such file or directory @ rb_sysopen

huangapple go评论81阅读模式
英文:

Action Job can't seem to find an Action Storage attachment with error: Errno::ENOENT (No such file or directory @ rb_sysopen

问题

It seems like you're encountering an issue with the file path when trying to transcribe audio using the openai gem in your Rails application. The error message "Errno::ENOENT (No such file or directory @ rb_sysopen)" indicates that the system is unable to find the file at the specified path.

In your code, you are using transcription.audio_file_url to obtain the file URL, and then trying to open it using File.open(file_path, "rb"). However, the File.open method expects a local file path, not a URL.

To resolve this issue, you should download the file from the URL and then pass the local path to File.open. Here's a modified version of your TranscriptionJob perform method to achieve this:

  1. class TranscriptionJob < ApplicationJob
  2. queue_as :default
  3. require 'openai'
  4. require 'open-uri'
  5. def perform(transcription)
  6. client = OpenAI::Client.new(access_token: Rails.application.credentials.dig(:openai, :api_key))
  7. logger.info "SMC DEBUG: OpenAI Key set"
  8. file_url = transcription.audio_file_url
  9. begin
  10. # Download the file from the URL to a temporary location
  11. temp_file = Tempfile.new(['audio', '.mp3'])
  12. temp_file.binmode
  13. open(file_url, 'rb') do |url_file|
  14. temp_file.write(url_file.read)
  15. end
  16. temp_file.rewind
  17. response = client.transcribe(
  18. parameters: {
  19. model: "whisper-1",
  20. file: temp_file
  21. })
  22. logger.info "SMC DEBUG: transcription sent"
  23. # Update the transcription object with the returned text
  24. transcription.transcriptionresult = response['text']
  25. logger.info "SMC DEBUG: TranscriptionResult is: #{transcription.transcriptionresult}"
  26. # Save the updated transcription object
  27. transcription.save
  28. ensure
  29. temp_file.close
  30. temp_file.unlink
  31. end
  32. end
  33. end

This code downloads the file from the URL, saves it to a temporary location, and then opens it using File.open. Make sure to require 'open-uri' at the beginning of your code to use the open method.

This should resolve the "No such file or directory" error and allow you to transcribe the audio correctly.

英文:

I have a Rails 7.0.4 app in which I have a simple TranscriptionController that once a form with the title, description and audio_file are submitted, an Action Job is kicked off to process an audio transcription using the openai gem. I keep getting this error in spite of the URL being produced as pointing to the audio_file I want transcoded:
Errno::ENOENT (No such file or directory @ rb_sysopen

Here is the Transcription model:

  1. class Transcription &lt; ApplicationRecord
  2. has_one_attached :audio_file
  3. def audio_file_url
  4. Rails.application.routes.url_helpers.url_for(audio_file) if audio_file.attached?
  5. end
  6. end

Here is the create action in the TranscriptionController:

  1. def create
  2. @transcription = Transcription.new(transcription_params)
  3. respond_to do |format|
  4. if @transcription.save
  5. # Process audio file using OpenAI&#39;s Whisper API
  6. TranscriptionJob.perform_later(@transcription)
  7. format.html { redirect_to transcription_url(@transcription), notice: &quot;Transcription was successfully created. Check back later for transcription text.&quot; }
  8. format.json { render :show, status: :created, location: @transcription }
  9. else
  10. format.html { render :new, status: :unprocessable_entity }
  11. format.json { render json: @transcription.errors, status: :unprocessable_entity }
  12. end
  13. end
  14. end

And here is the most important part, the Active Job called transcription_job.rb:

  1. class TranscriptionJob &lt; ApplicationJob
  2. queue_as :default
  3. require &#39;openai&#39;
  4. def perform(transcription)
  5. # Do something later
  6. client = OpenAI::Client.new(access_token: Rails.application.credentials.dig(:openai, :api_key))
  7. logger.info &quot;SMC DEBUG: OpenAI Key set&quot;
  8. file_path = transcription.audio_file_url
  9. logger.info &quot;SMC DEBUG: Audio file path is: #{file_path}&quot;
  10. response = client.transcribe(
  11. parameters: {
  12. model: &quot;whisper-1&quot;,
  13. file: File.open(file_path, &quot;rb&quot;)
  14. })
  15. logger.info &quot;SMC DEBUG: transcription sent&quot;
  16. # Update the transcription object with the returned text
  17. transcription.transcriptionresult = response[&#39;text&#39;]
  18. logger.info &quot;SMC DEBUG: TranscriptionResult is: #{transcription.transcriptionresult}&quot;
  19. # Save the updated transcription object
  20. transcription.save
  21. end
  22. end

Here is some relevant feedback from the Rails logs for the Action Job:

  1. 15:21:58 web.1 | [ActiveJob] Enqueued ActiveStorage::AnalyzeJob (Job ID: 7b3600ec-ee85-4be6-8faa-18f467fc719a) to Async(default) with arguments: #&lt;GlobalID:0x00000001073c6880 @uri=#&lt;URI::GID gid://transcriptionservice/ActiveStorage::Blob/59&gt;&gt;
  2. 15:21:58 web.1 | [ActiveJob] Enqueued TranscriptionJob (Job ID: 974566f7-7d83-48ee-b3ae-d6f02a006efb) to Async(default) with arguments: #&lt;GlobalID:0x00000001073d7ba8 @uri=#&lt;URI::GID gid://transcriptionservice/Transcription/61&gt;&gt;
  3. 15:21:58 web.1 | Redirected to http://localhost:3000/transcriptions/61
  4. 15:21:58 web.1 | Completed 302 Found in 60ms (ActiveRecord: 13.1ms | Allocations: 24625)
  5. 15:21:58 web.1 |
  6. 15:21:58 web.1 |
  7. 15:21:58 web.1 | Started GET &quot;/transcriptions/61&quot; for ::1 at 2023-05-14 15:21:58 -0400
  8. 15:21:58 web.1 | [ActiveJob] [ActiveStorage::AnalyzeJob] [7b3600ec-ee85-4be6-8faa-18f467fc719a] ActiveStorage::Blob Load (2.2ms) SELECT &quot;active_storage_blobs&quot;.* FROM &quot;active_storage_blobs&quot; WHERE &quot;active_storage_blobs&quot;.&quot;id&quot; = $1 LIMIT $2 [[&quot;id&quot;, 59], [&quot;LIMIT&quot;, 1]]
  9. 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: #&lt;GlobalID:0x0000000107426ac8 @uri=#&lt;URI::GID gid://transcriptionservice/ActiveStorage::Blob/59&gt;&gt;
  10. 15:21:58 web.1 | [ActiveJob] [ActiveStorage::AnalyzeJob] [7b3600ec-ee85-4be6-8faa-18f467fc719a] Disk Storage (0.6ms) Downloaded file from key: 49zqmrx6g54pk1pzuc3y2uyvtiyx
  11. 15:21:58 web.1 | [ActiveJob] [TranscriptionJob] [974566f7-7d83-48ee-b3ae-d6f02a006efb] Transcription Load (0.3ms) SELECT &quot;transcriptions&quot;.* FROM &quot;transcriptions&quot; WHERE &quot;transcriptions&quot;.&quot;id&quot; = $1 LIMIT $2 [[&quot;id&quot;, 61], [&quot;LIMIT&quot;, 1]]
  12. 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: #&lt;GlobalID:0x000000010743ca80 @uri=#&lt;URI::GID gid://transcriptionservice/Transcription/61&gt;&gt;
  13. 15:21:58 web.1 | [ActiveJob] [TranscriptionJob] [974566f7-7d83-48ee-b3ae-d6f02a006efb] SMC DEBUG: OpenAI Key set
  14. 15:21:58 web.1 | Processing by TranscriptionsController#show as TURBO_STREAM
  15. 15:21:58 web.1 | Parameters: {&quot;id&quot;=&gt;&quot;61&quot;}
  16. 15:21:58 web.1 | [ActiveJob] [TranscriptionJob] [974566f7-7d83-48ee-b3ae-d6f02a006efb] ActiveStorage::Attachment Load (7.0ms) SELECT &quot;active_storage_attachments&quot;.* FROM &quot;active_storage_attachments&quot; WHERE &quot;active_storage_attachments&quot;.&quot;record_id&quot; = $1 AND &quot;active_storage_attachments&quot;.&quot;record_type&quot; = $2 AND &quot;active_storage_attachments&quot;.&quot;name&quot; = $3 LIMIT $4 [[&quot;record_id&quot;, 61], [&quot;record_type&quot;, &quot;Transcription&quot;], [&quot;name&quot;, &quot;audio_file&quot;], [&quot;LIMIT&quot;, 1]]
  17. 15:21:58 web.1 | [ActiveJob] [TranscriptionJob] [974566f7-7d83-48ee-b3ae-d6f02a006efb] app/models/transcription.rb:5:in `audio_file_url&#39;
  18. 15:21:58 web.1 | Transcription Load (1.7ms) SELECT &quot;transcriptions&quot;.* FROM &quot;transcriptions&quot; WHERE &quot;transcriptions&quot;.&quot;id&quot; = $1 LIMIT $2 [[&quot;id&quot;, 61], [&quot;LIMIT&quot;, 1]]
  19. 15:21:58 web.1 | ↳ app/controllers/transcriptions_controller.rb:83:in `set_transcription&#39;
  20. 15:21:58 web.1 | Rendering layout layouts/application.html.erb
  21. 15:21:58 web.1 | Rendering transcriptions/show.html.erb within layouts/application
  22. 15:21:58 web.1 | Rendered transcriptions/_transcription.html.erb (Duration: 0.0ms | Allocations: 25)
  23. 15:21:58 web.1 | [ActiveJob] [TranscriptionJob] [974566f7-7d83-48ee-b3ae-d6f02a006efb] ActiveStorage::Blob Load (1.4ms) SELECT &quot;active_storage_blobs&quot;.* FROM &quot;active_storage_blobs&quot; WHERE &quot;active_storage_blobs&quot;.&quot;id&quot; = $1 LIMIT $2 [[&quot;id&quot;, 59], [&quot;LIMIT&quot;, 1]]
  24. 15:21:58 web.1 | Rendered transcriptions/show.html.erb within layouts/application (Duration: 1.1ms | Allocations: 843)
  25. 15:21:58 web.1 | [ActiveJob] [TranscriptionJob] [974566f7-7d83-48ee-b3ae-d6f02a006efb] app/models/transcription.rb:5:in `audio_file_url&#39;
  26. 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.mp3
  27. 15: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):

When I try to put that url in my browser it downloads the correct file.

I have tried to use the following to reference the path instead of the URL:

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

But this gives me a similar error pointing to the path instead of the url:

  1. 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):

I am at a loss for how to address this problem. I would love to find an answer from the brain trust.

答案1

得分: 0

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

  1. class TranscriptionJob &lt; ApplicationJob
  2. queue_as :default
  3. require 'openai'
  4. def perform(transcription)
  5. # 提供openai API密钥并初始化openai客户端的实例
  6. client = OpenAI::Client.new(access_token: Rails.application.credentials.dig(:openai, :api_key))
  7. # 初始化transcriptionresult变量
  8. transcription.transcriptionresult = ''
  9. # 必须首先将文件下载到临时存储位置,然后使用openai API提交。
  10. transcription.audio_file.open do |file|
  11. # 我在应用根目录创建了一个名为“transcribe”的文件夹
  12. system '/tmp/transcribe', file.path
  13. response = client.transcribe(
  14. parameters: {
  15. model: "whisper-1",
  16. file: File.open(file.path, "rb")
  17. })
  18. # 使transcriptionresult等于openai转录产生的response['text']。
  19. transcription.transcriptionresult = response['text']
  20. # 保存更新后的transcription对象
  21. transcription.save
  22. end
  23. end
  24. end
英文:

Thank you for @Chiperific pointing me to this edge guide: https://edgeguides.rubyonrails.org/active_storage_overview.html#downloading-files This helped me to rewrite my code as follows. The key is to download the file to a temporary file location on the system and then point to that local path in the openai API.

  1. class TranscriptionJob &lt; ApplicationJob
  2. queue_as :default
  3. require &#39;openai&#39;
  4. def perform(transcription)
  5. # Provide the openai API key and initialize an instance of the openai client
  6. client = OpenAI::Client.new(access_token: Rails.application.credentials.dig(:openai, :api_key))
  7. # Initialize the transcriptionresult variable
  8. transcription.transcriptionresult = &#39;&#39;
  9. # It is necessary to download the file to temporary storage location first and then submit with the openai API.
  10. transcription.audio_file.open do |file|
  11. # I created a folder in the app root /tmp called “transcribe”
  12. system &#39;/tmp/transcribe&#39;, file.path
  13. response = client.transcribe(
  14. parameters: {
  15. model: &quot;whisper-1&quot;,
  16. file: File.open(file.path, &quot;rb&quot;)
  17. })
  18. # Make the transcriptionresult equal to the response[&#39;text&#39;] produced by the openai transcription.
  19. transcription.transcriptionresult = response[&#39;text&#39;]
  20. # Save the updated transcription object
  21. transcription.save
  22. end
  23. end
  24. end

huangapple
  • 本文由 发表于 2023年5月15日 03:42:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/76249378.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定