Automatically-generated Code Documentation

Interact with Canonical services such as Charmhub and the Snap Store.

class craft_store.Auth(application_name: str, host: str, ephemeral: bool = False, environment_auth: str | None = None, *, file_fallback: bool = False)

Auth wraps around the keyring to store credentials.

The application_name and host are used as key/values in the keyring to set, get and delete credentials.

If environment_auth is set on initialization of this class, then a MemoryKeyring is setup in lieu of the system one.

Credentials are base64 encoded into the keyring and decoded on retrieval.

Variables:
  • application_name – name of the application using this library.

  • host – specific host for the store used.

static decode_credentials(encoded_credentials: str) str

Decode base64 encoded credentials.

Raises:

errors.CredentialsNotParseable – when the credentials are incorrectly encoded.

del_credentials() None

Delete credentials from the keyring.

static encode_credentials(credentials: str) str

Encode credentials to base64.

ensure_no_credentials() None

Check that no credentials exist.

Raises:
  • errors.CredentialsAvailable – if credentials have already been set.

  • errors.KeyringUnlockError – if the keyring cannot be unlocked.

get_credentials() str

Retrieve credentials from the keyring.

set_credentials(credentials: str, force: bool = False) None

Store credentials in the keyring.

Parameters:
  • credentials – token to store.

  • force – overwrite existing credentials.

class craft_store.BaseClient(*, base_url: str, storage_base_url: str, endpoints: Endpoints, application_name: str, user_agent: str, environment_auth: str | None = None, ephemeral: bool = False, file_fallback: bool = False)

Encapsulates API calls for the Snap Store or Charmhub.

Parameters:
  • base_url – the base url of the API endpoint.

  • storage_base_url – the base url for storage.

  • endpointsendpoints.CHARMHUB or endpoints.SNAP_STORE.

  • application_name – the name application using this class, used for the keyring.

  • user_agent – User-Agent header to use for HTTP(s) requests.

  • environment_auth – environment variable to use for credentials.

  • ephemeral – keep everything in memory.

Raises:

errors.NoKeyringError – if there is no usable keyring.

get_list_releases(*, name: str) MarshableModel

Query the list_releases endpoint and return the result.

list_registered_names(*, include_collaborations: bool = False) list[RegisteredNameModel]

List the registered names available to the logged in account.

Parameters:

include_collaborations – if True, includes names the user is a collaborator on but does not own.

list_resource_revisions(name: str, resource_name: str) list[CharmResourceRevision]

List the revisions for a specific resource of a specific name.

list_revisions(name: str) list[RevisionModel]

Get the list of existing revisions for a package.

Parameters:

name – the package to lookup.

Returns:

a list of revisions that have been uploaded for this package.

Charmhub example: https://api.charmhub.io/docs/default.html#list_revisions

login(*, permissions: Sequence[str], description: str, ttl: int, packages: Sequence[Package] | None = None, channels: Sequence[str] | None = None, **kwargs) str

Obtain credentials to perform authenticated requests.

Credentials are stored on the system’s keyring, handled by craft_store.auth.Auth.

The list of permissions to select from can be referred to on craft_store.attenuations.

The login process requires 3 steps:

  • request an initial macaroon on endpoints.Endpoints.tokens.

  • discharge that macaroon using Candid

  • send the discharge macaroon to endpoints.Endpoints.tokens_exchange to obtain final authorization of the macaroon

This last macaroon is stored into the system’s keyring to perform authenticated requests.

Parameters:
  • permissions – Set of permissions to grant the login.

  • description – Client description to refer to from the Store.

  • ttl – time to live for the credential, in other words, how long until it expires, expressed in seconds.

  • packages – Sequence of packages to limit the credentials to.

  • channels – Sequence of channel names to limit the credentials to.

Raises:

errors.CredentialsAlreadyAvailable – if credentials already exist.

logout() None

Clear credentials.

Raises:

errors.CredentialsUnavailable – if credentials cannot be found.

notify_revision(*, name: str, revision_request: RevisionsRequestModel) RevisionsResponseModel

Post to the revisions endpoint to notify the store about an upload.

This request usually takes place after a successful upload.

push_resource(name: str, resource_name: str, *, upload_id: str, resource_type: CharmResourceType | None = None, bases: Annotated[list[RequestCharmResourceBase], FieldInfo(annotation=NoneType, required=True, metadata=[MinLen(min_length=1)])] | None = None) str

Push a resource revision to the server.

Parameters:
  • name – the (snap, charm, etc.) name to attach the upload to

  • resource_name – The name of the resource.

  • upload_id – The ID of the upload (the output of upload)

  • resource_type – If necessary for the namespace, the type of resource.

  • bases – A list of bases that this file supports.

Returns:

The path and query string (as a single string) of the status URL.

API docs: http://api.staging.charmhub.io/docs/default.html#push_resource

The status URL returned is likely a pointer to list_upload_reviews: http://api.staging.charmhub.io/docs/default.html#list_upload_reviews

register_name(name: str, *, entity_type: Literal['charm', 'bundle', 'snap'] | None = None, private: bool = False, team: str | None = None) str

Register a name on the store.

Parameters:
  • name – the name to register.

  • entity_type – The type of package to register (e.g. charm or snap)

  • private – Whether this entity is private or not.

  • team – An optional team ID to register the name with.

Returns:

the ID of the registered name.

release(*, name: str, release_request: Sequence[ReleaseRequestModel]) None

Request a release of name.

Parameters:
  • name – name to release.

  • release_request – sequence of items to release.

request(method: str, url: str, params: dict[str, str] | None = None, headers: dict[str, str] | None = None, **kwargs) Response

Perform an authenticated request if auth_headers are True.

Parameters:
  • method – HTTP method used for the request.

  • url – URL to request with method.

  • params – Query parameters to be sent along with the request.

  • headers – Headers to be sent along with the request.

Raises:
  • errors.StoreServerError – for error responses.

  • errors.NetworkError – for lower level network issues.

  • errors.CredentialsUnavailable – if credentials cannot be found.

Returns:

Response from the request.

unregister_name(name: str) str

Unregister a name with no published packages.

Parameters:

name – The name to unregister.

Returns:

the ID of the deleted name.

update_resource_revision(name: str, resource_name: str, *, revision: int, bases: Annotated[list[RequestCharmResourceBase], FieldInfo(annotation=NoneType, required=True, metadata=[MinLen(min_length=1)])]) int

Update a single resource revision.

update_resource_revisions(*updates: CharmResourceRevisionUpdateRequest, name: str, resource_name: str) int

Update one or more resource revisions.

Parameters:
  • name – The package.

  • resource_name – The resource name to update.

  • updates – The updates to make of any revisions

Returns:

The number of revisions updated.

upload_file(*, filepath: Path, monitor_callback: Callable | None = None) str

Upload filepath to storage.

The monitor_callback is a method receiving one argument of type MultipartEncoder, the total length of the upload can be accessed from this encoder from the len attribute to setup a progress bar instance.

The callback is to return a function that receives a MultipartEncoderMonitor from which the .bytes_read attribute can be read to update progress.

The simplest implementation can look like:

def monitor_callback(encoder: requests_toolbelt.MultipartEncoder):

    # instantiate progress class with total bytes encoder.len

    def progress_printer(monitor: requests_toolbelt.MultipartEncoderMonitor):
       # Print progress using monitor.bytes_read

    return progress_printer
Parameters:

monitor_callback – a callback to monitor progress.

whoami() dict[str, Any]

Return whoami json data queyring endpoints.Endpoints.whoami.

class craft_store.HTTPClient(*, user_agent: str)

Generic HTTP Client to communicate with Canonical’s Developer Gateway.

This client has a requests like interface, it creates a requests.Session on initialization to handle retries over HTTP and HTTPS requests.

The default number of retries is set in REQUEST_TOTAL_RETRIES and can be overridden with the CRAFT_STORE_RETRIES environment variable.

The backoff factor has a default set in REQUEST_BACKOFF and can be overridden with the CRAFT_STORE_BACKOFF environment variable.

Retries are done for the following return codes: 500, 502, 503 and 504.

Variables:

user_agent – User-Agent header to identify the client.

get(*args, **kwargs) Response

Perform an HTTP GET request.

post(*args, **kwargs) Response

Perform an HTTP POST request.

put(*args, **kwargs) Response

Perform an HTTP PUT request.

request(method: str, url: str, params: dict[str, str] | None = None, headers: dict[str, str] | None = None, **kwargs) Response

Send a request to url.

user_agent is set as part of the headers for the request. All requests are logged through a debug logs, headers matching Authorization and Macaroons have their value replaced.

Parameters:
  • method – HTTP method used for the request.

  • url – URL to request with method.

  • params – Query parameters to be sent along with the request.

  • headers – Headers to be sent along with the request.

Raises:
  • errors.StoreServerError – for error responses.

  • errors.NetworkError – for lower level network issues.

Returns:

Response from the request.

class craft_store.StoreClient(*, base_url: str, storage_base_url: str, endpoints: Endpoints, application_name: str, user_agent: str, environment_auth: str | None = None, ephemeral: bool = False, file_fallback: bool = False)

Encapsulates API calls for the Snap Store or Charmhub.

class craft_store.UbuntuOneStoreClient(*, base_url: str, storage_base_url: str, auth_url: str, endpoints: Endpoints, application_name: str, user_agent: str, environment_auth: str | None = None, ephemeral: bool = False, file_fallback: bool = False)

Encapsulates API calls for the Snap Store or Charmhub with Ubuntu One.

request(method: str, url: str, params: dict[str, str] | None = None, headers: dict[str, str] | None = None, **kwargs) Response

Make a request to the store.