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.
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¶
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:
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:
What's next?¶
- Content Management — upload files to your new site
- Authentication — understand authentication options, including per-site tokens
- Advanced Topics — WebDAV, CORS, custom applications, site cloning