sites.sdk.sites package¶
Submodules¶
sites.sdk.sites.authenticator module¶
- class sites.sdk.sites.authenticator.Authenticator(username: str | None = None, password: str | None = None, token: str | None = None)[source]¶
An Authenticator instance is an object that manages user authentication against the ECMWF OpenIDConnect authentication system, or simple site unique tokens.
An Authenticator instance requires either credentials or a sites authentication token.
Example usage:
# authenticating using your credentials:authenticator = Authenticator.from_credentials(username=’username’, password=’password’)# authentication using the site authentication bearer token:my_token_authenticator = Authenticator.from_token(token=’c1268a9b07068a9b07…07c8797c7d6d18b69b5b557c1d007dfa’)# authentication using obfuscated credentials from a previous instance of Authenticator:my_credentials_base64 = authenticator.get_credentials_base64()my_authenticator_base64 = Authenticator.from_credentials_base64(credentials=my_credentials_base64)# authenticator from environment variables, either plain string or base64 encodedexport SITES_AUTHENTICATOR_USERNAME=”username”export SITES_AUTHENTICATOR_PASSWORD=”cGFzc3dvcmQK” # base64 encodedauthenticator = Authenticator.from_environment_variables()Arguments to instantiate a
Authenticator:- Param:
username: str - a username
- Param:
password: str - a password
- Param:
token: str - a Bearer unique site token
- Raise:
Exception if http_code is not in 20x
- classmethod from_credentials(username: str, password: str) Authenticator[source]¶
Creates an instance of
Authenticatorfrom user credentials username / password.- Param:
username: str - a username
- Param:
password: str - a password
- Returns:
an instance of
Authenticator
- classmethod from_credentials_base64(credentials: str) Authenticator[source]¶
Creates an instance of
Authenticatorfrom user credentials encoded in base64.- Param:
credentials:
- Returns:
an instance of
Authenticator- Raise:
Exception if credentials are not provided or have an invalid format or if http_code is not in 20x
- classmethod from_environment_variables() Authenticator[source]¶
Creates an instance of
Authenticatorfrom values defined in Environment Variables.Expects 2 Environment Variables
SITES_AUTHENTICATOR_USERNAMEandSITES_AUTHENTICATOR_PASSWORD.These variables can be defined with plain strings or base64 encoded values. When
SITES_AUTHENTICATOR_ENCODING=base64is set the values are always decoded, bypassing the auto-detection heuristic. This is the recommended approach when the credential values are known to be base64-encoded, as the auto-detection may not be reliable for all passwords.- Returns:
an instance of
Authenticator
- classmethod from_token(token: str) Authenticator[source]¶
Creates an instance of
Authenticatorfrom a Bearer Token. Check the Site configuration to get it.- Param:
token: str - the Site unique generated token
- Returns:
an instance of
Authenticator
- get_authorization_header() Dict[str, str][source]¶
Returns the authorization header in the format: ‘Authorization: Bearer eyJhbGciOiJIUz.eyJzdWIiOiIx.SflKxwRJc’
- Returns:
str - the authorization header
sites.sdk.sites.site module¶
- class sites.sdk.sites.site.Site(name: str | None = None, space: str | None = None, owner: str | None = None, template: str | None = None, config: Configuration = <sites.sdk.common.configuration.Configuration object>)[source]¶
A site URL is composed by the username and a site name: https://sites.ecmwf.int/username/site_name
In some cases a site can be configured instead with a custom space instead of using the username, e.g., https://sites.ecmwf.int/custom_space/site_name
This class is used to represent either of these cases.
A Site instance requires a space a name and an
Authenticator.Example usage:
# creating an authenticatorauthenticator = Authenticator.from_token(‘c1268a9b07068a9b07…07c8797c7d6d18b69b5b557c1d007dfa’)# instantiating a site with username spacesite = Site(space=’owner’, name=’site-name’, authenticator=authenticator)# instantiating a site with a custom spacesite = Site(space=’custom_space’, name=’site-name’, authenticator=authenticator)# instantiating a site in stage:site = Site(space=’user’, name=’name’, authenticator=authenticator, sites_base_url=’https://sites-stage.ecmwf.int’)Arguments to instantiate a
Site:- Param:
space: str - the username or custom space of the site
- Param:
name: str - the site name
- Param:
config: Configuration - the configuration file
- classmethod from_dict(dic: ~typing.Dict[str, ~typing.Any], config: ~sites.sdk.common.configuration.Configuration = <sites.sdk.common.configuration.Configuration object>) Site[source]¶
Creates an instance of
Sitefrom a dictionary.- Param:
dic: dict - a dictionary to retrieve data from
- Param:
config:
Configuration- a configuration object- Returns:
an instance of
Site
- classmethod from_owner_and_name(owner: str, name: str, config: Configuration = <sites.sdk.common.configuration.Configuration object>) Site[source]¶
Creates an instance of
Sitefrom the site owner and name.Deprecated since version Use:
from_space_and_name()instead.- Param:
owner: str - the site owner
- Param:
name: str - the site name
- Param:
config:
Configuration- optional - a configuration object- Returns:
an instance of
Site
- classmethod from_space_and_name(space: str, name: str, config: Configuration = <sites.sdk.common.configuration.Configuration object>) Site[source]¶
Creates an instance of
Sitefrom a space and site name.- Param:
space: str - the site space
- Param:
name: str - the site name
- Param:
config:
Configuration- optional - a configuration object- Returns:
an instance of
Site
- classmethod from_template(template: str, config: Configuration = <sites.sdk.common.configuration.Configuration object>) Site[source]¶
Creates an instance of
Sitefrom a site template.- Param:
template: str - a site template, e.g. iver, ecbox, repository
- Returns:
an instance of
Site
- get_config() Configuration[source]¶
Returns the current
Configurationobject- Returns:
an instance of
Configuration
- get_content_manager(authenticator: AuthorizationBuilder | None = None) SiteContentManagement[source]¶
Returns an instance of current
SiteContentManagementto manage the current Sites’ content- Param:
authenticator:
AuthorizationBuilder- the authenticator to use- Returns:
an instance of
SiteContentManagement
- get_path() str[source]¶
Returns the current Sites’ path
- Returns:
str - the path in the form ‘space/name’
- load_from_server(authenticator: AuthorizationBuilder | None = None) None[source]¶
This method loads the current site configuration by requesting its information from the API
- Param:
authenticator:
AuthorizationBuilder- the authenticator to use
sites.sdk.sites.site_content module¶
- class sites.sdk.sites.site_content.SiteContentManagement(site: Site, authenticator: AuthorizationBuilder | None = None)[source]¶
Client to manage sites content
Arguments to instantiate a
SiteContentManagement:- Param:
site:
Site- the site to manage the content- Param:
authenticator:
AuthorizationBuilder- the authenticator to be used by default
- backup_token_history() Dict[str, Any][source]¶
Create a backup of all token history entries.
Creates a gzipped JSON backup of all token history entries stored on the server.
- Returns:
returns a JSON with backup metadata including timestamp, row count, and SHA256 checksum
- checksum(remote_path: str) Dict[str, Any][source]¶
Retrieve the SHA-256 checksum and metadata for a remote file without downloading it.
Sends a HEAD request with
Want-Repr-Digest: sha-256and returns metadata from the response headers.- Parameters:
remote_path – str - the remote file path
- Returns:
dict with keys
content_length,content_type,last_modified,etag,checksum(base64-encoded SHA-256 orNonefor empty files)- Raises:
FileNotFoundError – if the file does not exist (404)
ApiCallException – on any other non-success status
- clone(to_site: Site | None = None, authenticator: AuthorizationBuilder | None = None, cleanup_after: bool = False, ignore_errors: bool = False, local_path: str = '/tmp/sites/') None[source]¶
Clones all the content of the site into the file system first and uploads all the content to another site, if a to_site is provided.
- Parameters:
to_site –
Site, optional - the site to clone toauthenticator –
AuthorizationBuilder- optional - the authenticator for the to_sitecleanup_after – bool, optional - if the local file system clone should be clean after completion (Default to False)
ignore_errors – bool, optional - if errors should be ignored (Default to False)
- create_symlink(path: str, target_path: str, force: bool = False) Dict[str, Any][source]¶
Create a symlink to a file or directory remotely on your website.
- Param:
path: str - the path of the symlink to create
- Param:
target_path: str - the path of the symlink target on the remote file system
- Param:
force: bool - if the operation should be forced (in case a symlink already exists)
- Returns:
returns a JSON with the generated symlink
- decode_token(token: str) Dict[str, Any][source]¶
Decode a branca token used to access this websites’ REST API.
- Param:
token: str - the token to decode
- Returns:
returns a JSON with the token data
- delete(remote_path: str = '', match_pattern: str = '', recursive: bool = False) Dict[str, Any][source]¶
Deletes content from the site.
- Param:
remote_path: str, optional - the remote path to clean
- Param:
match_pattern: str, optional - a glob pattern to run as a match pattern for files
- Param:
recursive: bool, optional - if the search should be recursive (Default to False)
- Returns:
a JSON with the result of the deletion. On
200this is a standardApiResponse. On207 Multi-Status(partial failure when using match_pattern) the dict containsdeleted(list of removed paths) andfailed(list of dicts withpathandreasonkeys).
- delete_symlink(path: str, force: bool = False) Dict[str, Any][source]¶
Delete a symbolic link on your website.
- Param:
path: str - the path of the symlink to delete
- Param:
force: bool - if the operation should be forced (Default to False)
- Returns:
returns a JSON with the result of the deletion
- Raises:
RuntimeError – if path is empty
FileNotFoundError – if the symlink does not exist (404)
ApiCallException – on any other non-success status
- delete_token_history(token_hash: str) Dict[str, Any][source]¶
Delete a token history entry by its hash.
- Param:
token_hash: str - the SHA256 hash of the token to delete (64-character hex string)
- Returns:
returns a JSON with the result of the deletion
- download(remote_path: str = '', match_pattern: str = '', verify: bool = False, archive: ArchiveFormat | None = None) Dict[str, Any] | bytes[source]¶
Downloads content from the site. If using a regex or doing recursive searched list_files should be set to True as this method can only download a file at a time.
- Param:
remote_path: str - the remote path of the file or directory
- Param:
match_pattern: str - a glob expression to run as a match pattern for files
- Param:
verify: bool - if
True, request and verifyRepr-Digestwhen available- Param:
archive: ArchiveFormat, optional - if provided, the response will be a compressed archive in the specified format (
zip,tar, ortgz). The server does not returnRepr-Digestfor archive responses, so verify is ignored when archive is set.- Raises:
ChecksumMismatchError – if
verify=Trueand the local digest does not match the server-reported digest- Returns:
returns a JSON with the list of files or the content of the file
- download_with_checksum(remote_path: str = '', match_pattern: str = '', verify: bool = False) Dict[str, Any][source]¶
Download content from the site and optionally verify its SHA-256 checksum.
Deprecated since version next: release Use
download()withverify=True. This method will be removed in the next release.When verify is
Trueand the server returns aRepr-Digestheader, the downloaded content is hashed locally and compared against the server digest. AChecksumMismatchErroris raised on mismatch.- Parameters:
remote_path – str - the remote path of the file
match_pattern – str - a glob expression to match files
verify – bool - if
True, verify the checksum after download (defaultFalse)
- Returns:
dict with keys
content(bytes or dict),checksum(str or None),etag(str or None),verified(bool)- Raises:
ChecksumMismatchError – if verify is
Trueand the local digest does not match the server-reported digestFileNotFoundError – if the file does not exist (404)
ApiCallException – on any other non-success status
- generate_signed_url(target_url: str, duration: int, permission: SiteAccessPermission = SiteAccessPermission.Read) Dict[str, Any][source]¶
Generate a Signed Url to access a specified resource on a specified Site.
- Param:
url: str - a url to sign
- Param:
duration: int - the duration of the token in seconds
- Param:
permission: SiteTokenPermission - the permission of the token, Read or ReadWrite
- Returns:
returns a JSON with the generated token
- generate_token(identifier: str, duration: int, permission: SiteAccessPermission = SiteAccessPermission.Read) Dict[str, Any][source]¶
Generate a branca token to be used to access this websites’ REST API.
- Param:
identifier: str - an identifier that will be used as username for audit purposes
- Param:
duration: int - the duration of the token in seconds
- Param:
permission: SiteTokenPermission - the permission of the token, Read or ReadWrite
- Returns:
returns a JSON with the generated token
- get_symlink(path: str) Dict[str, Any][source]¶
Get information about a symbolic link on your website.
- Param:
path: str - the path of the symlink to query
- Returns:
returns a JSON with the symlink information (including
target)- Raises:
RuntimeError – if path is empty
FileNotFoundError – if the symlink does not exist (404)
ApiCallException – on any other non-success status
- get_version() Dict[str, Any][source]¶
Returns the version of the site API.
- Returns:
returns a JSON with the site version, e.g.
{'version': '2.0.0'}- Raises:
ApiCallException – on any non-success status
- health() Dict[str, Any][source]¶
Returns the health status of the site.
- Returns:
returns a JSON with the site health status
- list(remote_path: str | None = '/', match_pattern: str | None = '*', file_type: FileType | None = None, recursive: bool = False, limit: int = 100, continuation_token: str | None = None, version: int = 0) Dict[str, Any][source]¶
Please note that this function has been abstracted in order to allow the use of both versions of the REST API, and now defaults to Configuration.API_VERSION.
- Param:
recursive: bool - recurse all directories
- Param:
file_type: FileType (f, d) - filter by file type, file ‘f’ or directory ‘d’
- Param:
remote_path: str - the remote path of the file or directory (resource) to list
- Param:
match_pattern: str - a glob expression to run as a match pattern for files
- Param:
limit: int - the max number of items to retrieve
- Param:
continuation_token: str - the token retrieved from a previous listing, in order to retrieve the remaining results
- Param:
version: int - the version of the api to use
- Returns:
returns a JSON with the list of files or the content of the file
- list_v1(remote_path: str | None = '/', match_pattern: str | None = '*', file_type: FileType | None = None, recursive: bool = False) Dict[str, Any][source]¶
Lists content from a site using version 1 of the REST API.
See list().
- Param:
recursive: bool - recurse all directories
- Param:
file_type: FileType (f, d) - filter by file type, file ‘f’ or directory ‘d’
- Param:
remote_path: str - the remote path of the file or directory (resource) to list
- Param:
match_pattern: str - a glob expression to run as a match pattern for files
- Returns:
returns a JSON with the list of files or the content of the file
- list_v2(remote_path: str | None = '/', match_pattern: str | None = '*', file_type: FileType | None = None, recursive: bool = False, limit: int = 100, continuation_token: str | None = None) Dict[str, Any][source]¶
Lists content from a site using version 2 of the REST API.
See list().
- Param:
recursive: bool - recurse all directories
- Param:
file_type: FileType (f, d) - filter by file type, file ‘f’ or directory ‘d’
- Param:
remote_path: str - the remote path of the file or directory (resource) to list
- Param:
match_pattern: str - a glob expression to run as a match pattern for files
- Param:
limit: int - the max number of items to retrieve
- Param:
continuation_token: str - the token retrieved from a previous listing, in order to retrieve the remaining results
- Param:
version: int - the version of the api to use
- Returns:
returns a JSON with the list of files or the content of the file
- list_walk(remote_path: str | None = '/', match_pattern: str | None = '*', file_type: FileType | None = None, recursive: bool = False, limit: int = 100) Iterator[Any][source]¶
Lists content from a site.
- Example:
- for path in list_walk(recursive=True, match=’*’):
print(path)
- Param:
recursive: bool - recurse all directories
- Param:
file_type: FileType (f, d) - filter by file type, file ‘f’ or directory ‘d’
- Param:
remote_path: str - the remote path of the file or directory (resource) to list
- Param:
match_pattern: str - a glob expression to run as a match pattern for files
- Returns:
returns a JSON with the list of files or the content of the file
- restore_token_history() Dict[str, Any][source]¶
Restore token history from the latest backup.
This is a destructive operation: all current token history entries are deleted and replaced with the backup data.
- Returns:
returns a JSON with restore metadata including rows restored count
- revoke_token(token: str | None = None, token_hash: str | None = None) Dict[str, Any][source]¶
Revoke a branca token by either the token string or its hash.
Provide either ‘token’ or ‘token_hash’ to identify which token to revoke. Do not provide both.
- Param:
token: str, optional - the token string to revoke
- Param:
token_hash: str, optional - the SHA256 hash of the token to revoke (64-character hex string)
- Returns:
returns a JSON with the result of the revocation
- token_history(identifier: str | None = None, permission: SiteAccessPermission | None = None, expiring_within: int | None = None, include_expired: bool | None = None) Dict[str, Any][source]¶
Retrieve token usage history with optional filtering.
Returns a list of token usage history entries. Each unique identifier+permission pair is tracked with its most recent usage information only. By default, expired tokens are excluded unless explicitly requested with include_expired=True.
- Param:
identifier: str, optional - filter by token identifier
- Param:
permission: SiteAccessPermission, optional - filter by token permission (Read or ReadWrite)
- Param:
expiring_within: int, optional - filter tokens expiring within N seconds (e.g., 604800 for 7 days)
- Param:
include_expired: bool, optional - include expired tokens in results (default False)
- Returns:
returns a JSON with the token history list
- upload(local_path: str, match_pattern: str = '*', remote_path: str | None = None, recursive: bool = False, ignore_errors: bool = False, if_exists_rename_to: str | None = None, if_exists_backup: bool = False, upload_zero_byte_files: bool = False) List[Dict[str, Any]][source]¶
Uploads content to a site.
- Param:
recursive: bool - if search should be recursive (Default to False)
- Param:
local_path: str - the local path to upload, if this is a directory the whole directory will be uploaded
- Param:
match_pattern: str, optional - a regex to match the files in local_path to be uploaded
- Param:
remote_path: str, optional - the remote path to upload to, can be a new folder, etc.
- Param:
ignore_errors: bool, optional - if errors should be ignored (Default to False)
- Param:
if_exists_rename_to: str, optional - rename a file to this if it exists
- Param:
if_exists_backup: bool, optional - backs-up a file if it exists (Default to False)
- Param:
upload_zero_byte_files: bool, optional - to upload empty files (Default to False)
- Returns:
list[dict] - one result dict per uploaded file. Each dict contains at minimum
statusandmessagekeys. Achecksumkey is included when the server returns aRepr-Digestheader.
- verify_signed_url(url: str) Dict[str, Any][source]¶
Verify if a provided Signed Url is valid to access a specified resource on specified Site.
The API returns
204 No Contenton success (empty body), so this method returns a simple{'status': 'ok'}dict in that case.- Param:
url: str - the url to verify
- Returns:
returns a dict —
{'status': 'ok'}on 204 success, or the parsed JSON body otherwise
sites.sdk.sites.utils module¶
- class sites.sdk.sites.utils.ArchiveFormat(*values)[source]¶
Represents the supported archive formats for downloading compressed content.
Supported values: ‘zip’, ‘tar’, ‘tgz’
- TAR = 'tar'¶
- TGZ = 'tgz'¶
- ZIP = 'zip'¶
- class sites.sdk.sites.utils.ContextRoot(*values)[source]¶
Represents the site root context: ‘Root Context’ or ‘Site Context’ Depending on the custom application, one can select if this will be served from the ‘Root context’ -> ‘/’ or from the ‘Site Context’ -> ‘/space/name/’
- RootContext = 'root_context'¶
- SiteContext = 'site_context'¶
- class sites.sdk.sites.utils.FileType(*values)[source]¶
Represents the file types: ‘File’ or ‘Directory’ When listing files from a specific site, one might want to list depending on the file type
- DIR = 'd'¶
- FILE = 'f'¶
- static convert(value: str, default: str | None = None) str | None[source]¶
Will return the current value if it is a valid one, otherwise defaults to None @param value: the value to convert @param default: the default value to return if value is not valid @return: the value if valid, otherwise the default (if not provided defaults to None)
- class sites.sdk.sites.utils.ProxyType(*values)[source]¶
Represents the type of proxy to serve applications: ‘ProxyPass’ or ‘FastCGI’ On custom applications users can serve their own image using either ‘ProxyPass’ or ‘FastCGI’
- FastCGI = 'fastcgi'¶
- ProxyPass = 'proxy'¶
- class sites.sdk.sites.utils.SiteAccessPermission(*values)[source]¶
Represents the possible types of permissions: ‘Read’ or ‘ReadWrite’
Where ‘Read’ is read only access, and ‘ReadWrite’ is read/write access.
ReadWrite is Administrator level permissions which allow users to generate tokens as well!
- Read = 'r'¶
- ReadWrite = 'rw'¶
- class sites.sdk.sites.utils.SiteType(*values)[source]¶
Represents the possible types of sites: ‘Private’ or ‘Public’ ‘Public’ sites are available to anyone without authorization ‘Private’ sites are available only to specific users or groups of users, they must be authenticated and match the ACL
- Private = 'private'¶
- Public = 'public'¶