tools
Module¶
Auth, Mail, PluginManager and various utilities¶
-
class
gluon.tools.
Mail
(server=None, sender=None, login=None, tls=True)[source]¶ Bases:
object
Class for configuring and sending emails with alternative text / html body, multiple attachments and encryption support
Works with SMTP and Google App Engine.
Parameters: - server – SMTP server address in address:port notation
- sender – sender email address
- login – sender login name and password in login:password notation or None if no authentication is required
- tls – enables/disables encryption (True by default)
In Google App Engine use
server='gae'
For sake of backward compatibility all fields are optional and default to None, however, to be able to send emails at least server and sender must be specified. They are available under following fields:
mail.settings.server mail.settings.sender mail.settings.login mail.settings.timeout = 60 # seconds (default)
When server is ‘logging’, email is logged but not sent (debug mode)
Optionally you can use PGP encryption or X509:
mail.settings.cipher_type = None mail.settings.gpg_home = None mail.settings.sign = True mail.settings.sign_passphrase = None mail.settings.encrypt = True mail.settings.x509_sign_keyfile = None mail.settings.x509_sign_certfile = None mail.settings.x509_sign_chainfile = None mail.settings.x509_nocerts = False mail.settings.x509_crypt_certfiles = None cipher_type : None gpg - need a python-pyme package and gpgme lib x509 - smime gpg_home : you can set a GNUPGHOME environment variable to specify home of gnupg sign : sign the message (True or False) sign_passphrase : passphrase for key signing encrypt : encrypt the message (True or False). It defaults to True ... x509 only ... x509_sign_keyfile : the signers private key filename or string containing the key. (PEM format) x509_sign_certfile: the signers certificate filename or string containing the cert. (PEM format) x509_sign_chainfile: sets the optional all-in-one file where you can assemble the certificates of Certification Authorities (CA) which form the certificate chain of email certificate. It can be a string containing the certs to. (PEM format) x509_nocerts : if True then no attached certificate in mail x509_crypt_certfiles: the certificates file or strings to encrypt the messages with can be a file name / string or a list of file names / strings (PEM format)
Examples
Create Mail object with authentication data for remote server:
mail = Mail('example.com:25', 'me@example.com', 'me:password')
- Notice for GAE users:
- attachments have an automatic content_id=’attachment-i’ where i is progressive number in this way the can be referenced from the HTML as <img src=”cid:attachment-0” /> etc.
-
class
Attachment
(payload, filename=None, content_id=None, content_type=None, encoding='utf-8')[source]¶ Bases:
email.mime.base.MIMEBase
Email attachment
Parameters: - payload – path to file or file-like object with read() method
- filename – name of the attachment stored in message; if set to None, it will be fetched from payload path; file-like object payload must have explicit filename specified
- content_id – id of the attachment; automatically contained within < and >
- content_type – content type of the attachment; if set to None, it will be fetched from filename using gluon.contenttype module
- encoding – encoding of all strings passed to this function (except attachment body)
Content ID is used to identify attachments within the html body; in example, attached image with content ID ‘photo’ may be used in html message as a source of img tag <img src=”cid:photo” />.
- Example::
Create attachment from text file:
attachment = Mail.Attachment('/path/to/file.txt') Content-Type: text/plain MIME-Version: 1.0 Content-Disposition: attachment; filename="file.txt" Content-Transfer-Encoding: base64 SOMEBASE64CONTENT=
Create attachment from image file with custom filename and cid:
attachment = Mail.Attachment('/path/to/file.png', filename='photo.png', content_id='photo') Content-Type: image/png MIME-Version: 1.0 Content-Disposition: attachment; filename="photo.png" Content-Id: <photo> Content-Transfer-Encoding: base64 SOMEOTHERBASE64CONTENT=
-
Mail.
send
(to, subject='[no subject]', message='[no message]', attachments=None, cc=None, bcc=None, reply_to=None, sender=None, encoding='utf-8', raw=False, headers={}, from_address=None, cipher_type=None, sign=None, sign_passphrase=None, encrypt=None, x509_sign_keyfile=None, x509_sign_chainfile=None, x509_sign_certfile=None, x509_crypt_certfiles=None, x509_nocerts=None)[source]¶ Sends an email using data specified in constructor
Parameters: - to – list or tuple of receiver addresses; will also accept single object
- subject – subject of the email
- message –
email body text; depends on type of passed object:
- if 2-list or 2-tuple is passed: first element will be source of plain text while second of html text;
- otherwise: object will be the only source of plain text and html source will be set to None
If text or html source is:
- None: content part will be ignored,
- string: content part will be set to it,
- file-like object: content part will be fetched from it using it’s read() method
- attachments – list or tuple of Mail.Attachment objects; will also accept single object
- cc – list or tuple of carbon copy receiver addresses; will also accept single object
- bcc – list or tuple of blind carbon copy receiver addresses; will also accept single object
- reply_to – address to which reply should be composed
- encoding – encoding of all strings passed to this method (including message bodies)
- headers – dictionary of headers to refine the headers just before sending mail, e.g. {‘X-Mailer’ : ‘web2py mailer’}
- from_address – address to appear in the ‘From:’ header, this is not the envelope sender. If not specified the sender will be used
- cipher_type – gpg - need a python-pyme package and gpgme lib x509 - smime
- gpg_home – you can set a GNUPGHOME environment variable to specify home of gnupg
- sign – sign the message (True or False)
- sign_passphrase – passphrase for key signing
- encrypt – encrypt the message (True or False). It defaults to True. ... x509 only ...
- x509_sign_keyfile – the signers private key filename or string containing the key. (PEM format)
- x509_sign_certfile – the signers certificate filename or string containing the cert. (PEM format)
- x509_sign_chainfile – sets the optional all-in-one file where you can assemble the certificates of Certification Authorities (CA) which form the certificate chain of email certificate. It can be a string containing the certs to. (PEM format)
- x509_nocerts – if True then no attached certificate in mail
- x509_crypt_certfiles – the certificates file or strings to encrypt the messages with can be a file name / string or a list of file names / strings (PEM format)
Examples
Send plain text message to single address:
mail.send('you@example.com', 'Message subject', 'Plain text body of the message')
Send html message to single address:
mail.send('you@example.com', 'Message subject', '<html>Plain text body of the message</html>')
Send text and html message to three addresses (two in cc):
mail.send('you@example.com', 'Message subject', ('Plain text body', '<html>html body</html>'), cc=['other1@example.com', 'other2@example.com'])
Send html only message with image attachment available from the message by ‘photo’ content id:
mail.send('you@example.com', 'Message subject', (None, '<html><img src="cid:photo" /></html>'), Mail.Attachment('/path/to/photo.jpg' content_id='photo'))
Send email with two attachments and no body text:
mail.send('you@example.com, 'Message subject', None, [Mail.Attachment('/path/to/fist.file'), Mail.Attachment('/path/to/second.file')])
Returns: True on success, False on failure. Before return, method updates two object’s fields:
- self.result: return value of smtplib.SMTP.sendmail() or GAE’s mail.send_mail() method
- self.error: Exception message or None if above was successful
-
class
gluon.tools.
Auth
(environment=None, db=None, mailer=True, hmac_key=None, controller='default', function='user', cas_provider=None, signature=True, secure=False, csrf_prevention=True, propagate_extension=None, url_index=None)[source]¶ Bases:
object
-
accessible_query
(name, table, user_id=None)[source]¶ Returns a query with all accessible records for user_id or the current logged in user this method does not work on GAE because uses JOIN and IN
Example
Use as:
db(auth.accessible_query('read', db.mytable)).select(db.mytable.ALL)
-
add_membership
(group_id=None, user_id=None, role=None)[source]¶ Gives user_id membership of group_id or role if user is None than user_id is that of current logged in user
-
add_permission
(group_id, name='any', table_name='', record_id=0)[source]¶ Gives group_id ‘name’ access to ‘table_name’ and ‘record_id’
-
static
archive
(form, archive_table=None, current_record='current_record', archive_current=False, fields=None)[source]¶ If you have a table (db.mytable) that needs full revision history you can just do:
form=crud.update(db.mytable,myrecord,onaccept=auth.archive)
or:
form=SQLFORM(db.mytable,myrecord).process(onaccept=auth.archive)
crud.archive will define a new table “mytable_archive” and store a copy of the current record (if archive_current=True) or a copy of the previous record (if archive_current=False) in the newly created table including a reference to the current record.
fields allows to specify extra fields that need to be archived.
If you want to access such table you need to define it yourself in a model:
db.define_table('mytable_archive', Field('current_record',db.mytable), db.mytable)
Notice such table includes all fields of db.mytable plus one: current_record. crud.archive does not timestamp the stored record unless your original table has a fields like:
db.define_table(..., Field('saved_on','datetime', default=request.now,update=request.now,writable=False), Field('saved_by',auth.user, default=auth.user_id,update=auth.user_id,writable=False),
there is nothing special about these fields since they are filled before the record is archived.
If you want to change the archive table name and the name of the reference field you can do, for example:
db.define_table('myhistory', Field('parent_record',db.mytable), db.mytable)
and use it as:
form=crud.update(db.mytable,myrecord, onaccept=lambda form:crud.archive(form, archive_table=db.myhistory, current_record='parent_record'))
-
basic
(basic_auth_realm=False)[source]¶ Performs basic login.
Parameters: basic_auth_realm – optional basic http authentication realm. Can take str or unicode or function or callable or boolean. reads current.request.env.http_authorization and returns basic_allowed,basic_accepted,user.
if basic_auth_realm is defined is a callable it’s return value is used to set the basic authentication realm, if it’s a string its content is used instead. Otherwise basic authentication realm is set to the application name. If basic_auth_realm is None or False (the default) the behavior is to skip sending any challenge.
-
cas_login
(next=<function <lambda>>, onvalidation=<function <lambda>>, onaccept=<function <lambda>>, log=<function <lambda>>, version=2)[source]¶
-
change_password
(next=<function <lambda>>, onvalidation=<function <lambda>>, onaccept=<function <lambda>>, log=<function <lambda>>)[source]¶ Returns a form that lets the user change password
-
default_messages
= {'invalid_email': 'Invalid email', 'verify_email_subject': 'Email verification', 'password_change_button': 'Change password', 'unable_send_email': 'Unable to send email', 'has_permission_log': None, 'label_email': 'E-mail', 'add_group_log': 'Group %(group_id)s created', 'verify_email': 'Welcome %(username)s! Click on the link %(link)s to verify your email', 'impersonate_log': 'User %(id)s is impersonating %(other_id)s', 'retrieve_username': 'Your username is: %(username)s', 'label_record_id': 'Record ID', 'register_log': 'User %(id)s Registered', 'username_taken': 'Username already taken', 'verify_password': 'Verify Password', 'label_remember_me': 'Remember me (for 30 days)', 'retrieve_username_log': 'User %(id)s Username retrieved', 'email_taken': 'This email already has an account', 'registration_successful': 'Registration successful', 'label_password': 'Password', 'logged_in': 'Logged in', 'profile_save_button': 'Apply changes', 'login_disabled': 'Login disabled by administrator', 'label_user_id': 'User ID', 'label_first_name': 'First name', 'del_group_log': 'Group %(group_id)s deleted', 'registration_verifying': 'Registration needs verification', 'add_permission_log': None, 'invalid_username': 'Invalid username', 'del_membership_log': None, 'login_button': 'Log In', 'registration_pending': 'Registration is pending approval', 'retrieve_password': 'Your password is: %(password)s', 'invalid_login': 'Invalid login', 'retrieve_username_subject': 'Username retrieve', 'change_password_log': 'User %(id)s Password changed', 'reset_password': 'Click on the link %(link)s to reset your password', 'email_sent': 'Email sent', 'register_button': 'Sign Up', 'logout_log': 'User %(id)s Logged-out', 'access_denied': 'Insufficient privileges', 'new_password_sent': 'A new password was emailed to you', 'delete_label': 'Check to delete', 'verify_password_comment': 'please input your password again', 'submit_button': 'Submit', 'label_reset_password_key': 'Reset Password key', 'label_role': 'Role', 'label_time_stamp': 'Timestamp', 'profile_updated': 'Profile updated', 'logged_out': 'Logged out', 'login_failed_log': None, 'verify_email_log': 'User %(id)s Verification email sent', 'label_name': 'Name', 'function_disabled': 'Function disabled', 'label_registration_key': 'Registration key', 'label_last_name': 'Last name', 'label_description': 'Description', 'label_table_name': 'Object or table name', 'password_changed': 'Password changed', 'new_password': 'New password', 'label_registration_id': 'Registration identifier', 'retrieve_password_log': 'User %(id)s Password retrieved', 'label_origin': 'Origin', 'reset_password_log': 'User %(id)s Password reset', 'invalid_password': 'Invalid password', 'login_log': 'User %(id)s Logged-in', 'profile_log': 'User %(id)s Profile updated', 'invalid_reset_password': 'Invalid reset password', 'password_reset_button': 'Request reset password', 'is_empty': 'Cannot be empty', 'add_membership_log': None, 'label_client_ip': 'Client IP', 'invalid_user': 'Invalid user', 'has_membership_log': None, 'group_description': 'Group uniquely assigned to user %(id)s', 'unable_to_send_email': 'Unable to send email', 'reset_password_subject': 'Password reset', 'label_group_id': 'Group ID', 'email_verified': 'Email verified', 'mismatched_password': "Password fields don't match", 'del_permission_log': None, 'retrieve_password_subject': 'Password retrieve', 'username_sent': 'Your username was emailed to you', 'old_password': 'Old password', 'label_username': 'Username'}¶ Class for authentication, authorization, role based access control.
Includes:
- registration and profile
- login and logout
- username and password retrieval
- event logging
- role creation and assignment
- user defined group/role based permission
Parameters: - environment – is there for legacy but unused (awful)
- db – has to be the database where to create tables for authentication
- mailer – Mail(...) or None (no mailer) or True (make a mailer)
- hmac_key – can be a hmac_key or hmac_key=Auth.get_or_create_key()
- controller – (where is the user action?)
- cas_provider – (delegate authentication to the URL, CAS2)
Authentication Example:
from gluon.contrib.utils import * mail=Mail() mail.settings.server='smtp.gmail.com:587' mail.settings.sender='you@somewhere.com' mail.settings.login='username:password' auth=Auth(db) auth.settings.mailer=mail # auth.settings....=... auth.define_tables() def authentication(): return dict(form=auth())
Exposes:
- http://.../{application}/{controller}/authentication/login
- http://.../{application}/{controller}/authentication/logout
- http://.../{application}/{controller}/authentication/register
- http://.../{application}/{controller}/authentication/verify_email
- http://.../{application}/{controller}/authentication/retrieve_username
- http://.../{application}/{controller}/authentication/retrieve_password
- http://.../{application}/{controller}/authentication/reset_password
- http://.../{application}/{controller}/authentication/profile
- http://.../{application}/{controller}/authentication/change_password
On registration a group with role=new_user.id is created and user is given membership of this group.
You can create a group with:
group_id=auth.add_group('Manager', 'can access the manage action') auth.add_permission(group_id, 'access to manage')
Here “access to manage” is just a user defined string. You can give access to a user:
auth.add_membership(group_id, user_id)
If user id is omitted, the logged in user is assumed
Then you can decorate any action:
@auth.requires_permission('access to manage') def manage(): return dict()
You can restrict a permission to a specific table:
auth.add_permission(group_id, 'edit', db.sometable) @auth.requires_permission('edit', db.sometable)
Or to a specific record:
auth.add_permission(group_id, 'edit', db.sometable, 45) @auth.requires_permission('edit', db.sometable, 45)
If authorization is not granted calls:
auth.settings.on_failed_authorization
Other options:
auth.settings.mailer=None auth.settings.expiration=3600 # seconds ... ### these are messages that can be customized ...
-
default_settings
= {'profile_fields': None, 'table_permission': None, 'table_event_name': 'auth_event', 'login_userfield': None, 'table_event': None, 'register_captcha': None, 'label_separator': None, 'hideerror': False, 'table_permission_name': 'auth_permission', 'pre_registration_div': None, 'table_cas_name': 'auth_cas', 'allow_basic_login_only': False, 'manager_actions': {}, 'remember_me_form': True, 'logout_onlogout': None, 'client_side': True, 'table_membership': None, 'ondelete': 'CASCADE', 'register_verify_password': True, 'renew_session_onlogout': True, 'long_expiration': 2592000, 'registration_requires_verification': False, 'username_case_sensitive': True, 'logging_enabled': True, 'keep_session_onlogout': False, 'login_after_password_change': True, 'prevent_password_reset_attacks': True, 'expiration': 3600, 'allow_basic_login': False, 'create_user_groups': 'user_%(id)s', 'wiki': <Storage {}>, 'update_fields': ['email'], 'showid': False, 'retrieve_username_captcha': None, 'two_factor_authentication_group': None, 'password_field': 'password', 'keep_session_onlogin': True, 'table_cas': None, 'captcha': None, 'registration_requires_approval': False, 'table_user_name': 'auth_user', 'table_user': None, 'password_min_length': 4, 'renew_session_onlogin': True, 'register_fields': None, 'allow_delete_accounts': False, 'auth_manager_role': None, 'login_email_validate': True, 'alternate_requires_registration': False, 'email_case_sensitive': True, 'use_username': False, 'formstyle': None, 'everybody_group_id': None, 'prevent_open_redirect_attacks': True, 'reset_password_requires_verification': False, 'cas_maps': None, 'login_after_registration': False, 'login_captcha': None, 'multi_login': False, 'retrieve_password_captcha': None, 'on_failed_authentication': <function <lambda> at 0x7fd4c88162a8>, 'table_group_name': 'auth_group', 'table_group': None, 'table_membership_name': 'auth_membership'}¶
-
define_tables
(username=None, signature=None, migrate=None, fake_migrate=None)[source]¶ To be called unless tables are defined manually
Examples
Use as:
# defines all needed tables and table files # 'myprefix_auth_user.table', ... auth.define_tables(migrate='myprefix_') # defines all needed tables without migration/table files auth.define_tables(migrate=False)
-
del_membership
(group_id=None, user_id=None, role=None)[source]¶ Revokes membership from group_id to user_id if user_id is None than user_id is that of current logged in user
-
del_permission
(group_id, name='any', table_name='', record_id=0)[source]¶ Revokes group_id ‘name’ access to ‘table_name’ and ‘record_id’
-
enable_record_versioning
(tables, archive_db=None, archive_names='%(tablename)s_archive', current_record='current_record', current_record_label=None)[source]¶ Used to enable full record versioning (including auth tables):
auth = Auth(db) auth.define_tables(signature=True) # define our own tables db.define_table('mything',Field('name'),auth.signature) auth.enable_record_versioning(tables=db)
tables can be the db (all table) or a list of tables. only tables with modified_by and modified_on fiels (as created by auth.signature) will have versioning. Old record versions will be in table ‘mything_archive’ automatically defined.
when you enable enable_record_versioning, records are never deleted but marked with is_active=False.
enable_record_versioning enables a common_filter for every table that filters out records with is_active = False
Note
If you use auth.enable_record_versioning, do not use auth.archive or you will end up with duplicates. auth.archive does explicitly what enable_record_versioning does automatically.
-
get_or_create_user
(keys, update_fields=['email'], login=True, get=True)[source]¶ Used for alternate login methods: If the user exists already then password is updated. If the user doesn’t yet exist, then they are created.
-
has_membership
(group_id=None, user_id=None, role=None)[source]¶ Checks if user is member of group_id or role
-
has_permission
(name='any', table_name='', record_id=0, user_id=None, group_id=None)[source]¶ Checks if user_id or current logged in user is member of a group that has ‘name’ permission on ‘table_name’ and ‘record_id’ if group_id is passed, it checks whether the group has the permission
-
impersonate
(user_id=<function <lambda>>)[source]¶ To use this make a POST to http://..../impersonate request.post_vars.user_id=<id>
Set request.post_vars.user_id to 0 to restore original user.
requires impersonator is logged in and:
has_permission('impersonate', 'auth_user', user_id)
-
is_logged_in
()[source]¶ Checks if the user is logged in and returns True/False. If so user is in auth.user as well as in session.auth.user
-
log_event
(description, vars=None, origin='auth')[source]¶ Examples
Use as:
auth.log_event(description='this happened', origin='auth')
-
login
(next=<function <lambda>>, onvalidation=<function <lambda>>, onaccept=<function <lambda>>, log=<function <lambda>>)[source]¶ Returns a login form
-
login_bare
(username, password)[source]¶ Logins user as specified by username (or email) and password
-
logout
(next=<function <lambda>>, onlogout=<function <lambda>>, log=<function <lambda>>)[source]¶ Logouts and redirects to login
Navbar with support for more templates This uses some code from the old navbar.
Parameters: mode – see options for list of
You can change the view for this page to make it look as you like
-
profile
(next=<function <lambda>>, onvalidation=<function <lambda>>, onaccept=<function <lambda>>, log=<function <lambda>>)[source]¶ Returns a form that lets the user change his/her profile
-
register
(next=<function <lambda>>, onvalidation=<function <lambda>>, onaccept=<function <lambda>>, log=<function <lambda>>)[source]¶ Returns a registration form
-
register_bare
(**fields)[source]¶ Registers a user as specified by username (or email) and a raw password.
-
request_reset_password
(next=<function <lambda>>, onvalidation=<function <lambda>>, onaccept=<function <lambda>>, log=<function <lambda>>)[source]¶ Returns a form to reset the user password
-
requires
(condition, requires_login=True, otherwise=None)[source]¶ Decorator that prevents access to action if not logged in
-
requires_membership
(role=None, group_id=None, otherwise=None)[source]¶ Decorator that prevents access to action if not logged in or if user logged in is not a member of group_id. If role is provided instead of group_id then the group_id is calculated.
-
requires_permission
(name, table_name='', record_id=0, otherwise=None)[source]¶ Decorator that prevents access to action if not logged in or if user logged in is not a member of any group (role) that has ‘name’ access to ‘table_name’, ‘record_id’.
-
requires_signature
(otherwise=None, hash_vars=True)[source]¶ Decorator that prevents access to action if not logged in or if user logged in is not a member of group_id. If role is provided instead of group_id then the group_id is calculated.
-
reset_password
(next=<function <lambda>>, onvalidation=<function <lambda>>, onaccept=<function <lambda>>, log=<function <lambda>>)[source]¶ Returns a form to reset the user password
-
reset_password_deprecated
(next=<function <lambda>>, onvalidation=<function <lambda>>, onaccept=<function <lambda>>, log=<function <lambda>>)[source]¶ Returns a form to reset the user password (deprecated)
-
retrieve_password
(next=<function <lambda>>, onvalidation=<function <lambda>>, onaccept=<function <lambda>>, log=<function <lambda>>)[source]¶
-
retrieve_username
(next=<function <lambda>>, onvalidation=<function <lambda>>, onaccept=<function <lambda>>, log=<function <lambda>>)[source]¶ Returns a form to retrieve the user username (only if there is a username field)
-
user_group
(user_id=None)[source]¶ Returns the group_id of the group uniquely associated to this user i.e. role=user:[user_id]
-
user_id
¶ user.id or None
-
verify_email
(next=<function <lambda>>, onaccept=<function <lambda>>, log=<function <lambda>>)[source]¶ Action used to verify the registration email
-
wiki
(slug=None, env=None, render='markmin', manage_permissions=False, force_prefix='', restrict_search=False, resolve=True, extra=None, menu_groups=None, templates=None, migrate=True, controller=None, function=None, force_render=False, groups=None)[source]¶
To be used in menu.py for app wide wiki menus
-
-
class
gluon.tools.
Recaptcha
(request=None, public_key='', private_key='', use_ssl=False, error=None, error_message='invalid', label='Verify:', options='', comment='', ajax=False)[source]¶ Bases:
gluon.html.DIV
Examples
Use as:
form = FORM(Recaptcha(public_key='...',private_key='...'))
or:
form = SQLFORM(...) form.append(Recaptcha(public_key='...',private_key='...'))
-
API_SERVER
= 'http://www.google.com/recaptcha/api'¶
-
API_SSL_SERVER
= 'https://www.google.com/recaptcha/api'¶
-
VERIFY_SERVER
= 'http://www.google.com/recaptcha/api/verify'¶
-
-
class
gluon.tools.
Recaptcha2
(request=None, public_key='', private_key='', error_message='invalid', label='Verify:', options=None, comment='')[source]¶ Bases:
gluon.html.DIV
Experimental: Creates a DIV holding the newer Recaptcha from Google (v2)
Parameters: - request – the request. If not passed, uses current request
- public_key – the public key Google gave you
- private_key – the private key Google gave you
- error_message – the error message to show if verification fails
- label – the label to use
- options (dict) –
takes these parameters
- hl
- theme
- type
- tabindex
- callback
- expired-callback
see https://developers.google.com/recaptcha/docs/display for docs about those
- comment – the comment
Examples
Use as:
form = FORM(Recaptcha2(public_key='...',private_key='...'))
or:
form = SQLFORM(...) form.append(Recaptcha2(public_key='...',private_key='...'))
to protect the login page instead, use:
from gluon.tools import Recaptcha2 auth.settings.captcha = Recaptcha2(request, public_key='...',private_key='...')
-
API_URI
= 'https://www.google.com/recaptcha/api.js'¶
-
VERIFY_SERVER
= 'https://www.google.com/recaptcha/api/siteverify'¶
-
class
gluon.tools.
Crud
(environment, db=None, controller='default')[source]¶ Bases:
object
-
create
(table, next=<function <lambda>>, onvalidation=<function <lambda>>, onaccept=<function <lambda>>, log=<function <lambda>>, message=<function <lambda>>, formname=<function <lambda>>, **attributes)[source]¶
-
search
(*tables, **args)[source]¶ Creates a search form and its results for a table .. rubric:: Examples
Use as:
form, results = crud.search(db.test, queries = ['equals', 'not equal', 'contains'], query_labels={'equals':'Equals', 'not equal':'Not equal'}, fields = ['id','children'], field_labels = { 'id':'ID','children':'Children'}, zero='Please choose', query = (db.test.id > 0)&(db.test.id != 3) )
-
-
class
gluon.tools.
Service
(environment=None)[source]¶ Bases:
object
-
Service.
amfrpc
(f)[source]¶ Example
Use as:
service = Service() @service.amfrpc def myfunction(a, b): return a + b def call(): return service()
Then call it with:
wget http://..../app/default/call/amfrpc/myfunction?a=hello&b=world
-
Service.
amfrpc3
(domain='default')[source]¶ Example
Use as:
service = Service() @service.amfrpc3('domain') def myfunction(a, b): return a + b def call(): return service()
Then call it with:
-
Service.
csv
(f)[source]¶ Example
Use as:
service = Service() @service.csv def myfunction(a, b): return a + b def call(): return service()
Then call it with:
wget http://..../app/default/call/csv/myfunction?a=3&b=4
-
Service.
json
(f)[source]¶ Example
Use as:
service = Service() @service.json def myfunction(a, b): return [{a: b}] def call(): return service()
Then call it with:;
-
Service.
jsonrpc
(f)[source]¶ Example
Use as:
service = Service() @service.jsonrpc def myfunction(a, b): return a + b def call(): return service()
Then call it with:
-
Service.
jsonrpc2
(f)[source]¶ Example
Use as:
service = Service() @service.jsonrpc2 def myfunction(a, b): return a + b def call(): return service()
Then call it with:
wget –post-data ‘{“jsonrpc”: “2.0”, “id”: 1, “method”: “myfunction”, “params”: {“a”: 1, “b”: 2}}’ http://..../app/default/call/jsonrpc2
-
Service.
jsonrpc_errors
= {-32700: ('Parse error. Invalid JSON was received by the server.', 'An error occurred on the server while parsing the JSON text.'), -32603: ('Internal error', 'Internal JSON-RPC error.'), -32602: ('Invalid params', 'Invalid method parameter(s).'), -32601: ('Method not found', 'The method does not exist / is not available.'), -32600: ('Invalid Request', 'The JSON sent is not a valid Request object.'), -32099: ('Server error', 'Reserved for implementation-defined server-errors.')}¶
-
Service.
rss
(f)[source]¶ Example
Use as:
service = Service() @service.rss def myfunction(): return dict(title=..., link=..., description=..., created_on=..., entries=[dict(title=..., link=..., description=..., created_on=...]) def call(): return service()
Then call it with:
-
Service.
run
(f)[source]¶ Example
Use as:
service = Service() @service.run def myfunction(a, b): return a + b def call(): return service()
Then call it with:
wget http://..../app/default/call/run/myfunction?a=3&b=4
-
Service.
soap
(name=None, returns=None, args=None, doc=None)[source]¶ Example
Use as:
service = Service() @service.soap('MyFunction',returns={'result':int},args={'a':int,'b':int,}) def myfunction(a, b): return a + b def call(): return service()
Then call it with:
from gluon.contrib.pysimplesoap.client import SoapClient client = SoapClient(wsdl="http://..../app/default/call/soap?WSDL") response = client.MyFunction(a=1,b=2) return response['result']
It also exposes online generated documentation and xml example messages at http://..../app/default/call/soap
-
-
class
gluon.tools.
Wiki
(auth, env=None, render='markmin', manage_permissions=False, force_prefix='', restrict_search=False, extra=None, menu_groups=None, templates=None, migrate=True, controller=None, function=None, groups=None)[source]¶ Bases:
object
adds the menu if not present
-
static
component
(text)[source]¶ In wiki docs allows @{component:controller/function/args} which renders as a LOAD(..., ajax=True)
-
everybody
= 'everybody'¶
-
rows_page
= 25¶
-
class
gluon.tools.
PluginManager
(plugin=None, **defaults)[source]¶ Bases:
object
Plugin Manager is similar to a storage object but it is a single level singleton. This means that multiple instances within the same thread share the same attributes. Its constructor is also special. The first argument is the name of the plugin you are defining. The named arguments are parameters needed by the plugin with default values. If the parameters were previous defined, the old values are used.
Example
in some general configuration file:
plugins = PluginManager() plugins.me.param1=3
within the plugin model:
_ = PluginManager('me',param1=5,param2=6,param3=7)
where the plugin is used:
>>> print plugins.me.param1 3 >>> print plugins.me.param2 6 >>> plugins.me.param3 = 8 >>> print plugins.me.param3 8
Here are some tests:
>>> a=PluginManager() >>> a.x=6 >>> b=PluginManager('check') >>> print b.x 6 >>> b=PluginManager() # reset settings >>> print b.x <Storage {}> >>> b.x=7 >>> print a.x 7 >>> a.y.z=8 >>> print b.y.z 8 >>> test_thread_separation() 5 >>> plugins=PluginManager('me',db='mydb') >>> print plugins.me.db mydb >>> print 'me' in plugins True >>> print plugins.me.installed True
-
instances
= {}¶
-
-
gluon.tools.
fetch
(url, data=None, headers=None, cookie=<SimpleCookie: >, user_agent='Mozilla/5.0')[source]¶