Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
I
insights
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
insights
Commits
0aeeecba
Commit
0aeeecba
authored
May 11, 2013
by
Piotr Mitros
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Relative to absolute import bug fixed. Untested code for merging analytics object. Better docs
parent
bbf7494e
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
90 additions
and
8 deletions
+90
-8
README.md
+20
-0
src/djanalytics/core/djobject.py
+68
-6
src/djanalytics/core/registry.py
+2
-2
No files found.
README.md
View file @
0aeeecba
...
@@ -101,6 +101,26 @@ To build on top of the framework, you will need several things:
...
@@ -101,6 +101,26 @@ To build on top of the framework, you will need several things:
A very minimal example of how to build applications on top of this
A very minimal example of how to build applications on top of this
framework is in the example directory.
framework is in the example directory.
Using Analytics Externally (djobject)
-------------------------------------
djobject.py has an abstraction for accessing analytics both locally
(function calls) and remotely (RPC). This is a standard Python
object. All of the standard Python introspection of the methods in
this object works.
When using analytics remotely, there are issues of security and
permissions. Specifically, a sysadmin might want to see an analytic
per-course/per-student. An instructor of that course might want to
have that fixed to the course (so it transforms into a per-student
analytic). djobject's transform_embed defines a DSL for restricting
permissions to analytics, as well as for fixing specific commandline
parameters.
There is an issue of network reliability and timeouts when access
remotely. This is planned to be handled by being able to set timeouts
on djembed objects.
Shortcuts/invariants
Shortcuts/invariants
--------------------
--------------------
...
...
src/djanalytics/core/djobject.py
View file @
0aeeecba
...
@@ -3,9 +3,9 @@ etc. as Python objects.
...
@@ -3,9 +3,9 @@ etc. as Python objects.
This is prototype-grade code.
This is prototype-grade code.
It
will remain ugly into production, however. I'm not sure if there is
It
is very ugly. It will be cleaned up, but still slightly ugly,
a good way to make this clean, but the ugliness here will save a lo
t
however. I'm not sure if there is a good way to make this clean, bu
t
of ugliness for the API caller.
the ugliness here will save a lot
of ugliness for the API caller.
'''
'''
import
decorator
import
decorator
...
@@ -29,7 +29,7 @@ def find_in_schema(cls = None, name = None):
...
@@ -29,7 +29,7 @@ def find_in_schema(cls = None, name = None):
items
.
append
(
item
)
items
.
append
(
item
)
return
items
return
items
def
http_rpc_helper
(
baseurl
,
view_or_query
,
function
,
headers
=
{}):
def
http_rpc_helper
(
baseurl
,
view_or_query
,
function
,
headers
=
{}
,
timeout
=
None
):
''' Make an RPC call to a remote djanalytics instance
''' Make an RPC call to a remote djanalytics instance
'''
'''
if
baseurl
:
if
baseurl
:
...
@@ -39,7 +39,12 @@ def http_rpc_helper(baseurl, view_or_query, function, headers = {}):
...
@@ -39,7 +39,12 @@ def http_rpc_helper(baseurl, view_or_query, function, headers = {}):
url
=
urllib
.
basejoin
(
baseembedurl
,
function
)
url
=
urllib
.
basejoin
(
baseembedurl
,
function
)
if
kwargs
:
if
kwargs
:
url
=
url
+
"?"
+
urllib
.
urlencode
(
kwargs
)
url
=
url
+
"?"
+
urllib
.
urlencode
(
kwargs
)
response
=
requests
.
get
(
url
,
headers
=
headers
)
kwargs
=
{}
if
headers
:
kwargs
[
'headers'
]
=
headers
if
timeout
:
kwargs
[
'timeout'
]
=
float
(
timeout
)
response
=
requests
.
get
(
url
,
**
kwargs
)
if
response
.
status_code
==
200
:
if
response
.
status_code
==
200
:
return
response
.
content
return
response
.
content
if
response
.
status_code
==
404
:
if
response
.
status_code
==
404
:
...
@@ -56,12 +61,62 @@ def local_call_helper(view_or_query, function):
...
@@ -56,12 +61,62 @@ def local_call_helper(view_or_query, function):
return
djanalytics
.
core
.
registry
.
handle_request
(
view_or_query
,
function
,
**
kwargs
)
return
djanalytics
.
core
.
registry
.
handle_request
(
view_or_query
,
function
,
**
kwargs
)
return
rpc_call
return
rpc_call
class
multi_embed
():
''' Lets you merge multiple embeds into one. E.g. talk to 5
analytics servers.
This code is scaffolding meant to define the interface. It is
untested.
'''
def
__init__
(
self
,
embeds
):
self
.
_embeds
=
embeds
def
__getattr__
(
self
,
attr
):
for
x
in
self
.
_embeds
:
try
:
attr
=
x
.
__getattr
(
attr
)
except
AttributeError
:
pass
if
attr
:
return
attr
raise
AttributeError
(
attr
)
def
_refresh_schema
(
self
):
for
x
in
self
.
_embeds
:
x
.
_refresh_schema
def
__dir__
(
self
):
return
list
(
sum
(
map
(
lambda
x
:
set
(
x
.
__dir__
()),
self
.
_embeds
)))
def
__repr__
(
self
):
return
"/"
.
join
(
map
(
lambda
x
:
repr
(
x
),
self
.
_embeds
))
class
embed
():
class
embed
():
def
__init__
(
self
,
view_or_query
,
baseurl
=
None
,
headers
=
{}):
def
__init__
(
self
,
view_or_query
,
baseurl
=
None
,
headers
=
{}):
self
.
_baseurl
=
baseurl
self
.
_baseurl
=
baseurl
self
.
_view_or_query
=
view_or_query
self
.
_view_or_query
=
view_or_query
self
.
_headers
=
headers
self
.
_headers
=
headers
self
.
_refresh_schema
()
self
.
_refresh_schema
()
self
.
_timeout
=
[
None
]
class
MetaEmbed
(
object
):
''' Allows operations on the view or query through view.meta.
E.g. view.meta.set_timeout(t)
This code is scaffolding meant to define the interface. It
is untested.
'''
def
__init__
(
self
,
embed
):
self
.
_embed
=
embed
def
set_timout
(
self
,
t
):
''' Set the timeout for object if it is going over a
network. Timeouts are kept on a stack; when you're
done, call unset_timeout, to return the timeout to
where it was. '''
self
.
_embed
.
_timeout
.
append
(
t
)
def
unset_timeout
(
self
):
''' Unset the timeout for object. See set_timeout for
details. '''
self
.
_embed
.
_timeout
.
pop
()
self
.
meta
=
MetaEmbed
(
self
)
def
_refresh_schema
(
self
):
def
_refresh_schema
(
self
):
global
schema
global
schema
...
@@ -82,7 +137,8 @@ class embed():
...
@@ -82,7 +137,8 @@ class embed():
# Return a caller to the function
# Return a caller to the function
if
self
.
_baseurl
:
if
self
.
_baseurl
:
helper
=
http_rpc_helper
(
self
.
_baseurl
,
self
.
_view_or_query
,
attr
)
helper
=
http_rpc_helper
(
self
.
_baseurl
,
self
.
_view_or_query
,
attr
,
headers
=
self
.
_headers
,
timeout
=
self
.
_timeout
[
-
1
])
else
:
else
:
helper
=
local_call_helper
(
self
.
_view_or_query
,
attr
)
helper
=
local_call_helper
(
self
.
_view_or_query
,
attr
)
...
@@ -120,6 +176,12 @@ class embed():
...
@@ -120,6 +176,12 @@ class embed():
return
self
.
_view_or_query
+
" object host: ["
+
self
.
_baseurl
+
"]"
return
self
.
_view_or_query
+
" object host: ["
+
self
.
_baseurl
+
"]"
class
transform_embed
:
class
transform_embed
:
'''
Defines a DSL for restricting permissions to analytics and for
locking down specific parameters.
TODO: This is prototype-grade code. It needs a cleanup pass.
'''
def
__init__
(
self
,
transform_policy
,
context
,
embed
):
def
__init__
(
self
,
transform_policy
,
context
,
embed
):
self
.
_embed
=
embed
self
.
_embed
=
embed
self
.
_context
=
context
self
.
_context
=
context
...
...
src/djanalytics/core/registry.py
View file @
0aeeecba
...
@@ -6,8 +6,8 @@ log=logging.getLogger(__name__)
...
@@ -6,8 +6,8 @@ log=logging.getLogger(__name__)
event_handlers
=
[]
event_handlers
=
[]
request_handlers
=
{
'view'
:{},
'query'
:{}}
request_handlers
=
{
'view'
:{},
'query'
:{}}
import
views
import
djanalytics.core.
views
funcskips
=
views
.
default_optional_kwargs
.
keys
()
+
[
'params'
]
# params are additional GET/POST parameters
funcskips
=
djanalytics
.
core
.
views
.
default_optional_kwargs
.
keys
()
+
[
'params'
]
# params are additional GET/POST parameters
def
register_handler
(
cls
,
category
,
name
,
description
,
f
,
args
):
def
register_handler
(
cls
,
category
,
name
,
description
,
f
,
args
):
''' Helper function for @view and @query decorators.
''' Helper function for @view and @query decorators.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment