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)[source]

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[source]

Decode base64 encoded credentials.

Raises:

errors.CredentialsNotParseable – when the credentials are incorrectly encoded.

del_credentials() None[source]

Delete credentials from the keyring.

static encode_credentials(credentials: str) str[source]

Encode credentials to base64.

ensure_no_credentials() None[source]

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[source]

Retrieve credentials from the keyring.

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

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)[source]

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[source]

Query the list_releases endpoint and return the result.

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

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][source]

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

list_revisions(name: str) list[RevisionModel][source]

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/#list-revisions

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

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[source]

Clear credentials.

Raises:

errors.CredentialsUnavailable – if credentials cannot be found.

notify_revision(*, name: str, revision_request: RevisionsRequestModel) RevisionsResponseModel[source]

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[source]

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/#push-resource

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

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

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[source]

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[source]

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[source]

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[source]

Update a single resource revision.

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

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[source]

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][source]

Return whoami json data queyring endpoints.Endpoints.whoami.

class craft_store.CandidAuth(*, auth: Auth, auth_type: Literal['bearer', 'macaroon'] = 'macaroon')[source]

Candid based authentication class for httpx store clients.

get_token_from_keyring() str[source]

Get token stored in the credentials storage.

class craft_store.DeveloperTokenAuth(*, auth: Auth, auth_type: Literal['bearer', 'macaroon'] = 'bearer')[source]

Developer token based authentication class for httpx store clients.

get_token_from_keyring() str[source]

Get token stored in the credentials storage.

class craft_store.HTTPClient(*, user_agent: str)[source]

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[source]

Perform an HTTP GET request.

post(*args, **kwargs) Response[source]

Perform an HTTP POST request.

put(*args, **kwargs) Response[source]

Perform an HTTP PUT request.

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

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.PublisherGateway(base_url: str, namespace: str, auth: Auth | Auth)[source]

Client for the publisher gateway.

This class is a client wrapper for the Canonical Publisher Gateway. The latest version of the server API can be seen at: https://api.charmhub.io/docs/

Each instance is only valid for one particular namespace.

create_tracks(name: str, *tracks: _request.CreateTrackRequest) int[source]

Create one or more tracks in the store.

Parameters:
  • name – The store name (i.e. the specific charm, snap or other package) to which this track will be attached.

  • tracks – Each track is a dictionary mapping query values.

Returns:

The number of tracks created by the store.

Raises:

InvalidRequestError if the name field of any passed track is invalid.

API docs: https://api.charmhub.io/docs/default/#create-tracks

get_package_metadata(name: str) RegisteredNameModel[source]

Get general metadata for a package.

Parameters:

name – The name of the package to query.

Returns:

A dictionary matching the result from the publisher gateway.

API docs: https://api.charmhub.io/docs/default/#package-metadata

list_registered_names(include_collaborations: bool = False) Sequence[RegisteredNameModel][source]

Return names registered by the authenticated user.

Parameters:

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

Returns:

A sequence of names registered to the user.

API docs: https://api.charmhub.io/docs/default/#list-registered-names

list_releases(name: str) Releases[source]

Get the information about the releases of a name.

Parameters:

name – The name of the package to query.

Returns:

Channel info, package info and revision info.

The revision information returned is only for the revisions that are currently published in a channel.

API docs: https://api.charmhub.io/docs/default/#list-releases

list_revisions(name: str, *, fields: Collection[str] | None = None, include_craft_yaml: bool = False, revision: int | None = None) Sequence[Revision][source]

List the revisions for a specific name.

Parameters:
  • name – The name of the package to query.

  • fields – A list of fields to include. These vary by namespace and are only checked server-side.

  • include_craft_yaml – Whether to include the craft YAML file in the response.

  • revision – If provided, get only the specified revision.

Returns:

A list of revisions in the store and their metadata.

API docs: https://api.charmhub.io/docs/default/#list-revisions

register_name(name: str, *, entity_type: str, private: bool = False, team: str | None = None) str[source]

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.

unregister_name(name: str) str[source]

Unregister a name with no published packages.

Parameters:

name – The name to unregister.

Returns:

the ID of the deleted name.

API docs: https://api.charmhub.io/docs/default/#unregister-package

whoami() dict[str, Any][source]

Return whoami json data.

API docs: https://api.charmhub.io/docs/default/#macaroon-info

classmethod with_ubuntu_one(base_url: str, namespace: str, *, auth: Auth | None = None, application_name: str = 'craft-store', client_description: str = 'craft-store') PublisherGateway[source]

Create a publisher gateway client using Ubuntu One SSO authentication.

This is a convenience constructor that creates the UbuntuOneAuth internally. Credentials must already be saved in the system keyring (e.g. by calling login_with() first).

Parameters:
  • base_url – The base URL of the publisher gateway API (e.g. "https://api.charmhub.io").

  • namespace – The package namespace (e.g. "charm" or "snap").

  • auth – An optional Auth instance for keyring access. If not provided, one is created automatically using application_name and the host derived from base_url.

  • application_name – The application name used for keyring storage. Must match the name used when credentials were saved. Defaults to "craft-store".

  • client_description – A description passed to the store during token exchange. Defaults to "craft-store".

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)[source]

Encapsulates API calls for the Snap Store or Charmhub.

class craft_store.UbuntuOneAuth(*, auth: Auth, api_base_url: str, client_description: str = 'craft-store')[source]

Ubuntu One macaroon auth class for httpx store clients.

auth_flow(request: Request) Generator[Request, Response, None][source]

Execute the authentication flow.

To dispatch a request, yield it:

` yield request `

The client will .send() the response back into the flow generator. You can access it like so:

` response = yield request `

A return (or reaching the end of the generator) will result in the client returning the last response obtained from the server.

You can dispatch as many requests as is necessary.

get_token_from_keyring() str[source]

Exchange Ubuntu One macaroons stored in the credentials storage.

On first call, exchanges the macaroons for a store token and caches it. On subsequent calls, uses the cached token instead of re-exchanging.

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)[source]

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[source]

Make a request to the store.