I want to update/ insert items through API

Dear Team
I want to insert a new row correctly, and without deleting or overwriting the existing rows through the API for each API.
Here my code

@frappe.whitelist()
def update_inv(item_code=None, erp_inv_name=None):
url = f"http://xxxxxxx/api/resource/Sales Invoice/{erp_inv_name}"
headers = {
“Authorization”: “Basic xxxxxxxxxxxxxx”,
“Content-Type”: “application/json”,
“Cookie”: “sid=Guest”
}

# Fetch the existing data
response = requests.get(url, headers=headers)
existing_data = response.json()

# Retrieve the existing items
existing_items = existing_data.get("items", [])

# Create a new item with the provided item_code
new_item = {"item_code": item_code}

# Append the new item to the existing items
existing_items.append(new_item)

# Update the data with the new items
existing_data["items"] = existing_items

# Send the updated data in a PUT request
response = requests.put(url, headers=headers, data=json.dumps(existing_data))

print(response.text)

erp_inv_name = “{erp_inv_name}”
Item_code = “{item_code}”

update_inv(item_code=item_code, erp_inv_name=erp_inv_name)

new my code not working
plz help me

@frappe.whitelist()
def update_inv(item_code=None):
url = f"http://xxxxxxxx/api/resource/Sales Invoice/MP-SINV-2023-00004"
headers = {
“Authorization”: “Basic xxxxxxxxxxxxx”,
“Content-Type”: “application/json”,
“Cookie”: “sid=Guest”
}

# Fetch the existing data
response = requests.get(url, headers=headers)
existing_data = response.json()

# Retrieve the existing items
existing_items = existing_data.get("items", [])

# Find the first empty row index
empty_row_idx = None
for idx, item in enumerate(existing_items):
    if not item.get("item_code"):
        empty_row_idx = idx
        break

# Check if there is an empty row
if empty_row_idx is not None:
    # Update the empty row with the new item_code
    existing_items[empty_row_idx]["item_code"] = item_code
else:
    # Create a new item with the item_code
    new_item = {"item_code": item_code}

    # Insert the new item at the end of the list
    existing_items.append(new_item)

# Update the data with the updated items
existing_data["items"] = existing_items

# Send the updated data in a PUT request
response = requests.put(url, headers=headers, data=json.dumps(existing_data))

if response.status_code == 200:
    print("Data successfully written to the database.")
else:
    print(f"Failed to write data to the database. Response: {response.text}")

item_code = “{item_code}”

update_inv(item_code=item_code)

Hi @msiam,

Your code looks mostly correct.
is there any issue?

Dear NCP
my issue, the records did not write on the database

Hmm :thinking:,

Verify that the authentication credentials (Authorization header) are correct and have the necessary permissions. Double-check the URL and endpoint used for the API request to ensure they are accurate. Make sure the item_code value being passed to the update_inv function is valid and exists. Check the response object from the requests.put method for any error messages or status codes indicating the reason for the failure. Print response.text to inspect the response content. Add print statements at different stages of the code to identify any issues. Print existing_data and existing_items to confirm their values before sending the PUT request.

Thanks!

everything is ok
but the records not writing in DB

@msiam How about you try something like this…

import json

import frappe
from frappe import _, _dict
from frappe.utils import get_request_session


@frappe.whitelist()
def update_inv(item_code=None):
    url = "http://xxxxxxxx/api/resource/Sales Invoice/MP-SINV-2023-00004"
    
    # Fetch the existing data
    response = request(url)
    
    if "error" in response:
        print("Failed to get data.")
        return 0
    
    # Retrieve the existing items
    existing_items = response.data.get("items", [])
    
    # Find the first empty row index
    empty_row_idx = None
    for idx, item in enumerate(existing_items):
        if not item.get("item_code"):
            empty_row_idx = idx
            break
    
    # Check if there is an empty row
    if empty_row_idx is not None:
        # Update the empty row with the new item_code
        existing_items[empty_row_idx]["item_code"] = item_code
    else:
        # Create a new item with the item_code
        new_item = {"item_code": item_code}
    
        # Insert the new item at the end of the list
        existing_items.append(new_item)
    
    # Update the data with the updated items
    existing_data["items"] = existing_items
    
    # Send the updated data in a PUT request
    response = request(ur, existing_data)
    
    if "error" in response:
        print(f"Failed to write data to the database. Status: {to_json(response.data, "")}")
    else:
        print("Data successfully written to the database.")


def request(url, data=None, method=None):
    _headers = {
        "Authorization": "Basic xxxxxxxxxxxxx",
        "Content-Type": "application/json",
        "Cookie": "sid=Guest"
    }
    _data = to_json(data) if isinstance(data, dict) else None
    _method = method or ("PUT" if _data else "GET")
    
    try:
        request = get_request_session().request(
            _method, url, data=_data, headers=_headers
        )
        status_code = request.status_code
        response = request.json()
    except Exception as exc:
        frappe.throw(_("Unable to send the request"))
    
    response = parse_json(response)
    data = _dict({"data": response, "status": status_code})
    
    if status_code != 200 and status_code != 201:
        data["error"] = True
    
    return data


def parse_json(data, default=None):
    if not isinstance(data, str):
        return data
    if default is None:
        default = data
    try:
        return json.loads(data)
    except Exception:
        return default


def to_json(data, default=None):
    if isinstance(data, str):
        return data
    if default is None:
        default = data
    try:
        return json.dumps(data)
    except Exception:
        return default