Skip to content

Site Management

A site is the core resource on the ECMWF Sites platform. It has a URL like https://sites.ecmwf.int/docs/mysite/, a storage allocation, an access control list, and optional features like WebDAV or a custom application.

This page covers how to create, configure, query, enable/disable, and delete sites.


Concepts

  • Space — the namespace your site lives under. Usually your username (myuser/mysite) or a custom shared space (docs/mysite).
  • Site name — the identifier for the site within the space. Together, space + name form a unique path.
  • Quota — the maximum storage in GB allocated to the site.
  • Site type"private" (default, requires authentication) or "public" (accessible by anyone).
  • Retention date — the date the platform will automatically delete the site if it is not renewed. Defaults to one year from creation.

Creating a site

Start by importing SitesClient, Site, and Authenticator:

from sites.sdk import SitesClient
from sites.sdk.sites import Site, Authenticator

# Authenticate
authenticator = Authenticator.from_credentials(username='myuser', password='mypassword')
client = SitesClient(authenticator=authenticator)

# Define the site
site = Site.from_space_and_name(space='docs', name='my-project')
site.description = 'Documentation for my project'
site.quota = 5                       # 5 GB
site.site_type = 'public'            # or 'private'
site.access_groups = ['ecmwf_staff'] # who can read it
site.admin_users = ['myuser']        # who can administer it

# Create it on the platform
result = client.create_site(site=site)
print(result['message'])
# Site '/docs/my-project/' Created!

After a successful call the site object is automatically refreshed from the server, so all its properties (like owner, enabled, retention_date) are up to date.


Site properties reference

The table below describes every property you can read or set on a Site object.

Property Type Default Description
custom_space str (required) The namespace (username or custom space)
site_name str (required) The site identifier within the space
owner str set by server Username of the site owner
site_type str 'private' 'private' or 'public'
quota int 1 Storage quota in GB
enabled bool True Whether the site is currently live
retention_date str 1 year from now Date (YYYY-MM-DD) when the site is deleted if not renewed
description str '' Human-readable description
admin_groups list[str] [] Groups with administrator access
admin_users list[str] [] Users with administrator access
access_groups list[str] [] Groups with read/write access
access_users list[str] [] Users with read/write access
site_monitored bool False Enable platform monitoring for the site
webdav_enabled bool False Enable WebDAV access
no_robots_enabled bool False Serve noindex in robots.txt
cors_enabled bool False Enable CORS headers
cors_extra_domains list[str] [] Extra domains allowed in CORS
custom_application_image str None Docker image URI for custom application hosting
custom_application_proxy str 'proxy' Proxy type: 'proxy' (ProxyPass) or 'fastcgi'
custom_application_context_root str 'root_context' Context root: 'root_context' or 'site_context'
custom_application_extra_env list[str] [] Extra environment variables for the custom application
template str None Site template name (e.g., 'iver', 'ecbox', 'repository')

Loading a site from the server

If a site already exists (you did not just create it), load its current configuration from the server:

from sites.sdk.sites import Site

site = Site.from_space_and_name(space='docs', name='my-project')
site.load_from_server()

print(site.owner)
print(site.quota)
print(site.site_type)

Listing sites

List all sites

result = client.list()
for s in result.get('data', []):
    print(s['custom_space'], '/', s['site_name'])

Filter the list

# Only enabled private sites owned by 'myuser'
result = client.list(
    owner='myuser',
    site_type=SiteType.Private,  # from sites.sdk.sites.utils import SiteType
    enabled_only=True
)

# Search by name or space
result = client.list(name='docs', space='team')

# Free-text search
result = client.list(query='climate data')

SiteType values:

from sites.sdk.sites.utils import SiteType

SiteType.Public    # sites accessible by anyone
SiteType.Private   # sites requiring authentication

Iterate lazily with list_walk

list_walk returns a generator — ideal for large numbers of sites, since it does not load everything into memory at once:

for site_data in client.list_walk(enabled_only=True):
    print(site_data['custom_space'], '/', site_data['site_name'])

Updating a site

Modify properties on the local site object, then push the changes to the server:

# Load current state
site = Site.from_space_and_name(space='docs', name='my-project')
site.load_from_server()

# Update
site.quota = 20
site.description = 'Updated project documentation'
site.access_groups = ['ecmwf_staff', 'external_collaborators']

result = client.update_site(space='docs', name='my-project', site=site)
print(result['message'])

After a successful update the site object is automatically refreshed from the server again.


Enabling and disabling a site

toggle_site flips the enabled/disabled state of a site. If it is enabled, calling this disables it; if it is disabled, it re-enables it:

# Disable the site (making it temporarily unavailable)
client.toggle_site(site=site)

# Re-enable it
client.toggle_site(site=site)

Deleting a site

Warning: Deleting a site permanently removes all its content and configuration. This cannot be undone.

result = client.delete_site(site=site)
print(result['message'])

Checking who you are

user_info = client.whoami()
print(user_info['data']['username'])   # e.g., 'myuser'
print(user_info['data']['role'])       # e.g., 'Administrator'
print(user_info['data']['policies'])   # list of groups

Health checks

Platform health (all services)

health = client.health()
# Returns status of Kubernetes, NFS, Redis, and other infrastructure components.
print(health['data'])

Sites service health

sites_health = client.sites_health()
print(sites_health['data'])

Individual site health

Use the site's content manager:

from sites.sdk.common import ApiCallException

content_manager = site.get_content_manager()
try:
    content_manager.health()
    print('Site is up and ready')
except ApiCallException:
    print('Site is not ready yet')

Site API version

Retrieve the version of the site's API:

version_info = content_manager.get_version()
print(version_info)
# {'version': '2.0.0'}

Serialising and inspecting a site

# Pretty-print the site as a dict
print(site.to_dict())

# Get the site path string
print(site.get_path())  # e.g., 'docs/my-project'

# Get the full base URL of the platform
print(site.get_base_url())  # e.g., 'https://sites.ecmwf.int'

Create a site from a template

Templates pre-configure a site with a specific layout or application stack:

site = Site.from_template(template='ecbox')
client.create_site(site=site)

What's next?