API Reference

Utility

flask_mongo_profiler.utils.combine_events_to_queries(_mongo_events)[source]

Combines pymongo.monitoring events to queries.

CommandStartedEvent has queries information. CommandSuccessfulEvent has timing information.

Iterate over events and map against mongo’s request_id (the query).

flask_mongo_profiler.utils.sanitize_dict(d, reverse=False)[source]

ValidationError: ValidationError (ProfilingRequest:None) (Invalid dictionary key name - keys may not contain “.” or “$” characters 1.Invalid dictionary key name - keys may not contain “.” or “$” characters 2.Invalid dictionary key name - keys may not contain “.” or “$” characters: [‘queries’])

Helpers

flask_mongo_profiler.helpers.add_template_dirs(app)[source]

Add flask_mongo_profiler’s template directories.

Parameters:app (flask.Flask) –

Constants

flask_mongo_profiler.constants.MONGO_COMMAND_KEY_DOLLAR_SIGN_REPLACEMENT = '__'

e.g. $exists, $in

flask_mongo_profiler.constants.MONGO_COMMAND_KEY_PERIOD_SIGN_REPLACEMENT = '-'

e.g. parent.ref.$id ($ would be __ thanks to above)

flask_mongo_profiler.constants.RE_OBJECTID = re.compile('([0-9a-f]{24})')

Match MongoDB ObjectID pattern

flask_mongo_profiler.constants.WERKZEUG_ENVIRON_KEY_REPLACEMENT = '-'

Used to replace keys with . for mongodb compatibility e.g. wsgi.url_scheme

Werkzeug support

See also

pymongo.monitoring

http
//api.mongodb.com/python/current/api/pymongo/monitoring.html
class flask_mongo_profiler.contrib.werkzeug.mongo.BaseMongoCommandLogger(quiet=True, command_filter=['create', 'find', 'update', 'delete'])[source]

Log Mongo queries we make. Differences from plain-old listener:

  1. Turn logging output on/off since there’s no public pymongo API to unregister or monitor queries temporarily.
  2. Enable logging to various endpoints without having to rewrite everything. It can be valuable to log to standard library logging (stdout, logfile), or database (django-silk style).
  3. Can be tailored to output only commands requested.
Parameters:
  • quiet (bool, optional) – Silence MongoDB CommandListener from logging (default: True)
  • command_filter (list of str, optional) – MongoDB queries commands to send to logger

See also

-

failed(event)[source]

Abstract method to handle a CommandFailedEvent.

Parameters:
  • event: An instance of CommandFailedEvent.
start()[source]
started(event)[source]

Abstract method to handle a CommandStartedEvent.

Parameters:
  • event: An instance of CommandStartedEvent.
stop()[source]
succeeded(event)[source]

Abstract method to handle a CommandSucceededEvent.

Parameters:
  • event: An instance of CommandSucceededEvent.
class flask_mongo_profiler.contrib.werkzeug.mongo.LoggingMongoCommandLogger(quiet=True, command_filter=['create', 'find', 'update', 'delete'])[source]
failed(event)[source]

Abstract method to handle a CommandFailedEvent.

Parameters:
  • event: An instance of CommandFailedEvent.
started(event)[source]

Abstract method to handle a CommandStartedEvent.

Parameters:
  • event: An instance of CommandStartedEvent.
succeeded(event)[source]

Abstract method to handle a CommandSucceededEvent.

Parameters:
  • event: An instance of CommandSucceededEvent.
class flask_mongo_profiler.contrib.werkzeug.mongo.QueuedMongoCommandLogger(quiet=True, command_filter=['create', 'find', 'update', 'delete'])[source]

Record the commands in self.collector list.

failed(event)[source]

Abstract method to handle a CommandFailedEvent.

Parameters:
  • event: An instance of CommandFailedEvent.
start()[source]
started(event)[source]

Abstract method to handle a CommandStartedEvent.

Parameters:
  • event: An instance of CommandStartedEvent.
stop()[source]
succeeded(event)[source]

Abstract method to handle a CommandSucceededEvent.

Parameters:
  • event: An instance of CommandSucceededEvent.
class flask_mongo_profiler.contrib.werkzeug.werkzeug_middleware.ProfilerMiddleware(app, pymongo_logger, ignored_url_patterns=None)[source]

MongoEngine support

class flask_mongo_profiler.contrib.mongoengine.mixins.FlaskAdminURLMixin[source]

Add get_admin_url to models supported by Flask-Admin

Flask-Admin creates URL’s namespaced w/ model class name, lowercase.

classmethod get_admin_list_url(_external=False)[source]
get_admin_url(_external=False)[source]
class flask_mongo_profiler.contrib.mongoengine.mixins.GetAttributeMixin[source]
get(attr, default=None)[source]
class flask_mongo_profiler.contrib.mongoengine.profiling.ProfilingQuery(*args, **values)[source]
exception DoesNotExist[source]
exception MultipleObjectsReturned[source]
command

A dictionary field that wraps a standard Python dictionary. This is similar to an embedded document, but the structure is not defined.

Note

Required means it cannot be empty - as the default for DictFields is {}

New in version 0.3.

Changed in version 0.5: - Can now handle complex / varying types of data

command_name

A unicode string field.

connection

An embedded document field - with a declared document_type. Only valid values are subclasses of EmbeddedDocument.

database_name

A unicode string field.

duration

Fixed-point decimal number field. Stores the value as a float by default unless force_string is used. If using floats, beware of Decimal to float conversion (potential precision loss)

Changed in version 0.8.

New in version 0.3.

failure

A dictionary field that wraps a standard Python dictionary. This is similar to an embedded document, but the structure is not defined.

Note

Required means it cannot be empty - as the default for DictFields is {}

New in version 0.3.

Changed in version 0.5: - Can now handle complex / varying types of data

id

A field wrapper around MongoDB’s ObjectIds.

objects

The default QuerySet Manager.

Custom QuerySet Manager functions can extend this class and users can add extra queryset functionality. Any custom manager methods must accept a Document class as its first argument, and a QuerySet as its second argument.

The method function should return a QuerySet , probably the same one that was passed in, but modified in some way.

operation_id

32-bit integer field.

request

A reference to a document that will be automatically dereferenced on access (lazily).

Note this means you will get a database I/O access everytime you access this field. This is necessary because the field returns a Document which precise type can depend of the value of the _cls field present in the document in database. In short, using this type of field can lead to poor performances (especially if you access this field only to retrieve it pk field which is already known before dereference). To solve this you should consider using the LazyReferenceField.

Use the reverse_delete_rule to handle what should happen if the document the field is referencing is deleted. EmbeddedDocuments, DictFields and MapFields does not support reverse_delete_rule and an InvalidDocumentError will be raised if trying to set on one of these Document / Field types.

The options are:

  • DO_NOTHING (0) - don’t do anything (default).
  • NULLIFY (1) - Updates the reference to null.
  • CASCADE (2) - Deletes the documents associated with the reference.
  • DENY (3) - Prevent the deletion of the reference object.
  • PULL (4) - Pull the reference from a ListField of references

Alternative syntax for registering delete rules (useful when implementing bi-directional delete rules)

class Org(Document):
    owner = ReferenceField('User')

class User(Document):
    org = ReferenceField('Org', reverse_delete_rule=CASCADE)

User.register_delete_rule(Org, 'owner', DENY)

Changed in version 0.5: added reverse_delete_rule

request_id

A unicode string field.

class flask_mongo_profiler.contrib.mongoengine.profiling.ProfilingQueryConnection(*args, **kwargs)[source]

Examples

Unpack (‘localhost’, 27017) tuple to dictionary:

>>> params = dict(
>>>    connection=model.ProfilingQueryConnection(*event.connection_id),
>>> )

All pymongo.monitoring event types include connection_id. The address (host, port) of the server this command was sent to.

References

http://api.mongodb.com/python/current/api/pymongo/monitoring.html

host

A unicode string field.

port

32-bit integer field.

class flask_mongo_profiler.contrib.mongoengine.profiling.ProfilingRequest(*args, **values)[source]
exception DoesNotExist[source]
exception MultipleObjectsReturned[source]
duration

Fixed-point decimal number field. Stores the value as a float by default unless force_string is used. If using floats, beware of Decimal to float conversion (potential precision loss)

Changed in version 0.8.

New in version 0.3.

environ

A dictionary field that wraps a standard Python dictionary. This is similar to an embedded document, but the structure is not defined.

Note

Required means it cannot be empty - as the default for DictFields is {}

New in version 0.3.

Changed in version 0.5: - Can now handle complex / varying types of data

id

A field wrapper around MongoDB’s ObjectIds.

method

A unicode string field.

objects

The default QuerySet Manager.

Custom QuerySet Manager functions can extend this class and users can add extra queryset functionality. Any custom manager methods must accept a Document class as its first argument, and a QuerySet as its second argument.

The method function should return a QuerySet , probably the same one that was passed in, but modified in some way.

path

A unicode string field.

pyprofile

A unicode string field.

query_count

32-bit integer field.

query_duration

Fixed-point decimal number field. Stores the value as a float by default unless force_string is used. If using floats, beware of Decimal to float conversion (potential precision loss)

Changed in version 0.8.

New in version 0.3.

referrer

A unicode string field.

status

A dictionary field that wraps a standard Python dictionary. This is similar to an embedded document, but the structure is not defined.

Note

Required means it cannot be empty - as the default for DictFields is {}

New in version 0.3.

Changed in version 0.5: - Can now handle complex / varying types of data

time

Datetime field.

Uses the python-dateutil library if available alternatively use time.strptime to parse the dates. Note: python-dateutil’s parser is fully featured and when installed you can utilise it to convert varying types of date formats into valid python datetime objects.

Note: To default the field to the current datetime, use: DateTimeField(default=datetime.utcnow)

Note: Microseconds are rounded to the nearest millisecond.
Pre UTC microsecond support is effectively broken. Use ComplexDateTimeField if you need accurate microsecond support.

Flask Admin support

Helpers

flask_mongo_profiler.contrib.flask_admin.helpers.get_list_url_filtered_by_field_value(view, model, name, reverse=False)[source]

Get the URL if a filter of model[name] value was appended.

This allows programatically adding filters. This is used in the specialized case of filtering deeper into a list by a field’s value.

For instance, since there can be multiple assignments in a list of handins. The assignment column can have a URL generated by get_filter_url to filter the handins to show only ones for that assignment.

Parameters:
  • view (View instance) –
  • model (document (model instance, not the class itself)) –
  • name (field name) –
  • reverse (bool) – Whether to remove an applied filter from url
Returns:

string

Return type:

URL of current list args + filtering on field value

flask_mongo_profiler.contrib.flask_admin.helpers.search_relative_field(model_class, fields, term)[source]

Searches a ReferenceField’s fields, returning ID’s to be used in __in

There is no JOIN, so no Assignment.objects.filter(course__title=’My Course’). To get around this, we return a list of ID’s.

Since this is an internal tool, we allow multiple fields to AND/OR group.

Formatters

flask_mongo_profiler.contrib.flask_admin.formatters.date.date_formatter(view, value)[source]

We appear to store naive datetimes in our database.

Formats the date, and if the user has a timezone that’s different from the naive date, will append the naive date below appended with UTC.

flask_mongo_profiler.contrib.flask_admin.formatters.lookup.search_field_formatter(view, context, model, name)[source]

Formatters that do polymorphic relation resolution against GenericReferienceField. They will look up the original model in the field, then lookup like a normal relational formatter.

See also

model.AdminLog.document, model.Answer.parent

References

[1]mongoengine.fields.GenericReferenceField. MongoEngine Docs. http://docs.mongoengine.org/apireference.html#mongoengine.fields.GenericReferenceField
[2]mongoengine.fields.GenericLazyReferenceField. MongoEngine Docs. http://docs.mongoengine.org/apireference.html#mongoengine.fields.GenericLazyReferenceField
flask_mongo_profiler.contrib.flask_admin.formatters.polymorphic_relations.generic_document_type_formatter(view, context, model, name)[source]

Return AdminLog.document field wrapped in URL to its list view.

flask_mongo_profiler.contrib.flask_admin.formatters.polymorphic_relations.generic_lazy_ref_formatter(view, context, model, name)[source]

See also

diff_formatter()

flask_mongo_profiler.contrib.flask_admin.formatters.polymorphic_relations.generic_ref_formatter(view, context, model, name, lazy=False)[source]

For GenericReferenceField and LazyGenericReferenceField

See also

diff_formatter()

flask_mongo_profiler.contrib.flask_admin.formatters.polymorphic_relations.generic_ref_list_formatter(view, context, model, name)[source]
flask_mongo_profiler.contrib.flask_admin.formatters.profiling.http_method_formatter(view, context, model, name)[source]

Wrap HTTP method value in a bs3 label.

flask_mongo_profiler.contrib.flask_admin.formatters.profiling.map_to_bootstrap_column_formatter(view, context, model, name, key_formatter_fn=None)[source]
flask_mongo_profiler.contrib.flask_admin.formatters.profiling.mongo_command_name_formatter(view, context, model, name)[source]
flask_mongo_profiler.contrib.flask_admin.formatters.profiling.profile_pyprofile_formatter(view, context, model, name)[source]

Format pyprofile output

flask_mongo_profiler.contrib.flask_admin.formatters.profiling.profiling_pure_query_formatter(view, context, model, name, tag='pre')[source]
flask_mongo_profiler.contrib.flask_admin.formatters.profiling.profiling_query_formatter(view, context, query_document, name)[source]

Format a ProfilingQuery entry for a ProfilingRequest detail field

Parameters:query_document (model.ProfilingQuery) –
flask_mongo_profiler.contrib.flask_admin.formatters.profiling.profiling_query_list_formatter(queryset)[source]
Parameters:queryset (mongoengine.Queryset of model.ProfilingQuery) –
flask_mongo_profiler.contrib.flask_admin.formatters.profiling.profiling_request_formatter(view, context, model, name)[source]

Wrap HTTP method value in a bs3 label.

flask_mongo_profiler.contrib.flask_admin.formatters.profiling.request_environ_formatter(view, context, model, name)[source]
flask_mongo_profiler.contrib.flask_admin.formatters.relational.qs_field(model_class, field, filters=None, formatter=<function queryset_formatter>, manager_name='objects')[source]

Show computed fields based on QuerySet’s.

This is a workaround since sometimes some filtering is involved to see if a user owns and object, is a student, etc.

Example

class MyModel(ModelView):
details_extra_columns = [
(‘courses_owned’, ‘Courses (Owner of)’),

] column_formatters_detail = {

‘courses_owner’: qs_field(model.Course, ‘owner’),

]

flask_mongo_profiler.contrib.flask_admin.formatters.relational.queryset_formatter(queryset)[source]

This is used for custom detail fields returning a QuerySet of admin objects.

Views

class flask_mongo_profiler.contrib.flask_admin.views.base.BaseModelView(*args, **kwargs)[source]
action_view()[source]

Mass-model action view.

ajax_lookup()[source]
ajax_update()[source]

Edits a single column of a record in list view.

api_file_view()[source]
create_view()[source]

Create model view

delete_view()[source]

Delete model view. Only POST method is allowed.

details_view()[source]

Details model view

edit_view()[source]

Edit model view

export(export_type)[source]
index_view()[source]

List view

named_filter_urls = True
class flask_mongo_profiler.contrib.flask_admin.views.base.ColumnFieldTypeFormattersMixin(*args, **kwargs)[source]
class flask_mongo_profiler.contrib.flask_admin.views.base.ExtraDetailColumnsMixin[source]
details_extra_columns = []
get_details_columns()[source]

Add details_extra_columns. (Not in normal Flask-Admin)

class flask_mongo_profiler.contrib.flask_admin.views.base.PrettyDatesMixin[source]
column_type_formatters = {<class 'datetime.date'>: <function date_formatter>}
column_type_formatters_detail = {<class 'datetime.date'>: <function date_formatter>}
class flask_mongo_profiler.contrib.flask_admin.views.base.ReadOnlyMixin[source]
can_create = False
can_delete = False
can_edit = False
can_view_details = True
class flask_mongo_profiler.contrib.flask_admin.views.base.RelationalFieldMixin[source]
allowed_search_types = (<class 'mongoengine.fields.StringField'>, <class 'mongoengine.fields.URLField'>, <class 'mongoengine.fields.EmailField'>, <class 'mongoengine.base.fields.ObjectIdField'>, <class 'mongoengine.fields.ReferenceField'>, <class 'mongoengine.fields.ListField'>)
column_field_type_formatters = {<class 'mongoengine.fields.ReferenceField'>: <function generic_ref_formatter>, <class 'mongoengine.fields.GenericLazyReferenceField'>: <function generic_lazy_ref_formatter>, <class 'mongoengine.fields.GenericReferenceField'>: <function generic_ref_formatter>, <class 'mongoengine.fields.ListField'>: <function generic_ref_list_formatter>}
column_field_type_formatters_detail = {<class 'mongoengine.fields.ReferenceField'>: <function generic_ref_formatter>, <class 'mongoengine.fields.GenericLazyReferenceField'>: <function generic_lazy_ref_formatter>, <class 'mongoengine.fields.GenericReferenceField'>: <function generic_ref_formatter>, <class 'mongoengine.fields.ListField'>: <function generic_ref_list_formatter>}
class flask_mongo_profiler.contrib.flask_admin.views.base.RelationalSearchMixin[source]
column_searchable_refs = {}
flask_mongo_profiler.contrib.flask_admin.views.date.date_formatter(view, value)[source]

We appear to store naive datetimes in our database.

Formats the date, and if the user has a timezone that’s different from the naive date, will append the naive date below appended with UTC.

class flask_mongo_profiler.contrib.flask_admin.views.profiling.ProfilingCommonView(*args, **kwargs)[source]
action_view()[source]

Mass-model action view.

ajax_lookup()[source]
ajax_update()[source]

Edits a single column of a record in list view.

api_file_view()[source]
clear_entities()[source]
create_view()[source]

Create model view

delete_view()[source]

Delete model view. Only POST method is allowed.

details_view()[source]

Details model view

edit_view()[source]

Edit model view

export(export_type)[source]
index_view()[source]

List view

list_template = 'admin/model/profiling-list.html'
class flask_mongo_profiler.contrib.flask_admin.views.profiling.ProfilingQueryView(*args, **kwargs)[source]
action_view()[source]

Mass-model action view.

ajax_lookup()[source]
ajax_update()[source]

Edits a single column of a record in list view.

api_file_view()[source]
clear_entities()[source]
column_filters = ['command_name', 'request']
column_formatters = {'command': <function profiling_pure_query_formatter>, 'command_name': <function mongo_command_name_formatter>, 'request': <function profiling_request_formatter>}
column_formatters_detail = {'command_name': <function mongo_command_name_formatter>, 'command_pretty': <function profiling_query_formatter>, 'request': <function profiling_request_formatter>}
column_labels = {'duration': 'Duration (ms)'}
column_list = ['command_name', 'request', 'duration', 'command']
column_searchable_list = ['command_name', 'request']
create_view()[source]

Create model view

delete_view()[source]

Delete model view. Only POST method is allowed.

details_extra_columns = [('command_pretty', 'Command (pretty)')]
details_view()[source]

Details model view

edit_view()[source]

Edit model view

export(export_type)[source]
index_view()[source]

List view

class flask_mongo_profiler.contrib.flask_admin.views.profiling.ProfilingRequestView(*args, **kwargs)[source]
action_view()[source]

Mass-model action view.

ajax_lookup()[source]
ajax_update()[source]

Edits a single column of a record in list view.

api_file_view()[source]
clear_entities()[source]
column_descriptions = {'referrer': 'Page requesting API endpoint. If empty, is the page itself.'}
column_details_exclude_list = ['pyprofile']
column_filters = ['method', 'path', 'referrer', 'duration', 'query_duration', 'query_count', 'time']
column_formatters = {'method': <function http_method_formatter>, 'path': <function search_field_formatter>, 'referrer': <function search_field_formatter>}
column_formatters_detail = {'environ': <function request_environ_formatter>, 'method': <function http_method_formatter>, 'path': <function search_field_formatter>, 'pyprofile': <function profile_pyprofile_formatter>, 'queries': <function qs_field.<locals>._>, 'referrer': <function search_field_formatter>, 'status': <function map_to_bootstrap_column_formatter>}
column_labels = {'duration': 'Duration (ms)', 'query_duration': 'Query Duration (ms)'}
column_list = ['method', 'path', 'referrer', 'duration', 'query_duration', 'query_count', 'time']
column_searchable_list = ['path', 'method']
create_view()[source]

Create model view

delete_view()[source]

Delete model view. Only POST method is allowed.

details_extra_columns = [('queries', 'Queries'), ('pyprofile', 'Profile')]
details_view()[source]

Details model view

edit_view()[source]

Edit model view

export(export_type)[source]
index_view()[source]

List view

list_template = 'admin/model/profilingrequest-list.html'