diff --git a/helpers/requirements.txt b/helpers/requirements.txt
new file mode 100644
index 0000000..cfbb471
--- /dev/null
+++ b/helpers/requirements.txt
@@ -0,0 +1,22 @@
+cachetools==5.3.3
+certifi==2024.2.2
+charset-normalizer==3.3.2
+google-api-core==2.17.1
+google-api-python-client==2.120.0
+google-auth==2.28.1
+google-auth-httplib2==0.2.0
+googleapis-common-protos==1.62.0
+httplib2==0.22.0
+idna==3.6
+isodate==0.6.1
+protobuf==4.25.3
+pyasn1==0.5.1
+pyasn1-modules==0.3.0
+pyparsing==3.1.1
+python-dotenv==1.0.1
+requests==2.31.0
+rsa==4.9
+six==1.16.0
+uritemplate==4.1.1
+urllib3==2.2.1
+youtube-transcript-api==0.6.2
diff --git a/helpers/vm b/helpers/vm
index cc19d21..2aa1210 100755
--- a/helpers/vm
+++ b/helpers/vm
@@ -1,28 +1,30 @@
 #!/usr/bin/env python3
 
-import sys
+import argparse
+import json
+import os
 import re
+
+import isodate
+from dotenv import load_dotenv
 from googleapiclient.discovery import build
 from googleapiclient.errors import HttpError
 from youtube_transcript_api import YouTubeTranscriptApi
-from dotenv import load_dotenv
-import os
-import json
-import isodate
-import argparse
+
 
 def get_video_id(url):
     # Extract video ID from URL
-    pattern = r'(?:https?:\/\/)?(?:www\.)?(?:youtube\.com\/(?:[^\/\n\s]+\/\S+\/|(?:v|e(?:mbed)?)\/|\S*?[?&]v=)|youtu\.be\/)([a-zA-Z0-9_-]{11})'
+    pattern = r"(?:https?:\/\/)?(?:www\.)?(?:youtube\.com\/(?:[^\/\n\s]+\/\S+\/|(?:v|e(?:mbed)?)\/|\S*?[?&]v=)|youtu\.be\/)([a-zA-Z0-9_-]{11})"
     match = re.search(pattern, url)
     return match.group(1) if match else None
 
+
 def main(url, options):
     # Load environment variables from .env file
-    load_dotenv(os.path.expanduser('~/.config/fabric/.env'))
+    load_dotenv(os.path.expanduser("~/.config/fabric/.env"))
 
     # Get YouTube API key from environment variable
-    api_key = os.getenv('YOUTUBE_API_KEY')
+    api_key = os.getenv("YOUTUBE_API_KEY")
     if not api_key:
         print("Error: YOUTUBE_API_KEY not found in ~/.config/fabric/.env")
         return
@@ -35,26 +37,25 @@ def main(url, options):
 
     try:
         # Initialize the YouTube API client
-        youtube = build('youtube', 'v3', developerKey=api_key)
+        youtube = build("youtube", "v3", developerKey=api_key)
 
         # Get video details
-        video_response = youtube.videos().list(
-            id=video_id,
-            part='contentDetails'
-        ).execute()
+        video_response = (
+            youtube.videos().list(id=video_id, part="contentDetails").execute()
+        )
 
         # Extract video duration and convert to minutes
-        duration_iso = video_response['items'][0]['contentDetails']['duration']
+        duration_iso = video_response["items"][0]["contentDetails"]["duration"]
         duration_seconds = isodate.parse_duration(duration_iso).total_seconds()
         duration_minutes = round(duration_seconds / 60)
 
         # Get video transcript
         try:
             transcript_list = YouTubeTranscriptApi.get_transcript(video_id)
-            transcript_text = ' '.join([item['text'] for item in transcript_list])
-            transcript_text = transcript_text.replace('\n', ' ')
+            transcript_text = " ".join([item["text"] for item in transcript_list])
+            transcript_text = transcript_text.replace("\n", " ")
         except Exception as e:
-            transcript_text = "Transcript not available."
+            transcript_text = f"Transcript not available: {e}"
 
         # Output based on options
         if options.duration:
@@ -63,24 +64,29 @@ def main(url, options):
             print(transcript_text)
         else:
             # Create JSON object
-            output = {
-                "transcript": transcript_text,
-                "duration": duration_minutes
-            }
+            output = {"transcript": transcript_text, "duration": duration_minutes}
             # Print JSON object
             print(json.dumps(output))
     except HttpError as e:
-        print("Error: Failed to access YouTube API. Please check your YOUTUBE_API_KEY and ensure it is valid.")
+        print(
+            f"Error: Failed to access YouTube API. Please check your YOUTUBE_API_KEY and ensure it is valid. {e}"
+        )
+
 
-if __name__ == '__main__':
-    parser = argparse.ArgumentParser(description='vm (video meta) extracts metadata about a video, such as the transcript and the video\'s duration. By Daniel Miessler.')
-    parser.add_argument('url', nargs='?', help='YouTube video URL')
-    parser.add_argument('--duration', action='store_true', help='Output only the duration')
-    parser.add_argument('--transcript', action='store_true', help='Output only the transcript')
+if __name__ == "__main__":
+    parser = argparse.ArgumentParser(
+        description="vm (video meta) extracts metadata about a video, such as the transcript and the video's duration. By Daniel Miessler."
+    )
+    parser.add_argument("url", nargs="?", help="YouTube video URL")
+    parser.add_argument(
+        "--duration", action="store_true", help="Output only the duration"
+    )
+    parser.add_argument(
+        "--transcript", action="store_true", help="Output only the transcript"
+    )
     args = parser.parse_args()
 
     if args.url:
         main(args.url, args)
     else:
         parser.print_help()
-