From Fedora Project Wiki
(Add kitchen)
(Make web frameworks a subhead of libraries)
Line 1: Line 1:
== Best Practices for Fedora Infrastructure Apps ==
== Coding style ==                                                                                                                                                                  
 
=== Coding style ===                                                                                                                                                                   
* Python code should be [http://www.python.org/dev/peps/pep-0008/ PEP8 compliant]
* Python code should be [http://www.python.org/dev/peps/pep-0008/ PEP8 compliant]


==== Tools to improve style ====
You can run pylint over your code once in a while to help catch PEP8 violations.  pyflakes and pep8 (the program) are fast enough that you could  setup your editor to [http://lewk.org/blog/python-vim-pyflakes run them whenever you save] a python file (but they don't catch nearly as many things as pylint does).
You can run pylint over your code once in a while to help catch PEP8 violations.  pyflakes and pep8 (the program) are fast enough that you could  setup your editor to [http://lewk.org/blog/python-vim-pyflakes run them whenever you save] a python file (but they don't catch nearly as many things as pylint does).


== Common Programming Issues ==
=== Centralized logging ===
=== Centralized logging ===
                                                                                                                                                                            
                                                                                                                                                                            
Line 62: Line 62:
# The exception messages aren't intended for end users -- they're to help with debugging or other coders.  So it's not very useful to translate them.
# The exception messages aren't intended for end users -- they're to help with debugging or other coders.  So it's not very useful to translate them.


=== Libraries to use ===
=== fedmsg ===
 
Think about how to add fedmsg hooks into every event that changes data.  However, also make it so that fedmsg is optional (ie: the app doesn't fail if fedmsg is not available/installed).  This makes it easier to test apps outside of infrastructure and makes us more robust in case fedmsg starts failing sometime.
 
== Libraries to use ==


* kitchen: A library of common code that we've needed in Fedora.  Lots of code to deal with unicode issues and localization.  A few other things as well. [http://packages.python.org/kitchen/ Docs]  <code>yum install python-kitchen</code>
* kitchen: A library of common code that we've needed in Fedora.  Lots of code to deal with unicode issues and localization.  A few other things as well. [http://packages.python.org/kitchen/ Docs]  <code>yum install python-kitchen</code>
Line 70: Line 74:
Use one of Flask, Pyramid, or TurboGears2.  Limiting the number of web frameworks we're responsible for will greatly help with our long term maintenance burden.
Use one of Flask, Pyramid, or TurboGears2.  Limiting the number of web frameworks we're responsible for will greatly help with our long term maintenance burden.


== Common Development Tasks ==
=== Use git flow ===
=== Use git flow ===
First, <code>yum install gitflow</code>.
First, <code>yum install gitflow</code>.
Line 111: Line 116:


{{admon/question|hotfix recipe|Add a hotfix recipe in the cheatsheet}}
{{admon/question|hotfix recipe|Add a hotfix recipe in the cheatsheet}}
=== fedmsg ===
Think about how to add fedmsg hooks into every event that changes data.  However, also make it so that fedmsg is optional (ie: the app doesn't fail if fedmsg is not available/installed).  This makes it easier to test apps outside of infrastructure and makes us more robust in case fedmsg starts failing sometime.

Revision as of 21:33, 24 January 2013

Coding style

Tools to improve style

You can run pylint over your code once in a while to help catch PEP8 violations. pyflakes and pep8 (the program) are fast enough that you could setup your editor to run them whenever you save a python file (but they don't catch nearly as many things as pylint does).

Common Programming Issues

Centralized logging

Most of our apps use the standard Python logging module, which usually ends up logging to /var/log/httpd/error_log on the app server.

To have your app logs shipped to our central logging server, you can configure the SysLogHandler to do so.

For config-file based logging setups, you can do something like the following:

[logging]                                                                                                                                                             
                                                                                                                                                                          
[[handlers]]                                                                                                                                                          
                                                                                                                                                                         
[[[syslog_out]]]                                                                                                                                                      
class='handlers.SysLogHandler'                                                                                                                                        
args="('/dev/log', handlers.SysLogHandler.LOG_LOCAL4,)"                                                                                                               
formatter='full_content'                                                                                                                                              
                                                                                                                                                                          
[[loggers]]                                                                                                                                                           
                                                                                                                                                                          
[[[bodhi]]]                                                                                                                                                           
level='DEBUG'                                                                                                                                                         
qualname='bodhi'                                                                                                                                                      
handlers=['syslog_out']                                                                                                                                               
propagate=0                                                                                                                                                           

Here is an example of doing it in pure Python:

import logging
import logging.handlers

syslogger = logging.getLogger('bodhi')
syslogger.setLevel(logging.DEBUG)
handler = logging.handlers.SysLogHandler(address='/dev/log', facility=logging.handlers.SysLogHandler.LOG_LOCAL4)
syslogger.addHandler(handler)
syslogger.info('Hello SysLog!')

The app logs will then appear in /var/log/hosts/<HOST>/<YEAR>/<MONTH>/<DAY>/apps.log as well as the merged log /var/log/merged/apps.log on our central rsyslog server.

Translations

Use transifex to manage translations and add the projects to the Fedora Project Team so the Fedora i18n team can translate.

Do not mark Exception messages for translation. We want those to remain untranslated for several reasons:

  1. It's easier to do a web search for the exceptions if the messages aren't translated.
  2. Translators don't know what all the technical information in exception messages are so the translations aren't always accurate.
  3. The exception messages aren't intended for end users -- they're to help with debugging or other coders. So it's not very useful to translate them.

fedmsg

Think about how to add fedmsg hooks into every event that changes data. However, also make it so that fedmsg is optional (ie: the app doesn't fail if fedmsg is not available/installed). This makes it easier to test apps outside of infrastructure and makes us more robust in case fedmsg starts failing sometime.

Libraries to use

  • kitchen: A library of common code that we've needed in Fedora. Lots of code to deal with unicode issues and localization. A few other things as well. Docs yum install python-kitchen

Web Frameworks

Use one of Flask, Pyramid, or TurboGears2. Limiting the number of web frameworks we're responsible for will greatly help with our long term maintenance burden.

Common Development Tasks

Use git flow

First, yum install gitflow.

Quick cheatsheet for getting started. You can also read:

# First thing when you initially clone a repo
$ git flow init

# Always work on the 'devel' or 'develop' branch if just doing small maintenance

# Working on a major feature
# git flow creates feature branches that are prefixed with feature/
$ git flow feature start my-new-feature
$ # make edits, commit

# Share that feature with others for review
$ git flow feature publish my-new-feature

# When you're done.. you can merge it on github with a click, or if you'd like to do so from the CLI
$ git flow feature finish my-new-feature

# Working on a release
# Releases end up on the master branch
$ git flow release start 0.3.32
$ # make some edits, bump version numbers, commit, release to pypi.
$ git flow release finish 0.3.32
$ git push --all
$ git push --tags

This quick overview and a more in depth article on using it.

If you're more comfortable using vanilla git without the gitflow addon, the things to be aware of are:

  • new commits should go to the devel branch (the default on the repos we set up on github).
  • master is used to make releases from and should reflect what's in production (or in an rpm, ready to be pushed to production) at any given time.
  • hotfixes have their own branches that need to be merged into both master (for release) and devel.
hotfix recipe
Add a hotfix recipe in the cheatsheet