Source code of the recurrent donations platform Liberapay
liberapay/liberapay.com
master
Name already in use
Code
- Clone
Use Git or checkout with SVN using the web URL.
Work fast with our official CLI.Learn more about the CLI.
- Open with GitHub Desktop
- Download ZIP
Sign In Required
Pleasesign in to use Codespaces.
Launching GitHub Desktop
If nothing happens,download GitHub Desktop and try again.
Launching GitHub Desktop
If nothing happens,download GitHub Desktop and try again.
Launching Xcode
If nothing happens,download Xcode and try again.
Launching Visual Studio Code
Your codespace will open once ready.
There was a problem preparing your codespace, please try again.
Latest commit
Files
PermalinkREADME.md
Liberapay
Liberapay is a recurrent donations platform. We help you fund the creators and projects you appreciate.
Note: This webapp is not self-hostable.
Table of Contents
Contact
Want to chat?Join us on Gitter. (If you use IRC,Gitter has a gateway.)
Alternatively you can post a message inour GitHub salon.
Contributing to the translations
You can help translate Liberapayvia Weblate. Current status:
If you have questions about translating Liberapay, you can ask themin the salon.
Contributing to the code
Introduction
Liberapay was originally forked fromGratipay and inherited its web micro-frameworkPando (né Aspen), which is based on filesystem routing andsimplates. Don't worry, it's quite simple. For example to make Liberapay return aHello $user, your id is $userid
message for requests to the URL/$user/hello
, you only need to create the filewww/%username/hello.spt
with this inside:
from liberapay.utils import get_participant[---]participant = get_participant(state)[---] text/html{{ _("Hello {0}, your id is {1}", request.path['username'], participant.id) }}
As illustrated by the last line our default template engine isJinja.
The_
function attempts to translate the message into the user's language and escapes the variables properly (it knows that it's generating a message for an HTML page).
The python code inside simplates is only for request-specific logic, common backend code is in theliberapay/
directory.
Installation
Make sure you have the following dependencies installed first:
- python ≥ 3.8
- including the C headers of python and libffi, which are packaged separately in many Linux distributions
- postgresql 13 (seethe official download & install docs)
- make
Then run:
make env
Now you need to give yourself superuser postgres powers (if it hasn't been done already), and create two databases:
su postgres -c "createuser --superuser $(whoami)"createdb liberapaycreatedb liberapay_tests
If you need a deeper understanding take a look at theDatabase Roles andManaging Databases sections of PostgreSQL's documentation.
Then you can set up the DB:
make schema
Configuration
Environment variables are used for configuration, the default values are indefaults.env
andtests/test.env
. You can override them inlocal.env
andtests/local.env
respectively.
Running
Once you've installed everything and set up the database, you can run the app:
make run
It should now be accessible athttp://localhost:8339/.
There are no users provided by default. You can create accounts as you would on the real website, and if you want you can also create a bunch of fake users (but they're not great):
make data
To grant admin permissions to an account, modify the database like so:
psql liberapay -c "update participants set privileges = 1 where username = 'account-username'"
Payday
To run a local payday openhttp://localhost:8339/admin/payday and click the "Run payday" button. You can addOVERRIDE_PAYDAY_CHECKS=yes
in thelocal.env
file to disable the safety checks that prevent running payday at the wrong time.
SQL
The python code interacts with the database by sending raw SQL queries throughthepostgres.py library.
Theofficial PostgreSQL documentation is your friend when dealing with SQL, especially the sections "The SQL Language" and "SQL Commands".
The DB schema is insql/schema.sql
, but don't modify that file directly,instead put the changes insql/branch.sql
. During deployment that script willbe run on the production DB and the changes will be merged intosql/schema.sql
.That process is semi-automated byrelease.sh
.
CSS and JavaScript
For our styles we useSASS andBootstrap 3. Stylesheets are in thestyle/
directory and our JavaScript code is injs/
. Our policy for both is to include as little as possible of them: the website should be almost entirely usable without JS, and our CSS should leverage Bootstrap as much as possible instead of containing lots of custom rules that would become a burden to maintain.
We compile Bootstrap ourselves from the SASS source in thestyle/bootstrap/
directory. We do that to be able to easily customize it by changing values instyle/variables.scss
. Modifying the files instyle/bootstrap/
is probablynot a good idea.
Testing
The easiest way to run the test suite is:
make test
This recreates the test DB's schema and runs all the tests. To speed things upyou can also use the following commands:
make pytest
only runs the python tests without recreating the test DBmake pytest-re
only runs the tests that failed previously
Updating test fixtures
Some of our tests include interactions with external services. In order to speed up those tests we record the requests and responses automatically usingvcr. The records are in thetests/py/fixtures
directory, one per test class.
If you add or modify interactions with external services, then the tests will fail, because VCR will not find the new or modified request in the records, and will refuse to record the new request by default (seeRecord Modes for more information). When that happens you can either addVCR=new_episodes
to your test command (e.g.make pytest VCR=new_episodes
) or delete the obsolete fixture files (e.g.rm tests/py/fixtures/TestPayinsStripe.yml
).
If you're testing an API which uses idempotency keys (for example Stripe's API), then some requests will fail if they're no longer exactly identical. In that case, increase the value of the test class'offset
attribute so that different idempotency keys will be used.
Speeding up the tests
PostgreSQL is designed to prevent data loss, so it does a lot of synchronous disk writes by default. To reduce the number of those blocking writes, ourrecreate-schema.sh
script automatically switches thesynchronous_commit
option tooff
for the test database, however this doesn't completely disable syncing. If your PostgreSQL instance only contains data that you can afford to lose, then you can speed things up further by settingfsync
tooff
,wal_level
tominimal
andmax_wal_senders
to0
in the server's configuration file (postgresql.conf
).
Tinkering with payments
Liberapay currently supports two payment processors:Stripe andPayPal.
Testing Stripe webhooks
You can forward Stripe's callbacks to your local Liberapay instance by runningmake stripe-bridge
. Thestripe-cli program has to be installed for this to work.
Modifying python dependencies
All new dependencies need to be audited to check that they don't contain malicious code or security vulnerabilities.
We usepip's Hash-Checking Mode to protect ourselves from dependency tampering. Thus, when adding or upgrading a dependency the new hashes need to be computed and put in the requirements file. For that you can usehashin:
pip install hashinhashin package==x.y -r requirements_base.txt
If for some reason you need to rehash all requirements, runmake rehash-requirements
.
To upgrade all the dependencies in the requirements file, runhashin -u -r requirements_base.txt
. You may have to run extrahashin
commands if new subdependencies are missing.
The testing dependencies inrequirements_tests.txt
don't follow these rules because they're not installed in production. It's up to you to isolate your development environment from the rest of your system in order to protect it from possible vulnerabilities in the testing dependencies.
Processing personal data
When writing code that handles personal information, keep in mind the principles enshrined in theGDPR.
Deploying the app
Note: Liberapay cannot be self-hosted, this section is only meant to document how we deploy new versions.
Liberapay is currently hosted onAWS (Ireland).
To deploy the app simply runrelease.sh
, it'll guide you through it. Of course you need to be given access first.
License
CC0 Public Domain Dedication (Seethis discussion for details.)
About
Source code of the recurrent donations platform Liberapay