S3 bucket RAR file extraction using Python script and AWS Lambda

Please write a python script for when a user wants to extracting a particular existing rar file stored in an S3 bucket and stored in the same bucket as a folder using lambda function

If you need code written consider hiring a consultant.

If you have written code yourself we can give advice on problems you are encountering.

2 Likes

Hi Barry,
Thanks for your reply.

I have written a Python script and pasted it here:

type or paste code here

import os
import boto3
import rarfile
import tempfile

# Create an S3 client
s3 = boto3.client(‘s3’)

def lambda_handler(event, context):

  • Specify the bucket name and the key of the RAR file*

  • bucket_name = ‘testrarbucket’*
  • rar_file_key = ‘Scripts.rar’*
  • Specify the folder where you want to store the extracted contents*

  • output_folder = ‘extracted rar data//’*
  • try:*
  •    # Create a temporary directory to extract the files*
    
  •    temp_dir = tempfile.mkdtemp()*
    
  •    *
    
  •    # Download the RAR file from S3 to the temporary directory*
    
  •    rar_file_path = os.path.join(temp_dir, 'file.rar')*
    
  •    s3.download_file(bucket_name, rar_file_key, rar_file_path)*
    
  •    *
    
  •    # Extract the contents of the RAR file*
    
  •    with rarfile.RarFile(rar_file_path, 'r') as rar_ref:*
    
  •        rar_ref.extractall(os.path.join(temp_dir, output_folder))*
    
  •    *
    
  •    # Upload the extracted files back to the same S3 bucket*
    
  •    for root, dirs, files in os.walk(os.path.join(temp_dir, output_folder)):*
    
  •        for file in files:*
    
  •            local_file_path = os.path.join(root, file)*
    
  •            s3_key = os.path.relpath(local_file_path, temp_dir)*
    
  •            s3.upload_file(local_file_path, bucket_name, s3_key)*
    
  •    *
    
  • except Exception as e:*
  •    print("Error:", e)*
    
  •    raise e*
    
  •    *
    
  • finally:*
  •    # Clean up: Delete the temporary directory and files*
    
  •    if os.path.exists(temp_dir):*
    
  •        for root, dirs, files in os.walk(temp_dir, topdown=False):*
    
  •            for file in files:*
    
  •                file_path = os.path.join(root, file)*
    
  •                os.remove(file_path)*
    
  •            for dir in dirs:*
    
  •                dir_path = os.path.join(root, dir)*
    
  •                os.rmdir(dir_path)*
    
  •        os.rmdir(temp_dir)*
    

An error message appears when I use this code in a lambda function.

Test Event Name
test

Response
{
“errorMessage”: “Cannot find working tool”,
“errorType”: “RarCannotExec”,
“requestId”: “cb67c127-fa9f-4264-bb68-98ae31af1fc8”,
“stackTrace”: [
" File "/var/task/lambda_function.py", line 38, in lambda_handler\n raise e\n",
" File "/var/task/lambda_function.py", line 27, in lambda_handler\n rar_ref.extractall(os.path.join(temp_dir, output_folder))\n",
" File "/opt/python/rarfile.py", line 875, in extractall\n dst = self._extract_one(inf, path, pwd, not inf.is_dir())\n",
" File "/opt/python/rarfile.py", line 940, in _extract_one\n return self._make_file(info, dstfn, pwd, set_attrs)\n",
" File "/opt/python/rarfile.py", line 953, in _make_file\n with self.open(info, "r", pwd) as src:\n",
" File "/opt/python/rarfile.py", line 811, in open\n return self._file_parser.open(inf, pwd)\n",
" File "/opt/python/rarfile.py", line 1278, in open\n return self._open_hack(inf, pwd)\n",
" File "/opt/python/rarfile.py", line 2156, in _open_hack\n return self._open_hack_core(inf, pwd, RAR5_ID + main_hdr, endarc_hdr)\n",
" File "/opt/python/rarfile.py", line 1318, in _open_hack_core\n return self._open_unrar(tmpname, inf, pwd, tmpname)\n",
" File "/opt/python/rarfile.py", line 1329, in _open_unrar\n setup = tool_setup()\n",
" File "/opt/python/rarfile.py", line 3474, in tool_setup\n raise RarCannotExec("Cannot find working tool")\n"
]
}

Please fix the code and output to be preformatted text by selecting the text and clicking the </> button. It will surround the text with backquotes.
E.g. like this as you edit:

```
    Code here
```

This preserves the indentation etc of the code.

Hi Barry,
Please find my python code here:

import os
import boto3
import rarfile
import tempfile

# Create an S3 client
s3 = boto3.client('s3')

def lambda_handler(event, context):
    # Specify the bucket name and the key of the RAR file
    bucket_name = 'testrarbucket'
    rar_file_key = 'Scripts.rar'
    
    # Specify the folder where you want to store the extracted contents
    output_folder = 'extracted rar data//'
    
    try:
        # Create a temporary directory to extract the files
        temp_dir = tempfile.mkdtemp()
        
        # Download the RAR file from S3 to the temporary directory
        rar_file_path = os.path.join(temp_dir, 'file.rar')
        s3.download_file(bucket_name, rar_file_key, rar_file_path)
        
        # Extract the contents of the RAR file
        with rarfile.RarFile(rar_file_path, 'r') as rar_ref:
            rar_ref.extractall(os.path.join(temp_dir, output_folder))
        
        # Upload the extracted files back to the same S3 bucket
        for root, dirs, files in os.walk(os.path.join(temp_dir, output_folder)):
            for file in files:
                local_file_path = os.path.join(root, file)
                s3_key = os.path.relpath(local_file_path, temp_dir)
                s3.upload_file(local_file_path, bucket_name, s3_key)
        
    except Exception as e:
        print("Error:", e)
        raise e
        
    finally:
        # Clean up: Delete the temporary directory and files
        if os.path.exists(temp_dir):
            for root, dirs, files in os.walk(temp_dir, topdown=False):
                for file in files:
                    file_path = os.path.join(root, file)
                    os.remove(file_path)
                for dir in dirs:
                    dir_path = os.path.join(root, dir)
                    os.rmdir(dir_path)
            os.rmdir(temp_dir)

and error like i get

Test Event Name
test

Response
{
  "errorMessage": "Cannot find working tool",
  "errorType": "RarCannotExec",
  "requestId": "722f0d42-1c50-4174-a747-a6c83d68d57c",
  "stackTrace": [
    "  File \"/var/task/lambda_function.py\", line 38, in lambda_handler\n    raise e\n",
    "  File \"/var/task/lambda_function.py\", line 27, in lambda_handler\n    rar_ref.extractall(os.path.join(temp_dir, output_folder))\n",
    "  File \"/opt/python/rarfile.py\", line 875, in extractall\n    dst = self._extract_one(inf, path, pwd, not inf.is_dir())\n",
    "  File \"/opt/python/rarfile.py\", line 940, in _extract_one\n    return self._make_file(info, dstfn, pwd, set_attrs)\n",
    "  File \"/opt/python/rarfile.py\", line 953, in _make_file\n    with self.open(info, \"r\", pwd) as src:\n",
    "  File \"/opt/python/rarfile.py\", line 811, in open\n    return self._file_parser.open(inf, pwd)\n",
    "  File \"/opt/python/rarfile.py\", line 1278, in open\n    return self._open_hack(inf, pwd)\n",
    "  File \"/opt/python/rarfile.py\", line 2156, in _open_hack\n    return self._open_hack_core(inf, pwd, RAR5_ID + main_hdr, endarc_hdr)\n",
    "  File \"/opt/python/rarfile.py\", line 1318, in _open_hack_core\n    return self._open_unrar(tmpname, inf, pwd, tmpname)\n",
    "  File \"/opt/python/rarfile.py\", line 1329, in _open_unrar\n    setup = tool_setup()\n",
    "  File \"/opt/python/rarfile.py\", line 3474, in tool_setup\n    raise RarCannotExec(\"Cannot find working tool\")\n"
  ]
}

Sorry for the delay in answering.

It seems that you are missing a supported backend that the rarfile package depends on.
See the docs here that talk about the backends: rarfile · PyPI