If you want to contribute code to xrpl-py, the following sections describe how to set up your developer environment.
To make it easy to manage your Python environment with xrpl-py, including switching between versions, install pyenv and follow these steps:
-
Install
pyenv:brew install pyenvFor other installation options, see the
pyenvREADME. -
Use
pyenvto install the optimized version forxrpl-py(currently 3.11.6):pyenv install 3.11.6 -
Set the global version of Python with
pyenv:pyenv global 3.11.6
To enable autocompletion and other functionality from your shell, add pyenv to your environment.
These steps assume that you're using a Zsh shell. For other shells, see the pyenv README.
-
Add
pyenv initto your Zsh shell:echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init -)"\nfi' >> ~/.zshrc -
Source or restart your terminal:
. ~/.zshrc
To simplify managing library dependencies and the virtual environment, xrpl-py uses poetry.
-
curl -sSL https://install.python-poetry.org | python3 -
May need to run export PATH="$HOME/.local/bin:$PATH" to invoke Poetry (see step 3 "Add Poetry to your PATH").
-
Install
poetrydependencies from pyproject.toml:poetry install
To run linting and other checks, xrpl-py uses pre-commit.
Note: You only need to install pre-commit if you want to contribute code to xrpl-py.
-
Install
pre-commit:pip3 install pre-commit pre-commit install
To run the linter:
poetry run poe lint# Works for single or multiple unit/integration tests
# Ex: poetry run poe test tests/unit/models/test_response.py tests/integration/transactions/test_account_delete.py
poetry run poe test FILE_PATHSpoetry run poe test_unitTo run integration tests, you'll need a standalone rippled node running with WS port 6006 and JSON RPC port 5005. You can run a docker container for this:
docker run -dit -p 5005:5005 -p 6006:6006 --volume $PWD/.ci-config/:/etc/opt/ripple/ --entrypoint bash rippleci/rippled:develop -c 'rippled -a'Breaking down the command:
docker run -p 5005:5005 -p 6006:6006starts a Docker container with an open port for admin JsonRPC and WebSocket requests.-itallows you to interact with the container.-druns the docker container in detached mode. The container will run in the background and developer gets back control of the terminal-tstarts a terminal in the container for you to send commands to.--volume $PWD/.ci-config:/etc/opt/ripple/mounts the directories as indicated. It must be an absolute path, so we use$PWDinstead of./.rippledsoftware searches the location/etc/opt/ripple/(default behavior) for the config files. Hence there is no need to explicitly specify the config-file path.rippleci/rippled:developis an image that is regularly updated with the latest build of thedevelopbranch ofrippled.-astartsrippledin standalone mode
Then to actually run the tests, run the command:
poetry run poe test_integrationpoetry run poe test_faucetTo run both unit and integration tests and see code coverage:
poetry run poe test_coverageTo see manually code coverage after running unit tests or integration tests:
poetry run coverage reportTo switch your python version before running tests:
pyenv local 3.11
poetry env use python3.11
poetry installReplace python3.11 with whatever version of Python you want to use (you must have it installed with pyenv for it to work).
You can see the complete reference documentation at xrpl-py docs. You can also generate them locally using poetry and sphinx:
# Go to the docs/ folder
cd docs/
# Build the docs
poetry run sphinx-apidoc -o source/ ../xrpl
poetry run make htmlTo see the output:
# Go to docs/_build/html/
cd docs/_build/html/
# Open the index file to view it in a browser:
open index.htmlYou can view docs builds for xrpl-py versions on the ReadTheDocs website here: https://readthedocs.org/projects/xrpl-py/builds/
In order to test how a change in docs configuration looks like on ReadTheDocs before merging:
- Publish a branch with your docs configuration changes
- Active and hide the branch by scrolling down on this page: https://readthedocs.org/projects/xrpl-py/versions/
- View the page / build results here: https://readthedocs.org/projects/xrpl-py/builds/
- Once you're done testing, make the test branch inactive.
- If adding functionality to a new part of the library, create new file with a class that inherits
IntegrationTestCasefromtests.integration.integration_test_caseto store all individual tests under (ex:class TestWallet(IntegrationTestCase)). Otherwise, add to an existing file. - Create an async function for each test case (unless the test is only being used for the sync client)
- Include the
@test_async_and_syncdecorator to test against all client types, unless you specifically only want to test with one client. You can also use the decorator to:- Limit tests to sync/async only
- Limit the number of retries
- Use Testnet instead of a standalone network
- Import modules for sync equivalents of any async functions used
- Be sure to reuse pre-made values,
WALLET,DESTINATION,TESTNET_WALLET,TESTNET_DESTINATION,OFFER, andPAYMENT_CHANNEL, fromtests/integrations/reusable_values.py - Be sure to use condensed functions, like
submit_transaction_asyncandsign_and_reliable_submission_async, fromtests/integrations/it_utils.py
Examples can be found in subfolders of tests/integrations
To update just the definitions.json file:
poetry run poe definitions https://github.com/XRPLF/rippled/tree/developAny Github branch link or local path to rippled will work here.
To update the models as well:
poetry run poe generate https://github.com/XRPLF/rippled/tree/developVerify that the changes make sense by inspection before submitting, as there may be updates required for the xrpl-codec-gen tool depending on the latest amendments we're updating to match.
- Your changes should have unit and/or integration tests.
- Your changes should pass the linter.
- Your code should pass all the unit and integration tests on Github (which check all versions of Python).
- Open a PR against
mainand ensure that all CI passes. - Get a full code review from one of the maintainers.
- Merge your changes.
- Please increment the version in
pyproject.tomland update theCHANGELOG.mdfile appropriately. We follow Semantic Versioning. - Please select a commit that is suitable for release and create a tag. The following commands can be helpful:
git tag -s -a <tag-title> -m "Optional Message describing the tag"git tag-- This command displays all the tags in the repository.git push <remote_name, e.g. upstream> tag <tag_title> - A Github Workflow completes the rest of the Release steps (building the project, generating a .whl and tarball, publishing on the PyPI platform). The workflow uses OpenID Connect's temporary keys to obtain the necessary PyPI authorization.
As a prerequisite, the PyPI
xrpl-pyproject needs to authorize Github Actions as a "Trusted Publisher". This page contains helpful resources: https://packaging.python.org/en/latest/guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows/#configuring-trusted-publishing - Send an email to xrpl-announce.
- Post an announcement in the XRPL Discord #python channel with a link to the changes and highlighting key changes.
Note: If maintainers prefer to manually release the xrpl-py software distribution, the below steps are relevant.
- Create a branch off main that properly increments the version in
pyproject.tomland updates theCHANGELOGappropriately. We follow Semantic Versioning. - Merge this branch into
main. - Locally build and download the package.
- Pull main locally.
- Run
poetry buildto build the package locally. - Locally download the package by running
pip install path/to/local/xrpl-py/dist/.whl. - Make sure that this local installation works as intended, and that the changes are reflected properly.
- Run
poetry publish --dry-runand make sure everything looks good. - Publish the update by running
poetry publish.- This will require entering PyPI login info.
- Create a new Github release/tag off of this branch.
- Send an email to xrpl-announce.
- Post an announcement in the XRPL Discord #python channel with a link to the changes and highlighting key changes.
We have a low-traffic mailing list for announcements of new xrpl-py releases. (About 1 email every couple of weeks)
If you're using the XRP Ledger in production, you should run a rippled server and subscribe to the ripple-server mailing list as well.