latest PDF - Read the Docs

XBlock Documentation
Release 0.3
edX.org
January 29, 2015
Contents
1
Getting Started
1.1 Getting Started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2
User’s Guide
2.1 Concepts . . . . . . . .
2.2 XBlocks . . . . . . . .
2.3 Runtimes . . . . . . . .
2.4 Creating a new Runtime
2.5 Fragment . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
7
7
8
12
13
14
API
3.1
3.2
3.3
3.4
3.5
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
15
15
18
22
29
32
Project Info
4.1 Change history for XBlock . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
33
33
3
4
XBlock . .
Fields . . .
Runtime .
Fragment .
Exceptions
.
.
.
.
.
Python Module Index
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
3
3
35
i
ii
XBlock Documentation, Release 0.3
Note: This is still preliminary documentation. Please get in touch with us if you have any questions or concerns. Do
not make any plans based on this document without talking to us first.
edX is in the process of implementing XBlock support, and that effort could produce changes to these documents.
To create rich, engaging online courses, course authors must be able to combine components from a variety of sources.
XBlock is edX’s component architecture that makes this possible. Courses are built hierarchically of pieces called
XBlocks. Like an HTML <div>, XBlocks can represent pieces as small as a paragraph of text, a video, or a multiplechoice input field, or as large as a section, a chapter, or an entire course.
XBlocks are not limited to just delivering courses. A complete educational ecosystem will make use of a number of
web applications, all of which will need access to course content and data. XBlocks provide the structure and APIs
needed to build components for use in all of these applications.
Contents
1
XBlock Documentation, Release 0.3
2
Contents
CHAPTER 1
Getting Started
How to begin writing an XBlock.
Required Background Knowledge
To understand the contents of this document, you must understand the following concepts/ideas: Git, Github,
Virtual environments in Python, and Shell configuration files (ex: .bashrc/.bash_profile)
1.1 Getting Started
Creating a new XBlock means creating an installable Python kit with a class derived from XBlock. That sounds
complicated, but it isn’t.
1.1.1 Prerequisites
You’ll need some software installed in order to work with XBlock:
• Git for source control
• Something to create Python virtual environments. Available options include:
– PyEnv
– VirtualEnv and VirtualEnvWrapper
1.1.2 Get and Configure the XBlock Repo
1. The XBlock code is on Github. Get the code by cloning the XBlock repo:
$ git clone https://github.com/edx/XBlock.git
2. Create a virtual environment for your XBlock development work.
3. Activate your virtual environment and install prerequisite Python packages:
$ pip install -r requirements.txt
3
XBlock Documentation, Release 0.3
1.1.3 Create a new XBlock
The simplest way to get started on a new XBlock is to use the script/startnew.py script in the XBlock SDK
repo:
https://github.com/edx/xblock-sdk
Make a directory for your development work, outside the XBlock directory, let’s call it ~/edxwork, and run the
startnew.py script from there:
$
$
$
$
cd ~
mkdir edxwork
cd edxwork
/path/to/xblock-sdk/script/startnew.py
The script will need two pieces of information, both related to the name of your XBlock: a short name that can be used
for directory names, and a Python class name. You might choose “myxblock” for the short name and “MyXBlock”
for the class name. We’ll use those names in the rest of these instructions. Your files will be named using the actual
name you gave.
When the script is done, you’ll have a myxblock directory with a complete working XBlock. Of course, it’s just the
boilerplate for your XBlock, now you have to start writing your code.
Most of your work will be in the myxblock/myxblock/myxblock.py file, which contains the MyXBlock class. There
are “TO-DO” comments in the file indicating where you should make changes:
# TO-DO: change this view to display your data your own way.
def student_view(self, context=None):
etc...
1.1.4 Write your XBlock
Now comes the hard part! You’ll modify myxblock.py and the other files in the generated XBlock to make it do
whatever it is you want your XBlock to do.
Define your fields
The first step is to define your fields. These are declarations of the data your XBlock will store. XBlock fields have a
rich scoping mechanism that lets you associate data with particular blocks and users. See Fields for more details.
Define your view
The view is a function that creates the HTML to display your block in a course. It may be a simple rendering of your
data, or you may have complex logic to determine what to show.
Many XBlocks will need only a single view, called “student_view”.
Your view includes not only HTML, but also whatever Javascript and CSS are needed to support the HTML.
Define your handlers
If your XBlock is interactive, you will likely need to receive events from the Javascript. A handler is a function bound
to a URL. You can use the URL in your Javascript to communicate back to the server.
You can define as many handlers as you need, and name them whatever you like.
4
Chapter 1. Getting Started
XBlock Documentation, Release 0.3
Write tests
TBD
1.1.5 Test your XBlock
It’s important to thoroughly test your XBlock to be sure that it does what you want and that it works properly in the
environments you need.
To run your XBlock another application, you’ll install it. Using pip, you can install your XBlock so that your working
tree (the code you are editing) is the installed version. The makes it easy to change the code and see the changes
running without a cumbersome edit-install-run cycle.
Use pip to install your block:
$ cd ~/edxwork
$ pip install -e myxblock
Testing with the workbench
The simplest test environment is the XBlock workbench. It can be found in the XBlock SDK.
Testing with the edX LMS
See testing documentation.
1.1.6 Deploying your XBlock
See deployment documentation.
1.1.7 Submitting your XBlock to edX
If you would like your XBlock to be available on edx.org, please do the following:
• Upload your XBlock to a public Git repository on a reliable host. We recommend Github.
• Create a pull request against edx-platform. However, do not include your XBlock code in this request. Instead,
add a line to the requirements file, indicating which version of your XBlock you would like to use. That line
should be the only change in your pull request. Additionally, in your pull request description, please include a
link to where the XBlock code is hosted.
• A developer at edX will see the pull request and review your XBlock to ensure that it can integrate safely with
the rest of edx-platform.
• To expedite the review process, please include, in the pull request, a thorough description of what your XBlock
does, so that we can find the best person to review your code.
1.1. Getting Started
5
XBlock Documentation, Release 0.3
6
Chapter 1. Getting Started
CHAPTER 2
User’s Guide
The concepts of XBlock, in depth.
2.1 Concepts
XBlock is a component architecture for building courseware. They are similar in structure to web applications.
2.1.1 Roles
The XBlock design recognizes a few different roles people can play:
Block Developer
An XBlock Developer is the author of an XBlock type. This is a Python developer writing Python classes
to implement a new kind of XBlock.
Content Author
Original course material is written by a Content Author. This material may be made available to others to
use in their own courses.
Course Assembler
A Course Assembler creates or modifies courses by using content created by someone else. Note that
the same person can act as a content author and as a course assembler, often within the same authoring
session.
Student
The Student (or User) is whoever uses the web applications composed of XBlocks.
2.1.2 XBlocks
XBlocks are components that combine together to create interactive course content. They need to satisfy two conflicting goals: work together with other blocks to build a complete course; and be independent of other blocks, so they can
be combined flexibly.
XBlocks are built similarly to web applications. They maintain state in a storage layer, render themselves through
views, and process user actions through handlers.
They differ from web applications, though, because each XBlock renders only a small piece of a complete web page.
7
XBlock Documentation, Release 0.3
2.1.3 Runtime
XBlocks do not run by themselves, they run within web applications, such as edX Studio or edX LMS, that are known
as runtimes. Each runtime provides services to the XBlock, such as storage, URL mapping, and analytics. Runtimes
should perform functions common to all blocks, leaving the XBlock developer to write code particular to their block.
Runtimes will differ in the context they provide to XBlocks. For example, while editing content, Studio won’t provide
user state, because there is no interesting user state. Another runtime might provide user state, but as read-only data.
Runtimes also differ in what views they make use of. Studio might use “author_view” to edit the XBlock content,
and “student_view” to preview that content, while the LMS might only use the “student_view” view to render the
XBlock for students. Each runtime is free to define view names it will use for its purposes. XBlock Developers need
to understand the runtimes they will be running in to write the proper views.
Runtimes are responsible for performing any authentication needed before executing a view or handler in an XBlock.
Examples of runtimes:
• edX Studio
• edX LMS
• XBlock workbench
• XBlock Runtime for Google App Engine
2.2 XBlocks
XBlocks are Python classes that implement a small web application. Like full applications, they have state and
methods, and operate on both the server and the client.
2.2.1 Python Structure
XBlocks are implemented as Python code, and packaged using standard Python techniques. They have Python code,
and other file resources, including CSS and Javascript needed to fully render themselves in a browser.
2.2.2 Fields
XBlock state (or data) is arbitrary JSON-able data stored in Python attributes called fields.
Fields declare their relationship to both blocks and users, by specifying their scope.
• By user: fields declare how they relate to the user:
– No user: the data is related to no users, for example, the content of the course which is independent of any
users.
– One user: the data is particular to a single user, such as an answer to a problem.
– All users: the data shared for all users. An example is the total number of students answering a question.
Note that this is not the same as aggregate or query data. The same value will be shared for all users, and
there’s no way to link specific actions to specific users.
• By XBlock: fields declare how they relate to the block:
– Block usage: the fields are related only to that instance, or usage, of the XBlock in a particular course.
8
Chapter 2. User’s Guide
XBlock Documentation, Release 0.3
– Block definition: the fields are related to the definition of the XBlock. This definition is specified by the
content creator. A definition can be shared across one or more usages. For instance, you could create a
single XBlock definition with many usages, and those usages can appear across courses or within the same
course.
– Block type: the fields are related to the Python type of the XBlock, and thus shared across all instances of
the XBlock in all courses.
– All: the fields are related to all XBlocks, of all types (thus, any XBlock can access the data).
These two aspects, user and block, are independent. A field scope specifies both. For example:
• A user’s progress through a particular set of problems would be stored in a scope with User=One and
XBlock=Usage.
• The content to display in an XBlock would be stored in a scope with User=None and XBlock=Definition.
• A user’s preferences for a type of XBlock, such as the preferences for a circuit editor, would be stored in a scope
with User=One and XBlock=Type.
• Information about the user, such as language or timezone, would be stored in a scope with User=One and
XBlock=All.
For convenience, we also provide six predefined scopes:
Scope.content, Scope.settings,
Scope.user_state, Scope.preferences, Scope.user_info, and Scope.user_state_summary:
BlockScope.USAGE
BlockScope.DEFINITION
BlockScope.TYPE
BlockScope.ALL
UserScope.NONE
Scope.settings
Scope.content
UserScope.ONE
Scope.user_state
UserScope.ALL
Scope.user_state_summary
Scope.preferences
Scope.user_info
Examples of Situations. The following list shows examples of cases in which you may want to use a particular
(UserScope, BlockScope) pairing. There are many other situations in which you may want to use these scopes.
BlockScope.USAGE:
• UserScope.NONE: Settings. You want something to be true only for a specific instance of an XBlock.
• UserScope.ONE: User state. You want to keep track of questions a user has answered correctly and incorrectly
for a specific instance of an XBlock.
• UserScope.ALL: User state summary. You want to show how all the users respond to a question on a specific
instance of an XBlock.
BlockScope.DEFINITION:
• UserScope.NONE: Content. You have some content you would like to share across several courses (i.e., a table
of math formulas), but it is not specific to any user. All content is in this scope.
• UserScope.ONE: Multi-course user state. You want to keep track of the user’s state across multiple instances of
this XBlock. For instance, you could have a Test XBlock and then show the user their comparative scores on
pre-tests and post-tests.
• UserScope.ALL: Multi-course user state summary. For instance, you could show the average score of users on
all Tests and display this average to users.
BlockScope.TYPE:
• UserScope.NONE: XBlock settings. You have information related to this XBlock’s functionality that needs to
be shared across all XBlocks of its type, but it is not user-specific.
2.2. XBlocks
9
XBlock Documentation, Release 0.3
• UserScope.ONE: User preferences. In courses where this XBlock is present, you want to keep track of what
preferences the user has chosen (for instance, a user can set a default speed for the video player, and that default
is accessible to all video player instances).
• UserScope.ALL: User XBlock-related interaction summary. For instance, you could find the total number of
users who use various features of the XBlock for every instance of this XBlock in all courses.
BlockScope.ALL:
• UserScope.NONE: Global settings. You want to establish information that all XBlocks anywhere should have
access to.
• UserScope.ONE: User information. You want all XBlocks of all types to be able to access basic information
such as user name, geographic location, language, etc.
• UserScope.ALL: User demographics. You want to establish user-related information that all XBlocks anywhere
should have access to. For instance, a count of the total number of users.
A note about sharing data across XBlocks: Sharing data between two blocks that are differently typed is difficult.
In particular, the only way to share information across differently-typed blocks (say, between a video xblock and a
problem xblock) is by putting that data in ALL. However, putting data in ALL can introduce scoping and name conflict
issues. For instance, if two fields that are both scoped to ALL have the same field name, both blocks will actually be
pointing to the same data.
For this reason, we encourage developers to be careful when deciding how to scope their fields.
XBlocks declare their fields as class attributes in the XBlock class definition. Each field has at least a name, a type,
and a scope:
class ThumbsBlock(XBlock):
upvotes = Integer(help="Number of up votes", default=0, scope=Scope.user_state_summary)
downvotes = Integer(help="Number of down votes", default=0, scope=Scope.user_state_summary)
voted = Boolean(help="Has this student voted?", default=False, scope=Scope.user_state)
In XBlock code, state is accessed as attributes on self. In our example above, the data is available as self.upvotes,
self.downvotes, and self.voted. The data is automatically scoped for the current user and block. Modifications to the attributes are stored in memory, and persisted to underlying FieldData instance when save() is called
on the XBlock. Runtimes will call save() after an XBlock is constructed, and after every invocation of a handler,
view, or method on an XBlock.
Important note: Unlike Python classes you may have worked with before, you may not use an init method in an
XBlock. This is because XBlocks get called in many contexts (various views and runtimes), and the init function
may not be able to do certain things depending on the scope or context in which it is run.
If you would like to use init function for some reason, such as to implement more complicated logic for default field
values, consider one of the following alternatives:
• Use xblock.fields.UNIQUE_ID if you want the field to default to a unique string value.
• Use a lazy property decorator, so that when you first access an attribute, a function will be called to set that
attribute.
• Call the default-field-value logic in the view, instead of in init.
Important note: At present, XBlocks does not support storing a very large amount of data in a single field. This is
because XBlocks fields are written and retrieved as single entities, reading the whole field into memory. Thus, a field
that contains, say, a list of one million items would become problematic. If you need to store very large amounts of
data, a possible workaround is to split the data across many smaller fields.
10
Chapter 2. User’s Guide
XBlock Documentation, Release 0.3
2.2.3 Children
In contrast to the conceptual view of XBlocks, an XBlock does not refer directly to its children. Instead, the structure
of a tree of XBlocks is maintained by the runtime, and is made available to the XBlock through a runtime service.
This allows the runtime to store, access, and modify the structure of a course without incurring the overhead of the
XBlock code itself. The children will not be implicitly available. The runtime will provide a list of child ids, and a
child can be loaded with a get_child() function call. This means the runtime can defer loading children until they are
actually required (if ever).
Accessing Children (Server-Side)
To access children via the server-side, the best method is:
• Iterate over the XBlock’s children attribute (self.children), which will yield you the usage IDs for each
of the children.
• Then, to access a child block, use self.runtime.get_block(usage_id) for your desired usage_id.
You can then modify the child block using its .save() method.
• To render a given child, use self.runtime.render_child(usage_id)
• To render all children for a given XBlock, use self.runtime.render_children
• To ensure things render correctly, template the fragment.content into the parent block’s html, and then
use fragment.add_frag_resources (or .add_frags_resources, in the case of rendering all children). This will ensure that the javascript and CSS of child elements are included.
Accessing Children (Client-Side)
To access children via the client-side (via Javascript), the best method is:
• Call runtime.children(element), where element is the DOM node that contains the HTML representation of your XBlock’s server-side view. (runtime is automatically given to you by whichever runtime
your XBlock is running in.)
• Similarly, you can use runtime.childMap(element, name) to get a child element that has a specific
name.
• This client-side XBlock code provides examples of these usages.
2.2.4 Methods
The behavior of an XBlock is determined by its methods, which come in a few categories:
• Views: These are invoked by the runtime to render the XBlock. There can be any number of these, written as
ordinary Python methods. Each view has a specific name, such as “edit” or “read”, specified by the runtime that
will invoke it.
A typical use of a view is to produce a fragment for rendering the block as part of a web page. The user state,
settings, and preferences may be used to affect the output in any way the XBlock likes. Views can indicate what
data they rely on, to aid in caching their output.
Although views typically produce HTML-based renderings, they can be used for anything the runtime wants.
The runtime description of each view should be clear about what return type is expected and how it will be used.
• Handlers: Handlers provide server-side logic invoked by AJAX calls from the browser. There can be any number
of these, written as ordinary Python methods. Each handler has a specific name of your choice, such as “submit”
or “preview.” The runtime provides a mapping from handler names to actual URLs so that XBlock Javascript
code can make requests to its handlers. Handlers can be used with GET requests as well as POST requests.
2.2. XBlocks
11
XBlock Documentation, Release 0.3
• Methods: XBlocks have access to their children and parent, and can invoke methods on them simply by invoking
Python methods.
Views and handlers are both inspired by web applications, but have different uses, and therefore different designs.
Views are invoked by the runtime to produce a rendering of some course content. Their results are aggregated together
hierarchically, and so are not expressed as an HTTP response, but as a structured Fragment. Handlers are invoked by
XBlock code in the browser, so they are defined more like traditional web applications: they accept an HTTP request,
and produce an HTTP response.
2.2.5 Views
Views are methods on the XBlock that render the block. The runtime will invoke a view as part of creating a webpage
for part of a course. The XBlock view should return data in the form needed by the runtime. Often, the result will be
a fragment that the runtime can compose together into a complete page.
Views can specify caching information to let runtimes avoid invoking the view more frequently than needed. TODO:
Describe this.
2.2.6 Handlers
Handlers are methods on the XBlock that process requests coming from the browser. Typically, they’ll be used to
implement ajax endpoints. They get a standard request object and return a standard response. You can have as many
handlers as you like, and name them whatever you like. Your code asks the runtime for the URL that corresponds to
your handler, and then you can use that URL to make ajax requests.
2.2.7 Services
XBlocks often need other services to implement full functionality. As Python programs, they can import whatever
libraries they need. But some services need to be provided by the surrounding application in order to work properly as
a unified whole. Perhaps they need to be implemented specially, or integrated into the full application.
XBlocks can request services from their runtime to get the best integration. TODO: finish describing the service()
method.
2.3 Runtimes
In casual XBlock terms, a Runtime is the application that hosts XBlocks.
2.3.1 Nomenclature
There are several entities that go by the name Runtime. This will attempt to provide context and names to disambiguate them.
Runtime Application
This is a general term used to refer to the application code hosting the XBlocks.
Runtime
This is the interface that XBlocks use to access resources from the runtime application. For
example, the XBlock can ask for the URL to use in order to call into one of its handlers using Runtime.handler_url() or it can render a view on one of its children using
Runtime.render_child().
12
Chapter 2. User’s Guide
XBlock Documentation, Release 0.3
2.3.2 Responsibilities
As hosts for XBlocks, runtime applications are responsible for instantiating XBlocks with the correct data access
functionality, displaying the HTML returned by XBlock views, binding the front-end Javascript to the correct DOM
elements, and routing handler requests back from the client-side XBlock to the server-side handlers.
2.3.3 Contracts
Runtime applications SHOULD document which views they will call on the XBlock. A runtime is permitted to provide
additional methods on its Runtime instance for use inside those views.
2.3.4 Extending XBlocks
When constructing a Runtime instance, a runtime application can provide a list of mixin classes. These classes will
be used whenever the Runtime constructs an XBlock to generate a new subclass of that XBlock with the mixins
added as base classes. This allows a runtime application to add field data and methods to all XBlocks that it hosts,
without requiring that the XBlocks themselves being aware of the runtime they are being hosted in.
2.4 Creating a new Runtime
To build a new host for XBlocks, an author must provide several things:
• A Runtime implementation, which provides access to external resources and is responsible for constructing
XBlocks.
• A FieldData implementation, which provides access the underlying data storage for the XBlock fields.
• [Proposed] A UsageStore, which provides mappings between the various fields of ScopeIds.
In each case, by overriding specific methods in those classes, the runtime application determines the behavior of the
XBlocks.
A runtime application also provides access to some set of XBlock views and handlers.
2.4.1 Rendering Views
A runtime application document which views it will render on the XBlocks that it hosts, and in what context it will
render those views. XBlock developers write views with those specific names so that they interact properly with the
application.
When a runtime application renders a view (by calling Runtime.render() or XBlock.render()), it will
receive a Fragment as a result. It should embed Fragment.content into the HTML it is producing, add
Fragment.head_html() to the head of the page, and add Fragment.foot_html() to the foot of the page.
This ensures that the Javascript and CSS of all of the fragments on the page are combined properly.
2.4.2 Routing Handlers
The runtime application needs to route requests from the client-side XBlock to the server-side XBlock handler functions. The runtime’s implementation of Runtime.handler_url() must return a relative URL that the client-side
XBlock can call to pass data back to the server. Authentication of the handler is managed by the runtime application,
although you can also request a URL that is unauthenticated for use from third-party applications.
2.4. Creating a new Runtime
13
XBlock Documentation, Release 0.3
XBlock implementations may have arbitrarily named handler functions, so the runtime application must be able to
route to any of them.
2.5 Fragment
When XBlock views are used to make a web page, each block produces just one piece of the page, by returning a
Fragment. A Fragment carries content (usually HTML) and resources (for example, Javascript and CSS) needed by
the content. These allow for the composition of HTML, Javascript and CSS elements in a predictable fashion.
Fragments have a number of attributes:
• Content: Content is most often HTML, but could also have an arbitrary mimetype. Each fragment only has a
single content value.
• Javascript: Javascript resources can include both external files to link to, and inline Javascript source code.
When fragments are composed, external Javascript links will be uniqued, so that any individual page isn’t
loaded multiple times.
• CSS: Like Javascript, CSS can be both external and inline, and the external resources will be uniqued when
fragments are composed.
• Javascript initializer: The Javascript specified for a fragment can also specify a function to be called when that
fragment is rendered on the page. This function will be passed the DOM element containing all of the content
from the fragment, and is then expected to execute any code needed to make that fragment operational. The
Javascript view will also be passed a Javascript runtime object containing a set of functions that generate links
back to the XBlocks handlers and views on the runtime server.
Since XBlocks nest hierarchically, a single XBlock view might require collecting renderings from each of its children,
and composing them together. The parent will be responsible for deciding how the children’s content composes
together to create the parent content. The fragment system has utilities for composing children’s resources together
into the parent.
Other information on fragments [[TODO: write this.]]:
Caching information specifying how long a fragment can be cached for. This can be specified at fragment
creation, or by using a decorator on the view function (if the cache duration is known ahead of time)
See also:
The Fragment API documentation.
14
Chapter 2. User’s Guide
CHAPTER 3
API
Details of the XBlock APIs.
3.1 XBlock
class xblock.core.XBlock(runtime, field_data=None, scope_ids=<object object at 0x7f45534839a0>)
Base class for XBlocks.
Derive from this class to create a new kind of XBlock. There are no required methods, but you will probably
need at least one view.
Don’t provide the __init__ method when deriving from this class.
Construct a new XBlock.
This class should only be instantiated by runtimes.
Parameters
• runtime (Runtime) – Use it to access the environment. It is available in XBlock code as
self.runtime.
• field_data (FieldData) – Interface used by the XBlock fields to access their data from
wherever it is persisted. Deprecated.
• scope_ids (ScopeIds) – Identifiers needed to resolve scopes.
__delattr__
x.__delattr__(‘name’) <==> del x.name
__format__()
default object formatter
__getattribute__
x.__getattribute__(‘name’) <==> x.name
__hash__
x.__hash__() <==> hash(x)
__reduce__()
helper for pickle
__reduce_ex__()
helper for pickle
15
XBlock Documentation, Release 0.3
__setattr__
x.__setattr__(‘name’, value) <==> x.name = value
__sizeof__() → int
size of object in memory, in bytes
__str__
x.__str__() <==> str(x)
add_xml_to_node(node)
For exporting, set data on node from ourselves.
get_parent()
Return the parent block of this block, or None if there isn’t one.
handle(handler_name, request, suffix=’‘)
Handle request with this block’s runtime.
classmethod handler(func)
A decorator to indicate a function is usable as a handler.
The wrapped function must return a webob.Response object.
index_dictionary()
return key/value fields to feed an index within in a Python dict object values may be numeric / string or
dict default implementation is an empty dict
classmethod json_handler(func)
Wrap a handler to consume and produce JSON.
Rather than a Request object, the method will now be passed the JSON-decoded body of the request. The
request should be a POST request in order to use this method. Any data returned by the function will be
JSON-encoded and returned as the response.
The wrapped function can raise JsonHandlerError to return an error response with a non-200 status code.
This decorator will return a 405 HTTP status code if the method is not POST. This decorator will return a
400 status code if the body contains invalid JSON.
classmethod load_class(identifier, default=None, select=None)
Load a single class specified by identifier.
If identifier specifies more than a single class, and select is not None, then call select on the list of entry_points. Otherwise, choose the first one and log a warning.
If default is provided, return it if no entry_point matching identifier is found. Otherwise, will raise a
PluginMissingError
If select is provided, it should be a callable of the form:
def select(identifier, all_entry_points):
# ...
return an_entry_point
The all_entry_points argument will be a list of all entry_points matching identifier that were found, and
select should return one of those entry_points to be loaded. select should raise PluginMissingError if no
plugin is found, or AmbiguousPluginError if too many plugins are found
classmethod load_classes(fail_silently=True)
Load all the classes for a plugin.
Produces a sequence containing the identifiers and their corresponding classes for all of the available
instances of this plugin.
16
Chapter 3. API
XBlock Documentation, Release 0.3
fail_silently causes the code to simply log warnings if a plugin cannot import. The goal is to be able to
use part of libraries from an XBlock (and thus have it installed), even if the overall XBlock cannot be used
(e.g. depends on Django in a non-Django application). There is diagreement about whether this is a good
idea, or whether we should see failures early (e.g. on startup or first page load), and in what contexts.
Hence, the flag.
classmethod load_tagged_classes(tag, fail_silently=True)
Produce a sequence of all XBlock classes tagged with tag.
fail_silently causes the code to simply log warnings if a plugin cannot import. The goal is to be able to
use part of libraries from an XBlock (and thus have it installed), even if the overall XBlock cannot be used
(e.g. depends on Django in a non-Django application). There is diagreement about whether this is a good
idea, or whether we should see failures early (e.g. on startup or first page load), and in what contexts.
Hence, the flag.
classmethod needs(service_name)
A class decorator to indicate that an XBlock class needs a particular service.
classmethod open_local_resource(uri)
Open a local resource.
The container calls this method when it receives a request for a resource on a URL which was generated
by Runtime.local_resource_url(). It will pass the URI from the original call to local_resource_url() back
to this method. The XBlock must parse this URI and return an open file-like object for the resource.
For security reasons, the default implementation will return only a very restricted set of file types, which
must be located in a folder called “public”. XBlock authors who want to override this behavior will need
to take care to ensure that the method only serves legitimate public resources. At the least, the URI should
be matched against a whitelist regex to ensure that you do not serve an unauthorized resource.
classmethod parse_xml(node, runtime, keys, id_generator)
Use node to construct a new block.
Parameters
• node (etree.Element) – The xml node to parse into an xblock.
• runtime (Runtime) – The runtime to use while parsing.
• keys (ScopeIds) – The keys identifying where this block will store its data.
• id_generator (IdGenerator) – An object that will allow the runtime to generate correct
definition and usage ids for children of this block.
classmethod register_temp_plugin(class_, identifier=None, dist=’xblock’)
Decorate a function to run with a temporary plugin available.
Use it like this in tests:
@register_temp_plugin(MyXBlockClass):
def test_the_thing():
# Here I can load MyXBlockClass by name.
render(view, context=None)
Render view with this block’s runtime and the supplied context
save()
Save all dirty fields attached to this XBlock.
classmethod service_declaration(service_name)
Find and return a service declaration.
3.1. XBlock
17
XBlock Documentation, Release 0.3
XBlocks declare their service requirements with @XBlock.needs and @XBlock.wants decorators. These
store information on the class. This function finds those declarations for a block.
Parameters service_name (string) – the name of the service requested.
Returns One of “need”, “want”, or None.
static tag(tags)
Returns a function that adds the words in tags as class tags to this class.
validate()
Ask this xblock to validate itself. Subclasses are expected to override this method, as there is currently
only a no-op implementation. Any overriding method should call super to collect validation results from
its superclasses, and then add any additional results as necessary.
classmethod wants(service_name)
A class decorator to indicate that an XBlock class wants a particular service.
xml_element_name()
What XML element name should be used for this block?
xml_text_content()
What is the text content for this block’s XML node?
3.2 Fields
Fields declare storage for XBlock data. They use abstract notions of scopes to associate each field with particular sets
of blocks and users. The hosting runtime application decides what actual storage mechanism to use for each scope.
class xblock.fields.BlockScope
Enumeration of block scopes.
The block scope specifies how a field relates to blocks. A BlockScope and a UserScope are combined to
make a Scope for a field.
USAGE: The data is related to a particular use of a block in a course.
DEFINITION: The data is related to the definition of the block. Although unusual, one block definition
can be used in more than one place in a course.
TYPE: The data is related to all instances of this type of XBlock.
ALL: The data is common to all blocks. This can be useful for storing information that is purely about the
student.
classmethod scopes()
Return a list of valid/understood class scopes.
class xblock.fields.UserScope
Enumeration of user scopes.
The user scope specifies how a field relates to users. A BlockScope and a UserScope are combined to
make a Scope for a field.
NONE: Identifies data agnostic to the user of the XBlock. The data is related to no particular user. All
users see the same data. For instance, the definition of a problem.
ONE: Identifies data particular to a single user of the XBlock. For instance, a student’s answer to a problem.
18
Chapter 3. API
XBlock Documentation, Release 0.3
ALL: Identifies data aggregated while the block is used by many users. The data is related to all the users.
For instance, a count of how many students have answered a question, or a histogram of the answers
submitted by all students.
classmethod scopes()
Return a list of valid/understood class scopes. Why do we need this? I believe it is not used anywhere.
class xblock.fields.Scope
Defines six types of scopes to be used:
user_state_summary.
content, settings, user_state, preferences, user_info, and
The content scope is used to save data for all users, for one particular block, across all runs of a course. An
example might be an XBlock that wishes to tabulate user “upvotes”, or HTML content ti display literally on the
page (this example being the reason this scope is named content).
The settings scope is used to save data for all users, for one particular block, for one specific run of a course.
This is like the content scope, but scoped to one run of a course. An example might be a due date for a problem.
The user_state scope is used to save data for one user, for one block, for one run of a course. An example might
be how many points a user scored on one specific problem.
The preferences scope is used to save data for one user, for all instances of one specific TYPE of block, across
the entire platform. An example might be that a user can set their preferred default speed for the video player.
This default would apply to all instances of the video player, across the whole platform, but only for that student.
The user_info scope is used to save data for one user, across the entire platform. An example might be a user’s
time zone or language preference.
The user_state_summary scope is used to save data aggregated across many users of a single block. For example,
a block might store a histogram of the points scored by all users attempting a problem.
classmethod named_scopes()
Return all named Scopes.
classmethod scopes()
Return all possible Scopes.
class xblock.fields.ScopeIds
A simple wrapper to collect all of the ids needed to correctly identify an XBlock (or other classes deriving from
ScopedStorageMixin) to a FieldData. These identifiers match up with BlockScope and UserScope attributes, so
that, for instance, the def_id identifies scopes that use BlockScope.DEFINITION.
class xblock.fields.Field(help=None, default=fields.UNSET, scope=ScopeBase(user=UserScope.NONE,
block=BlockScope.DEFINITION, name=u’content’), display_name=None,
values=None, enforce_type=False, xml_node=False, **kwargs)
A field class that can be used as a class attribute to define what data the class will want to refer to.
When the class is instantiated, it will be available as an instance attribute of the same name, by proxying through
to the field-data service on the containing object.
Parameters
• help (str) – documentation for the field, suitable for presenting to a user (defaults to None).
• default – field’s default value.
Can be a static value or the special
xblock.fields.UNIQUE_ID reference.
When set to xblock.fields.UNIQUE_ID, the
field defaults to a unique string that is deterministically calculated for the field in the given
scope (defaults to None).
• scope – this field’s scope (defaults to Scope.content).
• display_name – the display name for the field, suitable for presenting to a user (defaults to
name of the field).
3.2. Fields
19
XBlock Documentation, Release 0.3
• values – a specification of the valid values for this field. This can be specified as either a
static specification, or a function that returns the specification. For example specification
formats, see the values property definition.
• enforce_type – whether the type of the field value should be enforced on set, using
self.enforce_type, raising an exception if it’s not possible to convert it. This provides a
guarantee on the stored value type.
• xml_node – if set, the field will be serialized as a separate node instead of an xml attribute
(default: False).
• kwargs – optional runtime-specific options/metadata. Will be stored as runtime_options.
__delete__(xblock)
Deletes xblock from the underlying data store. Deletes are not cached; they are performed immediately.
__get__(xblock, xblock_class)
Gets the value of this xblock. Prioritizes the cached value over obtaining the value from the field-data
service. Thus if a cached value exists, that is the value that will be returned.
__set__(xblock, value)
Sets the xblock to the given value. Setting a value does not update the underlying data store; the new value
is kept in the cache and the xblock is marked as dirty until save is explicitly called.
default
Returns the static value that this defaults to.
delete_from(xblock)
Delete the value for this field from the supplied xblock
display_name
Returns the display name for this class, suitable for use in a GUI.
If no display name has been set, returns the name of the class.
enforce_type(value)
Coerce the type of the value, if necessary
Called on field sets to ensure that the stored type is consistent if the field was initialized with enforce_type=True
This must not have side effects, since it will be executed to trigger a DeprecationWarning even if enforce_type is disabled
from_json(value)
Return value as a native full featured python type (the inverse of to_json)
Called during field reads to convert the stored value into a full featured python object
from_string(serialized)
Returns a native value from a YAML serialized string representation. Since YAML is a superset of JSON,
this is the inverse of to_string.)
is_set_on(xblock)
Return whether this field has a non-default value on the supplied xblock
name
Returns the name of this field.
read_from(xblock)
Retrieve the value for this field from the specified xblock
read_json(xblock)
Retrieve the serialized value for this field from the specified xblock
20
Chapter 3. API
XBlock Documentation, Release 0.3
to_json(value)
Return value in the form of nested lists and dictionaries (suitable for passing to json.dumps).
This is called during field writes to convert the native python type to the value stored in the database
to_string(value)
Return a JSON serialized string representation of the value.
values
Returns the valid values for this class. This is useful for representing possible values in a UI.
Example formats:
•A finite set of elements:
[1, 2, 3]
•A finite set of elements where the display names differ from the values:
[
{"display_name": "Always", "value": "always"},
{"display_name": "Past Due", "value": "past_due"},
]
•A range for floating point numbers with specific increments:
{"min": 0 , "max": 10, "step": .1}
If this field class does not define a set of valid values, this property will return None.
write_to(xblock, value)
Set the value for this field to value on the supplied xblock
class xblock.fields.Boolean(help=None, default=fields.UNSET, scope=ScopeBase(user=UserScope.NONE,
block=BlockScope.DEFINITION,
name=u’content’),
display_name=None, **kwargs)
A field class for representing a boolean.
The value, as loaded or enforced, can be either a Python bool, a string, or any value that will then be converted
to a bool in the from_json method.
Examples:
True -> True
’true’ -> True
’TRUE’ -> True
’any other string’ -> False
[] -> False
[’123’] -> True
None - > False
class xblock.fields.Dict(help=None, default=fields.UNSET, scope=ScopeBase(user=UserScope.NONE,
block=BlockScope.DEFINITION, name=u’content’), display_name=None,
values=None, enforce_type=False, xml_node=False, **kwargs)
A field class for representing a Python dict.
The value, as loaded or enforced, must be either be None or a dict.
class xblock.fields.Float(help=None, default=fields.UNSET, scope=ScopeBase(user=UserScope.NONE,
block=BlockScope.DEFINITION, name=u’content’), display_name=None,
values=None, enforce_type=False, xml_node=False, **kwargs)
A field that contains a float.
3.2. Fields
21
XBlock Documentation, Release 0.3
The value, as loaded or enforced, can be None, ‘’ (which will be treated as None), a Python float, or a value that
will parse as an float, ie., something for which float(value) does not throw an error.
class xblock.fields.Integer(help=None, default=fields.UNSET, scope=ScopeBase(user=UserScope.NONE,
block=BlockScope.DEFINITION,
name=u’content’),
display_name=None, values=None, enforce_type=False, xml_node=False,
**kwargs)
A field that contains an integer.
The value, as loaded or enforced, can be None, ‘’ (which will be treated as None), a Python integer, or a value
that will parse as an integer, ie., something for which int(value) does not throw an error.
Note that a floating point value will convert to an integer, but a string containing a floating point number (‘3.48’)
will throw an error.
class xblock.fields.List(help=None, default=fields.UNSET, scope=ScopeBase(user=UserScope.NONE,
block=BlockScope.DEFINITION, name=u’content’), display_name=None,
values=None, enforce_type=False, xml_node=False, **kwargs)
A field class for representing a list.
The value, as loaded or enforced, can either be None or a list.
class xblock.fields.String(help=None, default=fields.UNSET, scope=ScopeBase(user=UserScope.NONE,
block=BlockScope.DEFINITION,
name=u’content’),
display_name=None, values=None, enforce_type=False, xml_node=False,
**kwargs)
A field class for representing a string.
The value, as loaded or enforced, can either be None or a basestring instance.
from_string(value)
String gets serialized and deserialized without quote marks.
to_string(value)
String gets serialized and deserialized without quote marks.
class xblock.fields.XBlockMixin(*args, **kwargs)
A wrapper around xblock.core.XBlockMixin that provides backwards compatibility for the old location.
Deprecated.
3.3 Runtime
Machinery to make the common case easy when building new runtimes
xblock.runtime.DbModel
alias of KvsFieldData
class xblock.runtime.DictKeyValueStore(storage=None)
A KeyValueStore that stores everything into a Python dictionary.
class xblock.runtime.IdGenerator
An abstract object that creates usage and definition ids
create_aside(definition_id, usage_id, aside_type)
Make a new aside definition and usage ids, indicating an XBlockAside of type aside_type commenting
on an XBlock usage usage_id
Returns (aside_definition_id, aside_usage_id)
22
Chapter 3. API
XBlock Documentation, Release 0.3
create_definition(block_type, slug=None)
Make a definition, storing its block type.
If slug is provided, it is a suggestion that the definition id incorporate the slug somehow.
Returns the newly-created definition id.
create_usage(def_id)
Make a usage, storing its definition id.
Returns the newly-created usage id.
class xblock.runtime.IdReader
An abstract object that stores usages and definitions.
get_aside_type_from_definition(aside_id)
Retrieve the XBlockAside aside_type associated with this aside definition id.
Parameters aside_id – The definition id of the XBlockAside.
Returns The aside_type of the aside.
get_aside_type_from_usage(aside_id)
Retrieve the XBlockAside aside_type associated with this aside usage id.
Parameters aside_id – The usage id of the XBlockAside.
Returns The aside_type of the aside.
get_block_type(def_id)
Retrieve the block_type of a particular definition
Parameters def_id – The id of the definition to query
Returns The block_type of the definition
get_definition_id(usage_id)
Retrieve the definition that a usage is derived from.
Parameters usage_id – The id of the usage to query
Returns The definition_id the usage is derived from
get_definition_id_from_aside(aside_id)
Retrieve the XBlock definition_id associated with this aside definition id.
Parameters aside_id – The definition id of the XBlockAside.
Returns The definition_id of the xblock the aside is commenting on.
get_usage_id_from_aside(aside_id)
Retrieve the XBlock usage_id associated with this aside usage id.
Parameters aside_id – The usage id of the XBlockAside.
Returns The usage_id of the usage the aside is commenting on.
class xblock.runtime.KeyValueStore
The abstract interface for Key Value Stores.
class Key
Keys are structured to retain information about the scope of the data. Stores can use this information
however they like to store and retrieve data.
KeyValueStore.default(key)
Returns the context relevant default of the given key or raise KeyError which will result in the field’s global
default.
3.3. Runtime
23
XBlock Documentation, Release 0.3
KeyValueStore.delete(key)
Deletes key from storage.
KeyValueStore.get(key)
Reads the value of the given key from storage.
KeyValueStore.has(key)
Returns whether or not key is present in storage.
KeyValueStore.set(key, value)
Sets key equal to value in storage.
KeyValueStore.set_many(update_dict)
For each (key, value) in update_dict, set key to value in storage.
The default implementation brute force updates field by field through set which may be inefficient for
any runtimes doing persistence operations on each set. Such implementations will want to override this
method.
Update_dict field_name, field_value pairs for all cached changes
class xblock.runtime.KvsFieldData(kvs, **kwargs)
An interface mapping value access that uses field names to one that uses the correct scoped keys for the underlying KeyValueStore
default(block, name)
Ask the kvs for the default (default implementation which other classes may override).
Parameters
• block (XBlock) – block containing field to default
• name – name of the field to default
delete(block, name)
Reset the value of the field named name to the default
get(block, name)
Retrieve the value for the field named name.
If a value is provided for default, then it will be returned if no value is set
has(block, name)
Return whether or not the field named name has a non-default value
set(block, name, value)
Set the value of the field named name
set_many(block, update_dict)
Update the underlying model with the correct values.
class xblock.runtime.MemoryIdManager
A simple dict-based implementation of IdReader and IdGenerator.
ASIDE_DEFINITION_ID
alias of MemoryAsideDefinitionId
ASIDE_USAGE_ID
alias of MemoryAsideUsageId
clear()
Remove all entries.
create_aside(definition_id, usage_id, aside_type)
Create the aside.
24
Chapter 3. API
XBlock Documentation, Release 0.3
create_definition(block_type, slug=None)
Make a definition, storing its block type.
create_usage(def_id)
Make a usage, storing its definition id.
get_aside_type_from_definition(aside_id)
Get an aside’s type from its definition id.
get_aside_type_from_usage(aside_id)
Get an aside’s type from its usage id.
get_block_type(def_id)
Get a block_type by its definition id.
get_definition_id(usage_id)
Get a definition_id by its usage id.
get_definition_id_from_aside(aside_id)
Extract the original xblock’s definition_id from an aside’s definition_id.
get_usage_id_from_aside(aside_id)
Extract the usage_id from the aside’s usage_id.
class xblock.runtime.Mixologist(mixins)
Provides a facility to dynamically generate classes with additional mixins.
Parameters mixins (iterable of class) – Classes to mixin
mix(cls)
Returns a subclass of cls mixed with self.mixins.
Parameters cls (class) – The base class to mix into
class xblock.runtime.NullI18nService
A simple implementation of the runtime “i18n” service.
strftime(dtime, format)
Locale-aware strftime, with format short-cuts.
class xblock.runtime.ObjectAggregator(*objects)
Provides a single object interface that combines many smaller objects.
Attribute access on the aggregate object acts on the first sub-object that has that attribute.
class xblock.runtime.RegexLexer(*toks)
Split text into lexical tokens based on regexes.
lex(text)
Iterator that tokenizes text and yields up tokens as they are found
class xblock.runtime.Runtime(id_reader, field_data=None, mixins=(), services=None,
fault_class=None, select=None, id_generator=None)
Access to the runtime environment for XBlocks.
de-
Arguments: id_reader (IdReader): An object that allows the Runtime to
map between usage_ids, definition_ids, and block_types.
id_generator (IdGenerator): The IdGenerator to use for creating ids when importing XML or loading
XBlockAsides.
field_data (FieldData): The FieldData to use by default when constructing an XBlock from this Runtime.
3.3. Runtime
25
XBlock Documentation, Release 0.3
mixins (tuple): Classes that should be mixed in with every XBlock created by this Runtime.
services (dictionary): Services to make available through the service() method. There’s no point passing anything here if you are overriding service() in your sub-class.
default_class (class): The default class to use if a class can’t be found for a particular
loading an XBlock.
block_type
when
select: A function to select from one or more XBlock subtypes found when
calling
XBlock.load_class() to resolve a block_type.
This is the same select as used by
Plugin.load_class().
add_block_as_child_node(block, node)
Export block as a child node of node.
add_node_as_child(block, node, id_generator=None)
Called by XBlock.parse_xml to treat a child node as a child block.
applicable_aside_types(block)
Return the set of applicable aside types for this runtime and block. This method allows the runtime to filter
the set of asides it wants to support or to provide even block-level or block_type level filtering. We may
extend this in the future to also take the user or user roles.
construct_xblock(block_type, scope_ids, field_data=None, *args, **kwargs)
Construct a new xblock of the type identified by block_type, passing *args and **kwargs into __init__.
construct_xblock_from_class(cls, scope_ids, field_data=None, *args, **kwargs)
Construct a new xblock of type cls, mixing in the mixins defined for this application.
create_aside(block_type, keys)
The aside version of construct_xblock: take a type and key. Return an instance
export_to_xml(block, xmlfile)
Export the block to XML, writing the XML to xmlfile.
field_data
Access the FieldData passed in the constructor.
Deprecated in favor of a ‘field-data’ service.
get_aside(aside_usage_id)
Create an XBlockAside in this runtime.
The aside_usage_id is used to find the Aside class and data.
get_aside_of_type(block, aside_type)
Return the aside of the given aside_type which might be decorating this block.
Parameters
• block (XBlock) – The block to retrieve asides for.
• aside_type (str) – the type of the aside
get_asides(block)
Return all of the asides which might be decorating this block.
Parameters block (XBlock) – The block to render retrieve asides for.
get_block(usage_id)
Create an XBlock instance in this runtime.
The usage_id is used to find the XBlock class and data.
26
Chapter 3. API
XBlock Documentation, Release 0.3
handle(block, handler_name, request, suffix=’‘)
Handles any calls to the specified handler_name.
Provides a fallback handler if the specified handler isn’t found.
Parameters
• handler_name – The name of the handler to call
• request (webob.Request) – The request to handle
• suffix – The remainder of the url, after the handler url prefix, if available
handler_url(block, handler_name, suffix=’‘, query=’‘, thirdparty=False)
Get the actual URL to invoke a handler.
handler_name is the name of your handler function. Any additional portion of the url will be passed as the
suffix argument to the handler.
The return value is a complete absolute URL that will route through the runtime to your handler.
Parameters
• block – The block to generate the url for
• handler_name – The handler on that block that the url should resolve to
• suffix – Any path suffix that should be added to the handler url
• query – Any query string that should be added to the handler url (which should not include
an initial ? or &)
• thirdparty – If true, create a URL that can be used without the user being logged in. This
is useful for URLs to be used by third-party services.
layout_asides(block, context, frag, view_name, aside_frag_fns)
Execute and layout the aside_frags wrt the block’s frag. Runtimes should feel free to override this method
to control execution, place, and style the asides appropriately for their application
This default method appends the aside_frags after frag. If you override this, you must call wrap_aside
around each aside as per this function.
Parameters
• block (XBlock) – the block being rendered
• frag (html) – The result from rendering the block
load_aside_type(aside_type)
Returns a subclass of XBlockAside that corresponds to the specified aside_type.
load_block_type(block_type)
Returns a subclass of XBlock that corresponds to the specified block_type.
local_resource_url(block, uri)
Get the URL to load a static resource from an XBlock.
block is the XBlock that owns the resource.
uri is a relative URI to the resource. The XBlock class’s get_local_resource(uri) method should be
able to open the resource identified by this uri.
Typically, this function uses open_local_resource defined on the XBlock class, which by default will
only allow resources from the “public/” directory of the kit. Resources must be placed in “public/” to be
successfully served with this URL.
The return value is a complete absolute URL which will locate the resource on your runtime.
3.3. Runtime
27
XBlock Documentation, Release 0.3
parse_xml_file(fileobj, id_generator=None)
Parse an open XML file, returning a usage id.
parse_xml_string(xml, id_generator=None)
Parse a string of XML, returning a usage id.
publish(block, event_type, event_data)
Publish an event.
For example, to participate in the course grade, an XBlock should set has_score to True, and should publish
a grade event whenever the grade changes.
In this case the event_type would be grade, and the event_data would be a dictionary of the following
form:
{ ‘value’: <number>, ‘max_value’: <number>,
}
The grade event represents a grade of value/max_value for the current user.
block is the XBlock from which the event originates.
query(block)
Query for data in the tree, starting from block.
Returns a Query object with methods for navigating the tree and retrieving information.
querypath(block, path)
An XPath-like interface to query.
render(block, view_name, context=None)
Render a block by invoking its view.
Finds the view named view_name on block. The default view will be used if a specific view hasn’t be
registered. If there is no default view, an exception will be raised.
The view is invoked, passing it context. The value returned by the view is returned, with possible modifications by the runtime to integrate it into a larger whole.
render_asides(block, view_name, frag, context)
Collect all of the asides’ add ons and format them into the frag. The frag already has the given block’s
rendering.
render_child(child, view_name=None, context=None)
A shortcut to render a child block.
Use this method to render your children from your own view function.
If view_name is not provided, it will default to the view name you’re being rendered with.
Returns the same value as render().
render_children(block, view_name=None, context=None)
Render a block’s children, returning a list of results.
Each child of block will be rendered, just as render_child() does.
Returns a list of values, each as provided by render().
resource_url(resource)
Get the URL for a static resource file.
resource is the application local path to the resource.
The return value is a complete absolute URL that will locate the resource on your runtime.
28
Chapter 3. API
XBlock Documentation, Release 0.3
service(block, service_name)
Return a service, or None.
Services are objects implementing arbitrary other interfaces. They are requested by agreed-upon names,
see [XXX TODO] for a list of possible services. The object returned depends on the service requested.
XBlocks must announce their intention to request services with the XBlock.needs or XBlock.wants decorators. Use needs if you assume that the service is available, or wants if your code is flexible and can accept
a None from this method.
Runtimes can override this method if they have different techniques for finding and delivering services.
Parameters
• block (an XBlock) – this block’s class will be examined for service decorators.
• service_name (string) – the name of the service requested.
Returns An object implementing the requested service, or None.
wrap_aside(block, aside, view, frag, context)
Creates a div which identifies the aside, points to the original block, and writes out the json_init_args into
a script tag.
The default implementation creates a frag to wraps frag w/ a div identifying the xblock. If you have
javascript, you’ll need to override this impl
wrap_xblock(block, view, frag, context)
Creates a div which identifies the xblock and writes out the json_init_args into a script tag.
If there’s a wrap_child method, it calls that with a deprecation warning.
The default implementation creates a frag to wraps frag w/ a div identifying the xblock. If you have
javascript, you’ll need to override this impl
3.4 Fragment
Fragments for XBlocks.
This code is in the Runtime layer.
class xblock.fragment.Fragment(content=None)
A fragment of a web page, for XBlock views to return.
A fragment consists of HTML for the body of the page, and a series of resources needed by the body. Resources
are specified with a MIME type (such as “application/javascript” or “text/css”) that determines how they are
inserted into the page. The resource is provided either as literal text, or as a URL. Text will be included on the
page, wrapped appropriately for the MIME type. URLs will be used as-is on the page.
Resources are only inserted into the page once, even if many Fragments in the page ask for them. Determining
duplicates is done by simple text matching.
add_content(content)
Add content to this fragment.
content is a Unicode string, HTML to append to the body of the fragment. It must not contain a <body>
tag, or otherwise assume that it is the only content on the page.
add_css(text)
Add literal CSS to the Fragment.
3.4. Fragment
29
XBlock Documentation, Release 0.3
add_css_url(url)
Add a CSS URL to the Fragment.
add_frag_resources(frag)
Add all the resources from frag to my resources.
This is used by an XBlock to collect resources from Fragments produced by its children.
frag is a Fragment.
The content from the Fragment is ignored. The caller must collect together the content into this Fragment’s
content.
add_frags_resources(frags)
Add all the resources from frags to my resources.
This is used by an XBlock to collect resources from Fragments produced by its children.
frags is a sequence of Fragments.
The content from the Fragments is ignored. The caller must collect together the content into this Fragment’s content.
add_javascript(text)
Add literal Javascript to the Fragment.
add_javascript_url(url)
Add a Javascript URL to the Fragment.
add_resource(text, mimetype, placement=None)
Add a resource needed by this Fragment.
Other helpers, such as add_css() or add_javascript() are more convenient for those common
types of resource.
text: the actual text of this resource, as a unicode string.
mimetype: the MIME type of the resource.
placement: where on the page the resource should be placed:
None: let the Fragment choose based on the MIME type.
“head”: put this resource in the <head> of the page.
“foot”: put this resource at the end of the <body> of the page.
add_resource_url(url, mimetype, placement=None)
Add a resource by URL needed by this Fragment.
Other helpers, such as add_css_url() or add_javascript_url() are more convenent for those
common types of resource.
url: the URL to the resource.
Other parameters are as defined for add_resource().
body_html()
Get the body HTML for this Fragment.
Returns a Unicode string, the HTML content for the <body> section of the page.
content = None
The html content for this Fragment
30
Chapter 3. API
XBlock Documentation, Release 0.3
foot_html()
Get the foot HTML for this Fragment.
Returns a Unicode string, the HTML content for the end of the <body> section of the page.
classmethod from_pods(pods)
Returns a new Fragment from a pods.
pods is a Plain Old Data Structure, a Python dictionary with keys content, resources, js_init_fn, and
js_init_version.
head_html()
Get the head HTML for this Fragment.
Returns a Unicode string, the HTML content for the <head> section of the page.
initialize_js(js_func, json_args=None)
Register a Javascript function to initialize the Javascript resources.
js_func is the name of a Javascript function defined by one of the Javascript resources. As part of setting
up the browser’s runtime environment, the function will be invoked, passing a runtime object and a DOM
element.
static resource_to_html(resource)
Returns resource wrapped in the appropriate html tag for it’s mimetype.
resources
Returns list of unique FragmentResources by order of first appearance.
resources_to_html(placement)
Get some resource HTML for this Fragment.
placement is “head” or “foot”.
Returns a unicode string, the HTML for the head or foot of the page.
to_pods()
Returns the data in a dictionary.
‘pods’ = Plain Old Data Structure.
class xblock.fragment.FragmentResource
FragmentResource(kind, data, mimetype, placement)
__getnewargs__()
Return self as a plain tuple. Used by copy and pickle.
__getstate__()
Exclude the OrderedDict from pickling
__repr__()
Return a nicely formatted representation string
data
Alias for field number 1
kind
Alias for field number 0
mimetype
Alias for field number 2
placement
Alias for field number 3
3.4. Fragment
31
XBlock Documentation, Release 0.3
3.5 Exceptions
Module for all xblock exception classes
exception xblock.exceptions.DisallowedFileError
Raised by open_local_resource() if the requested file is not allowed.
exception xblock.exceptions.FieldDataDeprecationWarning
Warning for use of deprecated _field_data accessor
exception xblock.exceptions.InvalidScopeError
Raised to indicated that operating on the supplied scope isn’t allowed by a KeyValueStore
exception xblock.exceptions.JsonHandlerError(status_code, message)
Raised by a function decorated with XBlock.json_handler to indicate that an error response should be returned.
get_response(**kwargs)
Returns a Response object containing this object’s status code and a JSON object containing the key
“error” with the value of this object’s error message in the body. Keyword args are passed through to the
Response.
exception xblock.exceptions.KeyValueMultiSaveError(saved_field_names)
Raised to indicated an error in saving multiple fields in a KeyValueStore
Create a new KeyValueMultiSaveError
saved_field_names - an iterable of field names (strings) that were successfully saved before the exception occured
exception xblock.exceptions.NoSuchDefinition
Raised by IdReader.get_block_type() if the definition doesn’t exist.
exception xblock.exceptions.NoSuchHandlerError
Raised to indicate that the requested handler was not found.
exception xblock.exceptions.NoSuchServiceError
Raised to indicate that a requested service was not found.
exception xblock.exceptions.NoSuchUsage
Raised by IdReader.get_definition_id() if the usage doesn’t exist.
exception xblock.exceptions.NoSuchViewError(block, view_name)
Raised to indicate that the view requested was not found.
Create a new NoSuchViewError
Parameters
• block – The XBlock without a view
• view_name – The name of the view that couldn’t be found
exception xblock.exceptions.XBlockNotFoundError(usage_id)
Raised to indicate that an XBlock could not be found with the requested usage_id
exception xblock.exceptions.XBlockSaveError(saved_fields, dirty_fields)
Raised to indicate an error in saving an XBlock
Create a new XBlockSaveError
saved_fields - a set of fields that were successfully saved before the error occured dirty_fields - a set of fields
that were left dirty after the save
32
Chapter 3. API
CHAPTER 4
Project Info
Other information about the project.
4.1 Change history for XBlock
These are notable changes in XBlock.
4.1.1 0.4 - In Progress
• Make Scope enums (UserScope.* and BlockScope.*) into Sentinels, rather than just ints, so that they can have
more meaningful string representations.
• Rename export_xml to add_xml_to_node, to more accurately capture the semantics.
• Allowed Runtime implementations to customize loading from block_types to XBlock classes.
4.1.2 0.3 - 2014-01-09
• Added services available through Runtime.service, once XBlocks have announced their desires with
@XBlock.needs and @XBlock.wants.
• The “i18n” service provides a gettext.Translations object for retrieving localized strings.
• Make context an optional parameter for all views.
• Add shortcut method to make rendering an XBlock’s view with its own runtime easier.
• Change the user field of scopes to be three valued, rather than two. False becomes UserScope.NONE, True
becomes UserScope.ONE, and UserScope.ALL is new, and represents data that is computed based on input from
many users.
• Rename ModelData to FieldData.
• Rename ModelType to Field.
• Split xblock.core into a number of smaller modules:
– xblock.core: Defines XBlock.
– xblock.fields: Defines ModelType and subclasses, ModelData, and metaclasses for classes with fields.
– xblock.namespaces: Code for XBlock Namespaces only.
33
XBlock Documentation, Release 0.3
– xblock.exceptions: exceptions used by all parts of the XBlock project.
• Changed the interface for Runtime and ModelData so that they function as single objects that manage large
numbers of XBlocks. Any method that operates on a block now takes that block as the first argument. Blocks,
in turn, are responsible for storing the key values used by their field scopes.
• Changed the interface for model_data objects passed to XBlocks from dict-like to the being cache-like (as was
already used by KeyValueStore). This removes the need to support methods like iteration and length, which
makes it easier to write new ModelDatas. Also added an actual ModelData base class to serve as the expected
interface.
34
Chapter 4. Project Info
Python Module Index
x
xblock.exceptions, 32
xblock.fields, 18
xblock.fragment, 29
xblock.runtime, 22
35
XBlock Documentation, Release 0.3
36
Python Module Index
Index
Symbols
applicable_aside_types()
(xblock.runtime.Runtime
method),
26
__delattr__ (xblock.core.XBlock attribute), 15
ASIDE_DEFINITION_ID
__delete__() (xblock.fields.Field method), 20
(xblock.runtime.MemoryIdManager attribute),
__format__() (xblock.core.XBlock method), 15
24
__get__() (xblock.fields.Field method), 20
ASIDE_USAGE_ID
(xblock.runtime.MemoryIdManager
__getattribute__ (xblock.core.XBlock attribute), 15
attribute),
24
__getnewargs__() (xblock.fragment.FragmentResource
method), 31
__getstate__()
(xblock.fragment.FragmentResource B
BlockScope (class in xblock.fields), 18
method), 31
body_html() (xblock.fragment.Fragment method), 30
__hash__ (xblock.core.XBlock attribute), 15
Boolean (class in xblock.fields), 21
__reduce__() (xblock.core.XBlock method), 15
__reduce_ex__() (xblock.core.XBlock method), 15
__repr__() (xblock.fragment.FragmentResource method), C
31
clear() (xblock.runtime.MemoryIdManager method), 24
__set__() (xblock.fields.Field method), 20
construct_xblock() (xblock.runtime.Runtime method), 26
__setattr__ (xblock.core.XBlock attribute), 15
construct_xblock_from_class() (xblock.runtime.Runtime
__sizeof__() (xblock.core.XBlock method), 16
method), 26
__str__ (xblock.core.XBlock attribute), 16
content (xblock.fragment.Fragment attribute), 30
create_aside() (xblock.runtime.IdGenerator method), 22
A
create_aside()
(xblock.runtime.MemoryIdManager
method), 24
add_block_as_child_node()
(xblock.runtime.Runtime
create_aside() (xblock.runtime.Runtime method), 26
method), 26
create_definition() (xblock.runtime.IdGenerator method),
add_content() (xblock.fragment.Fragment method), 29
22
add_css() (xblock.fragment.Fragment method), 29
create_definition()
(xblock.runtime.MemoryIdManager
add_css_url() (xblock.fragment.Fragment method), 29
method),
24
add_frag_resources()
(xblock.fragment.Fragment
create_usage() (xblock.runtime.IdGenerator method), 23
method), 30
(xblock.runtime.MemoryIdManager
add_frags_resources()
(xblock.fragment.Fragment create_usage()
method),
25
method), 30
add_javascript() (xblock.fragment.Fragment method), 30
add_javascript_url()
(xblock.fragment.Fragment D
method), 30
data (xblock.fragment.FragmentResource attribute), 31
add_node_as_child() (xblock.runtime.Runtime method), DbModel (in module xblock.runtime), 22
26
default (xblock.fields.Field attribute), 20
add_resource() (xblock.fragment.Fragment method), 30
default() (xblock.runtime.KeyValueStore method), 23
add_resource_url() (xblock.fragment.Fragment method), default() (xblock.runtime.KvsFieldData method), 24
30
delete() (xblock.runtime.KeyValueStore method), 23
add_xml_to_node() (xblock.core.XBlock method), 16
delete() (xblock.runtime.KvsFieldData method), 24
delete_from() (xblock.fields.Field method), 20
37
XBlock Documentation, Release 0.3
Dict (class in xblock.fields), 21
DictKeyValueStore (class in xblock.runtime), 22
DisallowedFileError, 32
display_name (xblock.fields.Field attribute), 20
E
enforce_type() (xblock.fields.Field method), 20
export_to_xml() (xblock.runtime.Runtime method), 26
F
Field (class in xblock.fields), 19
field_data (xblock.runtime.Runtime attribute), 26
FieldDataDeprecationWarning, 32
Float (class in xblock.fields), 21
foot_html() (xblock.fragment.Fragment method), 30
Fragment (class in xblock.fragment), 29
FragmentResource (class in xblock.fragment), 31
from_json() (xblock.fields.Field method), 20
from_pods() (xblock.fragment.Fragment class method),
31
from_string() (xblock.fields.Field method), 20
from_string() (xblock.fields.String method), 22
G
get() (xblock.runtime.KeyValueStore method), 24
get() (xblock.runtime.KvsFieldData method), 24
get_aside() (xblock.runtime.Runtime method), 26
get_aside_of_type() (xblock.runtime.Runtime method),
26
get_aside_type_from_definition()
(xblock.runtime.IdReader method), 23
get_aside_type_from_definition()
(xblock.runtime.MemoryIdManager method),
25
get_aside_type_from_usage() (xblock.runtime.IdReader
method), 23
get_aside_type_from_usage()
(xblock.runtime.MemoryIdManager method),
25
get_asides() (xblock.runtime.Runtime method), 26
get_block() (xblock.runtime.Runtime method), 26
get_block_type() (xblock.runtime.IdReader method), 23
get_block_type()
(xblock.runtime.MemoryIdManager
method), 25
get_definition_id() (xblock.runtime.IdReader method),
23
get_definition_id() (xblock.runtime.MemoryIdManager
method), 25
get_definition_id_from_aside()
(xblock.runtime.IdReader method), 23
get_definition_id_from_aside()
(xblock.runtime.MemoryIdManager method),
25
get_parent() (xblock.core.XBlock method), 16
38
get_response()
(xblock.exceptions.JsonHandlerError
method), 32
get_usage_id_from_aside()
(xblock.runtime.IdReader
method), 23
get_usage_id_from_aside()
(xblock.runtime.MemoryIdManager method),
25
H
handle() (xblock.core.XBlock method), 16
handle() (xblock.runtime.Runtime method), 26
handler() (xblock.core.XBlock class method), 16
handler_url() (xblock.runtime.Runtime method), 27
has() (xblock.runtime.KeyValueStore method), 24
has() (xblock.runtime.KvsFieldData method), 24
head_html() (xblock.fragment.Fragment method), 31
I
IdGenerator (class in xblock.runtime), 22
IdReader (class in xblock.runtime), 23
index_dictionary() (xblock.core.XBlock method), 16
initialize_js() (xblock.fragment.Fragment method), 31
Integer (class in xblock.fields), 22
InvalidScopeError, 32
is_set_on() (xblock.fields.Field method), 20
J
json_handler() (xblock.core.XBlock class method), 16
JsonHandlerError, 32
K
KeyValueMultiSaveError, 32
KeyValueStore (class in xblock.runtime), 23
KeyValueStore.Key (class in xblock.runtime), 23
kind (xblock.fragment.FragmentResource attribute), 31
KvsFieldData (class in xblock.runtime), 24
L
layout_asides() (xblock.runtime.Runtime method), 27
lex() (xblock.runtime.RegexLexer method), 25
List (class in xblock.fields), 22
load_aside_type() (xblock.runtime.Runtime method), 27
load_block_type() (xblock.runtime.Runtime method), 27
load_class() (xblock.core.XBlock class method), 16
load_classes() (xblock.core.XBlock class method), 16
load_tagged_classes()
(xblock.core.XBlock
class
method), 17
local_resource_url() (xblock.runtime.Runtime method),
27
M
MemoryIdManager (class in xblock.runtime), 24
mimetype
(xblock.fragment.FragmentResource
tribute), 31
at-
Index
XBlock Documentation, Release 0.3
mix() (xblock.runtime.Mixologist method), 25
Mixologist (class in xblock.runtime), 25
name (xblock.fields.Field attribute), 20
named_scopes() (xblock.fields.Scope class method), 19
needs() (xblock.core.XBlock class method), 17
NoSuchDefinition, 32
NoSuchHandlerError, 32
NoSuchServiceError, 32
NoSuchUsage, 32
NoSuchViewError, 32
NullI18nService (class in xblock.runtime), 25
ScopeIds (class in xblock.fields), 19
scopes() (xblock.fields.BlockScope class method), 18
scopes() (xblock.fields.Scope class method), 19
scopes() (xblock.fields.UserScope class method), 19
service() (xblock.runtime.Runtime method), 28
service_declaration() (xblock.core.XBlock class method),
17
set() (xblock.runtime.KeyValueStore method), 24
set() (xblock.runtime.KvsFieldData method), 24
set_many() (xblock.runtime.KeyValueStore method), 24
set_many() (xblock.runtime.KvsFieldData method), 24
strftime() (xblock.runtime.NullI18nService method), 25
String (class in xblock.fields), 22
O
T
N
ObjectAggregator (class in xblock.runtime), 25
open_local_resource()
(xblock.core.XBlock
method), 17
P
tag() (xblock.core.XBlock static method), 18
class to_json() (xblock.fields.Field method), 20
to_pods() (xblock.fragment.Fragment method), 31
to_string() (xblock.fields.Field method), 21
to_string() (xblock.fields.String method), 22
parse_xml() (xblock.core.XBlock class method), 17
U
parse_xml_file() (xblock.runtime.Runtime method), 27
parse_xml_string() (xblock.runtime.Runtime method), 28 UserScope (class in xblock.fields), 18
placement
(xblock.fragment.FragmentResource
atV
tribute), 31
publish() (xblock.runtime.Runtime method), 28
validate() (xblock.core.XBlock method), 18
values (xblock.fields.Field attribute), 21
Q
query() (xblock.runtime.Runtime method), 28
querypath() (xblock.runtime.Runtime method), 28
R
read_from() (xblock.fields.Field method), 20
read_json() (xblock.fields.Field method), 20
RegexLexer (class in xblock.runtime), 25
register_temp_plugin()
(xblock.core.XBlock
class
method), 17
render() (xblock.core.XBlock method), 17
render() (xblock.runtime.Runtime method), 28
render_asides() (xblock.runtime.Runtime method), 28
render_child() (xblock.runtime.Runtime method), 28
render_children() (xblock.runtime.Runtime method), 28
resource_to_html() (xblock.fragment.Fragment static
method), 31
resource_url() (xblock.runtime.Runtime method), 28
resources (xblock.fragment.Fragment attribute), 31
resources_to_html()
(xblock.fragment.Fragment
method), 31
Runtime (class in xblock.runtime), 25
W
wants() (xblock.core.XBlock class method), 18
wrap_aside() (xblock.runtime.Runtime method), 29
wrap_xblock() (xblock.runtime.Runtime method), 29
write_to() (xblock.fields.Field method), 21
X
XBlock (class in xblock.core), 15
xblock.exceptions (module), 32
xblock.fields (module), 18
xblock.fragment (module), 29
xblock.runtime (module), 22
XBlockMixin (class in xblock.fields), 22
XBlockNotFoundError, 32
XBlockSaveError, 32
xml_element_name() (xblock.core.XBlock method), 18
xml_text_content() (xblock.core.XBlock method), 18
S
save() (xblock.core.XBlock method), 17
Scope (class in xblock.fields), 19
Index
39