diff --git a/docs/images/poser-architecture.png b/docs/images/poser-architecture.png new file mode 100644 index 00000000..7e697990 Binary files /dev/null and b/docs/images/poser-architecture.png differ diff --git a/docs/index.rst b/docs/index.rst index b5968992..10e95a39 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -2,25 +2,24 @@ Tailbone ======== -Welcome to Tailbone, part of the Rattail project. +Welcome to Tailbone, part of the Rattail project. While the core Rattail +package provides the data layer, the Tailbone package provides the (default, +back-end) web application layer. -.. - While the core Rattail package provides the data schema / ORM / application - layer, the Tailbone package provides the web application layer. - -The documentation you are currently reading is for the Tailbone web application -package. Some additional information is available on the `website`_. Clearly -not everything is documented yet. Below you can see what has received some +Some additional information is available on the `website`_. Certainly not +everything is documented yet, but here you can see what has received some attention thus far. .. _website: https://rattailproject.org/ -Getting Started: +Getting Started (with Custom Apps): .. toctree:: :maxdepth: 1 + structure devenv + newproject Narrative Documentation: diff --git a/docs/newproject.rst b/docs/newproject.rst new file mode 100644 index 00000000..30aaae89 --- /dev/null +++ b/docs/newproject.rst @@ -0,0 +1,154 @@ + +Creating a New Project +====================== + +.. contents:: :local: + +.. highlight:: bash + +This describes the process of creating a new app project based on +Rattail/Tailbone. It assumes you are working from a supported :doc:`devenv`. + +Per convention, this doc uses "Poser" (and ``poser``) to represent the custom +app. Please adjust commands etc. accordingly. See also :doc:`structure`. + + +Create the Virtual Environment +------------------------------ + +First step is simple enough:: + + mkvirtualenv poser + +Then with your new environment activated, install the Tailbone package:: + + pip install Tailbone + + +Create the Project +------------------ + +Now with your environment still activated, ``cd`` to wherever you like +(e.g. ``~/src``) and create a new project skeleton like so:: + + mkdir -p ~/src + cd ~/src + pcreate -s rattail poser + +This will have created a new project at ``~/src/poser`` which you can then edit +as you wish. At some point you will need to "install" this project to the +environment like so (again with environment active):: + + cd ~/src/poser + pip install -e . + + +Setup the App Environment +------------------------- + +Any project based on Rattail will effectively be its own "app" (usually), but +Rattail itself provides some app functionality as well. However all such apps +require config files, usually. If running a web app then you may also need to +have configured a folder for session storage, etc. To hopefully simplify all +this, there are a few commands you should now run, with your virtual +environment still active:: + + rattail make-appdir + cdvirtualenv app + rattail make-config -T rattail + rattail make-config -T quiet + rattail make-config -T web + +This will have created a new 'app' folder in your environment (e.g. at +``/srv/envs/poser/app``) and then created ``rattail.conf`` and ``web.conf`` +files within that app dir. Note that there will be other folders inside the +app dir as well; these are referenced by the config files. + +But you're not done yet... You should likely edit the config files, at the +very least edit ``rattail.conf`` and change the ``default.url`` value (under +``[rattail.db]`` section) which defines the Rattail database connection. + + +Create the Database +------------------- + +If applicable, it's time for that. First you must literally create the user +and database on your PostgreSQL server, e.g.:: + + sudo -u postgres createuser --no-createdb --no-createrole --no-superuser poser + sudo -u postgres psql -c "alter user poser password 'mypassword'" + sudo -u postgres createdb --owner poser poser + +Then you can install the schema; with your virtual environment activated:: + + cdvirtualenv + alembic -c app/rattail.conf upgrade heads + +At this point your 'poser' database should have some empty tables. To confirm, +on your PG server do:: + + sudo -u postgres psql -c '\d' poser + + +Create Admin User +----------------- + +If your intention is to have a web app, or at least to test one, you'll +probably want to create the initial admin user. With your env active:: + + cdvirtualenv + rattail -c app/quiet.conf make-user --admin myusername + +This should prompt you for a password, then create a single user and assign it +to the Administrator role. + + +Install Sample Data +------------------- + +If desired, you can install a bit of sample data to your fresh Rattail +database. With your env active do:: + + cdvirtualenv + rattail -c app/quiet.conf -P import-sample + + +Run Dev Web Server +------------------ + +With all the above in place, you may now run the web server in dev mode:: + + cdvirtualenv + pserve --reload app/web.conf + +And finally..you may browse your new project dev site at http://localhost:9080/ +(unless you changed the port etc.) + + +Schema Migrations +----------------- + +Often a new project will require custom schema additions to track/manage data +unique to the project. Rattail uses `Alembic`_ for handling schema migrations. +General usage of that is documented elsewhere, but a little should be said here +regarding new projects. + +.. _Alembic: https://pypi.python.org/pypi/alembic + +The new project template includes most of an Alembic "repo" for schema +migrations. However there is one step required to really bootstrap it, i.e. to +the point where normal Alembic usage will work: you must create the initial +version script. Before you do this, you should be reasonably happy with any +ORM classes you've defined, as the initial version script will be used to +create that schema. Once you're ready for the script, this command should do +it:: + + cdvirtualenv + bin/alembic -c app/rattail.conf revision --autogenerate --version-path ~/src/poser/poser/db/alembic/versions/ -m 'initial Poser tables' + +You should of course look over and edit the generated script as needed. One +change in particular you should make is to add a branch label, e.g.: + +.. code-block:: python + + branch_labels = ('poser',) diff --git a/docs/structure.rst b/docs/structure.rst new file mode 100644 index 00000000..b741475e --- /dev/null +++ b/docs/structure.rst @@ -0,0 +1,131 @@ + +App Organization & Structure +============================ + +.. contents:: :local: + +Tailbone doesn't try to be an "app" proper. But it does try to provide just +about everything you'd need to make one. These docs assume you are making a +custom app, and will refer to the app as "Poser" to be consistent. In practice +you would give your app a unique name which is meaningful to you. Please +mentally replace "Poser" with your app name as you read. + +.. note:: + + Technically it *is possible* to use Tailbone directly as the app. You may + do so for basic testing of the concepts, but you'd be stuck with Tailbone + logic, with far fewer customization options. All docs will assume a custom + "Poser" app which wraps and (as necessary) overrides Tailbone and Rattail. + + +Architecture +------------ + +In terms of how the Poser app hangs together, here is a conceptual diagram. +Note that all systems on the right-hand side are *external* to Poser, i.e. they +are not "plugins" although Poser may use plugin-like logic for the sake of +integrating with these systems. + +.. image:: images/poser-architecture.png + + +Data Layer vs. Web Layer +^^^^^^^^^^^^^^^^^^^^^^^^ + +While the above graphic doesn't do a great job highlighting the difference, it +will (presumably) help to understand the difference in purpose and function of +Tailbone vs. Rattail packages. + +**Rattail** is the data layer, and is responsible for database connectivity, +table schema information, and some business rules logic (among other things). + +**Tailbone** is the web app layer, and is responsible for presentation and +management of data objects which are made available by Rattail (and others). + +**Poser** is a custom layer which can make use of both data and web app layers, +supplementing each as necessary. In practice the lines may get blurry within +Poser. + +The reason for this distinction between layers, is to allow creation of custom +apps which use only the data layer but not the web app layer. This can be +useful for console-based apps; a traditional GUI app would also be possible +although none is yet planned. + + +File Layout +----------- + +Below is an example file layout for a Poser app project. This tries to be +"complete" and show most kinds of files a typical project may need. In +practice you can usually ignore anything which doesn't apply to your app, +i.e. relatively few of the files shown here are actually required. Of course +some apps may need many more files than this to achieve their goals. + +Note that all files in the root ``poser`` package namespace would correspond to +the "data layer" mentioned above, whereas everything under ``poser.web`` would +of course supply the web app layer. + +.. code-block:: none + + ~/src/poser/ + ├── CHANGELOG.md + ├── docs/ + ├── fabfile.py + ├── MANIFEST.in + ├── poser/ + │   ├── __init__.py + │   ├── batch/ + │   │   ├── __init__.py + │   │   └── foobatch.py + │   ├── commands.py + │   ├── config.py + │   ├── datasync/ + │   ├── db/ + │   │   ├── __init__.py + │   │   ├── alembic/ + │   │   └── model/ + │   │   ├── __init__.py + │   │   ├── batch/ + │   │   │   ├── __init__.py + │   │   │   └── foobatch.py + │   │   └── customers.py + │   ├── emails.py + │   ├── enum.py + │   ├── importing/ + │   │   ├── __init__.py + │   │   ├── model.py + │   │   ├── poser.py + │   │   └── versions.py + │   ├── problems.py + │   ├── templates/ + │   │   └── mail/ + │   │   └── warn_about_foo.html.mako + │   ├── _version.py + │   └── web/ + │   ├── __init__.py + │   ├── app.py + │   ├── static/ + │   │   ├── __init__.py + │   │   ├── css/ + │   │   ├── favicon.ico + │   │   ├── img/ + │   │   └── js/ + │   ├── subscribers.py + │   ├── templates/ + │   │   ├── base.mako + │   │   ├── batch/ + │   │   │   └── foobatch/ + │   │   ├── customers/ + │   │   ├── menu.mako + │   │   ├── mobile/ + │   │   └── products/ + │   └── views/ + │   ├── __init__.py + │   ├── batch/ + │   │   ├── __init__.py + │   │   └── foobatch.py + │   ├── common.py + │   ├── customers.py + │   └── products.py + ├── README.rst + └── setup.py