Aws Lambda function API Gateway working fine in AWS but not in Postman or other platforms

228 Views Asked by At

I have developed a python code where account details of bank user are stored as well as transactions happen between users and sub users. I want to integrate it to IBM Watson Assistant through webhook. I have used AWS Lambda function to develop the code and have tested in AWS cloud which is working fine but, once I test in Postman its only throwing me the else condition error as "{"error": "Invalid transaction type. Please provide a valid 'transaction_type'."}". But I have given proper input credentials like this: { "input_json": { "transaction_type": "self_transfer", "user_name": "Vivek kaushal", "amount": 100 } }

Here's the code:

import json
import boto3

s3 = boto3.resource(service_name='s3',
                    region_name='ap-south-1',
                    aws_access_key_id="*****************",
                    aws_secret_access_key="******************************")

bucket_name = 'bank.users'
file_key = 'user_details.json'


def get_file_object():
    try:
        obj = s3.Object(bucket_name, file_key)
        file_content = obj.get()['Body'].read().decode('utf-8')
        file_obj = json.loads(file_content)
        return file_obj
    except Exception as e:
        print(f"Error loading file from S3: {str(e)}")
        return None


def save_file_object(file_obj):
    try:
        obj = s3.Object(bucket_name, file_key)
        obj.put(Body=json.dumps(file_obj))
    except Exception as e:
        print(f"Error saving file to S3: {str(e)}")


def transfer_money_within_user(args):
    # Load the data from the JSON file
    file_obj = get_file_object()
    if file_obj is None:
        return {
            'error': "Failed to load user details from S3."
        }

    user_name = args.get('user_name')
    sub_user_name = args.get('sub_user_name')
    amount = args.get('amount')

    # Search for the user and sub user
    for user in file_obj['users']:
        if user['user_name'] == user_name:
            sub_users = user.get('sub_users', [])
            # Search for the sub user based on the name
            for sub_user in sub_users:
                if sub_user['sub_user_name'] == sub_user_name:
                    user_balance = user['bank_details']['balance']
                    # Check if the user has sufficient balance
                    if user_balance >= amount:
                        # Update the sub user balance
                        sub_user['bank_details']['balance'] += amount

                        # Update the user balance
                        user['bank_details']['balance'] -= amount

                        # Save the updated data to S3
                        save_file_object(file_obj)

                        # Return the updated data as a JSON response
                        return {
                            'message': f"Money transferred successfully from user '{user_name}' to sub user '{sub_user_name}'.",
                            'remaining_balance': user['bank_details']['balance']
                        }
                    else:
                        return {
                            'error': f"Insufficient balance in user '{user_name}' to transfer the amount.",
                            'current_balance': user['bank_details']['balance']
                        }

            # If sub user not found, ask if the user wants to add a new sub user
            return {
                'error': "Sub user not found. Do you want to add a new sub user?",
                'add_new_sub_user': True
            }

    # If user not found, return an error message
    return {
        'error': f"No user found with the name '{user_name}'."
    }


def transfer_money_between_users(args):
    # Load the data from the JSON file
    file_obj = get_file_object()
    if file_obj is None:
        return {
            'error': "Failed to load user details from S3."
        }

    sender_user_name = args.get('sender_user_name')
    recipient_user_name = args.get('recipient_user_name')
    amount = args.get('amount')

    # Search for the sender user and recipient user
    sender_user = None
    recipient_user = None

    for user in file_obj['users']:
        if user['user_name'] == sender_user_name:
            sender_user = user
        elif user['user_name'] == recipient_user_name:
            recipient_user = user

    # Check if both sender user and recipient user are found
    if sender_user and recipient_user:
        sender_user_balance = sender_user['bank_details']['balance']

        # Check if the sender user has sufficient balance
        if sender_user_balance >= amount:
            # Update the sender user balance
            sender_user['bank_details']['balance'] -= amount

            # Update the recipient user balance
            recipient_user['bank_details']['balance'] += amount

            # Save the updated data to S3
            save_file_object(file_obj)

            # Return the updated data as a JSON response
            return {
                'message': f"Money transferred successfully from user '{sender_user_name}' to user '{recipient_user_name}'.",
                'remaining_balance': sender_user['bank_details']['balance']
            }
        else:
            # If sender user does not have sufficient balance, return an error message
            return {
                'error': f"Insufficient balance in user '{sender_user_name}' to transfer the amount.",
                'current_balance': sender_user['bank_details']['balance']
            }
    else:
        # If either sender user or recipient user is not found, return an error message
        error_msg = ""
        if not sender_user:
            error_msg += f"No sender user found with the name '{sender_user_name}'.\n"
        if not recipient_user:
            error_msg += f"No recipient user found with the name '{recipient_user_name}'.\n"
        return {
            'error': error_msg.strip()
        }


def transfer_money_to_self(args):
    # Load the data from the JSON file
    file_obj = get_file_object()
    if file_obj is None:
        return {
            'error': "Failed to load user details from S3."
        }

    user_name = args.get('user_name')
    amount = args.get('amount')

    # Search for the user
    for user in file_obj['users']:
        if user['user_name'] == user_name:
            user_balance = user['bank_details']['balance']
            # Check if the user has sufficient balance
            if user_balance >= amount:
                # Update the user balance
                user['bank_details']['balance'] -= amount

                # Save the updated data to S3
                save_file_object(file_obj)

                # Return the updated data as a JSON response
                return {
                    'message': f"Money transferred successfully from user '{user_name}' to itself.",
                    'remaining_balance': user['bank_details']['balance']
                }
            else:
                return {
                    'error': f"Insufficient balance in user '{user_name}' to transfer the amount.",
                    'current_balance': user['bank_details']['balance']
                }

    # If user not found, return an error message
    return {
        'error': f"No user found with the name '{user_name}'."
    }





def lambda_handler(event, context):
    input_json = event.get('input_json', {})
    transaction_type = str(input_json.get('transaction_type'))

    if transaction_type == 'user':
        sender_user_name = str(input_json.get('sender_user_name'))
        recipient_user_name = str(input_json.get('recipient_user_name'))
        amount = float(input_json.get('amount'))

        # Invoke the transfer_money_between_users function with the parameters
        result = transfer_money_between_users({
            'sender_user_name': sender_user_name,
            'recipient_user_name': recipient_user_name,
            'amount': amount
        })

    elif transaction_type == 'sub_user':
        user_name = str(input_json.get('user_name'))
        sub_user_name = str(input_json.get('sub_user_name'))
        amount = float(input_json.get('amount'))

        # Invoke the transfer_money_within_user function with the parameters
        result = transfer_money_within_user({
            'user_name': user_name,
            'sub_user_name': sub_user_name,
            'amount': amount
        })

    elif transaction_type == 'add_sub_user':
        user_name = str(input_json.get('user_name'))
        sub_user_name = str(input_json.get('sub_user_name'))
        balance = float(input_json.get('balance', 0))
        account_number = str(input_json.get('account_number'))
        mobile_number = str(input_json.get('mobile_number'))
        bank = str(input_json.get('bank'))
        ifsc_code = str(input_json.get('ifsc_code'))

        # Load the data from the JSON file
        file_obj = get_file_object()
        if file_obj is None:
            return {
                'statusCode': 500,
                'body': json.dumps({
                    'error': "Failed to load user details from S3."
                })
            }

        # Search for the user based on the name
        for user in file_obj['users']:
            if user['user_name'] == user_name:
                sub_users = user.get('sub_users', [])
                # Check if the sub user already exists
                if any(sub_user['sub_user_name'] == sub_user_name for sub_user in sub_users):
                    return {
                        'statusCode': 400,
                        'body': json.dumps({
                            'error': f"Sub user '{sub_user_name}' already exists for user '{user_name}'."
                        })
                    }
                else:
                    # Add the new sub user with bank details
                    new_sub_user = {
                        'sub_user_name': sub_user_name,
                        'bank_details': {
                            'balance': balance,
                            'account_number': account_number,
                            'mobile_number': mobile_number,
                            'bank': bank,
                            'ifsc_code': ifsc_code
                        }
                    }
                    sub_users.append(new_sub_user)

                    # Save the updated data to S3
                    save_file_object(file_obj)

                    return {
                        'statusCode': 200,
                        'body': json.dumps({
                            'message': f"New sub user '{sub_user_name}' added for user '{user_name}' with balance {balance}."
                        })
                    }

        # If user not found, return an error message
        return {
            'statusCode': 404,
            'body': json.dumps({
                'error': f"No user found with the name '{user_name}'."
            })
        }

    elif transaction_type == 'self_transfer':
        user_name = str(input_json.get('user_name'))
        amount = float(input_json.get('amount'))

        # Invoke the transfer_money_to_self function with the parameters
        result = transfer_money_to_self({
            'user_name': user_name,
            'amount': amount
        })

    else:
        return {
            'statusCode': 400,
            'body': json.dumps({
                'error': "Invalid transaction type. Please provide a valid 'transaction_type'."
            })
        }

    return {
        'statusCode': 200,
        'body': json.dumps(result)
    }

enter image description here error:{"error": "Invalid transaction type. Please provide a valid 'transaction_type'."}

1

There are 1 best solutions below

0
PeeKay On

One possibility that I came across is when the event object you're trying to access isn't valid JSON. This happens when you try to grab values from the event without doing something like json.dumps(event) or json.loads(event).

To debug this, add print(event) to in the 1st line of your function handler to see the event that comes in when invoking through postman.

Then based on this, you may see that there is not valid JSON within the 'event' object. To make is valid json, do something like new_event = json.dumps(event)

Needless to say, adding print(event) and other log statements would be your friend here when debugging.