Files¶
Download¶
For the following methods, you'll have to provide the URL of the file you want to download. The file URL structure is as follows:
-
{server_url}is the URL of your server, for examplehttps://cloud.seatable.io -
You can find the
workspace_idby looking at any of your database URL which will look like{server_url}/workspace/{workspace_id}/dtable/{base_name}, or by checking the user manual -
You can find the base uuid in your Team administration (see the User manual, it's displayed as
IDin the base right panel) or by looking fordtableUuidin the source code of the web page while consulting any of your bases -
The file location is what you can find in the file manager of your base and will always have the same structure:
- if uploaded automatically, the file will be in the system folder
files(if uploaded in a file-type column, even if it's an image) and in the subdirectoryYYYY-MM(year and month of the upload), for examplehttps://cloud.seatable.io/dtable-web/workspace/74/asset-preview/41cd05da-b29a-4428-bc31-bd66f4600817/files/2020-10/invoice.pdfis the URL of a file called invoice.pdf and downloaded in October 2020 (2020-10) in the base whose uuid is41cd05da-b29a-4428-bc31-bd66f4600817in the workspace whose id is74onhttps://cloud.seatable.io. It will be the same for an image, but in theimagessystem folder instead of thefilesfolder (if uploaded in an image-type column only) - if uploaded by yourself in a custom folder, the file will be in directory
customand in the eventual directory you created, for example:https://cloud.seatable.io/dtable-web/workspace/74/asset-preview/41cd05da-b29a-4428-bc31-bd66f4600817/custom/My Personal Folder/quote.pdfis the URL of a file called quote.pdf that you stored in the folderMy Personal Folderof the custom folders in the same database.
- if uploaded automatically, the file will be in the system folder
Get easily the file URL
For files that need to open an external window to preview (almost all files except images), the URL of this new window will actually be the URL your looking for!
Download (simple one-step method)
Download a file to a local path. The save path as naturally to ends with the same extension as the original file.
Output Nothing (throws an error if the URL is invalid or if the save path is wrong)Example
from seatable_api import Base, context
base = Base(context.api_token, context.server_url)
base.auth()
file_url = "https://cloud.seatable.io/workspace/74/asset-preview/41cd05da-b29a-4428-bc31-bd66f4600817/files/2020-10/invoice.pdf"
save_path = "/tmp/invoice.pdf"
base.download_file(file_url, save_path)
Download every file from the File column of Table1 table, providing the id of the row.
from seatable_api import Base
server_url = 'https://cloud.seatable.io'
api_token = '5e165f8b7af...98950b20b022083'
base = Base(api_token, server_url)
base.auth()
target_row = base.get_row('Table1','Pd_pHLM8SgiEcnFW5I7HLA')
save_directory = './tmp/' # (1)!
files = target_row['File']
print(f"{len(files)} files to download")
for file in files :
print(f"Downloading {file['url']}")
base.download_file(file['url'], save_directory + file['name']) # (2)!
-
Ensure that your target directory exists! Directory beginning with
.are relative to the current working directory -
The download URL is found in the
urlkey of each element of the file-type column. Thenamekey is used so every files will keep their original names (and you don't have to bother with extensions)
Download (detailed two-steps method)
This detailed method is for handling complex situations, for example when the file is extremely large or the internet connection is slow. In this example, we assume that a file with URL https://cloud.seatable.io/dtable-web/workspace/74/asset-preview/41cd05da-b29a-4428-bc31-bd66f4600817/files/2020-10/invoice.pdf exists (a file called invoice.pdf and downloaded in October 2020 (2020-10) in the base whose uuid is 41cd05da-b29a-4428-bc31-bd66f4600817, located in the workspace whose id is 74).
This method actually relies on two different steps: first getting the file public download link and then downloading it using a GET request.
Compared to the file URL from the base.download_file method, the file path needed here is just the "file location" part of the URL corresponding to the location of the file in the base file system (starting with /files/, /images/ or /custom/).
Download link expires
The download link is only valid for some hours. After that the download link must be created again. That's why it's not possible to use permanent download links of files hosted on SeaTable in web pages. For such purpose, we recommend to store the files on public hosting services and to save only the links in SeaTable, which will allow direct use.
Output The public download link (looking like {server_url}/seafhttp/files/{access_token}/{file_name}). Keep in mind that it's not permanent as the token expires! (throws an error if the file path is wrong)
Example
from seatable_api import Base, context
import requests
base = Base(context.api_token, context.server_url)
base.auth()
download_link = base.get_file_download_link('files/2020-10/invoice.pdf')
response = requests.get(download_link)
if response.status_code in range(200,300) : # (1)!
with open("invoice.pdf", "wb") as f: # (2)!
f.write(response.content)
-
2xxresponse status codes correspond to a successful request -
Open the file with write permission and write the response content into it
Download file from a custom folder
This method is specific for files stored in a custom folder. Compared to the file URL from the base.download_file method, the custom path needed here is just the part of the URL corresponding to the location of the file in the custom folders file system (part of the URL starting after /custom/). In the following example, we consider the file quote.pdf described in the base.download_file section uploaded in the custom folder My Personal Folder whose URL is https://cloud.seatable.io/dtable-web/workspace/74/asset-preview/41cd05da-b29a-4428-bc31-bd66f4600817/custom/My Personal Folder/quote.pdf.
Output Nothing (throws an error if the URL is invalid or if the save path is wrong)
Example
from seatable_api import Base, context
base = Base(context.api_token, context.server_url)
base.auth()
custom_file_path = "My Personal Folder/quote.pdf" # (1) !
local_path = "/Users/Desktop/quote.pdf"
base.download_custom_file(custom_file_path, local_path)
- Unlike the
get_file_download_linkmethod,custom_file_partdoesn't include/custom/
Upload¶
Please note that uploading a file to a cell will require two or three steps, depending on the method you use: you'll first need to upload the file to the base, and then you'll be able to update the row with the newly uploaded file details in the cell. You can learn more about this process in the API Reference. As for download, there are one simple (one-step) and one detailed (two-steps) process to upload a file:
Upload (simple ones-step method)
Upload a file from your local drive, memory or a website.
base.upload_local_file(file_path, name=None, file_type='file', replace=False) # (1)!
# or
base.upload_bytes_file(name, content, file_type='file', replace=False) # (2)!
-
-
name: the name of the file once uploaded. Ifnameis not provided, the uploaded file will keep the same name than the original -
file_type: can be eitherfileorimage(default isfile) replace: if set toTrue, uploading a new file with the same name as an existing one will overwrite it (default isFalse)
-
-
When using
base.upload_bytes_file,nameis mandatory as their is no named attached to thecontent
Output File dict containing the same keys as every element in a file-type column: type (file or image), size, name and url
Example: Upload a file from local hard drive
local_file = '/Users/Markus/Downloads/seatable-logo.png'
info_dict = base.upload_local_file(local_file, name='seatable-logo.png', file_type='image', replace=True)
Example: Upload a file from memory
local_file = '/Users/Markus/Downloads/seatable-logo.png'
with open (local_file, 'rb') as f:
content = f.read()
info_dict = base.upload_bytes_file = ('seatable-logo.png', content, file_type='image')
Example: Upload a file from a website
Upload (detailed two-steps method)
As for the download detailed method, this method actually relies on two different steps: first getting a file upload link and then uploading it using a POST request.
Output - base.get_file_upload_link outputs a dict containing upload_link, parent_path, img_relative_path and file_relative_path keys
- the
POSTrequest will return a400errorParent dir doesn't exist.ifparent_diris wrong or a403errorAccess token not found.ifupload_linkis wrong
Example
import requests
from seatable_api import Base, context
base = Base(context.api_token, context.server_url)
base.auth()
# Get the upload link and file path allocated by server
upload_link_dict = base.get_file_upload_link()
upload_link = upload_link_dict['upload_link'] # (1)!
parent_dir = upload_link_dict['parent_path'] # (2)!
file_relative_path = upload_link_dict['file_relative_path']
img_relative_path = upload_link_dict['img_relative_path']
# Upload the file
upload_file_name = "file_uploaded.txt"
replace = True
response = requests.post(upload_link, data={
'parent_dir': parent_dir,
'replace': 1 if replace else 0 # (3)!
}, files={
'file': (upload_file_name, open('/User/Desktop/file.txt', 'rb')),
'relative_path': file_relative_path # (4)!
})
-
upload_linkwill look like{server_url}/seafhttp/upload-api/{temporary_upload_token} -
parent_pathwill look like/asset/{base_uuid}. Please note that the name of the corresponding parameter for the uploadPOSTrequest isparent_dir! -
replacerequires0or1. You can use this syntax if you prefer to specifyTrueorFalse -
Choose either the file relative path or the image relative path depending on the type of column you want to upload your file to
Upload local file to a custom folder
This method is specific for files to store in a custom folder. It is the counterpart of the base.download_custom_file method. Please note that using this method, existing files will not be replaced (a new My file(2) will be created if My file already exists).
-
custom_folder_path: the path in the custom folders of the base where you want to upload the file
name: the name of the file once uploaded. Ifnameis not provided, the uploaded file will keep the same name than the original
Output Single file dict containing type, size, name and url keys. This dict can be used to "assign" a file to a row.
Example
from seatable_api import Base, context
base = Base(context.api_token, context.server_url)
base.auth()
#Step 1: Uploading a file to the base
local_path = "/Users/Desktop/sky.png"
custom_path = "/Main/"
info_dict = base.upload_local_file_to_custom_folder(local_path, custom_path)
#Step 2: Update a row with the uploaded file
row_id = "xxxx"
FILE_COL_NAME = "File" # (1)!
base.update_row('Table1', row_id, {FILE_COL_NAME: [info_dict]})
- Get in the habit of storing column and/or table names in variables, this will make your scripts much easier to update if names change
List files¶
List files
List files in any folder of the custom folders file system (use / as path if you want to see the content of Custom folders). If you need to list the files present in a system (non-custom) folder, please refer to the API Reference.
path: Absolute path of the directory you want to list the assets for (for example/My Personal Folder/Photosfor a subdirectoryPhotoslocated in the directoryMy Personal Folder)
Output A dict containing a dir and a file key, each containing a list of respectively directories and files present in the path you specified (throws an error if the path is not valid)
Example
from seatable_api import Base, context
base = Base(context.api_token, context.server_url)
base.auth()
folder_dir = "/Main/photos"
main_photos_content = base.list_custom_assets(folder_dir)
print(main_photos_content)
Example: display the whole Custom folders file structure
from seatable_api import Base, context
def list_assets(path):
global indent
if path == "/" :
print(f"📁 {path}")
else :
print(f"{indent}∟ 📁 {path.split('/')[-1]}")
assets = base.list_custom_assets(path)
if assets:
indent += ' '
for f in assets['file']:
print(f"{indent}∟ 📄 {f['name']}")
for d in assets['dir']: # (1)!
if path == '/' :
list_assets(path+d['name'])
else :
list_assets(path+'/'+d['name'])
indent = indent[:-1]
base = Base(context.api_token, context.server_url)
base.auth()
indent = ''
list_assets('/') # (2)!
-
Recursive function: for each directory of the current directory, the functions calls itself
-
The
list_assetsfunction we created starts at the root level (/)
Get file info¶
Get file info
This methods allows you to get the file dict of any name file in any folder (path) of the custom folders file system.
path: Absolute path of the directory you want to list the assets for (for example/My Personal Folder/Photosfor a subdirectoryPhotoslocated in the directoryMy Personal Folder)
Output Single file dict containing type, size, name and url keys (throws an error if path or name is not valid). This dict can be used to "assign" a file to a row.
Example
from seatable_api import Base, context
base = Base(context.api_token, context.server_url)
base.auth()
#Step 1: Get file info
folder_dir = "/Main/"
file_name = "sky.png"
file_dict = base.get_custom_file_info(folder_dir, file_name)
print(file_dict)
#Step 2: Update row content with file info (overwriting current content)
row_id = "fDMHEdraSRuUMNPGEj-4kQ"
FILE_COL_NAME = "File"
base.update_row("Table1", row_id, {FILE_COL_NAME: [file_dict]})
from seatable_api import Base, context
base = Base(context.api_token, context.server_url)
base.auth()
#Step 1: Get file info
folder_dir = "/Main/"
file_name = "sky.png"
file_dict = base.get_custom_file_info(folder_dir, file_name)
print(file_dict)
#Step 2: Update row content with file info (appending to current content)
row_id = "fDMHEdraSRuUMNPGEj-4kQ"
FILE_COL_NAME = "File"
row = base.get_row("Table1", row_id)
current_files = row[file_col_name]
current_files.append(file_dict)
print(base.update_row("Table1", row_id, {FILE_COL_NAME: current_files}))
from seatable_api import Base, context
base = Base(context.api_token, context.server_url)
base.auth()
#Step 1: Get file info
folder_dir = "/Main/"
file_name = "sky.png"
file_dict = base.get_custom_file_info(folder_dir, file_name)
print(file_dict)
#Step 2: Update row content with file info (appending to current content)
row_id = "fDMHEdraSRuUMNPGEj-4kQ"
FILE_COL_NAME = "File"
print(base.update_row("Table1", row_id, {FILE_COL_NAME: base.get_row("Table1",row_id)[FILE_COL_NAME] + [file_dict]}))