Python API file upload to CODA

Hey Everyone,

I am trying to upload files to coda through an API automation. The idea is when you press a button in my python application it sends all the data to coda. It will make a new row, put in all the text data and then use that row-id to upload the files to their columns. The columns are file type columns and the files will be CSV. However every time I try it it gives me the 404 error of not found. Even if I put in delays so the coda has time to actually make the row. I have been testing it out with a smaller code to figure out how it works, this is my code:

import requests
import os
import time

# Replace these with your actual values
doc_id = 'YOUR_DOC_ID'
table_id = 'YOUR_TABLE_ID
column_name = 'File'  # Column name where the file will be uploaded
api_key = 'YOUR_API_TOKEN'
file_path = 'test 3.csv'

# Set the Coda API base URL and headers
base_url = "https://coda.io/apis/v1"
headers = {
    "Authorization": f"Bearer {api_key}",
    "Content-Type": "application/json"
}


def create_row_in_coda(doc_id, table_id):
    """Create a new row in the specified Coda table"""
    url = f"{base_url}/docs/{doc_id}/tables/{table_id}/rows"
    data = {
        "rows": [
            {
                "cells": [
                    {"column": "SKU Code", "value": "New Order"},  # Example data for the new row
                    {"column": "Version Code", "value": "V2"}
                ]
            }
        ]
    }

    response = requests.post(url, headers=headers, json=data)

    # Check for 202 status code, which is correct for Coda write operations
    if response.status_code == 202:
        row_data = response.json()
        # Extract row ID from the addedRowIds field
        if 'addedRowIds' in row_data and len(row_data['addedRowIds']) > 0:
            row_id = row_data['addedRowIds'][0]
            print(f"Created a new row with ID: {row_id}")
            return row_id
        else:
            print("Row was created but couldn't find row ID in response")
            print(response.text)
            return None
    else:
        print(f"Error creating row: {response.status_code}")
        print(response.text)
        return None


def upload_csv_to_coda(doc_id, table_id, column_name, file_path):
    try:
        # Create a new row
        row_id = create_row_in_coda(doc_id, table_id)
        if not row_id:
            return False

        # IMPORTANT: Wait longer for row to be processed
        print("Waiting for row to be processed...")
        time.sleep(15)  # Increased wait time

        # Get column ID
        columns_url = f"{base_url}/docs/{doc_id}/tables/{table_id}/columns"
        response = requests.get(columns_url, headers=headers)

        if response.status_code != 200:
            print(f"Failed to fetch columns: {response.status_code} - {response.text}")
            return False

        columns_data = response.json()
        column_id = None

        for column in columns_data.get('items', []):
            if column.get('name') == column_name:
                column_id = column.get('id')
                break

        if not column_id:
            print(f"Error: Column '{column_name}' not found.")
            return False

        # REVISED: Use the cells endpoint instead of attachments
        upload_url = f"{base_url}/docs/{doc_id}/tables/{table_id}/rows/{row_id}/cells/{column_id}"

        # Clean headers for upload
        upload_headers = {
            "Authorization": f"Bearer {api_key}"
        }

        if not os.path.exists(file_path):
            print(f"Error: File {file_path} does not exist.")
            return False

        with open(file_path, 'rb') as file_data:
            files = {
                'file': (os.path.basename(file_path), file_data, 'application/octet-stream')
            }
            response = requests.put(upload_url, headers=upload_headers, files=files)

        if response.status_code in [200, 202]:
            print(f"Successfully uploaded CSV to column '{column_name}' (ID: {column_id})")
            return True
        else:
            print(f"Error uploading CSV: {response.status_code}")
            print(response.text)
            return False

    except Exception as e:
        print(f"Exception occurred: {e}")
        return False


# Run the test upload function with the actual file
upload_csv_to_coda(doc_id, table_id, column_name, file_path)

I also tried to upload to an already existing row, to check if that would work, but I also get the 404 not found error. Does anybody know how to make this work?

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.