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: Optional[Sequence[str]] = None, exclude_tags: Optional[Sequence[str]] = None, exclude_imported: bool = False) List[Type[Table]]¶
Rather than explicitly importing and registering table classes with the
AppConfig,table_findercan be used instead. It imports anyTablesubclasses in the given modules. Tags can be used to limit whichTablesubclasses are imported.- Parameters:
modules – The module paths to check for
Tablesubclasses. For example,['blog.tables']. The path should be from the root of your project, not a relative path.include_tags – If the
Tablesubclass has one of these tags, it will be imported. The special tag'__all__'will import allTablesubclasses found.exclude_tags – If the
Tablesubclass has any of these tags, it won’t be imported.exclude_tagsoverridesinclude_tags.exclude_imported –
If
True, onlyTablesubclasses defined within the module are used. AnyTablesubclasses 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)