Take a look at our GitHub issues. The labelling scheme should be self-explanatory. You're welcome to pick anything that takes your fancy and that you deem important. We encourage you to discuss with us your approach before you start the implementation, to avoid wasting time on out-of-scope work.
We do not assign issues to people. If you want to indicate you're working on something, just start a draft pull request, indicating the issue you're targeting.
Of course, you're welcome to propose and contribute new ideas. We encourage you to open a discussion so that we can have a chat and align.
We are not against coding agents. But deep-river was made by humans who enjoy working with each other, and we want to preserve that human touch. Here are our rules:
- Coding agents can write code, but not comments.
We have a codebase that is of good quality, with enough examples for coding agents to write idiomatic code. Therefore, AI generated code is not a problem per se. But using an AI to write comments is worrying, because it's a sign we did not put in the effort to understand the generated code.
- Prose is written by humans. This covers issues, pull request descriptions, commit messages, docstrings, release notes, and any kind of discussion.
We don't want coding agents to do the high-level thinking for us. Therefore, we should force ourselves to write all our discussions with our own words. AI generated prose almost always reads like slop, and too much of it is off-putting. We believe using our own words is more polite, friendly, and enjoyable for everyone. Docstrings and release notes count too: they're how we talk to our users, so they deserve the same care.
Of course, you can use a coding agent to run a benchmark and produce a summary table. But you should editorialize and insert it into a message you've written yourself.
- Code written by agents should be disclosed as such.
We should not deceive each other by asking an AI to generate code, and merging it into the codebase without indicating its source. We want to be able to differentiate between the two. A Co-authored-by: trailer on the commit is a simple way to do this.
- Be thorough on tests.
Good tests usually span more lines than implementations themselves. They can be tedious to write. Access to coding agents means there is no more excuse for not writing tests.
- Align before you build.
Don't let an agent open a drive-by pull request. As above, discuss your approach with us first, and start from a draft pull request. This matters all the more when an agent makes it cheap to produce a lot of code quickly.
- You are accountable for what your agent submits.
An agent acting on your behalf is still you. You own its output, and the project's contribution standards apply to it just as they do to anything you write yourself.
- Any infringement of the rules above allows the maintainers to close any associated discussion or pull request.
These rules are enforced in AGENTS.md.
The typical workflow for contributing to deep-river is:
- Fork the
mainbranch from the GitHub repository. - Clone your fork locally.
- Commit changes.
- Push the changes to your fork.
- Send a pull request from your fork back to the original
mainbranch.
Start by cloning the repository:
git clone https://github.com/online-ml/deep-river
cd deep-riverNext, install uv and a supported Python version:
curl -LsSf https://astral.sh/uv/install.sh | sh
uv python install 3.12Now you're set to install deep-river and its development dependencies:
uv sync --extra devFinally, install the prek push hooks. This will run some code quality checks every time you push to GitHub.
prek install --hook-type pre-push --overwriteYou can optionally run prek at any time as so:
prek run --all-filesYou're now ready to make some changes. We strongly recommend that you check out deep-river's source code for inspiration before getting into the thick of it. How you make the changes is up to you of course. However we can give you some pointers as to how to test your changes. Here is an example workflow that works for most cases:
- Create and open a Jupyter notebook at the root of the directory.
- Add the following in the code cell:
%load_ext autoreload
%autoreload 2- The previous code will automatically reimport deep-river for you whenever you make changes.
- For instance, if a change is made to
regression.Regressor, then rerunning the following code doesn't require rebooting the notebook:
from deep_river.regression import Regressor
from torch import nn
class MyModule(nn.Module):
def __init__(self, n_features):
super(MyModule, self).__init__()
def forward(self, X, **kwargs):
# your transformation here
return X
model = Regressor(module=MyModule)- Pick a base class from the
base.pyfile, which can either beDeepEstimatororRollingDeepEstimator. - Check if any of the mixin classes from the
basemodule apply to your implementation. - Make sure you've implemented the required methods, with the following exceptions:
- Stateless transformers do not require a
learn_onemethod. - In case of a classifier, the
predict_oneis implemented by default, but can be overridden.
- Stateless transformers do not require a
- Add type hints to the parameters of the
__init__method. - If possible provide a default value for each parameter. If, for whatever reason, no good default exists, then implement the
_unit_test_paramsmethod. This is a private method that is meant to be used for testing. - Write a comprehensive docstring with example usage. Try to have empathy for new users when you do this.
- Check that the class you have implemented is imported in the
__init__.pyfile of the module it belongs to. - When you're done, run the
utils.check_estimatorfunction on your class and check that no exceptions are raised.
If you're adding a class or a function, then you'll need to add a docstring. We follow the Google docstring convention, so please do too.
To build the documentation, install the development dependencies:
uv sync --extra devFrom the root of the repository, you can then run the make livedoc command to take a look at the documentation in your browser. This will run the benchmark renderer and API reference generator before starting the Zensical preview server.
Unit tests
These tests absolutely have to pass.
uv run pytestStatic typing
These tests absolutely have to pass.
uv run mypy deep_riverNotebook tests
You don't have to worry too much about these, as we only check them before each release. If you break them because you changed some code, then it's probably because the notebooks have to be modified, not the other way around.
make execute-notebooks- Checkout
main - Run
make execute-notebooksjust to be safe - Run the benchmarks
- Bump the version in
deep_river/__version__.py - Bump the version in
pyproject.toml - Commit and push
- Wait for CI to run the unit tests
- Push the release tag:
DEEP_RIVER_VERSION=$(python -c "import deep_river; print(deep_river.__version__)")
echo $DEEP_RIVER_VERSIONgit tag "v$DEEP_RIVER_VERSION"
git push origin "v$DEEP_RIVER_VERSION"- Wait for CI to ship to PyPI and publish the new docs
The documentation site publishes one entry per git tag and keeps dev up to date from main.
- Tagged releases are published under the exact tag name, for example
v0.3.2. - The newest stable release is also copied to the
latestalias. - The site root redirects to
latest. devis rebuilt frommainon every docs deployment.
If you need to rebuild all historical documentation versions, run the manual Backfill Documentation Versions workflow.