Make your Odoo scripts sing.
Project description
Anthem is a tool to help scripting Odoo instances for automated setup, upgrades, testing and more.
It should be an alternative to the other tools like oerpscenario.
Make your own songs
Writing your songs is as easy as creating a Python Package. The songs functions called by anthem must have a positional ctx argument.
ctx is essentially the execution context - you can access ctx.env from it, which is an Odoo environment instance that you should be pretty much familiar with.
## songs/install.py def setup_company(ctx): """ Setup company """ company = ctx.env.ref('base.main_company') company.name = 'My Company' def main(ctx): setup_company(ctx)
Logs
A song can display some logs when executed with @anthem.log, Context.log and Context.log_line.
import anthem
@anthem.log
def setup_company(ctx):
""" Setting up company """
company = ctx.env.ref('base.main_company')
with ctx.log('Changing name'):
company.name = 'My Company'
ctx.log_line('Name changed')
with ctx.log('Loading a logo'):
company.logo = b64encode(LOGO_CONTENT)
ctx.log_line('Logo changed')
The decorator on the function will display the first line of the docstring. Both the decorator and the context manager will show the timing of the execution. The upper example gives:
Execute your songs
Use the command line anthem. Provided your songs and openerp are in the PYTHONPATH:
Anthem will execute the function main of the module songs.install with a ctx initialized with an Odoo env.
Instead of using -c for the command line, you can export the environment variable OPENERP_SERVER with the path of the configuration file.
In order to have openerp in the PYTHONPATH, you might install it as a package with pip install -e or directly modify the PYTHONPATH.
In order to have your songs in the PYTHONPATH, the better is to make a Python package out of them.
Testing
Dependencies
To run the tests, you must have Postgresql running, with accesses for your user (or you will have to modify tests/config/odoo.cfg with your database username and password).
Run the tests
To run anthem’s tests, it is a good idea to do an editable install of it in a virtualenv. You must also prepare the environment by installing odoo packages.
Odoo 9.0 (Python 2):
Odoo 10.0 (Python 2):
Odoo 11.0 (Python 3):
If need be, you can drop the test database with (adapt the version):
These steps will download the nightly release of Odoo install it as a package then install a database, so tests can be run against it (and that’s also why it is important to use a virtualenv!)
When calling pytest, you have to define the OPENERP_SERVER environment variable with the configuration file for the Odoo database that will be used for the tests.
Lyrics
Lyrics are predefined snippets written for the most commonly used cases, like:
Loading data: read (load) a data file (CSV format is supported at the moment)
Upserting a record: essentially search for the record and update it with given values, or create it in case it isn’t there yet
Updating module configuration: pre-defining a set of settings for a particular module (or set of modules)
Loading data
There’s an ability to supply data in a handy CSV format - Anthem is just able to parse and load those. load_csv method is meant to be the main entrypoint for doing so:
Param |
Description |
---|---|
ctx |
Anthem context instance |
model |
Odoo model name or model klass from ctx.env |
path |
absolute or relative path to CSV file. If a relative path is given you must provide a value for ODOO_DATA_PATH in your environment or set --odoo-data-path option. |
header |
whitelist of CSV columns to load |
header_exclude |
blacklist of CSV columns to ignore |
fmtparams |
keyword params for csv_unireader |
CSV format is similar to that of an Odoo export format, namely: * it should contain a set of field names in a header * each consecutive row defines a set of values to use to create records on a given model
Records
This section is dedicated to methods that operate on records.
Provide XMLIDs for records
This is as simple as calling anthem.records.add_xmlid with a record as a first parameter and a desired XMLID as a second.
E.g., you have a very special res.partner record foo:
from anthem.records import add_xmlid
[...]
@anthem.log
def add_xmlid_to_foo(ctx):
"""Make Jhony Foo great again."""
foo = ctx.env['res.partner'].create({
'name': 'Jhony',
'lastname': 'Foo',
})
add_xmlid(foo, '__setup__.res_partner_foo_jhony')
From now on, Jhony could be referred to as ctx.env.ref('__setup__.res_partner_foo_jhony').
Upserting a record
“Upsert” is a commonly used term that basically stands for UPDATE or INSERT. Anthem features a facility that is capable of executing that kind of operations on Odoo databases. There is a method called anthem.records.create_or_update that relies on the model, a set of values and a record XMLID.
If your goal is to create the record in the first place as well as provide an XMLID, as was shown in a previous section, create_or_update does just what you need.
Example
from anthem.records import create_or_update
[...]
@anthem.log
def create_partner_foo(ctx):
"""Ensure that Jhony Foo is known to our Company."""
create_or_update(
ctx,
model='res.partner',
xmlid='__setup__.res_partner_foo_jhony',
values={
'name': 'Jhony',
'lastname': 'Foo',
}
)
Upon calling, it would:
Try to fetch the record by a given XMLID
- If the record was found:
Update it with the given values (call record.update(values) on it)
- Otherwise:
Create a record with given values (call model.create(values))
Provide an XMLID to it (using anthem.records.add_xmlid)
In any case: return that record back
Modules
This section is dedicated to methods that operate on modules.
Uninstalling a module(s)
Sometimes you just need some particular module to be gone from your instance(s) and you’d like it done programmatically, without having to reach for each instance, search for it and hit the “Uninstall” button. Anthem can do the job for you: you can simply call an anthem.lyrics.modules.uninstall with a list of module names that you won’t use anymore.
Example (given that there are modules foo and bar that you want gone):
from anthem.lyrics.modules import uninstall
[...]
@anthem.log
def uninstall_foo(ctx):
"""Get rid of legacy `foo` and `bar`."""
uninstall(['foo', 'bar'])
Updating translations on module(s)
In a similar fashion, sometimes you need to update translations on a set of modules - anthem.lyrics.modules.update_translations is there for you :wink:
Example is similar to the previous case - just call the different method instead.
Updating module configuration
By using this feature, you’re able to preconfigure your module setup via Anthem song: you’ll just need a straight idea what needs to be done, an instance of a configuration settings model for your module (model name will do as well) and a mapping (in a form of Python dictionary) of technical configuration names with desired values.
Here’s a brief example of sale module configuration:
from anthem.lyrics import settings
[...]
@anthem.log
def define_sale_settings(ctx):
"""Configure `sale` module."""
model = ctx.env['sale.config.settings']
# it's okay to use 'sale.config.settings' as a string though
model = 'sale.config.settings'
settings(ctx, model, {
'default_invoice_policy': 'delivery',
...: ...,
'et': 'cetera',
})
Be advised: settings onchange are not triggered by this function.
Usage within Marabunta
Anthem and Marabunta are powerful when combined: you can call a set of songs inside Marabunta’s migration steps using following syntax:
...
- version: 10.0.1.0.0
operations:
pre:
- anthem songs.upgrade.your_pre_song::main
post:
- anthem songs.upgrade.your_post_song::main
By using this approach, you possess the power of full-pledged Odoo Environment instance initialized on a live database while performing a regular upgrade powered by Marabunta.
Let’s say that you have to enable multicompany with inter-company transactions on a migration to next version, lets say, 10.0.1.1.0. In this case, you’ll need a song to back this up on a Python side first:
# songs.upgrade.upgrade_10_0_1_1_0.py
from anthem.lyrics import settings
[...]
@anthem.log
def enable_multicompany(ctx):
"""Set up multicompany."""
settings(ctx, 'base.config.settings', {
# enable multicompany as it is
'group_light_multi_company': True,
# enable inter-company transactions
'module_inter_company_rules': True,
})
[...]
@anthem.log
def main(ctx):
enable_multicompany(ctx)
And then you’ll need to call it on a migration step:
...
- version: 10.0.1.1.0
operations:
post:
- anthem songs.upgrade.upgrade_10_0_1_1_0::main
Boom! Enjoy your new multicompany settings.
That’s all, folks!
Thanks for reading. Happy hacking and enjoy your songwriting skills!
Release History
Unreleased
Features
Bugfixes
Improvements
Documentation
Build
0.12.1 (2018-11-09)
Documentation
Improve API docs
Build
The lib is now automaticaly published to Pypi by Travis when a tag is added
0.12.0 (2018-03-19)
Features
Add a new option --odoo-data-path or env. variable ODOO_DATA_PATH.
The lyrics.loaders.load_csv method now accepts a relative path appended to the new option “odoo data path”. Absolute paths are still allowed.
Bugfixes
lyrics.loaders.update_translations is now deprecated as it was a duplicate from lyrics.modules.update_translations
0.11.0 (2017-12-22)
Features
Make it Python 3 and Odoo 11 compatible
Build
Switch to unicodecsv instead of custom code to handle that
Fix the flapping tests setup. Removed tox which was provoking that for some reason.
Add a lint check in build
0.10.0 (2017-09-19)
Bugfixes
Disable Odoo’s xmlrpc port
Build
Add ‘build-release.sh’ script with commands to build and upload the dist files
0.9.0 (2017-08-21)
Features
New lyrics: modules.update_translations to update translations from po files
Lyrics ‘uninstall’ has been moved from uninstaller.uninstall to modules.uninstall, previous path is still working for backward compatibility
New lyrics context manager ‘records.switch_company’
0.8.0 (2017-07-24)
Features
New lyrics: Define settings like being in the interface
Add CSV Loading columns control (columns whitelist and blacklist)
Bugfixes
Fix error when loading CSV with no rows
0.7.0 (2017-04-28)
Improvements
Split CSV loaders in functions to be able to get rows from a CSV or to load rows, enabling to modify the rows before loading them for instance
create_or_update lyrics accepts now a model so we can change its env (user, context, …)
New lyrics to uninstall module
0.6.0 (2017-01-18)
Features
CSV loaders can be used with a model in order to pass a context
Bugfixes
Fix tests by installing eggs from odoo/requirements.txt
0.5.0 (2016-10-12)
Features
Support Odoo 10
Allow to specify the encoding of an imported file, default is utf8
Bugfixes
‘records.add_xmlid’ lyrics do no longer fail when it already exists
0.4.0 (2016-08-19)
Features
New lyrics: CSV loaders from path or stream
New ctx.log_line to print a line respecting the current indentation
Improvements
Add tests for the existing lyrics
Build
Finally green builds!
0.3.0 (2016-07-26)
Features
Add –quiet mode
Fixes
Encode the logged strings to the default encoding or utf8
Allow to use Ctrl-c to stop anthem.
Set openerp’s loglevel to ERROR, its logs clutter anthem’s own outputs
0.2.0 (2016-07-22)
Features
Ability to log descriptions and timings in songs with the context manager Context.log and the decorator anthem.log.
from anthem import log @log def setup_company(ctx): """ Setup company """ # do stuff with ctx.log('other stuff'): # do other stuff @log def load_data(ctx): """ Load data """ # load @log def main(ctx): setup_company(ctx) load_data(ctx)
If we run anthem on main, we will get:
running... main running... Setup company running... other stuff other stuff: 0.850s Setup company: 1.100s running... Load data Load data: 2.900s main: 4.000s
0.1.3 (2016-07-07)
Fixes
Correct lyric to create or update a record
0.1.2 (2016-07-07)
Add a lyric to create a xmlid
Add a lyric to create or update a record
0.1.1 (2016-06-23)
Fixed crash on non-editable install.
0.1.0 (2016-06-23)
Initial release.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
File details
Details for the file anthem-0.12.1.tar.gz
.
File metadata
- Download URL: anthem-0.12.1.tar.gz
- Upload date:
- Size: 24.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/1.12.1 pkginfo/1.4.2 requests/2.20.1 setuptools/40.5.0 requests-toolbelt/0.8.0 tqdm/4.28.1 CPython/3.6.3
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | ce140da6527b8308ea4f90d262554bdf9b02df26d0c6e7cc103748096e8d48ec |
|
MD5 | 14ce7f297f61a80d35b0a2128e2dbb63 |
|
BLAKE2b-256 | 82497616bee8adfe5a61fe6807cbafd13e759c1ba8ab0f5dff82581d40380ad1 |
File details
Details for the file anthem-0.12.1-py3-none-any.whl
.
File metadata
- Download URL: anthem-0.12.1-py3-none-any.whl
- Upload date:
- Size: 19.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/1.12.1 pkginfo/1.4.2 requests/2.20.1 setuptools/40.5.0 requests-toolbelt/0.8.0 tqdm/4.28.1 CPython/3.6.3
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | b6198036ad81065de1aafffb8435d95d85524f1fe1b0174643065965dfd2cedd |
|
MD5 | d01290c40c895c3aaa34e501bc9cacfc |
|
BLAKE2b-256 | 4b667d8bf42505fdc52d8e90d5a5b272f5a9d3421b6af10f5db154051324c2a1 |
File details
Details for the file anthem-0.12.1-py2-none-any.whl
.
File metadata
- Download URL: anthem-0.12.1-py2-none-any.whl
- Upload date:
- Size: 19.0 kB
- Tags: Python 2
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/1.12.1 pkginfo/1.4.2 requests/2.20.0 setuptools/40.5.0 requests-toolbelt/0.8.0 tqdm/4.28.1 CPython/2.7.14
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | b40f83122cf38400c1683422fe23092a1f67ad154de850aa915036a2eadba0cc |
|
MD5 | 60d412b83f77893b99feff2d9abfe7ef |
|
BLAKE2b-256 | e3bdd40a8be3f78539ea38f32f56df346d6e735cf242d8102f13eba3bddf2b5e |