Commit 6a4974da by Piotr Mitros

Example application included

parent ca2814a0
...@@ -90,7 +90,11 @@ To build on top of the framework, you will need several things: ...@@ -90,7 +90,11 @@ To build on top of the framework, you will need several things:
should define appropriate (TBD) properties to ornament your events should define appropriate (TBD) properties to ornament your events
with and appropriate queries (TBD) to get data out of your with and appropriate queries (TBD) to get data out of your
read-replica databases, so that modules written by other folks can read-replica databases, so that modules written by other folks can
get at your data in a generic way. get at your data in a generic way. The best way to understand how
to do this is to read test cases in modules/testmodule/__init__.py
A very minimal example of how to build applications on top of this
framework is in the example directory.
Shortcuts/invariants Shortcuts/invariants
-------------------- --------------------
......
This is a minimal application built on top of djanalytics.
All it does is stream events verbatim into a database.
To run this, first install djanalytics:
sudo python setup.py install
Do the same for:
https://github.com/edx/loghandlersplus
https://github.com/edx/djeventstream
Now,
cd example/src/mongolog/
python manage.py syncdb
python manage.py migrate
python manage.py runserver localhost:8020
The server should be running. To stream an event, run:
cd example/src/sendevent
To confirm the event is there:
mongo
show dbs
use modules_dump_to_db
show collections
db.getCollection("event_log").find()
This is test and working as of April 12, 2013. This is not a normal
test case, so please let me know if this breaks (it is not entirely
unexpected that it might; the API is still quite fluid as of April).
#!/usr/bin/env python
import os
import sys
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mongolog.settings")
from django.core.management import execute_from_command_line
execute_from_command_line(sys.argv)
import sys
from djanalytics.core.decorators import event_handler
@event_handler()
def dump_to_db(db, events):
collection = db['event_log']
collection.insert([e.event for e in events])
# Django settings for mongolog project.
# Django settings for edxanalytics project.
#### djanalytics-specific settings
import datetime
import os.path
import path
import sys
import imp
from pkg_resources import resource_filename
DJ_REQUIRED_APPS = ( 'djeventstream.httphandler',
'djcelery',
'south',
'djanalytics.core',
'djanalytics.modulefs',
# 'modules',
)
# Types of parameters that queries and views can take.
# This is not properly used yet.
DJANALYTICS_PARAMETERS = ['user', 'filename']
DJFS = { 'type' : 'osfs',
'directory_root' : '/tmp/djfsmodule',
'url_root' : 'file:///tmp/'
}
TIME_BETWEEN_DATA_REGENERATION = datetime.timedelta(minutes=1)
INSTALLED_ANALYTICS_MODULES = ['modules.dump_to_db'] #'modules.testmodule',)
print INSTALLED_ANALYTICS_MODULES
#Initialize celery
import djcelery
djcelery.setup_loader()
SNS_SUBSCRIPTIONS = []
import django.contrib.auth.decorators
DJA_AUTH = { '.*' : django.contrib.auth.decorators.login_required }
MAKO_MODULE_DIR = '../../compiled_templates' # TODO: Use pkg_resources.resource_filename
DEBUG = True
TEMPLATE_DEBUG = DEBUG
ADMINS = (
# ('Your Name', 'your_email@example.com'),
)
MANAGERS = ADMINS
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
'NAME': '../../localdb.sql', # TODO: Use pkg_resources.resource_filename
'USER': '', # Not used with sqlite3.
'PASSWORD': '', # Not used with sqlite3.
'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
'PORT': '', # Set to empty string for default. Not used with sqlite3.
}
}
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'LOCATION': 'analytics-experiments'
}
}
# Local time zone for this installation. Choices can be found here:
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
# although not all choices may be available on all operating systems.
# In a Windows environment this must be set to your system time zone.
TIME_ZONE = 'America/Chicago'
# Language code for this installation. All choices can be found here:
# http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGE_CODE = 'en-us'
SITE_ID = 1
# If you set this to False, Django will make some optimizations so as not
# to load the internationalization machinery.
USE_I18N = True
# If you set this to False, Django will not format dates, numbers and
# calendars according to the current locale.
USE_L10N = True
# If you set this to False, Django will not use timezone-aware datetimes.
USE_TZ = True
# Absolute filesystem path to the directory that will hold user-uploaded files.
# Example: "/home/media/media.lawrence.com/media/"
MEDIA_ROOT = ''
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash.
# Examples: "http://media.lawrence.com/media/", "http://example.com/media/"
MEDIA_URL = ''
# Absolute path to the directory static files should be collected to.
# Don't put anything in this directory yourself; store your static files
# in apps' "static/" subdirectories and in STATICFILES_DIRS.
# Example: "/home/media/media.lawrence.com/static/"
STATIC_ROOT = ''
# URL prefix for static files.
# Example: "http://media.lawrence.com/static/"
STATIC_URL = '/static/'
# Additional locations of static files
STATICFILES_DIRS = (
# Put strings here, like "/home/html/static" or "C:/www/django/static".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
)
# List of finder classes that know how to find static files in
# various locations.
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
# 'django.contrib.staticfiles.finders.DefaultStorageFinder',
)
# Make this unique, and don't share it with anybody.
SECRET_KEY = 'v9+anmn#pu&@h^fmj^(qcb8cc@!rm3t)uq$_&fg4i@k94*lclk'
# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
# 'django.template.loaders.eggs.Loader',
)
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
# Uncomment the next line for simple clickjacking protection:
# 'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
ROOT_URLCONF = 'mongolog.urls'
# Python dotted path to the WSGI application used by Django's runserver.
WSGI_APPLICATION = 'mongolog.wsgi.application'
TEMPLATE_DIRS = (
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
)
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
) + DJ_REQUIRED_APPS
# A sample logging configuration. The only tangible logging
# performed by this configuration is to send an email to
# the site admins on every HTTP 500 error when DEBUG=False.
# See http://docs.djangoproject.com/en/dev/topics/logging for
# more details on how to customize your logging configuration.
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse'
}
},
'handlers': {
'mail_admins': {
'level': 'ERROR',
'filters': ['require_debug_false'],
'class': 'django.utils.log.AdminEmailHandler'
}
},
'loggers': {
'django.request': {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': True,
},
}
}
#Celery settings
BROKER_URL = 'redis://localhost:6379/0'
BROKER_TRANSPORT_OPTIONS = {'visibility_timeout': 3600}
CELERY_RESULT_BACKEND = 'redis://localhost:6379/0'
CELERY_TASK_RESULT_EXPIRES = 60 * 60 #1 hour
MODULE_DIR = "modules"
CELERY_IMPORTS = ()
for analytics_module in INSTALLED_ANALYTICS_MODULES:
module_name = "{0}.{1}.{2}".format(MODULE_DIR,analytics_module,"tasks")
try:
imp.find_module(module_name)
CELERY_IMPORTS += (module_name,)
except:
pass
from django.conf.urls import patterns, include, url
# Uncomment the next two lines to enable the admin:
# from django.contrib import admin
# admin.autodiscover()
urlpatterns = patterns('',
url(r'^httpevent$', 'djeventstream.httphandler.views.http_view'),
# Examples:
# url(r'^$', 'mongolog.views.home', name='home'),
# url(r'^mongolog/', include('mongolog.foo.urls')),
# Uncomment the admin/doc line below to enable admin documentation:
# url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
# Uncomment the next line to enable the admin:
# url(r'^admin/', include(admin.site.urls)),
)
import djanalytics.core.views
"""
WSGI config for mongolog project.
This module contains the WSGI application used by Django's development server
and any production WSGI deployments. It should expose a module-level variable
named ``application``. Django's ``runserver`` and ``runfcgi`` commands discover
this application via the ``WSGI_APPLICATION`` setting.
Usually you will have the standard Django WSGI application here, but it also
might make sense to replace the whole Django WSGI application with a custom one
that later delegates to the Django one. For example, you could introduce WSGI
middleware here, or combine a Django application with an application of another
framework.
"""
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mongolog.settings")
# This application object is used by any WSGI server configured to use this
# file. This includes Django's development server, if the WSGI_APPLICATION
# setting points here.
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
# Apply WSGI middleware here.
# from helloworld.wsgi import HelloWorldApplication
# application = HelloWorldApplication(application)
# Generates a dummy event for testing
# E.g.:
#
# python sendevent.py localhost:8020 /httpevent actor=bob action=submitanswer object=problem5
import json
import sys
import logging
from logging.handlers import HTTPHandler
logger=logging.getLogger('sendevent')
logger.addHandler(HTTPHandler(sys.argv[1], sys.argv[2]))
objects=[o.split("=") for o in sys.argv[3:]]
logger.error(json.dumps(dict(objects)))
...@@ -271,3 +271,7 @@ class StreamingEvent: ...@@ -271,3 +271,7 @@ class StreamingEvent:
def keys(self): def keys(self):
return self.event.keys() return self.event.keys()
def raw_json(self):
''' Still considering this API. Not long-term guaranteed. '''
return self.event
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment