InstallingTheServer

Implementation.InstallingTheServer History

Hide minor edits - Show changes to output

Changed lines 194-196 from:
to:
If the key order, @@<receivingaccountname>@@ followed by @@<unitname>@@, seems confusing, just remember that all exchanges are addressed by the @@from@@ field, followed by the @@to@@ field.

Changed lines 164-165 from:
 {"source_account": <sourceaccountname>,
  "target_account": <targetaccountname>,
to:
 {"from": <sourceaccountname>,
  "to": <targetaccountname>,
Changed lines 169-170 from:
This tells the server that it may, as part of Ripple transactions, convert value on the @@source_account@@ to value on the @@target_account@@ at the rate given.  (The amount on the source account is multiplied by the rate value to determine the amount on the target account.)
to:
This tells the server that it may, as part of Ripple transactions, convert value on the @@from@@ account to value on the @@to@@ account at the rate given.  (The amount on the source account is multiplied by the rate value to determine the amount on the target account.)
Changed lines 181-182 from:
 {"unit": <unitname>,
  "target_account": <targetaccountname>,
to:
 {"from": <receivingaccountname>,
  "to": <unitname>,
Changed lines 186-187 from:
This tells the server that it may receive payment in the specified value unit to the specified account at the specified rate.
to:
This tells the server that it may receive payment in the specified value unit to the specified account at the specified rate.  The conversion takes place by multiplying the amount in account units by the rate to get the amount in payment units.
Changed lines 190-191 from:
* POST a change to an in-exchange at @@/inexchanges/<unitname>/<targetaccountname>/@@.
to:
* POST a change to an in-exchange at @@/inexchanges/<receivingaccountname>/<unitname>/@@.
Changed lines 198-199 from:
 {"source_account": <sourceaccountname>,
  "unit": <unitname>,
to:
 {"from": <unitname>,
  "to": <payingaccountname>,
Changed lines 203-204 from:
This tells the server that it may send payment in the specified value unit from the specified account at the specified rate.
to:
This tells the server that it may send payment in the specified value unit from the specified account at the specified rate.  The conversion takes place by multiplying the amount in payment units by the rate to get the amount in account units.
Changed lines 207-208 from:
* POST a change to an out-exchange at @@/outexchanges/<sourceaccountname>/<unitname>/@@.
to:
* POST a change to an out-exchange at @@/outexchanges/<unitname/<payingaccountname>/@@.
Changed lines 133-134 from:
Each client can define as many named exchange rates as it wants.  Exchange rates determine the rate at which that client will exchange value on one account for value on another account.
to:
Each client can define as many named exchange rates as it wants.  Exchange rates determine the rate at which that client will exchange value on one account or payment unit for value on another account or payment unit (see Exchanges below).
Changed lines 153-156 from:
Exchanges tell the Ripple server how different accounts can be connected together for building payment paths.

* POST a new
exchange to @@/exchanges/@@:
to:
Exchanges tell the Ripple server how different accounts can be connected together for building payment paths.  There are three types of exchanges: thru-exchanges, in-exchanges, and out-exchanges.

Thru-exchanges define an exchange rate from one account to another account.  A payment path can be  viewed as a sequence of thru exchanges, beginning on the paying account, and ending on the receiving account.

In-exchanges define an exchange rate between an account for receiving payment and a payment unit.  In-exchanges allow Ripple to convert a payment amount to an amount on the receiving account, for when a payment specifies that the recipient receive a pre-defined amount.  In-exchanges determine which payment units may be used to receive payment on a particular account.

Out-exchanges define an exchange rate between a payment unit and an account for sending payment.  Out-exchanges allow Ripple to convert a payment amount to an amount on the paying account, for when a payment specifies that the payer pay a specified amount.  Out-exchanges determine which payment units may be used to send payment from a particular account.

* POST a new thru-
exchange to @@/exchanges/@@:
Changed lines 171-177 from:
* GET a list of exchanges at @@/exchanges/@@.

* POST a change to a rate at @@/exchanges/<sourceaccountname>/<targetaccountname>/@@.

The only field the client is permitted to change is @@rate@@.


to:
* GET a list of thru-exchanges at @@/exchanges/@@.

* POST a change to a thru-exchange at @@/exchanges/<sourceaccountname>/<targetaccountname>/@@.

The only field the client is permitted to change is @@rate@@, by specifying the name of a different exchange rate.


* POST a new in-exchange to @@/inexchanges/@@:

[@
 {"unit": <unitname>,
  "target_account": <targetaccountname>,
  "rate": <ratename>}
@]
 
This tells the server that it may receive payment in the specified value unit to the specified account at the specified rate.

* GET a list of in-exchanges at @@/inexchanges/@@.

* POST a change to an in-exchange at @@/inexchanges/<unitname>/<targetaccountname>/@@.

The only field the client is permitted to change is @@rate@@, by specifying the name of a different exchange rate.


* POST a new out-exchange to @@/outexchanges/@@:

[@
 {"source_account": <sourceaccountname>,
  "unit": <unitname>,
  "rate": <ratename>}
@]
 
This tells the server that it may send payment in the specified value unit from the specified account at the specified rate.

* GET a list of out-exchanges at @@/outexchanges/@@.

* POST a change to an out-exchange at @@/outexchanges/<sourceaccountname>/<unitname>/@@.

The only field the client is permitted to change is @@rate@@, by specifying the name of a different exchange rate.


Added line 123:
  "unit": <unitname>,
Changed lines 129-130 from:
@@name@@ and @@owner@@ do not need to be, and generally will not be, the same as the initiating partner's original account -- account names IDs for client use, and this new account may be on a different client than the original account.  Both accounts should become active once the second one is posted as confirmation.
to:
@@name@@ and @@owner@@ do not need to be, and generally will not be, the same as the initiating partner's original account -- account names IDs for client use, and this new account may be on a different client than the original account.  Similarly, @@unit@@ need not be the same as the original account, although please note that in this case Ripple assumes that these are different notations for the same unit and never performs any value conversions between the two accounts that comprise a credit relationship.  Both accounts should become active once the second one is posted as confirmation.
Added lines 26-39:
Communication with the server uses HTTP, with data in [[http://json.org | JSON]] format, utf-8 encoded, of course.

!!!! Units

Ripple clients need a common set of value units to refer to when creating accounts and making payments.  Any client may add a value unit by name, and all clients may refer to all such units.

* POST a new unit to @@/units/@@:

[@
{"name": <unitname>}
@]

* GET a list of units at @@/units/@@.

Changed lines 44-45 from:
* HTTP POST a new address to @@/addresses/@@, in [[http://json.org | JSON]] form, utf-8 encoded (everything is utf-8):
to:
* POST a new address to @@/addresses/@@:
Added line 72:
  "unit": <unitname>,
Changed lines 91-92 from:
  "balance": <decimal_string>, 
to:
  "balance": <decimal_string>,
  "unit": <unitname>,
Added line 112:
  "unit": <unitname>,
Changed line 122 from:
  "balance": <decimal_string>, 
to:
  "balance": <decimal_string>,
Changed line 11 from:
* the latest [[http://sqlalchemy.org/download.html | sqlalchemy]] (currently 0.4 or higher -- I keep up-to-date on the latest svn version*)
to:
* the latest [[http://sqlalchemy.org/ | sqlalchemy]] (the svn trunk version is best*)
Changed lines 113-114 from:

To get an idea of where this is going, look at [[ClientAPI]].
to:
!!!! Exchange Rates

Each client can define as many named exchange rates as it wants.  Exchange rates determine the rate at which that client will exchange value on one account for value on another account.

* POST a new exchange rate to @@/rates/@@:

[@
 {"name": <ratename>,
  "value": <decimal_string>,
  "expiry_time": <YYYY-MM-DD HH:mm:ss>}
@]

The expiry time is when the given value for this rate expires if it is not updated.  That means that any transactions that depend on this rate being known will not be processed.

* GET a list of exchange rates at @@/rates/@@.

When retrieving exchange rates, there is an addition read-only field @@effective_time@@.

* POST a change to a rate to @@/rates/<ratename/@@.

!!!! Exchanges

Exchanges tell the Ripple server how different accounts can be connected together for building payment paths.

* POST a new exchange to @@/exchanges/@@:

[@
 {"source_account": <sourceaccountname>,
  "target_account": <targetaccountname>,
  "rate": <ratename>}
@]
 
This tells the server that it may, as part of Ripple transactions, convert value on the @@source_account@@ to value on the @@target_account@@ at the rate given.  (The amount on the source account is multiplied by the rate value to determine the amount on the target account.)

* GET a list of exchanges at @@/exchanges/@@.

* POST a change to a rate at @@/exchanges/<sourceaccountname>/<targetaccountname>/@@.

The only field the client is permitted to change is @@rate@@.


Next up, payments.  To get an idea of where this is going, look at [[ClientAPI]].
Added line 34:
  "owner": <string>,
Changed lines 38-39 from:
(@@accounts@@ is optional.  Accounts must exist before being added to an address.  See below.)
to:
The @@owner@@ field simply stores an arbitrary string for the client, and may be used to identify the user on the client system that this address belongs to.  @@accounts@@ is optional.  Accounts must exist before being added to an address.  See below.
Changed lines 66-67 from:
The @@owner@@ field simply stores an arbitrary string for the client, and may be used to identify the user on the client system that this account belongs to.  @@decimal_string@@ means that decimal numbers are passed as JSON strings to avoid them getting parsed into floats, which can mean loss of precision or accuracy.  @@limits_expiry_time@@ is how long the specified limits are good for.  It can be @@null@@, meaning they never expire.  @@address@@ is the address this account should appear to be from when it is presented to the other participant.  @@partner@@ is an address for the other party to the account, so Ripple knows who should get the request to register an account.
to:
The @@owner@@ field, like in addresses, is for the arbitrary use of the client.  @@decimal_string@@ means that decimal numbers are passed as JSON strings to avoid them getting parsed into floats, which can mean loss of precision or accuracy.  @@limits_expiry_time@@ is how long the specified limits are good for.  It can be @@null@@, meaning they never expire.  @@address@@ is the address this account should appear to be from when it is presented to the other participant.  @@partner@@ is an address for the other party to the account, so Ripple knows who should get the request to register an account.
Changed lines 26-31 from:
!!!! Nodes

A node is a vertex where multiple accounts (edges) meet and where exchanges between them take place for payments
.

* HTTP POST a new node to @@http://<servername>/nodes/@@,
in [[http://json.org | JSON]] form, utf-8 encoded (everything is utf-8):
to:
!!!! Addresses

Ripple addresses are identities for sending and receiving payments, like email addresses are identities for sending and receiving email
.  An address can have zero or more accounts (described below), although it is not useful for payment until it has at least one account.

* HTTP POST a new address to @@/addresses
/@@, in [[http://json.org | JSON]] form, utf-8 encoded (everything is utf-8):
Changed lines 33-34 from:
 {"name": <nodename>,
  "addresses": [<address1>, <address2>]}
to:
 {"address": <address>,
  "accounts": [<accountname1>, <accountname2>, ...]}
Deleted lines 36-54:
(@@addresses@@ is optional.  Putting addresses makes this node show up under those addresses.)

* GET a list of nodes at @@http://<servername>/nodes/@@

* GET an individual node at @@/nodes/<nodename>/@@

* POST a change to a node at @@/nodes/<nodename>/@@, by posting a JSON object with the fields to change.  Fields that remain the same can be omitted.

!!!! Addresses

Ripple addresses are identities for sending and receiving payments, like email addresses are identities for sending and receiving email.  An address can have zero or more accounts (described below), although it is not useful for payment until it has at least one account.

* HTTP POST a new address to @@/addresses/@@, in [[http://json.org | JSON]] form, utf-8 encoded (everything is utf-8):

[@
 {"address": <address>,
  "accounts": [<accountname1>, <accountname2>, ...]}
@]

Changed lines 47-50 from:
Addresses are tag-like things on nodes to create groupings of nodes meant to serve as an identity for a user of a system, or as a payment target.  (A single user may need multiple nodes if no all her accounts inter-convert for through-payments.)

* POST a new address to @@/addresses/@@:
to:
Ripple addresses are identities for sending and receiving payments, like email addresses are identities for sending and receiving email.  An address can have zero or more accounts (described below), although it is not useful for payment until it has at least one account.

* HTTP POST a new address to @@/addresses/@@, in [[http://json.org | JSON]] form, utf-8 encoded (everything is utf-8):
Changed line 53 from:
  "nodes": [<nodename1>, <nodename2>, ...]}
to:
  "accounts": [<accountname1>, <accountname2>, ...]}
Changed lines 56-57 from:
(@@nodes@@ is optional.  Putting nodes makes this address show up under those nodes.)
to:
(@@accounts@@ is optional.  Accounts must exist before being added to an address.  See below.)
Added lines 64-65:
Only the fields with new values need to be included.
Changed lines 68-69 from:
OK, something more substantial.  A credit relationship connection between two nodes is made of two accounts, one for each node.  (You could say each node keeps its own copy of the account.)
to:
A credit relationship connection between two participants in the system is made of two accounts, one for each participant.  (You could say each participant keeps its own copy of the account.)
Changed line 74 from:
  "node": <nodename>,
to:
  "owner": <string>,
Changed lines 84-85 from:
@@decimal_string@@ means that decimal numbers are passed as JSON strings to avoid them getting parsed into floats, which can mean loss of precision or accuracy.  @@limits_expiry_time@@ is how long the specified limits are good for.  It can be @@null@@, meaning they never expire.  @@address@@ is the address this account should appear to be from when it is presented to the other user. @@partner@@ is the address of the other user -- it is not a node because the partner may be on a different client and nodes are not public knowledge.
to:
The @@owner@@ field simply stores an arbitrary string for the client, and may be used to identify the user on the client system that this account belongs to.  @@decimal_string@@ means that decimal numbers are passed as JSON strings to avoid them getting parsed into floats, which can mean loss of precision or accuracy.  @@limits_expiry_time@@ is how long the specified limits are good for.  It can be @@null@@, meaning they never expire.  @@address@@ is the address this account should appear to be from when it is presented to the other participant.  @@partner@@ is an address for the other party to the account, so Ripple knows who should get the request to register an account.
Changed line 93 from:
  "node": <nodename>,
to:
  "owner": <string>,
Changed lines 102-103 from:
@@node@@ is the node that owns this account.  @@relationship@@ is the internal Ripple ID that links this account with its dual version owned by the account partner.  @@limits_effective_time@@ is the time these limits came into effect.  @@is_active@@ is whether the account is able to be used for transactions at this time.
to:
@@relationship@@ is the internal Ripple ID that links this account with its dual version owned by the account partner.  @@limits_effective_time@@ is the time these limits came into effect.  @@is_active@@ is whether the account is able to be used for transactions at this time.
Changed line 122 from:
  "node": <nodename>,
to:
  "owner": <string>,
Changed lines 129-131 from:
@@name@@ does not need to be the same as the initiating partner's original account -- account names are for IDs for client use.  Both accounts should become active once the second one is posted as confirmation.

to:
@@name@@ and @@owner@@ do not need to be, and generally will not be, the same as the initiating partner's original account -- account names IDs for client use, and this new account may be on a different client than the original account.  Both accounts should become active once the second one is posted as confirmation.

Changed lines 41-42 from:
* Get an individual node at @@/nodes/<nodename>/@@
to:
* GET an individual node at @@/nodes/<nodename>/@@
Added lines 43-44:
* POST a change to a node at @@/nodes/<nodename>/@@, by posting a JSON object with the fields to change.  Fields that remain the same can be omitted.
Added lines 62-63:
* POST a change to an address at @@/addresses/<address>/@@
Added lines 104-105:
* POST a change to an account at @@/accounts/<accountname/@@.  @@limits_effective_time@@ and @@relationship@@ are set internally by the server and are read-only.
Changed lines 30-31 from:
* HTTP POST a new node to http://<servername>/nodes/, in [[http://json.org | JSON]] form, utf-8 encoded (everything is utf-8):
to:
* HTTP POST a new node to @@http://<servername>/nodes/@@, in [[http://json.org | JSON]] form, utf-8 encoded (everything is utf-8):
Changed lines 39-42 from:
* GET a list of nodes at http://<servername>/nodes/

* Get an individual node at http://<servername>/nodes/<nodename>/
to:
* GET a list of nodes at @@http://<servername>/nodes/@@

* Get an individual node at @@/nodes/<nodename>/@@
Changed lines 47-48 from:
* POST a new address to http://<servername>/addresses/:
to:
* POST a new address to @@/addresses/@@:
Changed lines 56-59 from:
* GET a list of addresses at http://<servername>/addresses

* GET an individual address at http://<servername>/addresses/<address>/
to:
* GET a list of addresses at @@/addresses/@@

* GET an individual address at @@/addresses/<address>/@@
Changed lines 64-65 from:
* POST a new account to http://<servername>/accounts/:
to:
* POST a new account to @@/accounts/@@:
Changed lines 82-87 from:
* GET a list of accounts at http://<servername>/accounts/

* GET an individual account at http://<servername>/accounts/<accountname>/

* GET a list of account confirmation requests at http://<servername>/accountrequests/
, in the format:
to:
* GET a list of accounts at @@/accounts/@@, in the format:
Changed lines 85-88 from:
 {"relationship": <integer>,
  "source_address": <address>,
  "dest_address": <address>,
  "note": <note>}
to:
 {"name": <accountname>,
  "relationship": <integer>,
  "node": <nodename>,
  "balance": <decimal_string>, 
  "upper_limit": <decimal_string>,
  "lower_limit": <decimal_string>,
  "limits_effective_time": <YYYY-MM-DD HH:mm:ss>,
  "limits_expiry_time": <YYYY-MM-DD HH:mm:ss>,
  "is_active": <boolean
>}
Added lines 96-123:
@@node@@ is the node that owns this account.  @@relationship@@ is the internal Ripple ID that links this account with its dual version owned by the account partner.  @@limits_effective_time@@ is the time these limits came into effect.  @@is_active@@ is whether the account is able to be used for transactions at this time.

* GET an individual account at @@/accounts/<accountname>/@@

* GET a list of account confirmation requests at @@/accountrequests/@@, in the format:

[@
 {"relationship": <integer>,
  "source_address": <address>,
  "dest_address": <address>,
  "note": <note>}
@]

* POST an account confirmation to @@/accounts/@@:

[@
 {"name": <accountname>,
  "relationship": <integer>,
  "node": <nodename>,
  "balance": <decimal_string>, 
  "upper_limit": <decimal_string>,
  "lower_limit": <decimal_string>,
  "limits_expiry_time": <YYYY-MM-DD HH:mm:ss>}
@]

@@name@@ does not need to be the same as the initiating partner's original account -- account names are for IDs for client use.  Both accounts should become active once the second one is posted as confirmation.

Added lines 60-94:
!!!! Accounts

OK, something more substantial.  A credit relationship connection between two nodes is made of two accounts, one for each node.  (You could say each node keeps its own copy of the account.)

* POST a new account to http://<servername>/accounts/:

[@
 {"name": <accountname>,
  "node": <nodename>,
  "balance": <decimal_string>,
  "upper_limit": <decimal_string>,
  "lower_limit": <decimal_string>,
  "limits_expiry_time": <YYYY-MM-DD HH:mm:ss>,
  "address": <address>,
  "partner": <address>,
  "note": <string>}
@]

@@decimal_string@@ means that decimal numbers are passed as JSON strings to avoid them getting parsed into floats, which can mean loss of precision or accuracy.  @@limits_expiry_time@@ is how long the specified limits are good for.  It can be @@null@@, meaning they never expire.  @@address@@ is the address this account should appear to be from when it is presented to the other user.  @@partner@@ is the address of the other user -- it is not a node because the partner may be on a different client and nodes are not public knowledge. 

Posting a new account generates an account confirmation request for the account partner.  The partner must confirm by posting her own version of the account before the account is made active.

* GET a list of accounts at http://<servername>/accounts/

* GET an individual account at http://<servername>/accounts/<accountname>/

* GET a list of account confirmation requests at http://<servername>/accountrequests/, in the format:

[@
 {"relationship": <integer>,
  "source_address": <address>,
  "dest_address": <address>,
  "note": <note>}
@]

Added lines 1-2:
This first version of the server is standalone -- it does not implement the Ripple protocol for inter-server transactions.  That comes later.  First we'll get the client protocol nailed.
Changed lines 35-36 from:
(@@addresses@@ is optional.)
to:
(@@addresses@@ is optional.  Putting addresses makes this node show up under those addresses.)
Changed lines 52-53 from:
(@@nodes@@ is optional.)
to:
(@@nodes@@ is optional.  Putting nodes makes this address show up under those nodes.)
Added lines 26-27:
A node is a vertex where multiple accounts (edges) meet and where exchanges between them take place for payments.
Changed lines 31-32 from:
 {"name": <nodename>}
to:
 {"name": <nodename>,
  "addresses": [<address1>, <address2>]
}
Added lines 35-36:
(@@addresses@@ is optional.)
Added lines 39-40:
* Get an individual node at http://<servername>/nodes/<nodename>/
Changed lines 43-44 from:
Addresses are groupings of nodes.  Payment endpoints are addresses.
to:
Addresses are tag-like things on nodes to create groupings of nodes meant to serve as an identity for a user of a system, or as a payment target.  (A single user may need multiple nodes if no all her accounts inter-convert for through-payments.)
Added lines 52-53:
(@@nodes@@ is optional.)
Changed lines 18-21 from:
Then in the ripplebase directory, run 'python createdb.py' to (re)create the database, and 'python server.py' to start the server.  The default port is 8080.

To run the test suite: 'trial test'
to:
Then in the ripplebase directory, run @@python createdb.py@@ to (re)create the database, and @@python server.py@@ to start the server.  The default port is 8080.

To run the test suite: @@trial test@@.
Changed lines 18-19 from:
Then in the ripplebase directory, run 'python server.py'.
to:
Then in the ripplebase directory, run 'python createdb.py' to (re)create the database, and 'python server.py' to start the server.  The default port is 8080.

To run the test suite: 'trial test'

Added lines 16-17:
Settings for various things like the database are in ripplebase/settings.py.
Added lines 44-45:

To get an idea of where this is going, look at [[ClientAPI]].
Changed lines 16-43 from:
Then in the ripplebase directory, run 'python server.py'.
to:
Then in the ripplebase directory, run 'python server.py'.

!! What the server can do so far

!!!! Nodes

* HTTP POST a new node to http://<servername>/nodes/, in [[http://json.org | JSON]] form, utf-8 encoded (everything is utf-8):

[@
 {"name": <nodename>}
@]

* GET a list of nodes at http://<servername>/nodes/

!!!! Addresses

Addresses are groupings of nodes.  Payment endpoints are addresses.

* POST a new address to http://<servername>/addresses/:

[@
 {"address": <address>,
  "nodes": [<nodename1>, <nodename2>, ...]}
@]

* GET a list of addresses at http://<servername>/addresses

* GET an individual address at http://<servername>/addresses/<address>/
Changed lines 12-13 from:
(* keep a fresh checkout of the sqlalchemy svn repository trunk (http://svn.sqlalchemy.org/sqlalchemy/trunk) somewhere, and link to the lib/sqlalchemy directory in usr/local/lib/python2.5/site-packages, or wherever your python install's site-packages directory is located.)
to:
(* keep a fresh checkout of the sqlalchemy svn repository trunk (http://svn.sqlalchemy.org/sqlalchemy/trunk) somewhere, and link to the lib/sqlalchemy directory in /usr/local/lib/python2.5/site-packages, or wherever your python install's site-packages directory is located.)
Changed line 9 from:
* the latest [[http://sqlalchemy.org/ | sqlalchemy]] (currently 0.4 or higher -- I keep up-to-date on the latest svn version*)
to:
* the latest [[http://sqlalchemy.org/download.html | sqlalchemy]] (currently 0.4 or higher -- I keep up-to-date on the latest svn version*)
Changed lines 12-13 from:
(* keep a fresh checkout of the sqlalchemy svn repository somewhere, and link to the lib/sqlalchemy directory in usr/local/lib/python2.5/site-packages, or wherever your python install's site-packages directory is located.)
to:
(* keep a fresh checkout of the sqlalchemy svn repository trunk (http://svn.sqlalchemy.org/sqlalchemy/trunk) somewhere, and link to the lib/sqlalchemy directory in usr/local/lib/python2.5/site-packages, or wherever your python install's site-packages directory is located.)
Changed lines 12-13 from:
* keep a fresh checkout of the sqlalchemy svn repository somewhere, and link to the lib/sqlalchemy directory in usr/local/lib/python2.5/site-packages, or wherever your python install's site-packages directory is located.
to:
(* keep a fresh checkout of the sqlalchemy svn repository somewhere, and link to the lib/sqlalchemy directory in usr/local/lib/python2.5/site-packages, or wherever your python install's site-packages directory is located.)
Added lines 1-16:
Get the code from:

http://github.com/rfugger/ripple/

Install (by linux package system preferably):

* [[http://python.org/ | python 2.5]] or higher,
* [[http://twistedmatrix.com/ | twisted 2.5]],
* the latest [[http://sqlalchemy.org/ | sqlalchemy]] (currently 0.4 or higher -- I keep up-to-date on the latest svn version*)
* [[http://www.sqlite.org/ | sqlite]] and [[http://pysqlite.org/ | pysqlite]] (for testing) or another sqlalchemy supported DB, like postgresql (for production or testing multiple simultaneous connections).

* keep a fresh checkout of the sqlalchemy svn repository somewhere, and link to the lib/sqlalchemy directory in usr/local/lib/python2.5/site-packages, or wherever your python install's site-packages directory is located.

Make sure your [[http://docs.python.org/tut/node8.html#SECTION008120000000000000000 | PYTHONPATH]] environment variable includes the directory where you put the ripplebase code (ie, the directory containing the ripplebase directory).

Then in the ripplebase directory, run 'python server.py'.