API - Permission denied

Hello,

I have a python script that should send out a email. My code starts like this.

import smtplib
from email.mime.text import MIMEText
from seatable_api import Base, context

When I run the script I get following error:

Traceback (most recent call last):
File "index.py", line 33, in <module>
base.auth()
File "/usr/local/lib/python3.7/site-packages/seatable_api/main.py", line 102, in auth
data = parse_response(response)
File "/usr/local/lib/python3.7/site-packages/seatable_api/main.py", line 40, in parse_response
raise ConnectionError(response.status_code, response.text)
ConnectionError: [Errno 403] {"error_msg":"Permission denied."}

What could be the issue and is there a solution?

Many thanks!

Hi @Kanu_Haselhorst.

Seems like you have an authorization problem to SeaTable or to you mail server. It would be esier to tell you more if you’d share more of your script at least until line 33 or a bit further.

This is the whole code. I changed the credentials into placeholders.

import smtplib
from email.mime.text import MIMEText
from seatable_api import Base, context

# Define your SMTP server information
SMTP_SERVER = 'xxx'
SMTP_PORT = 587
SMTP_USERNAME = 'xxx'
SMTP_PASSWORD = 'xxx'

# Define your email subject and message
EMAIL_SUBJECT = 'Test Betreff'

# Define the email message template with placeholders for the column values
EMAIL_MESSAGE = '''
<html>
<head></head>
<body>
    <p>Hello,</p>
    <p>Deine Wahl-ID ist {Wahl ID}.</p>
</body>
</html>
'''

# Define the server URL, base ID, table name, and view name
SERVER_URL = 'https://cloud.seatable.io'
BASE_ID = '123'
TABLE_NAME = 'TestEmail'
VIEW_NAME = 'Default View'

# Connect to your SeaTable base
base = Base(BASE_ID, server_url=SERVER_URL)
base.auth()

# Get the view ID
view_id = base.get_view_id(TABLE_NAME, VIEW_NAME)

# Get the column indexes for the email, name, doctor, date, and time columns
email_column_index = base.get_column_index(TABLE_NAME, 'email')
name_column_index = base.get_column_index(TABLE_NAME, 'Wahl ID')
doctor_column_index = base.get_column_index(TABLE_NAME, 'doctor')
date_column_index = base.get_column_index(TABLE_NAME, 'date')
time_column_index = base.get_column_index(TABLE_NAME, 'time')

# Get the rows in the view
view_rows = base.list_rows(TABLE_NAME, view_name=VIEW_NAME)

# Create a set to store unique email addresses
unique_emails = set()

# Loop through the rows in the view and add the email address to the set
for row in view_rows:
    email_address = row[email_column_index]
    unique_emails.add(email_address)

# Loop through the unique email addresses and send the email to each address
for email_address in unique_emails:
    # Get the rows with the current email address
    email_rows = base.filter(TABLE_NAME, formula=f"{email_column_index}='{email_address}'")
    
    # Loop through the rows with the current email address and get the column values
    for row in email_rows:
        name = row[name_column_index]
        doctor = row[doctor_column_index]
        date = row[date_column_index]
        time = row[time_column_index]
        
        # Format the email message with the column values
        email_message = EMAIL_MESSAGE.format(name=name, doctor=doctor, date=date, time=time)

        # Create a MIMEText object with the formatted email message and set the subtype to 'html'
        msg = MIMEText(email_message, 'html')
        
        # Set the email message headers
        msg['Subject'] = EMAIL_SUBJECT
        msg['From'] = SMTP_USERNAME
        msg['To'] = email_address

        # Send the email using SMTP
        smtp_obj = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
        smtp_obj.ehlo()
        smtp_obj.starttls()
        smtp_obj.login(SMTP_USERNAME, SMTP_PASSWORD)
        smtp_obj.sendmail(SMTP_USERNAME, [email_address], msg.as_string())
        smtp_obj.quit()

For me it seems like you are using wrong credential data to the SeaTable cloud. The base id, by telling from the name itself, isn’t working as authentication.

# Define the server URL, base ID, table name, and view name
SERVER_URL = 'https://cloud.seatable.io'
BASE_ID = '123'
TABLE_NAME = 'TestEmail'
VIEW_NAME = 'Default View'

# Connect to your SeaTable base
base = Base(BASE_ID, server_url=SERVER_URL)
base.auth()

You can create one api key here…

grafik

I changed it to this, but still getting Permission denied. Maybe it’s because I am using the SeaTable community edition?

# Define the server URL, base ID, table name, and view name
API_KEY = 'xxx'
SERVER_URL = 'https://cloud.seatable.io'
BASE_ID = 'xxx'
TABLE_NAME = 'TestEmail'
VIEW_NAME = 'Default View'

I don’t know. This can be answered by someone from the team.

Btw… if you run it from the SeaTable UI you should rather use the following code. But then it is required to save the script in the same base as the tables are in though.

server_url = context.server_url
api_token = context.api_token
base = Base(api_token, server_url)
base.auth()

@AkDk7 has given a lot of good tips.

I see one more issue here: SeaTable’s python runner does not come with a ton of preinstalled python module. You may need to install smtplib. For more info, see here: Customization - SeaTable Admin Manual

1 Like

Hey Just check whether you have installed all the required libraries if not the do it may be your issue get resolved after that, just checked that all necessary libraries are pre installed in your system or not.