pyams_utils package ⊞

PyAMS_utils package

PyAMS generic modules

pyams_utils.get_field_doc(self)[source]

Try to get FieldProperty field docstring from field interface

pyams_utils.includeme(config)[source]

pyams_utils features include

pyams_utils.adapter

Adapters management package

This package provides a small set of standard base adapters for context, context and request, and context and request and view.

See Zope Component Architecture with PyAMS to see how PyAMS can help components management.

class pyams_utils.adapter.ContextAdapter(context)[source]

Bases: object

Context adapter

class pyams_utils.adapter.ContextRequestAdapter(context, request)[source]

Bases: object

Context + request multi-adapter

class pyams_utils.adapter.ContextRequestViewAdapter(context, request, view)[source]

Bases: object

Context + request + view multi-adapter

class pyams_utils.adapter.NullAdapter[source]

Bases: object

An adapter which always return None!

Can be useful to override a default adapter…

class pyams_utils.adapter.adapter_config(**settings)[source]

Bases: object

Function or class decorator to declare an adapter

Annotation parameters can be:

Parameters:
  • name (str='') – name of the adapter
  • context ([Interface...]) – an interface, or a tuple of interfaces, that the component adapts
  • provides (Interface) – the interface that the adapter provides
  • registry – the registry into which adapter registration should be made
venusian = <module 'venusian' from '/home/docs/checkouts/readthedocs.org/user_builds/pyams/envs/latest/lib/python3.7/site-packages/venusian/__init__.py'>
pyams_utils.adapter.get_adapter_weight(item)[source]

Get adapters weight sort key

pyams_utils.adapter.get_annotation_adapter(context, key, factory=None, markers=None, notify=True, locate=True, parent=None, name=None, callback=None, **kwargs)[source]

Get an adapter via object’s annotations, creating it if not existent

Parameters:
  • context (object) – context object which should be adapted
  • key (str) – annotations key to look for
  • factory – if annotations key is not found, this is the factory which will be used to create a new object; factory can be a class or callable object, or an interface for which a factory has been registered; if factory is None and is requested object can’t be found, None is returned
  • markers – if not None, list of marker interfaces which created adapter should provide
  • notify (bool=True) – if ‘False’, no notification event will be sent on object creation
  • locate (bool=True) – if ‘False’, the new object is not attached to any parent
  • parent (object=None) – parent to which new object is attached; if None, object is attached to context
  • name (str=None) – if locate is not False, this is the name with which the new object is attached to it’s parent
  • callback – if not None, callback function which will be called after object creation

pyams_utils.attr

PyAMS_utils.attr module

This module provides an ITraversable adapter which can be used to get access to an object’s attribute from a browser URL. This adapter is actually used to get access to ‘file’ attributes in PyAMS_file package.

class pyams_utils.attr.AttributeTraverser(context)[source]

Bases: pyams_utils.adapter.ContextAdapter

++attr++ namespace traverser

This custom traversing adapter can be used to access an object attribute directly from an URL by using a path like this:

/path/to/object/++attr++name

Where name is the name of the requested attribute.

traverse(name, furtherpath=None)[source]

Traverse from current context to given attribute

pyams_utils.cache

PyAMS_utils.cache module

This module provides a small set of adapters which can be used to provide a “cache key” value to any kind of object.

The goal of such a cache key value is to provide a string representation, as stable as possible, of a given object; this string can be used as a cache key, but also to define an object ID inside an HTML page. A TALES helper extension is also provided to get an object’s cache key from a Chameleon template.

class pyams_utils.cache.CacheKeyTalesExtension(context, request, view)[source]

Bases: pyams_utils.adapter.ContextRequestViewAdapter

extension:cache_key(context) TALES extension

A PyAMS TALES extension which allows to render cache key value for a given context.

render(context=None)[source]

Rendering of TALES extension

pyams_utils.cache.object_cache_key_adapter(obj)[source]

Cache key adapter for any object

>>> from pyramid.testing import setUp, tearDown
>>> config = setUp()
>>> from pyams_utils.interfaces import ICacheKeyValue
>>> from pyams_utils.cache import object_cache_key_adapter
>>> config.registry.registerAdapter(object_cache_key_adapter, (object, ), ICacheKeyValue)
>>> value = object()
>>> key = ICacheKeyValue(value)
>>> key == str(id(value))
True
>>> tearDown()
pyams_utils.cache.persistent_cache_key_adapter(obj)[source]

Cache key adapter for persistent object

pyams_utils.cache.string_cache_key_adapter(obj)[source]

Cache key adapter for string value

>>> from pyramid.testing import setUp, tearDown
>>> config = setUp()
>>> from pyams_utils.interfaces import ICacheKeyValue
>>> from pyams_utils.cache import string_cache_key_adapter
>>> config.registry.registerAdapter(string_cache_key_adapter, (str, ), ICacheKeyValue)
>>> value = 'my test string'
>>> key = ICacheKeyValue(value)
>>> key == value
True
>>> tearDown()

pyams_utils.container

PyAMS_utils.container module

This module provides several classes, adapters and functions about containers.

class pyams_utils.container.BTreeOrderedContainer[source]

Bases: zope.container.ordered.OrderedContainer

BTree based ordered container

This container maintain a manual order of it’s contents

class pyams_utils.container.ContainerSublocationsAdapter(context)[source]

Bases: pyams_utils.adapter.ContextAdapter

Contained object sub-locations adapter

This adapter checks for custom ISublocations interface adapters which can be defined by any component to get access to inner locations, defined for example via annotations.

sublocations()[source]

See zope.location.interfaces.ISublocations interface

class pyams_utils.container.ParentSelector(ifaces, config)[source]

Bases: object

Interface based parent selector

This selector can be used as a subscriber predicate on IObjectAddedEvent to define an interface that the new parent must support for the event to be applied:

.. code-block:: python

from pyams_utils.interfaces.site import ISiteRoot

@subscriber(IObjectAddedEvent, parent_selector=ISiteRoot) def siteroot_object_added_event_handler(event):

‘’‘This is an event handler for an ISiteRoot object added event’‘’
phash()

Predicate string output

text()[source]

Predicate string output

pyams_utils.container.find_objects_matching(root, condition, ignore_root=False)[source]

Find all objects in root that match the condition

The condition is a Python callable object that takes an object as argument and must return a boolean result.

All sub-objects of the root will also be searched recursively.

Parameters:
  • root (object) – the parent object from which search is started
  • condition (callable) – a callable object which may return true for a given object to be selected
  • ignore_root (boolean) – if True, the root object will not be returned, even if it matches the given condition
Returns:

an iterator for all root’s sub-objects matching condition

pyams_utils.container.find_objects_providing(root, interface)[source]

Find all objects in root that provide the specified interface

All sub-objects of the root will also be searched recursively.

Parameters:
  • root (object) – object; the parent object from which search is started
  • interface (Interface) – interface; an interface that sub-objects should provide
Returns:

an iterator for all root’s sub-objects that provide the given interface

pyams_utils.context

PyAMS_utils.context module

This module provides a “context” selector which can be used as Pyramid’s subscriber predicate. Matching argument can be a class or an interface: for subscriber to be actually called, subscriber’s argument should inherit from it (if it’s a class) or implement it (if it’s an interface).

class pyams_utils.context.ContextSelector(ifaces, config)[source]

Bases: object

Interface based context selector

This selector can be used as a predicate to define a class or an interface that the context must inherit from or implement for the subscriber to be called:

.. code-block:: python

from zope.lifecycleevent.interfaces import IObjectModifiedEvent from pyams_site.interfaces import ISiteRoot

@subscriber(IObjectModifiedEvent, context_selector=ISiteRoot) def siteroot_modified_event_handler(event):

‘’‘This is an event handler for an ISiteRoot object modification event’‘’
phash()

Return selector

text()[source]

Return selector

pyams_utils.context.capture(func, *args, **kwargs)[source]

Context manager used to capture standard output

pyams_utils.context.capture_stderr(func, *args, **kwargs)[source]

Context manager used to capture error output

pyams_utils.data

PyAMS_utils.data module

The IObjectData interface is a generic interface which can be used to assign custom data to any object. This object data may be any object which can be serialized to JSON, and assigned to any HTML data attribute. It can typically be used to set a data-ams-data attribute to objects, which is afterwards converted to classic data- attributes by MyAMS.js framework.

For example, for a custom widget in a form:

.. code-block:: python
def updateWidgets(self):
super(MyForm, self).updateWidgets() widget = self.widgets[‘mywidget’] alsoProvides(widget, IObjectData) widget.object_data = {‘ams-colorpicker-position’: ‘top left’}

You can then set an attribute in a TAL template like this:

.. code-block:: xml
<div tal:attributes=”data-ams-data extension:object_data(widget)”>…</div>

After data initialization by MyAMS.js, the following code will be converted to:

.. code-block:: html
<div data-ams-colorpicker-position=”top left”>…</div>
class pyams_utils.data.ObjectDataExtension(context, request, view)[source]

Bases: pyams_utils.adapter.ContextRequestViewAdapter

extension:object_data TALES extension

This TALES extension is to be used in Chameleon templates to define a custom data attribute which stores all object data (see IObjectData interface), like this:

.. code-block:: xml
<div tal:attributes=”data-ams-data extension:object_data(context)”>…</div>
render(context=None)[source]

See ITALESExtension `pyams_utils.interfaces.tales.ITALESExtension interface

class pyams_utils.data.ObjectDataRenderer(context)[source]

Bases: pyams_utils.adapter.ContextAdapter

Object data JSON renderer

get_object_data()[source]

See IObjectDataRenderer interface

class pyams_utils.data.PyramidRequestDataExtension(context, request, view)[source]

Bases: pyams_utils.adapter.ContextRequestViewAdapter

extension:request_data TALES extension for Pyramid request

This TALES extension can be used to get a request data, previously stored in the request via an annotation. For example:

.. code-block:: xml
<div tal:content=”extension:request_data(‘my.annotation.key’)”>…</div>
render(params=None)[source]

See ITALESExtension interface

pyams_utils.date

PyAMS_utils.date module

This module provides several functions concerning conversion, parsing and formatting of dates and datetimes.

class pyams_utils.date.TimestampTalesAdapter(context, request, view)[source]

Bases: pyams_utils.adapter.ContextRequestViewAdapter

extension:timestamp(context) TALES adapter

A PyAMS TALES extension to get timestamp based on last context modification date.

render(context=None, formatting=None)[source]

Render TALES extension

pyams_utils.date.date_to_datetime(value)[source]

Get datetime value converted from a date or datetime object

Parameters:value (date/datetime) – a date or datetime value to convert
Returns:datetime; input value converted to datetime
>>> from datetime import date, datetime
>>> from pyams_utils.date import date_to_datetime
>>> value = date(2016, 11, 15)
>>> date_to_datetime(value)
datetime.datetime(2016, 11, 15, 0, 0)
>>> value = datetime(2016, 11, 15, 10, 13, 12)
>>> value
datetime.datetime(2016, 11, 15, 10, 13, 12)
>>> date_to_datetime(value) is value
True
pyams_utils.date.format_date(value, format_string='on %d/%m/%Y', request=None)[source]

Format given date with the given format

Parameters:
  • value (datetime) – the value to format
  • format_string (str) – a format string to use by strftime function
  • request – the request from which to extract localization info for translation
Returns:

str; input datetime converted to given format

>>> from datetime import datetime
>>> from pyams_utils.date import format_date, SH_DATE_FORMAT
>>> value = datetime(2016, 11, 15, 10, 13, 12)
>>> format_date(value)
'on 15/11/2016'
>>> format_date(value, SH_DATE_FORMAT)
'15/11/2016'
pyams_utils.date.format_datetime(value, format_string='on %d/%m/%Y at %H:%M', request=None)[source]

Format given datetime with the given format including time

Parameters:
  • value (datetime) – the value to format
  • format_string (str) – a format string to use by strftime function
  • request – request; the request from which to extract localization info for translation
Returns:

str; input datetime converted to given format

>>> from datetime import datetime
>>> from pyams_utils.date import format_datetime, SH_DATETIME_FORMAT
>>> value = datetime(2016, 11, 15, 10, 13, 12)
>>> format_datetime(value)
'on 15/11/2016 at 10:13'
>>> format_datetime(value, SH_DATETIME_FORMAT)
'15/11/2016 - 10:13'
pyams_utils.date.get_age(value, request=None)[source]

Get ‘human’ age of a given datetime (including timezone) compared to current datetime (in UTC)

Parameters:value (datetime) – input datetime to be compared with current datetime
Returns:str; the delta value, converted to months, weeks, days, hours or minutes
pyams_utils.date.get_duration(first, last=None, request=None)[source]

Get ‘human’ delta as string between two dates

Parameters:
  • first (datetime) – start date
  • last (datetime) – end date, or current date (in UTC) if None
  • request – the request from which to extract localization infos
Returns:

str; approximate delta between the two input dates

>>> from datetime import datetime
>>> from pyams_utils.date import get_duration
>>> from pyramid.testing import DummyRequest
>>> request = DummyRequest()
>>> date1 = datetime(2015, 1, 1)
>>> date2 = datetime(2014, 3, 1)
>>> get_duration(date1, date2, request)
'10 months'

Dates order is not important:

>>> get_duration(date2, date1, request)
'10 months'
>>> date2 = datetime(2014, 11, 10)
>>> get_duration(date1, date2, request)
'7 weeks'
>>> date2 = datetime(2014, 12, 26)
>>> get_duration(date1, date2, request)
'6 days'

For durations lower than 2 days, duration also display hours:

>>> date1 = datetime(2015, 1, 1)
>>> date2 = datetime(2015, 1, 2, 15, 10, 0)
>>> get_duration(date1, date2, request)
'1 day and 15 hours'
>>> date2 = datetime(2015, 1, 2)
>>> get_duration(date1, date2, request)
'24 hours'
>>> date2 = datetime(2015, 1, 1, 13, 12)
>>> get_duration(date1, date2, request)
'13 hours'
>>> date2 = datetime(2015, 1, 1, 1, 15)
>>> get_duration(date1, date2, request)
'75 minutes'
>>> date2 = datetime(2015, 1, 1, 0, 0, 15)
>>> get_duration(date1, date2, request)
'15 seconds'
pyams_utils.date.parse_date(value)[source]

Get date specified in unicode ISO format to Python datetime object

Dates are always assumed to be stored in GMT timezone

Parameters:value (str) – unicode date to be parsed
Returns:datetime; the specified value, converted to datetime
>>> from pyams_utils.date import parse_date
>>> parse_date('2016-11-15T10:13:12+00:00')
datetime.datetime(2016, 11, 15, 10, 13, 12, tzinfo=<StaticTzInfo 'GMT'>)
pyams_utils.date.unidate(value)[source]

Get specified date converted to unicode ISO format

Dates are always assumed to be stored in GMT timezone

Parameters:value (date) – input date to convert to unicode
Returns:unicode; input date converted to unicode
>>> from datetime import datetime
>>> from pyams_utils.date import unidate
>>> value = datetime(2016, 11, 15, 10, 13, 12)
>>> unidate(value)
'2016-11-15T10:13:12+00:00'

pyams_utils.decorator

PyAMS_utils.decorator module

This module only provides a single decorator, which can be used to mark a function as deprecated.

pyams_utils.decorator.deprecated(*msg)[source]

This is a decorator which can be used to mark functions as deprecated.

It will result in a warning being emitted when the function is used.

>>> from pyams_utils.context import capture_stderr
>>> from pyams_utils.decorator import deprecated
>>> @deprecated
... def my_function(value):
...     return value
>>> with capture_stderr(my_function, 1) as err:
...     print(err.split('\n')[0])
<doctest ... DeprecationWarning: Function my_function is deprecated.
>>> @deprecated('Deprecation message')
... def my_function_2(value):
...     return value
>>> with capture_stderr(my_function_2, 2) as err:
...     print(err.split('\n')[0])
<doctest ... DeprecationWarning: Function my_function_2 is deprecated. Deprecation message

pyams_utils.dict

PyAMS_utils.dict module

This helper module only contains a single function which can be used to update an input dictionary; if given value argument is a boolean ‘true’ value, given dictionary’s key is created or updated, otherwise dictionary is left unchanged.

pyams_utils.dict.update_dict(input_dict, key, value)[source]

Update given mapping if input value is a boolean ‘True’ value

Parameters:
  • input_dict (dict) – input dictionary
  • key – mapping key
  • value – new value

‘False’ values leave mapping unchanged:

>>> from pyams_utils.dict import update_dict
>>> mydict = {}
>>> update_dict(mydict, 'key1', None)
>>> mydict

{} >>> update_dict(mydict, ‘key1’, ‘’) >>> mydict {} >>> update_dict(mydict, ‘key1’, 0) >>> mydict {}

‘True’ values modify the mapping:

>>> update_dict(mydict, 'key1', 'value')
>>> mydict

{‘key1’: ‘value’} >>> update_dict(mydict, ‘key1’, ‘value2’) >>> mydict {‘key1’: ‘value2’}

pyams_utils.encoding

PyAMS_utils.encoding module

This module defines a vocabulary of available encodings, as well as an “encoding” choice field.

class pyams_utils.encoding.EncodingsVocabulary(terms, *interfaces)[source]

Bases: zope.schema.vocabulary.SimpleVocabulary

A vocabulary containing a set of registered encodings

pyams_utils.factory

PyAMS_utils.factory module

This module provides a decorator and a small set of functions to handle object factories.

Instead of directly using a class as an object factory, the object of this module is to let you create an object based on an interface. The first step is to create an object implementing this interface, and then to register it as a factory:

@implementer(IMyInterface)
class MyClass(object):
    '''Class implementing my interface'''

register_factory(IMyInterface, MyClass)

Factory registry can also be handle by a decorator called “factory_config”:

@factory_config(IMyInterface)
class MyClass(object):
    '''Class implementing my interface'''

A class declared as factory for a specific interface automatically implements the given interface. You can also provide a tuple or set of interfaces in “factory_config()” decorator.

When a factory is registered, you can look for a factory:

factory = get_object_factory(IMyInterface)
if factory is not None:
    myobject = factory()
else:
    myobject = MyDefaultImplementation()

By registering their own objects factories, extension packages can easily provide their own implementation of any PyAMS interface handled by factories.

class pyams_utils.factory.ObjectFactoryAdapter(context)[source]

Bases: object

Most basic object factory adapter

factory = None
class pyams_utils.factory.factory_config(provided, **settings)[source]

Bases: object

Class decorator to declare a default object factory

venusian = <module 'venusian' from '/home/docs/checkouts/readthedocs.org/user_builds/pyams/envs/latest/lib/python3.7/site-packages/venusian/__init__.py'>
pyams_utils.factory.get_interface_name(iface)[source]

Get interface full name

pyams_utils.factory.get_object_factory(interface, registry=None, name='')[source]

Get registered factory for given interface

Parameters:
  • interface – the interface for which a factory is requested
  • registry – the registry into which registered factory should be looked for
  • name – name of requested factory
Returns:

the requested object factory, or None if it can’t be found

pyams_utils.factory.is_interface(obj)[source]

Check if given object is an interface

pyams_utils.factory.register_factory(interface, klass, registry=None, name='')[source]

Register factory for a given interface

Parameters:
  • interface – the interface for which the factory is registered
  • klass – the object factory
  • registry – the registry into which factory adapter should be registered; if None, the global registry is used
  • name – custom name given to registered factory

pyams_utils.fanstatic

PyAMS_utils.fanstatic module

This module is a helper module to handle Fanstatic resources.

It includes several TALES extensions which can be used to include resources from a Chameleon template, or to get path of a given resources from a template.

class pyams_utils.fanstatic.ExternalResource(library, path, defer=False, resource_type=None, **kwargs)[source]

Bases: fanstatic.core.Resource

Fanstatic external resource

dependency_nr = 0
render(library_url)[source]

Render resource tag

class pyams_utils.fanstatic.FanstaticNeededResourceTalesExtension(context, request, view)[source]

Bases: pyams_utils.adapter.ContextRequestViewAdapter

tales:need_resource() TALES extension

This extension generates a call to Fanstatic resource.need() function to include given resource into generated HTML code. Resource is given as a string made of package name (in dotted form) followed by a colon and by the resource name.

For example:

.. code-block:: html
<tal:var define=”tales:need_resource(‘pyams_content.zmi:pyams_content’)” />
static render(resource)[source]

TALES extension rendering method

class pyams_utils.fanstatic.FanstaticTalesExtension(context, request, view)[source]

Bases: pyams_utils.adapter.ContextRequestViewAdapter

tales:resource_path() TALES extension

This TALES extension generates an URL matching a given Fanstatic resource. Resource is given as a string made of package name (in dotted form) followed by a colon and by the resource name.

For example:

.. code-block:: html
<div tal:attributes=”data-ams-plugin-pyams_content-src
extension:resource_path(‘pyams_content.zmi:pyams_content’)” />
static render(resource)[source]

TALES extension rendering method

pyams_utils.fanstatic.get_resource_path(resource, signature='--static--', versioning=True)[source]

Get path for given resource

pyams_utils.fanstatic.render_js(url, defer=False)[source]

Render tag to include Javascript resource

pyams_utils.html

PyAMS_utils.html module

This module provides functions which are used to convert HTML code to plain text, by extracting useful text and removing all HTML tags.

class pyams_utils.html.MyHTMLParser(*, convert_charrefs=True)[source]

Bases: html.parser.HTMLParser

HTML parser

Initialize and reset this instance.

If convert_charrefs is True (the default), all character references are automatically converted to the corresponding Unicode characters.

charrefs = {34: '"', 38: '&', 39: "'", 60: '<', 62: '>', 192: 'À', 193: 'A', 194: 'Â', 195: 'A', 196: 'Ä', 197: 'A', 198: 'AE', 199: 'Ç', 200: 'È', 201: 'É', 202: 'Ê', 203: 'Ë', 204: 'I', 205: 'I', 206: 'Î', 207: 'Ï', 208: 'D', 209: 'N', 210: 'O', 211: 'O', 212: 'Ô', 213: 'O', 214: 'Ö', 215: 'x', 216: 'O', 217: 'Ù', 218: 'U', 219: 'Û', 220: 'Ü', 221: 'Y', 222: 'T', 223: 'sz', 224: 'à', 225: 'a', 226: 'â', 227: 'a', 228: 'ä', 229: 'a', 230: 'ae', 231: 'ç', 232: 'è', 233: 'é', 234: 'ê', 235: 'ë', 236: 'i', 237: 'i', 238: 'î', 239: 'ï', 240: 'e', 241: 'n', 242: 'o', 243: 'o', 244: 'ô', 245: 'o', 246: 'ö', 248: 'o', 249: 'ù', 250: 'u', 251: 'û', 252: 'ü', 253: 'y', 255: 'ÿ'}
data = ''
entitydefs = {'AElig': 'AE', 'Aacute': 'A', 'Acirc': 'Â', 'Agrave': 'À', 'Aring': 'A', 'Atilde': 'A', 'Auml': 'Ä', 'Ccedil': 'Ç', 'Eacute': 'È', 'Ecirc': 'Ê', 'Egrave': 'É', 'Euml': 'Ë', 'Iacute': 'I', 'Icirc': 'I', 'Igrave': 'I', 'Iuml': 'I', 'Ntilde': 'N', 'Oacute': 'O', 'Ocirc': 'Ô', 'Ograve': 'O', 'Oslash': '0', 'Otilde': 'O', 'Ouml': 'Ö', 'THORN': 'T', 'Uacute': 'U', 'Ucirc': 'Û', 'Ugrave': 'Ù', 'Uuml': 'Ü', 'Yacute': 'Y', 'aacute': 'a', 'acirc': 'â', 'aelig': 'ae', 'agrave': 'à', 'amp': '&', 'apos': "'", 'aring': 'a', 'atilde': 'a', 'auml': 'ä', 'ccedil': 'ç', 'eacute': 'é', 'ecirc': 'ê', 'egrave': 'è', 'euml': 'ë', 'gt': '>', 'iacute': 'i', 'icirc': 'î', 'igrave': 'i', 'iuml': 'ï', 'lt': '<', 'nbsp': ' ', 'ntilde': 'n', 'oacute': 'o', 'ocirc': 'ô', 'ograve': 'o', 'oslash': 'o', 'otilde': 'o', 'ouml': 'ö', 'quot': '"', 'thorn': 't', 'uacute': 'u', 'ucirc': 'û', 'ugrave': 'ù', 'uuml': 'ü', 'yacute': 'y', 'yuml': 'ÿ'}
error(message)[source]
handle_charref(name)[source]
handle_data(data)[source]
handle_endtag(tag)[source]
handle_entityref(name)[source]
handle_starttag(tag, attrs)[source]
pyams_utils.html.html_to_text(value)[source]

Utility function to extract text content from HTML

>>> from pyams_utils.html import html_to_text
>>> html = '''<p>This is a HTML text part.</p>'''
>>> html_to_text(html)
'This is a HTML text part.\n'
>>> html = '''<p>This is text with french accents: <strong>é à è ù</strong></p>'''
>>> html_to_text(html)
'This is text with french accents: é à è ù\n'

HTML parser should handle entities correctly:

>>> html = '''<div><p>Header</p><p>This is an &lt; &#242; &gt; entity.<br /></p></div>'''
>>> html_to_text(html)
'Header\nThis is an < ò > entity.\n\n'
>>> html = '''<div><p>Header</p><p>This is an &lt;&nbsp;&#242;&nbsp;&gt; ''' +                '''entity.<br /></p></div>'''
>>> html_to_text(html)
'Header\nThis is an < ò > entity.\n\n'

pyams_utils.i18n

PyAMS_utils.i18n module

This module is used to get browser language from request

pyams_utils.i18n.get_browser_language(request)[source]

Custom locale negotiator

Copied from zope.publisher code

>>> from pyramid.testing import DummyRequest
>>> from pyams_utils.i18n import get_browser_language
>>> request = DummyRequest()
>>> request.headers['Accept-Language'] = 'fr, en-US ; q=0.9, en-GB ; q=0.8, en ; q=0.7'
>>> get_browser_language(request)
'fr'
pyams_utils.i18n.normalize_lang(lang)[source]

Normalize input languages string

>>> from pyams_utils.i18n import normalize_lang
>>> lang = 'fr,en-US ; q=0.9, en-GB ; q=0.8, en ; q=0.7'
>>> normalize_lang(lang)
'fr,en-us;q=0.9,en-gb;q=0.8,en;q=0.7'
pyams_utils.i18n.set_locales(config)[source]

Define locale environment variables

Parameters:config – Pyramid’s settings object

pyams_utils.include

PyAMS_utils.include module

This module is used for Pyramid integration

pyams_utils.include.include_package(config)[source]

Pyramid package include

pyams_utils.inherit

PyAMS_utils.inherit module

This module is used to manage a generic inheritance between a content and it’s parent container. It also defines a custom InheritedFieldProperty which allows to automatically manage inherited properties.

This PyAMS module is used to handle inheritance between a parent object and a child which can “inherit” from some of it’s properties, as long as they share the same “target” interface.

>>> from zope.interface import implementer, Interface, Attribute
>>> from zope.schema import TextLine
>>> from zope.schema.fieldproperty import FieldProperty
>>> from pyams_utils.adapter import adapter_config
>>> from pyams_utils.interfaces.inherit import IInheritInfo
>>> from pyams_utils.inherit import BaseInheritInfo, InheritedFieldProperty
>>> from pyams_utils.registry import get_global_registry

Let’s start by creating a “content” interface, and a marker interface for objects for which we want to provide this interface:

>>> class IMyInfoInterface(IInheritInfo):
...     '''Custom interface'''
...     value = TextLine(title="Custom attribute")
>>> class IMyTargetInterface(Interface):
...     '''Target interface'''
>>> @implementer(IMyInfoInterface)
... class MyInfo(BaseInheritInfo):
...     target_interface = IMyTargetInterface
...     adapted_interface = IMyInfoInterface
...
...     _value = FieldProperty(IMyInfoInterface['value'])
...     value = InheritedFieldProperty(IMyInfoInterface['value'])

Please note that for each field of the interface which can be inherited, you must define to properties: one using “InheritedFieldProperty” with the name of the field, and one using a classic “FieldProperty” with the same name prefixed by “_”; this property is used to store the “local” property value, when inheritance is unset.

The adapter is created to adapt an object providing IMyTargetInterface to IMyInfoInterface; please note that the adapter must attach the created object to it’s parent by setting __parent__ attribute:

>>> @adapter_config(context=IMyTargetInterface, provides=IMyInfoInterface)
... def my_info_factory(context):
...     info = getattr(context, '__info__', None)
...     if info is None:
...         info = context.__info__ = MyInfo()
...         info.__parent__ = context
...     return info

Adapter registration is here only for testing; the “adapter_config” decorator may do the job in a normal application context:

>>> registry = get_global_registry()
>>> registry.registerAdapter(my_info_factory, (IMyTargetInterface, ), IMyInfoInterface)

We can then create classes which will be adapted to support inheritance:

>>> @implementer(IMyTargetInterface)
... class MyTarget:
...     '''Target class'''
...     __parent__ = None
...     __info__ = None
>>> parent = MyTarget()
>>> parent_info = IMyInfoInterface(parent)
>>> parent.__info__
<pyams_utils.tests.test_utils...MyInfo object at ...>
>>> parent_info.value = 'parent'
>>> parent_info.value
'parent'
>>> parent_info.can_inherit
False

As soon as a parent is defined, the child object can inherit from it’s parent:

>>> child = MyTarget()
>>> child.__parent__ = parent
>>> child_info = IMyInfoInterface(child)
>>> child.__info__
<pyams_utils.tests.test_utils...MyInfo object at ...>
>>> child_info.can_inherit
True
>>> child_info.inherit
True
>>> child_info.value
'parent'

Setting child value while inheritance is enabled donesn’t have any effect:

>>> child_info.value = 'child'
>>> child_info.value
'parent'
>>> child_info.inherit_from == parent
True

You can disable inheritance and define your own value:

>>> child_info.inherit = False
>>> child_info.value = 'child'
>>> child_info.value
'child'
>>> child_info.inherit_from == child
True

Please note that parent and child in this example share the same class, but this is not a requirement; they just have to implement the same marker interface, to be adapted to the same content interface.

class pyams_utils.inherit.BaseInheritInfo[source]

Bases: zope.location.location.Location

Base inherit class

Subclasses may generaly override target_interface and adapted_interface to correctly handle inheritance (see example in doctests). Please note also that adapters to this interface must correctly ‘locate’

adapted_interface = <InterfaceClass zope.interface.Interface>
can_inherit

Check if inheritance is possible

inherit

Check if inheritance is possible and activated

inherit_from

Get current parent from which we inherit

no_inherit

Inverted boolean value to check if inheritance is possible and activated

parent[source]

Get current parent

target_interface = <InterfaceClass zope.interface.Interface>
class pyams_utils.inherit.InheritedFieldProperty(field, name=None)[source]

Bases: object

Inherited field property

pyams_utils.intids

PyAMS_utils.intids module

This module provides utility functions and helpers to help usage of IIntIds utilities. Pyramid events subscribers are also declared to match Zope events with Pyramid IntIds related events

class pyams_utils.intids.UniqueIdAdapter(context)[source]

Bases: pyams_utils.adapter.ContextAdapter

Object unique ID adapter

This adapter is based on a registered IIntIds utility to get a unique ID for any persistent object.

oid

Get context ID in hexadecimal form

pyams_utils.intids.handle_added_object(event)[source]

Notify IntId utility for added objects

This subscriber is used for all persistent objects to be registered in all locally registered IIntIds utilities.

pyams_utils.intids.handle_intid_event(event)[source]

IntId event subscriber

This event is used to dispatch all IIntIdEvent events using Pyramid events subscribers to matching subscribers using Zope events

pyams_utils.intids.handle_removed_object(event)[source]

Notify IntId utility for removed objects

This subscriber is used for all persistent objects to be unregistered from all locally registered IIntIds utilities.

pyams_utils.json

PyAMS_utils.json package

A small utility module which provides a default JSON encoder to automatically convert dates and datetimes to ISO format

>>> import json as stock_json
>>> from datetime import datetime
>>> from pyams_utils import json
>>> from pyams_utils.timezone import GMT
>>> value = datetime.fromtimestamp(1205000000, GMT)
>>> stock_json.dumps(value)
'"2008-03-08T18:13:20+00:00"'
pyams_utils.json.default_json_encoder(obj)[source]

Default JSON encoding of dates and datetimes

pyams_utils.list

PyAMS_utils list module

This module is dedicated to lists and iterators management. It provides function to extract unique values from a list or iterator in their original order, or to iterate over an iterator in random order; it also provides a “boolean_iter” function (usable as TALES extension) to check if an iterator returns at least one value, without consuming this iterator (the function returns a tuple containing a boolean value to specify if iterator is empty or not, and the original iterator).

class pyams_utils.list.IterValuesCheckerExpression(context, request, view)[source]

Bases: pyams_utils.adapter.ContextRequestViewAdapter

TALES expression used to handle iterators

The expression returns a tuple containing a boolean flag indicating if the original iterator is empty or not, and the original un-consumed iterator.

render(context=None)[source]

Render TALES extension; see ITALESExtension interface

pyams_utils.list.boolean_iter(iterable)[source]

Check if an iterable returns at least one value, without consuming it.

The function returns a tuple containing a boolean flag indicating if the original iterator is empty or not, and the original un-consumed iterator.

>>> from pyams_utils.list import boolean_iter
>>> def empty(input):
...     yield from input
>>> mylist = empty(())
>>> check, myiter = boolean_iter(mylist)
>>> check
False
>>> list(myiter)
[]
>>> mylist = empty((1,2,3))
>>> check, myiter = boolean_iter(mylist)
>>> check
True
>>> list(myiter)
[1, 2, 3]
>>> list(myiter)
[]
pyams_utils.list.random() → x in the interval [0, 1).
pyams_utils.list.random_iter(iterable, limit=1)[source]

Get items randomly from an iterator

>>> from pyams_utils.list import random_iter
>>> mylist = [1, 2, 3, 2, 1]
>>> list(random_iter(mylist, 2))
[..., ...]
pyams_utils.list.unique(seq, key=None)[source]

Extract unique values from list, preserving order

Parameters:
  • seq (iterator) – input list
  • key (callable) – an identity function which is used to get ‘identity’ value of each element in the list
Returns:

list; a new list containing only unique elements of the original list in their initial order. Original list is not modified.

>>> from pyams_utils.list import unique
>>> mylist = [1, 2, 3, 2, 1]
>>> unique(mylist)
[1, 2, 3]
>>> mylist = [3, 2, 2, 1, 4, 2]
>>> unique(mylist)
[3, 2, 1, 4]

You can also set an ‘id’ function applied on each element:

>>> mylist = [1, 2, 3, '2', 4]
>>> unique(mylist, key=str)
[1, 2, 3, 4]
>>> mylist = ['A', 'B', 'b', '2', 4]
>>> unique(mylist, key=lambda x: str(x).lower())
['A', 'B', '2', 4]
pyams_utils.list.unique_iter(iterable, key=None)[source]

Iterate over iterator values, yielding only unique values

Parameters:
  • iterable (iterator) – input iterator
  • key (callable) – an identity function which is used to get ‘identity’ value of each element in the list
Returns:

an iterator of unique values

>>> from pyams_utils.list import unique_iter
>>> mylist = [1, 2, 3, 2, 1]
>>> list(unique_iter(mylist))
[1, 2, 3]
>>> mylist = [3, 2, 2, 1, 4, 2]
>>> list(unique_iter(mylist))
[3, 2, 1, 4]

You can also set an ‘id’ function applied on each element:

>>> mylist = [1, 2, 3, '2', 4]
>>> list(unique_iter(mylist, key=str))
[1, 2, 3, 4]
>>> mylist = ['A', 'B', 'b', '2', 4]
>>> list(unique_iter(mylist, key=lambda x: str(x).lower()))
['A', 'B', '2', 4]

pyams_utils.lock

PyAMS_utils.lock module

This module is use to manage shared locks; these locks can be used accross several processes; the lock relies on a shared value stored info Beaker’s cache.

class pyams_utils.lock.CacheLock(name, wait=True)[source]

Bases: object

Beaker based lock

This lock can be used when you need to get a lot across several processes or even computers. The lock relies on a shared value stored into a shared Beaker cache.

Parameters:
  • name (str) – name of the lock to use as shared key
  • wait (boolean) – if False, a LockException is raised if lock can’t be taken; otherwise, application waits until lock is released

Lock can be used as a context manager.

exception pyams_utils.lock.LockException[source]

Bases: Exception

Cache lock exception

pyams_utils.lock.get_locks_cache()[source]

Get locks shared cache

pyams_utils.lock.locked(name, wait=True)[source]

Locked function decorator

Can be used with any function or method which requires a global shared lock.

Parameters:
  • name (str) – name of the lock to use as shared key
  • wait (boolean) – if False, a LockException is raised if lock can’t be taken; otherwise, application waits until lock is released

pyams_utils.progress

PyAMS_utils.progress module

This module can be used to get progress status on a long running operation.

The process is a s follow:

  • the client generate a “progress ID”; this ID can be any unique ID, and can be generated by MyAMS client library
  • the client browser send a POST request containg this progress ID to a view
  • the view calls “init_progress_status(progress_id, request.principal.id, “Task label”) when starting it’s long operation
  • during the operation, a call is made regularly to “set_progress_status(progress_id)”; additional arguments can contain a status (to indicate if operation is finished or not), and a simple “message” or two “length” and “current” arguments which can specify the length of the operation and it’s current position
  • at the end of the operation, the view calls “set_progress_status(progress_id, ‘finished’)” to specify that the operation is finished.

During the whole operation, while waiting for server response, the client browser can send requests to “get_progress_status.json”, providing the progress ID, to get the operation progress. This last operation is done automatically in PyAMS forms.

pyams_utils.progress.get_progress_cache()[source]

Get cache storing tasks progress

pyams_utils.progress.get_progress_status_view(request)[source]

Get progress status of a given task

Each submitted task is identified by an ID defined when the task is created

pyams_utils.progress.get_running_tasks()[source]

Get list of running tasks

pyams_utils.progress.get_tasks_cache()[source]

Get cache storing tasks list

pyams_utils.progress.set_running_tasks(tasks)[source]

Update list of running tasks

pyams_utils.property

PyAMS_utils.property module

This module is used to define:
  • a cached property; this read-only property is evaluated only once; it’s value is stored into object’s attributes, and so should be freed with the object (so it should behave like a Pyramid’s “reify” decorator, but we have kept it for compatibility of existing code)

  • a class property; this decorator is working like a classic property, but can be assigned to a class; to support class properties, this class also have to decorated with the “classproperty_support” decorator

    >>> from pyams_utils.property import cached_property
    
    >>> class ClassWithCache:
    ...     '''Class with cache'''
    ...     @cached_property
    ...     def cached_value(self):
    ...         print("This is a cached value")
    ...         return 1
    
    >>> obj = ClassWithCache()
    >>> obj.cached_value
    This is a cached value
    1
    

On following calls, cached property method shouldn’t be called again:

>>> obj.cached_value
1

Class properties are used to define properties on class level:

>>> from pyams_utils.property import classproperty, classproperty_support
>>> @classproperty_support
... class ClassWithProperties:
...     '''Class with class properties'''
...
...     class_attribute = 1
...
...     @classproperty
...     def my_class_property(cls):
...         return cls.class_attribute
>>> ClassWithProperties.my_class_property
1
class pyams_utils.property.cached_property(fget, doc=None)[source]

Bases: object

A read-only property decorator that is only evaluated once.

The value is cached on the object itself rather than the function or class; this should prevent memory leakage.

class pyams_utils.property.classproperty(fget=None, fset=None, fdel=None, doc=None)[source]

Bases: object

Same decorator as property(), but passes obj.__class__ instead of obj to fget/fset/fdel.

Original code for property emulation: https://docs.python.org/3.5/howto/descriptor.html#properties

deleter(fdel)[source]

Property deleter

getter(fget)[source]

Property getter

setter(fset)[source]

Property setter

pyams_utils.property.classproperty_support(cls)[source]

Class decorator to add metaclass to a class.

Metaclass uses to add descriptors to class attributes

pyams_utils.pygments

pyams_utils.registry

PyAMS_utils.registry module

This package is used to manage a local registry. A local registry is a site management component created automatically on application startup by PyAMS_utils package. It can be used to store and register components, mainly persistent utilities which are created and configured dynamically by a site administrator; this can include SQLAlchemy engines, ZEO connections, and several PyAMS utilities like security manager, medias converter, tasks scheduler and many other ones.

See Zope Component Architecture with PyAMS to get a brief introduction about using a local registry with PyAMS packages.

class pyams_utils.registry.LocalRegistry[source]

Bases: _thread._local

Local registry

The local registry is defined to allow access to persistent utility registered and stored into ZODB.

get_registry()[source]

Return local registry

set_registry(registry)[source]

Define local registry

pyams_utils.registry.get_all_utilities_registered_for(interface)[source]

Get list of registered utilities for given interface

Do a registry lookup for matching utilities into local registry first, then on each registry associated with current thread stack.

pyams_utils.registry.get_current_registry(context=None)[source]

Get current or global registry

The function is looking for given request registry. If registry is None, returns the global registry.

pyams_utils.registry.get_global_registry()[source]

Get global registry

pyams_utils.registry.get_local_registry()[source]

Get local registry

Local registry is automatically defined while traversing a site manager.

pyams_utils.registry.get_registries()[source]

Iterator on components registries

Returns an iterator on current local registry (if any) and registries associated in current thread stack.

pyams_utils.registry.get_utilities_for(interface)[source]

Get utilities registered with given interface as (name, util) tuples iterator

Do a registry lookup for matching utilities into local registry first, then on each registry associated with current thread stack.

pyams_utils.registry.get_utility(provided, name='')[source]

Get utility registered with given interface

Do a registry lookup for given utility into local registry first, then on each registry associated with current thread stack.

Parameters:
  • provided (Interface) – the requested interface
  • name (str) – name of the requested utility
Returns:

object; the requested object. A ComponentLookupError is raised if the utility can’t be found.

pyams_utils.registry.handle_new_request(event)[source]

New request event subscriber

Is used to initialize local registry to None for any new request

pyams_utils.registry.handle_site_before_traverse(event)[source]

Before traverse event subscriber

Define site’s local registry when an object implementing ISite is traversed

pyams_utils.registry.query_utility(provided, name='', default=None)[source]

Query utility registered with given interface

Do a registry lookup for given utility into local registry first, then on each registry associated with current thread stack.

Parameters:
  • provided (Interface) – the requested interface
  • name (str) – name of the requested utility
  • default (object) – the default object returned if the requested utility can’t be found
Returns:

object; the requested object, or default if it can’t be found

pyams_utils.registry.registered_utilities()[source]

Get utilities registrations as generator

Iterates over utilities defined in all registries, starting with local ones.

pyams_utils.registry.set_local_registry(registry)[source]

Define local registry

class pyams_utils.registry.utility_config(**settings)[source]

Bases: object

Function or class decorator to register a utility in the global registry

Parameters:
  • name (str) – default=’‘; name under which the utility is registered
  • provides (Interface) – the interface for which the utility is registered

Please note that a single utility can be registered several times (using several annotations), with different names.

If several utilities are registered for the same interface with the same name, the last registered utility will override the previous ones.

venusian = <module 'venusian' from '/home/docs/checkouts/readthedocs.org/user_builds/pyams/envs/latest/lib/python3.7/site-packages/venusian/__init__.py'>

pyams_utils.request

PyAMS_utils.request module

class pyams_utils.request.PyAMSRequest(environ, charset=None, unicode_errors=None, decode_param_names=None, **kw)[source]

Bases: pyramid.request.Request

Custom request factory

Used to add ‘context’ argument to ‘effective_principals’ method call to be able to get ‘roles’ principals

has_permission(*args, **kwargs)[source]
class pyams_utils.request.RequestSelector(ifaces, config)[source]

Bases: object

Interface based request selector

This selector can be used as a subscriber predicate to define an interface that the event’s ‘request’ attribute must support for the event to be applied:

.. code-block:: python

from pyams_utils.interfaces.site import ISiteRoot

@subscriber(IBeforeTraverseEvent, request_selector=IPyAMSLayer) def before_traverse_event(event):

‘’‘This is an event handler for an IPyAMSRequest modification event’‘’
phash()

Predicate label

text()[source]

Predicate label

pyams_utils.request.check_request(path='/', environ=None, base_url=None, headers=None, POST=None, registry=None, principal_id=None, **kwargs)[source]

Get current request, or create a new blank one if missing

pyams_utils.request.copy_request(request)[source]

Create clone of given request, keeping registry and root as well

pyams_utils.request.get_annotations(request)[source]

Define ‘annotations’ request property

This function is automatically defined as a custom request method on package include.

pyams_utils.request.get_debug(request)[source]

Define ‘debug’ request property

This function is automatically defined as a custom request method on package include.

pyams_utils.request.get_display_context(request)[source]

Get current display context

The display context can be used when we generate a page to display an object in the context of another one; PyAMS_content package is using this feature to display “shared” contents as is they were located inside another site or folder…

pyams_utils.request.get_request(raise_exception=True)[source]

Get current request

Raises a NoInteraction exception if there is no active request.

pyams_utils.request.get_request_data(request, key, default=None)[source]

Get data associated with request

Parameters:
  • request – the request containing requested data
  • key (str) – request data annotation key
  • default (object) – the default value when data is missing
Returns:

the requested value, or default

pyams_utils.request.query_request()[source]

Query current request

Returns None if there is no active request

pyams_utils.request.request_property(key=None, prefix=None)[source]

Define a method decorator used to store result into current request’s annotations

If no request is currently running, a new one is created. key is a required argument; if None, the key will be the method’s object

Parameters:
  • key (str) – annotations value key; if None, the key will be the method’s object; if key is a callable object, it will be called to get the actual session key
  • prefix – str; prefix to use for session key; if None, the prefix will be the property name
pyams_utils.request.set_request_data(request, key, value)[source]

Associate data with request

Parameters:
  • request – the request in which to set data
  • key (str) – request data annotation key
  • value (object) – the value to be set in request annotation

pyams_utils.schema

PyAMS_utils.schema module

This module is used to define custom schema fields

class pyams_utils.schema.ColorField(*args, **kw)[source]

Bases: zope.schema._bootstrapfields.TextLine

Color field

class pyams_utils.schema.DatesRangeField(value_type=None, unique=False, **kw)[source]

Bases: zope.schema._field.Tuple

Dates range field

class pyams_utils.schema.DottedDecimalField(min=None, max=None, default=None, **kw)[source]

Bases: zope.schema._field.Decimal

Dotted decimal field

class pyams_utils.schema.EncodedPasswordField(*args, **kw)[source]

Bases: zope.schema._bootstrapfields.Password

Encoded password field

constraint(value)[source]
fromUnicode(str)[source]
>>> from zope.schema.interfaces import WrongType
>>> from zope.schema.interfaces import ConstraintNotSatisfied
>>> from zope.schema import Text
>>> from zope.schema._compat import text_type
>>> t = Text(constraint=lambda v: 'x' in v)
>>> t.fromUnicode(b"foo x spam") # doctest: +IGNORE_EXCEPTION_DETAIL
Traceback (most recent call last):
...
zope.schema._bootstrapinterfaces.WrongType: ('foo x spam', <type 'unicode'>, '')
>>> result = t.fromUnicode(u"foo x spam")
>>> isinstance(result, bytes)
False
>>> str(result)
'foo x spam'
>>> t.fromUnicode(u"foo spam") # doctest: +IGNORE_EXCEPTION_DETAIL
Traceback (most recent call last):
...
zope.schema._bootstrapinterfaces.ConstraintNotSatisfied: (u'foo spam', '')
class pyams_utils.schema.EncodingField(vocabulary='pyams_utils.encodings', **kw)[source]

Bases: zope.schema._field.Choice

Encoding schema field

class pyams_utils.schema.HTMLField(*args, **kw)[source]

Bases: zope.schema._bootstrapfields.Text

HTML field

interface pyams_utils.schema.IColorField[source]

Extends: zope.schema.interfaces.ITextLine

Marker interface for color fields

interface pyams_utils.schema.IDatesRangeField[source]

Extends: zope.schema.interfaces.ITuple

Marker interface for dates range fields

interface pyams_utils.schema.IDottedDecimalField[source]

Extends: zope.schema.interfaces.IDecimal

Marker interface for dotted decimal fields

interface pyams_utils.schema.IEncodedPasswordField[source]

Extends: zope.schema.interfaces.IPassword

Encoded password field interface

interface pyams_utils.schema.IEncodingField[source]

Extends: zope.schema.interfaces.IChoice

Encoding field interface

interface pyams_utils.schema.IHTMLField[source]

Extends: zope.schema.interfaces.IText

HTML field interface

interface pyams_utils.schema.IJSONDictField[source]

Extends: zope.schema.interfaces.IDict

JSON dict value field interface

interface pyams_utils.schema.IJSONDictFieldsGetter[source]

Adapter interface used to get JSON value fields list

get_fields(self, data)

Returns an iterator made of tuples

Each tuple may ocntain field name, field label and field value

interface pyams_utils.schema.IMailAddressField[source]

Extends: zope.schema.interfaces.ITextLine

Marker interface for mail address field

interface pyams_utils.schema.IPersistentDictField[source]

Extends: zope.schema.interfaces.IDict

Persistent mapping field marker interface

interface pyams_utils.schema.IPersistentListField[source]

Extends: zope.schema.interfaces.IList

Persistent list field marker interface

interface pyams_utils.schema.ITextLineListField[source]

Extends: zope.schema.interfaces.IList

Marker interface for textline list field

interface pyams_utils.schema.ITimezoneField[source]

Extends: zope.schema.interfaces.IChoice

Marker interface for timezone field

exception pyams_utils.schema.InvalidEmail[source]

Bases: zope.schema._bootstrapinterfaces.ValidationError

Email address must be entered as « name@domain.name », without ‘<’ and ‘>’ characters

class pyams_utils.schema.JSONDictField(key_type=None, value_type=None, **kw)[source]

Bases: zope.schema._field.Dict

JSON dict value field

class pyams_utils.schema.MailAddressField(*args, **kw)[source]

Bases: zope.schema._bootstrapfields.TextLine

Mail address field

class pyams_utils.schema.PersistentDictField(key_type=None, value_type=None, **kw)[source]

Bases: zope.schema._field.Dict

Persistent mapping field

class pyams_utils.schema.PersistentListField(value_type=<Not Given>, unique=<Not Given>, **kw)[source]

Bases: zope.schema._field.List

Persistent list field

class pyams_utils.schema.TextLineListField(value_type=None, unique=False, **kw)[source]

Bases: zope.schema._field.List

TextLine list field

class pyams_utils.schema.TimezoneField(**kw)[source]

Bases: zope.schema._field.Choice

Timezone choice field

pyams_utils.session

PyAMS_utils session module

This helper module is used to add a “session_property” method decorator, which can be used to store method result into user’s session.

It also adds to function to get and set session data.

pyams_utils.session.get_session_data(request, app, key, default=None)[source]

Get data associated with current user session

PyAMS session management is based on Beaker package session management.

Parameters:
  • request – the request from which session is extracted
  • app (str) – application name
  • key (str) – session data key for given application
  • default – object; requested session data, or default if it can’t be found
APPLICATION_KEY = 'MyApp'
SESSION_KEY = 'MyFunction'

def my_function(request):
    return get_session_data(request, APPLICATION_KEY, SESSION_KEY)
pyams_utils.session.session_property(app, key=None, prefix=None)[source]

Define a method decorator used to store result into request’s session

If no request is currently running, a new one is created.

Parameters:
  • app (str) – application identifier used to prefix session keys
  • key (str) – session’s value key; if None, the key will be the method’s object; if key is a callable object, il will be called to get the actual session key
  • prefix – str; prefix to use for session key; if None, the prefix will be the property name
pyams_utils.session.set_session_data(request, app, key, value)[source]

Associate data with current user session

Parameters:
  • request – the request from which session is extracted
  • app (str) – application name
  • key (str) – session data key for given application
  • value (object) – any object that can be pickled can be stored into user session
APPLICATION_KEY = 'MyApp'
SESSION_KEY = 'MyFunction'

def my_function(request):
    value = {'key1': 'value1', 'key2': 'value2'}
    set_session_data(request, APPLICATION_KEY, SESSION_KEY, value)

pyams_utils.site

pyams_utils.size

PyAMS_utils.size module

This module provides a small function which can be used to convert a “size” value, given in bytes, to it’s “human” representation.

pyams_utils.size.get_human_size(value, request=None)[source]

Convert given bytes value in human readable format

>>> from pyramid.testing import DummyRequest
>>> request = DummyRequest(params={'_LOCALE_': 'en'})
>>> request.locale_name
'en'
>>> from pyams_utils.size import get_human_size
>>> get_human_size(256, request)
'256 bytes'
>>> get_human_size(3678, request)
'3.6 Kb'
>>> get_human_size(6785342, request)
'6.47 Mb'
>>> get_human_size(3674815342, request)
'3.422 Gb'
>>> request = DummyRequest(params={'_LOCALE_': 'fr'})
>>> request.locale_name
'fr'
>>> get_human_size(256, request)
'256 bytes'
>>> get_human_size(3678, request)
'3,6 Kb'
>>> get_human_size(6785342, request)
'6,47 Mb'
>>> get_human_size(3674815342, request)
'3,422 Gb'

pyams_utils.tales

PyAMS_utils.tales module

This module provides a custom TALES extension engine, which allows you to define custom TALES expressions which can be used from Chameleon or Zope templates.

class pyams_utils.tales.ContextExprMixin[source]

Bases: object

Mixin-class for expression compilers

transform = None
class pyams_utils.tales.ExtensionExpr(expression, braces_required=False)[source]

Bases: pyams_utils.tales.ContextExprMixin, chameleon.tales.StringExpr

tales: TALES expression

This expression can be used to call a custom named adapter providing ITALESExtension interface.

transform = <Symbol value=<function render_extension> at 7ff6d9342f60>
pyams_utils.tales.render_extension(econtext, name)[source]

TALES extension renderer

See TALES Extensions for complete description.

The requested extension can be called with our without arguments, like in ${structure:tales:my_expression} or ${structure:tales:my_expression(arg1, arg2)}. In the second form, arguments will be passed to the “render” method; arguments can be static (like strings or integers), or can be variables defined into current template context; other Python expressions including computations or functions calls are actually not supported, but dotted syntax is supported to access inner attributes of variables.

pyams_utils.text

PyAMS_utils.text module

This module provides text manipulation and conversion functions, as well as a set of TALES extensions (see ITALESExtension).

class pyams_utils.text.BaseHTMLRenderer(context, request)[source]

Bases: pyams_utils.adapter.ContextRequestAdapter

Raw text HTML renderer

This renderer renders input text ‘as is’, mainly for use in a <pre> tag.

render(**kwargs)[source]

Convert raw code as HTML

class pyams_utils.text.BrTalesExtension(context, request, view)[source]

Bases: pyams_utils.adapter.ContextRequestViewAdapter

extension:br(value, class) TALES expression

This expression can be used to context a given character (‘|’ by default) into HTML breaks with given CSS class.

static render(value, css_class='', character='|', start_tag=None, end_tag=None)[source]

Render TALES extension; see ITALESExtension

class pyams_utils.text.HTMLTalesExtension(context, request, view)[source]

Bases: pyams_utils.adapter.ContextRequestViewAdapter

extension:html TALES expression

If first context argument of the renderer is an object for which an IHTMLRenderer adapter can be found, this adapter is used to render the context to HTML; if context is a string, it is converted to HTML using the renderer defined as second parameter; otherwise, context is just converted to string using the str() function.

You can provide several renderers by giving their names separated by semicolon; renderers will then act as in a pipe, each renderer transforming output of the previous one.

render(context=<object object>, renderer='text')[source]

Render TALES extension; see ITALESExtension

class pyams_utils.text.JsRenderer(context, request)[source]

Bases: pyams_utils.text.BaseHTMLRenderer

Custom Javascript HTML renderer

This renderer replaces single quotes with escaped ones

render(**kwargs)[source]

Convert raw code as HTML

class pyams_utils.text.MarkdownTextRenderer(context, request)[source]

Bases: pyams_utils.text.BaseHTMLRenderer

Markdown HTML renderer

This renderer is converting Markdown formatted text to HTML.

label = 'Markdown text'
render(**kwargs)[source]

Render Markdown code to HTML

class pyams_utils.text.ReStructuredTextRenderer(context, request)[source]

Bases: pyams_utils.text.BaseHTMLRenderer

reStructuredText HTML renderer

This renderer is using docutils to convert text to HTML output.

label = 'ReStructured text'
render(**kwargs)[source]

Render reStructuredText to HTML

class pyams_utils.text.RenderersVocabulary(context=None)[source]

Bases: zope.schema.vocabulary.SimpleVocabulary

Text renderers vocabulary

class pyams_utils.text.TextRenderer(context, request)[source]

Bases: pyams_utils.text.BaseHTMLRenderer

Basic text HTML renderer

This renderer only replace newlines with HTML breaks.

label = 'Simple text'
render(**kwargs)[source]

Convert raw code as HTML

class pyams_utils.text.TruncateCharsTalesExtension(context, request, view)[source]

Bases: pyams_utils.adapter.ContextRequestViewAdapter

extension:truncate(value, length, max) TALES expression

Truncates a sentence if it is longer than the specified ‘length’ characters. Truncated strings will end with an ellipsis character (“…”) See also ‘get_text_start’

static render(value, length=50, maxlen=0)[source]

Render TALES extension; see ITALESExtension

pyams_utils.text.get_text_start(text, length, maxlen=0)[source]

Get first words of given text with maximum given length

If max is specified, text is shortened only if remaining text is longer this value

Parameters:
  • text (str) – initial text
  • length (integer) – maximum length of resulting text
  • maxlen (integer) – if > 0, text is shortened only if remaining text is longer than max
>>> from pyams_utils.text import get_text_start
>>> get_text_start('This is a long string', 10)
'This is a&#133;'
>>> get_text_start('This is a long string', 20)
'This is a long&#133;'
>>> get_text_start('This is a long string', 20, 7)
'This is a long string'
pyams_utils.text.text_to_html(text, renderer='text')[source]

Convert text to HTML using the given renderer

Renderer name can be any registered HTML renderer adapter.

You can provide several renderers by giving their names separated by semicolon; renderers will then act as in a pipe, each renderer transforming output of the previous one.

pyams_utils.traversing

PyAMS_utils.traversing module

This module provides a custom Pyramid “namespace” traverser: using “++name++” URLs allows to traverse URLs based on custom traversing adapters.

It also provides a “get_parent” function, which returns a parent object of given object providing a given interface.

class pyams_utils.traversing.NamespaceTraverser(root)[source]

Bases: pyramid.traversal.ResourceTreeTraverser

Custom traverser handling views and namespaces

This is an upgraded version of native Pyramid traverser. It adds: - a new BeforeTraverseEvent before traversing each object in the path - support for namespaces with “++” notation

NAMESPACE_SELECTOR = '++'
PLUS_SELECTOR = '+'
class pyams_utils.traversing.PathElementsAdapter(context)[source]

Bases: pyams_utils.adapter.ContextAdapter

Contained object path elements adapter

This interface is intended to be used inside a keyword index to be able to search object based on a given parent

parents

Get list of parents OIDs

pyams_utils.traversing.get_name(context)[source]

Get context name

pyams_utils.traversing.get_parent(context, interface=<InterfaceClass zope.interface.Interface>, allow_context=True, condition=None)[source]

Get first parent of the context that implements given interface

Parameters:
  • context (object) – base element
  • interface (Interface) – the interface that parend should implement
  • allow_context (boolean) – if ‘True’ (the default), traversing is done starting with context; otherwise, traversing is done starting from context’s parent
  • condition (callable) – an optional function that should return a ‘True’ result when called with parent as first argument

pyams_utils.unicode

PyAMS_utils.unicode module

This module provides a small set of functions which can be used to handle unicode data and their bytes equivalent.

pyams_utils.unicode.decode(value, encoding='utf-8')[source]

Decode given bytes value to unicode with given encoding

Parameters:
  • value (bytes) – the value to decode
  • encoding (str) – selected encoding
Returns:

str; value decoded to unicode string if input is a bytes, original value otherwise

>>> from pyams_utils.unicode import decode
>>> decode(b'Cha\xc3\xaene accentu\xc3\xa9e')
'Chaîne accentuée'
>>> decode(b'Cha\xeene accentu\xe9e', 'latin1')
'Chaîne accentuée'
pyams_utils.unicode.encode(value, encoding='utf-8')[source]

Encode given Unicode value to bytes with given encoding

Parameters:
  • value (str) – the value to encode
  • encoding (str) – selected encoding
Returns:

bytes; value encoded to bytes if input is a string, original value otherwise

>>> from pyams_utils.unicode import encode
>>> encode('Chaîne accentuée')
b'Cha\xc3\xaene accentu\xc3\xa9e'
>>> encode('Chaîne accentuée', 'latin1')
b'Cha\xeene accentu\xe9e'
pyams_utils.unicode.nvl(value, default='')[source]

Get specified value, or an empty string if value is empty

Parameters:
  • value (object) – value to be checked
  • default (object) – default value to be returned if value is false
Returns:

input value, or default if value is false

>>> from pyams_utils.unicode import nvl
>>> nvl(None)
''
>>> nvl('foo')
'foo'
>>> nvl(False, 'bar')
'bar'
pyams_utils.unicode.translate_string(value, escape_slashes=False, force_lower=True, spaces=' ', remove_punctuation=True, keep_chars='_-.')[source]

Remove extended characters and diacritics from string and replace them with ‘basic’ ones

Parameters:
  • value (str) – text to be translated
  • escape_slashes (boolean) – if True, slashes are also converted
  • force_lower (boolean) – if True, result is automatically converted to lower case
  • spaces (str) – character used to replace spaces
  • remove_punctuation (boolean) – if True, all punctuation characters are removed
  • keep_chars (str) – characters which may be kept in the input string
Returns:

text without diacritics or special characters

>>> from pyams_utils.unicode import translate_string
>>> input_string = 'Ceci est un test en Français !!!'
>>> translate_string(input_string)
'ceci est un test en francais'
>>> translate_string(input_string, force_lower=False)
'Ceci est un test en Francais'
>>> translate_string(input_string, spaces='-')
'ceci-est-un-test-en-francais'
>>> translate_string(input_string, remove_punctuation=False)
'ceci est un test en francais !!!'
>>> translate_string(input_string, keep_chars='!')
'ceci est un test en francais !!!'
pyams_utils.unicode.unidict(value, encoding='utf-8')[source]

Get specified dict with values converted to unicode

Parameters:
  • value (dict) – input mapping of strings which may be converted to unicode
  • encoding (str) – output encoding
Returns:

dict; a new mapping with each value converted to unicode

>>> from pyams_utils.unicode import unidict
>>> unidict({'input': b'Cha\xc3\xaene accentu\xc3\xa9e'})
{'input': 'Chaîne accentuée'}
>>> unidict({'input': b'Cha\xeene accentu\xe9e'}, 'latin1')
{'input': 'Chaîne accentuée'}
pyams_utils.unicode.unilist(value, encoding='utf-8')[source]

Get specified list with values converted to unicode

Parameters:
  • value (list) – input list of strings which may be converted to unicode
  • encoding (str) – output encoding
Returns:

list; a new list with each value converted to unicode

>>> from pyams_utils.unicode import unilist
>>> unilist([b'Cha\xc3\xaene accentu\xc3\xa9e'])
['Chaîne accentuée']
>>> unilist([b'Cha\xeene accentu\xe9e'], 'latin1')
['Chaîne accentuée']
pyams_utils.unicode.uninvl(value, default='', encoding='utf-8')[source]

Get specified value converted to unicode, or an empty unicode string if value is empty

Parameters:
  • value (str/bytes) – the input to be checked
  • default – str; default value
  • encoding – str; encoding name to use for conversion
Returns:

str; value, or default if value is empty, converted to unicode

>>> from pyams_utils.unicode import uninvl
>>> uninvl('String value')
'String value'
>>> uninvl(b'String value')
'String value'
>>> uninvl(b'Cha\xc3\xaene accentu\xc3\xa9e')
'Chaîne accentuée'
>>> uninvl(b'Cha\xeene accentu\xe9e', 'latin1')
'Chaîne accentuée'
pyams_utils.unicode.utf8(value)[source]

Encode given unicode value to UTF-8 encoded bytes

Parameters:value (str) – the value to encode to utf-8
Returns:bytes; value encoded to bytes if input is a string, original value otherwise
>>> from pyams_utils.unicode import utf8
>>> utf8('Chaîne accentuée')
b'Cha\xc3\xaene accentu\xc3\xa9e'

pyams_utils.url

PyAMS_utils.url module

This module provides several functions, adapters and TALES extensions which can be used to generate object’s URLs.

Three kinds of URLs can be used:
  • an absolute URL, which is the standard way to access an object via it’s physical path
  • a canonical URL; this URL is the “preferred” one used to access an object, and is typically used by search engines to index contents
  • a relative URL; some contents can use this kind of URL to get access to an object from another context.
class pyams_utils.url.AbsoluteUrlTalesExtension(context, request, view)[source]

Bases: pyams_utils.adapter.ContextRequestViewAdapter

extension:absolute_url(context, view_name) TALES extension

A PyAMS TALES extension used to get access to an object URL from a page template.

render(context=None, view_name=None)[source]

Extension rendering; see ITALESExtension

class pyams_utils.url.CanonicalUrlTalesExtension(context, request, view)[source]

Bases: pyams_utils.adapter.ContextRequestViewAdapter

extension:canonical_url(context, view_name) TALES extension

A PyAMS TALES extension used to get access to an object’s canonical URL from a page template.

render(context=None, view_name=None)[source]

Render TALES extension; see ITALESExtension

class pyams_utils.url.DefaultRelativeURLAdapter(context, request)[source]

Bases: pyams_utils.adapter.ContextRequestAdapter

Default relative URL adapter

get_url(display_context=None, view_name=None, query=None)[source]

Default adapter returns absolute URL

class pyams_utils.url.RelativeUrlTalesExtension(context, request, view)[source]

Bases: pyams_utils.adapter.ContextRequestViewAdapter

extension:relative_url(context, view_name, query) TALES extension

A PyAMS TALES extension used to get an object’s relative URL based on current request display context.

render(context=None, view_name=None, query=None)[source]

Rander TALES extension; see ITALESExtension

pyams_utils.url.absolute_url(context, request, view_name=None, query=None)[source]

Get resource absolute_url

Parameters:
  • context (object) – the persistent object for which absolute URL is required
  • request – the request on which URL is based
  • view_name (str) – an optional view name to add to URL
  • query (str/dict) – an optional URL arguments string or mapping

This absolute URL function is based on default Pyramid’s resource_url() function, but add checks to remove some double slashes, and add control on view name when it begins with a ‘#’ character which is used by MyAMS.js framework.

pyams_utils.url.canonical_url(context, request, view_name=None, query=None)[source]

Get resource canonical URL

We look for an ICanonicalURL adapter; if none is found, we use the absolute_url.

pyams_utils.url.generate_url(title, min_word_length=2)[source]

Generate an SEO-friendly content URL from it’s title

The original title is translated to remove accents, converted to lowercase, and words shorter than three characters (by default) are removed; terms are joined by hyphens.

Parameters:
  • title – the input text
  • min_word_length – minimum length of words to keep
>>> from pyams_utils.url import generate_url
>>> generate_url('This is my test')
'this-is-my-test'

Single letters are removed from generated URLs:

>>> generate_url('This word has a single a')
'this-word-has-single'

But you can define the minimum length of word:

>>> generate_url('This word has a single a', min_word_length=4)
'this-word-single'

If input text contains slashes, they are replaced with hyphens:

>>> generate_url('This string contains/slash')
'this-string-contains-slash'

Punctation and special characters are completely removed:

>>> generate_url('This is a string with a point. And why not?')
'this-is-string-with-point-and-why-not'
pyams_utils.url.get_display_context(request)[source]

Get current display context

The display context can be used when we generate a page to display an object in the context of another one; PyAMS_content package is using this feature to display “shared” contents as is they were located inside another site or folder…

pyams_utils.url.relative_url(context, request, display_context=None, view_name=None, query=None)[source]

Get resource URL relative to given context

pyams_utils.vocabulary

PyAMS_utils.vocabulary module

This module is used to handle vocabularies.

class pyams_utils.vocabulary.vocabulary_config(name, **settings)[source]

Bases: object

Class decorator to define a vocabulary

Parameters:name (str) – name of the registered vocabulary

This is, for example, how a vocabulary of registered ZEO connections utilities is created:

from pyams_utils.interfaces.zeo import IZEOConnection

from pyams_utils.registry import get_utilities_for
from pyams_utils.vocabulary import vocabulary_config
from zope.schema.vocabulary import SimpleTerm, SimpleVocabulary

@vocabulary_config(name='PyAMS ZEO connections')
class ZEOConnectionVocabulary(SimpleVocabulary):
    '''ZEO connections vocabulary'''

    def __init__(self, context=None):
        terms = [SimpleTerm(name, title=util.name)
                 for name, util in get_utilities_for(IZEOConnection)]
        super(ZEOConnectionVocabulary, self).__init__(terms)

You can then use such a vocabulary in any schema field:

from zope.interface import Interface
from zope.schema import Choice

class MySchema(Interface):
    '''Custom schema interface'''

    zeo_connection_name = Choice(title='ZEO connection name',
                                 description='Please select a registered ZEO connection',
                                 vocabulary='PyAMS ZEO connections',
                                 required=False)
venusian = <module 'venusian' from '/home/docs/checkouts/readthedocs.org/user_builds/pyams/envs/latest/lib/python3.7/site-packages/venusian/__init__.py'>

pyams_utils.wsgi

PyAMS_utils.wsgi module

This module provides a method decorator which can store it’s value into request environment

pyams_utils.wsgi.wsgi_environ_cache(*names)[source]

Wrap a function/method to cache its result for call into request.environ

Parameters:names ([string...]) – keys to cache into environ; len(names) must be equal to the result’s length or scalar

pyams_utils.zodb

“PyAMS_utils.zodb module

This modules provides several utilities used to manage ZODB connections and persistent objects

class pyams_utils.zodb.ZEOConnection[source]

Bases: object

ZEO connection object

This object can be used to store all settings to be able to open a ZEO connection. Note that this class is required only for tasks specifically targeting a ZEO database connection (like a ZEO packer scheduler task); for generic ZODB operations, just use a ZODBConnection class defined through Pyramid’s configuration file.

Note that a ZEO connection object is a context manager, so you can use it like this:

from pyams_utils.zodb import ZEOConnection

def my_method(zeo_settings):
    zeo_connection = ZEOConnection()
    zeo_connection.update(zeo_settings)
    with zeo_connection as root:
        # *root* is then the ZODB root object
        # do whatever you want with ZEO connection,
        # which is closed automatically
blob_dir

BLOBs directory: Directory path for blob data

connection

Connection getter

get_connection(wait_timeout=30, get_storage=False)[source]

Create ZEO client connection from current settings

Parameters:
  • wait_timeout (boolean) – connection timeout, in seconds
  • get_storage (boolean) – if True, the method should return a tuple containing storage and DB objects; otherwise only DB object is returned
Returns:

tuple containing ZEO client storage and DB object (if get_storage argument is set to True), or only DB object otherwise

get_settings()[source]

Get mapping of all connection settings

These settings can be converted to JSON and sent to another process, for example via a ØMQ connection.

Returns:dict
name

Connection name: Registration name of ZEO connection

password

ZEO password: User password on ZEO server; only for ZEO server before 5.0

server_name

ZEO server name: Hostname of ZEO server

server_port

ZEO server port: Port number of ZEO server

server_realm

ZEO server realm: Realm name on ZEO server; only for ZEO server before 5.0

shared_blob_dir

Shared BLOBs directory ?: Flag whether the blob_dir is a server-shared filesystem that should be used instead of transferring blob data over zrpc.

storage

ZEO server storage: Storage name on ZEO server

update(settings)[source]

Update connection properties with settings as dict

Parameters:settings (dict) – typically extracted via the get_settings() method from another process
username

ZEO user name: User name on ZEO server; only for ZEO server before 5.0

class pyams_utils.zodb.ZEOConnectionUtility[source]

Bases: pyams_utils.zodb.ZEOConnection, persistent.Persistent, zope.container.contained.Contained

Persistent ZEO connection utility

class pyams_utils.zodb.ZEOConnectionVocabulary(context=None)[source]

Bases: zope.schema.vocabulary.SimpleVocabulary

ZEO connections vocabulary

class pyams_utils.zodb.ZODBConnection(name='', settings=None)[source]

Bases: object

ZODB connection wrapper

Connections are extracted from Pyramid’s settings file in zodbconn.uri entries.

Note that a ZODB connection object is a context manager, so you can use it like this:

from pyams_utils.zodb import ZODBConnection

def my_method(zodb_name):
    zodb_connection = ZODBConnection(zodb_name)
    with zodb_connection as root:
        # *root* is then the ZODB root object
        # do whatever you want with ZODB connection,
        # which is closed automatically
close()[source]

Connection close

connection

Connection getter

db

Database getter

get_connection()[source]

Load named connection matching registry settings

storage

Storage getter

class pyams_utils.zodb.ZODBConnectionVocabulary(context=None)[source]

Bases: zope.schema.vocabulary.SimpleVocabulary

ZODB connections vocabulary

pyams_utils.zodb.get_connection_from_settings(settings=None)[source]

Load connection matching registry settings

pyams_utils.zodb.handle_added_connection(event)[source]

Register new ZEO connection when added

pyams_utils.zodb.handle_removed_connection(event)[source]

Un-register ZEO connection when deleted

pyams_utils.zodb.persistent_connection(obj)[source]

An adapter which gets a ZODB connection from a persistent object

We are assuming the object has a parent if it has been created in this transaction.

Raises ValueError if it is impossible to get a connection.

pyams_utils.zodb.persistent_transaction_manager(obj)[source]

Transaction manager adapter for persistent objects

class pyams_utils.zodb.volatile_property(fget, doc=None)[source]

Bases: object

Property decorator to define volatile attributes into persistent classes