Piccolo Apps¶
By leveraging Piccolo apps you can:
Modularise your code.
Share your apps with other Piccolo users.
Unlock some useful functionality like auto migrations.
Creating an app¶
Run the following command within your project:
piccolo app new my_app
Where my_app
is your new app’s name. This will create a folder like this:
my_app/
__init__.py
piccolo_app.py
piccolo_migrations/
__init__.py
tables.py
It’s important to register your new app with the APP_REGISTRY
in
piccolo_conf.py
.
# piccolo_conf.py
APP_REGISTRY = AppRegistry(apps=['my_app.piccolo_app'])
Anytime you invoke the piccolo
command, you will now be able to perform
operations on your app, such as Migrations.
AppConfig¶
Inside your app’s piccolo_app.py
file is an AppConfig
instance. This is
how you customise your app’s settings.
# piccolo_app.py
import os
from piccolo.conf.apps import AppConfig
from .tables import (
Author,
Post,
Category,
CategoryToPost,
)
CURRENT_DIRECTORY = os.path.dirname(os.path.abspath(__file__))
APP_CONFIG = AppConfig(
app_name='blog',
migrations_folder_path=os.path.join(
CURRENT_DIRECTORY,
'piccolo_migrations'
),
table_classes=[Author, Post, Category, CategoryToPost],
migration_dependencies=[],
commands=[]
)
app_name¶
This is used to identify your app, when using the piccolo
CLI, for example:
piccolo migrations forwards blog
migrations_folder_path¶
Specifies where your app’s migrations are stored. By default, a folder called
piccolo_migrations
is used.
table_classes¶
Use this to register your app’s Table
subclasses. This is important for
auto migrations.
You can register them manually (see the example above), or can use table_finder.
migration_dependencies¶
Used to specify other Piccolo apps whose migrations need to be run before the current app’s migrations.
commands¶
You can register functions and coroutines, which are automatically added to
the piccolo
CLI.
The targ library is used under the hood. It makes it really easy to write command lines tools - just use type annotations and docstrings. Here’s an example:
def say_hello(name: str):
"""
Say hello.
:param name:
The person to greet.
"""
print("hello,", name)
We then register it with the AppConfig
.
# piccolo_app.py
APP_CONFIG = AppConfig(
# ...
commands=[say_hello]
)
And from the command line:
>>> piccolo my_app say_hello bob
hello, bob
If the code contains an error to see more details in the output add a --trace
flag to the command line.
>>> piccolo my_app say_hello bob --trace
By convention, store the command definitions in a commands
folder in your
app.
my_app/
__init__.py
piccolo_app.py
commands/
__init__.py
say_hello.py
Piccolo itself is bundled with several apps - have a look at the source code for inspiration.
table_finder¶
Instead of manually registering Table
subclasses, you can use
table_finder
to automatically import any Table
subclasses from a given
list of modules.
from piccolo.conf.apps import table_finder
APP_CONFIG = AppConfig(
app_name='blog',
migrations_folder_path=os.path.join(
CURRENT_DIRECTORY,
'piccolo_migrations'
),
table_classes=table_finder(modules=['blog.tables']),
migration_dependencies=[],
commands=[]
)
The module path should be from the root of the project (the same directory as
your piccolo_conf.py
file, rather than a relative path).
You can filter the Table
subclasses returned using tags.
Source¶
- piccolo.conf.apps.table_finder(modules: Sequence[str], include_tags: Sequence[str] = None, exclude_tags: Sequence[str] = None, exclude_imported: bool = False) List[Type[Table]] ¶
Rather than explicitly importing and registering table classes with the
AppConfig
,table_finder
can be used instead. It imports anyTable
subclasses in the given modules. Tags can be used to limit whichTable
subclasses are imported.- Parameters
modules – The module paths to check for
Table
subclasses. For example,['blog.tables']
. The path should be from the root of your project, not a relative path.include_tags – If the
Table
subclass has one of these tags, it will be imported. The special tag'__all__'
will import allTable
subclasses found.exclude_tags – If the
Table
subclass has any of these tags, it won’t be imported.exclude_tags
overridesinclude_tags
.exclude_imported –
If
True
, onlyTable
subclasses defined within the module are used. AnyTable
subclasses imported by that module from other modules are ignored. For example:from piccolo.table import Table from piccolo.column import Varchar, ForeignKey from piccolo.apps.user.tables import BaseUser # excluded class Task(Table): # included title = Varchar() creator = ForeignKey(BaseUser)