Skip to content

Symlinks

A symlink (symbolic link) is a shortcut stored inside your site that points to another file or directory. When a visitor navigates to the symlink path, they see the content of the target automatically. This is useful for publishing "latest" pointers that always resolve to the most recent version of a file or folder.


  • Expose the latest release of a dataset at a fixed, well-known URL (e.g., /data/latest/data/2026-03-16/).
  • Create an alias for a long path that is easier to share.
  • Redirect one location in your site to content that lives elsewhere within the same site.

Getting a content manager

Symlink operations require a SiteContentManagement instance:

from sites.sdk.sites import Site, Authenticator

site = Site.from_space_and_name(space='docs', name='my-project')
content_manager = site.get_content_manager(
    authenticator=Authenticator.from_token(token='<admin_site_bearer_token>')
)

result = content_manager.create_symlink(
    path='/data/latest',              # the symlink path (what visitors access)
    target_path='/data/2026-03-16/'  # where the symlink points within the site
)
print(result)

Both path and target_path are paths within your site's file system (not full URLs).

If a symlink already exists at path you will get an error by default. Use force=True to replace it:

# Update the 'latest' symlink to point at a new folder
content_manager.create_symlink(
    path='/data/latest',
    target_path='/data/2026-04-01/',
    force=True        # overwrites the existing symlink
)

To check what a symlink points to:

info = content_manager.get_symlink(path='/data/latest')
print(info)
# {'target': '/data/2026-03-16/'}

The returned dict contains a target key with the path the symlink resolves to.


result = content_manager.delete_symlink(path='/data/latest')
print(result)
# {'status': 'OK', 'message': 'Symlink deleted.'}

If the symlink does not exist, a FileNotFoundError is raised.

Use force=True to force deletion even if there are edge cases the server would normally reject:

content_manager.delete_symlink(path='/data/latest', force=True)

End-to-end example: rotating a "latest" pointer

The following pattern is common for datasets published on a regular schedule:

from datetime import date
from sites.sdk.sites import Site, Authenticator
from sites.sdk.common import ApiCallException

site = Site.from_space_and_name(space='data', name='climate-archive')
mgr = site.get_content_manager(
    authenticator=Authenticator.from_token(token='<admin_site_bearer_token>')
)

today = date.today().isoformat()   # e.g., '2026-03-16'
new_data_path = f'/releases/{today}/'

# 1. Upload today's data release
mgr.upload(local_path=f'./output/{today}/', remote_path=new_data_path, recursive=True)

# 2. Update the 'latest' symlink to point at today's release
mgr.create_symlink(
    path='/releases/latest',
    target_path=new_data_path,
    force=True                   # replace yesterday's symlink
)

print(f'Published {today} as /releases/latest')

Visitors who access https://sites.ecmwf.int/data/climate-archive/releases/latest/ will now see today's data without needing to know the date-specific path.


What's next?