CEP 6 - Add Channel Notices to conda
Title | Add Channel Notices to conda |
Status | Accepted |
Author(s) | Travis Hathaway <thathaway@anaconda.com> |
Created | Apr 21, 2022 |
Updated | Aug 21, 2022 |
Discussion | https://github.com/conda-incubator/ceps/pull/19 |
Implementation | https://github.com/conda/conda/pull/11462 |
Abstract
In order to facilitate better communication between users of conda
and channel owners, we want to
implement a notification feature.
Specifically, this feature will give channel owners the ability to send users a small message (about the size
of a single Twitter post). How often this message displays will be set by channel owners
and will be displayed for each channel a user is actively using (i.e. everything under "channels" in a
user's .condarc
).
The messages may contain but are not limited to the following use cases:
- News about the latest package additions to the channel
- How to sponsor, volunteer or help out a particular channel
- Warnings about a breach of TOS while using a particular channel
- Status updates about the stability of the channel
- Announcements for planned security releases
Specification
The specification is described below via a question-answer format.
When will this message be shown?
The notification message will appear while running the following commands:
create
env create
env update
install
update
The reasoning behind this decision is that the above commands all retrieve repodata.json
from the configured
channels. Simply adding another file request (which is very small and immediately cached) would not add much more
overhead to the execution of these commands. Additionally, these are commands where our users already expect network
traffic to occur, so the requirement for having an active internet connection is assumed.
Here's an example of how a notification message may appear while running the conda create
command:
$ conda create -n geopandas geopandas
Collecting package metadata (repodata.json): done
Solving environment: done
## Package Plan ##
environment location: /Users/username/opt/conda_x86_64/envs/geopandas
added / updated specs:
- geopandas
... (output truncated)
Channel "defaults" has the following notices:
[info] -- Tue May 10 11:50:34 2022
This is a test message. It is not very long, and could have a link to a longer post:
https://example.com/short-link
How else can our users access this message?
Additionally, because our users may wish to see this message on demand, we will add a new sub-command called notices
.
The following are a couple examples to show exactly how it would function:
Basic usage: grabs notices for all current channels:
$ conda notices
Retrieving notices: done
Channel "defaults" has the following notices:
[info] -- Tue May 10 11:50:34 2022
This is a test message. It is not very long, and could have a link to a longer post:
https://example.com/short-link
Channel "conda-forge" has the following notices:
[info] -- Tue May 10 11:50:34 2022
Here is another message. It could have info about the latest happenings or blog posts from conda-forge:
https://conda-forge.org/
Show a single channel: grabs notices for a single channel:
$ conda notices -c defaults
Channel "defaults" has the following notices:
[info] -- Tue May 10 11:50:34 2022
This is a test message. It is not very long, and could have a link to a longer post:
https://example.com/short-link
What file format will this message have, and what will it contain?
The notification message will be in the JSON file format. This will allow us to not only store the message itself but also metadata about the message, including information about how often the client should display the message (more on this in the next section).
Here's an example of the notices.json
file which will be stored in the root of the channel directory structure.
{
"notices": [
{
"id": "1cd1d8e5-d96c-42d1-9c29-e8120ad80823",
"message": "Here is an example message that will be displayed to users",
"level": "info",
"created_at": "2022-04-21T11:50:34+00:00",
"expires_at": "2022-04-22T00:00:00+00:00"
}
]
}
Detailed overview of the JSON fields:
- notices [Array] holds zero or more notices that will be displayed to the client.
- id [String] unique ID for the message itself. UUIDs are preferred, but there is no required format.
- message [String] message that gets displayed to users.
- level [String] one of (info|warning|critical). These will let our users know the category of the message and will also allow the client to apply different formatting rules (e.g. text color).
- created_at [String] ISO 8601 formatted timestamp showing the creation time of the message.
- expires_at [String] ISO 8601 formatted timestamp showing the expiration time of the message.
How often will these messages appear?
How often these messages appear will be configurable by the channel owners and the client. This will be accomplished by
the expires_at
field in the notices.json
file itself. When a message has expired, it will trigger a refresh from the
server at which point it will show new messages if there are any.
The client will the have ultimate say over whether these messages are displayed. We will provide clients with a setting
to permanently disable these messages in their .condarc
files:
# Zero messages will be displayed while running commands such as "install", "update", etc.
number_channel_notices: 0
Motivation
The motivation for this CEP came about as channel owners (Anaconda specifically) needed a way to broadcast messages to users of their channels. These messages may contain specific notices for particular users (e.g. identified by IP address) or general messages for the wider audience of a particular channel.
Additionally, this new notification space can also provide a place for us to relocate conda update conda
reminders
to a more visible spot (at the end of command output versus in the middle of the output). On top of this, other channels
can use these notices as a way to share news with their users or requests for help in maintaining their channels.
Rationale
In order to keep this feature as a simple as possible and reduce the number of moving parts, we choose to serve messages via a flat JSON file on the server. The client is responsible for caching these messages which helps to reduce the number of HTTP requests that it has to make. In designing such a system, it is our goal to keep the code complexity to a minimum while still affording as much flexibility as possible. In the future, certain channels may choose to dynamically serve this JSON file and this specification allows for that.
The other consideration was keeping these messages to a minimum for our users and allowing them to easily disable these messages if they do not want to see them while running commands such as "install" or "create". Although we feel these messages are important for users to see, we also do not want to clutter their terminal output. Ultimately, this is why we are choosing to turn this on by default but are also providing a way to disable it.
Backwards Compatibility
We do not expect any backwards compatibility issues for this new feature.
Alternatives
- Show notices at the beginning of environment activation: This was deemed too intrusive/annoying.
- Show notices at the beginning of command output: Users may miss this if placed here, especially for commands with lots of output
- Message in an HTTP header when retrieving any file from the repository: This would be a better option for some kinds
of messages, like download rate limiting or other blocks due to abuse, since it could be turned on by a rule in a CDN.
However, this use case is probably better addressed by having a standard way for
conda
to display errors on the console from HTTP status codes like 429 (Too Many Requests) and 403 (Forbidden). Additionally, serving custom headers is challenging unless the repository owner has more control over the web server than is usually given by services like Github Pages. - Add notices to the repodata.json file: The repodata.json file is already being fetched, so adding some notices would reduce the number of requests. However, the repodata.json file is way too big already, so it would require clients to download a fairly large file before even being able to show the notification.
- Create a generic metadata.json file containing a notices key: This could be appealing for creating a space for other kinds of channel metadata, but in order to keep things as simple as possible at the moment it makes more sense to put these in their own file. Plus, it allows more flexibility for dynamic routing options to this file if that becomes necessary in the future.
References
This implementation is similar to the way that npm
handles version update reminders:
npm install travishathaway@thath-work-laptop
up to date, audited 365 packages in 3s
34 packages are looking for funding
run `npm fund` for details
5 vulnerabilities (1 moderate, 4 high)
To address all issues (including breaking changes), run:
npm audit fix --force
Run `npm audit` for details.
npm notice
npm notice New minor version of npm available! 8.5.5 -> 8.7.0
npm notice Changelog: https://github.com/npm/cli/releases/tag/v8.7.0
npm notice Run npm install -g npm@8.7.0 to update!
npm notice
Implementation
Pull request to the full implementation:
https://github.com/conda/conda/pull/11462
Please add any implementation related suggestions for improvements to this pull request.
FAQ
How often will I see notices?
Notices will be shown however often channel owners would like. Users will also be able to disable channel notices completely in order to never see them during normal operation.
Is this opt-in or opt-out?
Users will automatically be opted in to these feature. They will have the ability to turn it off via a configuration parameter.
Resolution
This was a standard, non-timed-out vote.
- Among Steering Council members there are 15 "yes", 0 "no", and no abstentions.
- No Emeritus Steering member voted.
This vote has reached quorum (15 + 0 = 15 which is at least 60% of 21).
It has also passed since it recorded 15 "yes" votes and 0 "no" votes giving 15/15 which is greater than 60% of 15.
It should be noted that multiple requests for change were recorded in the pull request about minor implementation details that do not invalidate the previous votes. The author made the requested change.
Copyright
All CEPs are explicitly CC0 1.0 Universal.