Participants on Gratipay give payments and take payouts.

class gratipay.models.participant.Participant(record)[source]

Represent a Gratipay participant.

classmethod with_random_username()[source]

Return a new participant with a random username.

classmethod from_id(id)[source]

Return an existing participant based on id.

classmethod from_username(username)[source]

Return an existing participant based on username.

classmethod from_session_token(token)[source]

Return an existing participant based on session token.


The path part of the URL for this participant on Gratipay.

update_session(new_token, expires)[source]

Set session_token and session_expires.

Database:One UPDATE, one row

Set session_expires to the given datetime.

Database:One UPDATE, one row
get_statement(langs, scrubbed=False)[source]

Get the participant’s statement in the language that best matches the list provided.


Given a username, return an URL path.


Close the participant’s account.


Zero out the participant’s payment_instructions.


Leave all teams by zeroing all takes.


Clear personal information such as statements.


Return an AccountElsewhere instance.


Return a dict of AccountElsewhere instances.


Return the list of (platform, user_id) tuples that the participant can log in with.

delete_elsewhere(platform, user_id)[source]

Deletes account elsewhere unless the user would not be able to log in anymore.

set_payment_instruction(team, amount, update_self=True, update_team=True, cursor=None)[source]

Given a Team instance, and amount as str, return a dict.

We INSERT instead of UPDATE, so that we have history to explore. The COALESCE function returns the first of its arguments that is not NULL. The effect here is to stamp all payment instructions with the timestamp of the first instruction from this ~user to that Team. I believe this is used to determine the order of payments during payday.

The dict returned represents the row inserted in the payment_instructions table.


Given a Team instance, return a dict.


Given a Team instance, return a Decimal.


Return a list and a Decimal.


Returns a tuple: (sum, number) of old-style 1.0 tips.

get_teams(only_approved=False, only_open=False, cursor=None)[source]

Return a list of teams this user is an owner or member of.


Given a Team object, return a boolean.


Raise Response or return None.

Usernames are limited to alphanumeric characters, plus ”.,-_:@ ”, and can only be 32 characters long.

final_check(cursor, require_zero_balance=True)[source]

Sanity-check that teams and balance have been dealt with.


Given a cursor, use it to archive ourself.

Archiving means changing to a random username so the username they were using is released. We also sign them out.

take_over(account, have_confirmation=False)[source]

Given an AccountElsewhere or a tuple (platform_name, user_id), associate an elsewhere account.

Returns None or raises NeedConfirmation.

This method associates an account on another platform (GitHub, Twitter, etc.) with the given Gratipay participant. Every account elsewhere has an associated Gratipay participant account, even if its only a stub participant.

In certain circumstances, we want to present the user with a confirmation before proceeding to transfer the account elsewhere to the new Gratipay account; NeedConfirmation is the signal to request confirmation. If it was the last account elsewhere connected to the old Gratipay account, then we absorb the old Gratipay account into the new one, effectively archiving the old account.

Here’s what absorbing means:

  • consolidated tips to and fro are set up for the new participant

    Amounts are summed, so if alice tips bob $1 and carl $1, and then bob absorbs carl, then alice tips bob $2(!) and carl $0.

    And if bob tips alice $1 and carl tips alice $1, and then bob absorbs carl, then bob tips alice $2(!) and carl tips alice $0.

    The ctime of each new consolidated tip is the older of the two tips that are being consolidated.

    If alice tips bob $1, and alice absorbs bob, then alice tips bob $0.

    If alice tips bob $1, and bob absorbs alice, then alice tips bob $0.

  • all tips to and from the other participant are set to zero

  • the absorbed username is released for reuse

  • the absorption is recorded in an absorptions table

This is done in one transaction.

exception gratipay.models.participant.NeedConfirmation(a, b, c)[source]

Represent the case where we need user confirmation during a merge.

This is used in the workflow for merging one participant into another.