MOOC: Python and Web as Architecture
Rizky Ariestiyansyah
Python Conference Malaysia 2016
Hi!
Mozilla Tech Speaker
CTO at IndonesiaX (Indonesia’s Premier E-learning Platform)
22 Years old feel like TEEN!
What is MOOC?
MOOC
Massive
Student number
can be 100.000+
Open Online Course
Study any course,
anywhere at any
time
Blended course Learning units in
an academic
subject, life skill.
MOOC with Python Stack
Why Python?
- Minimal Setup
- Hierarchical Module System
- Available Libraries
@app.route('/')
def home():
courses_list = courses.list_courses()
return render_template('index.html', courses_list =
courses_list)
app.py
@app.route('/course/<course_id>')
def course(course_id=None):
course_lecs = lectures[course_id]
args = {
'course_id': course_id,
'course_name': course_map[course_id],
'lectures': course_lecs,
}
return render_template('course.html', args = args);
app.py
@app.route('/course/<course_id>/<int:lec_no>')
def player(course_id, lec_no):
args = {
'course_name': course_map[course_id],
'course_id': course_id,
'lec_no': lec_no,
'lec_path': lectures[course_id][lec_no],
'total_lectures': len(lectures[course_id]),
}
return render_template('player.html', args = args)
app.py
def lectures():
lectures = dict()
for course_id in course_map:
exts = ['mp4', 'webm', 'ogg']
vid_files = []
for ext in exts:
search_exp = 'static/courses/%s/*.%s' % (course_id, ext)
vid_files.extend(glob(search_exp))
vid_files = sorted(vid_files)
course_lecs = dict((n+1, str(x)) for n,x in
enumerate(vid_files))
lectures[course_id] = course_lecs
return lectures
course.py
def list_courses():
courses = []
for course_path in glob('static/courses/*'):
course_id = os.path.basename(course_path)
courses.append((course_id,
course_map[course_id]))
return courses
course.py
<body>
<h1 id='brand' style="text-align:center;">PyMOOC</h1>
<h3 id='tagline' style="text-align:center;">Simple MOOC Platform</
h3> <p>Welcome to <b>PyMOOC</b></p>
<h2>Courses</h2>
<ol>
{% for course_id, course_name in courses_list %}
<li><a href='{{ url_for('course',
course_id=course_id) }}'>{{ course_name }}</a></li>
{% endfor %}
</ol>
index.html
<body>
<h1 id='course_name'>{{ args["course_name"] }}</h1>
<h3>Lectures</h3>
<ul id='lectures'>
{% for lec_no in args["lectures"] %}
<li><a href='{{ url_for('player', course_id =
args["course_id"], lec_no = lec_no) }}'>
Lecture {{ lec_no }}
</a></li>
{% endfor %}
</ul>
</body>
course.html
<body>
<h3 style="text-align:center;">Lecture {{ args["lec_no"] }}</h3>
<h2 style="text-align:center;">{{ args["course_name"] }}</h2>
<div id='player'>
<video width='100%' src='/{{ args["lec_path"] }}' controls autoplay>
</video>
<div id='controls'>
{% if args["lec_no"] > 1 %}
<a href='{{ url_for("player", course_id = args["course_id"], lec_no = args["lec_no"] -
1) }}' class='navbutton' id='prev_button'>&larr; Previous</a>
{% endif %}
{% if args["lec_no"] < args["total_lectures"] %}
<a href='{{ url_for("player", course_id = args["course_id"], lec_no = args["lec_no"] +
1) }}' class='navbutton' id='next_button'>&rarr; Next</a>
{% endif %}
</div>
</body>
player.html
Extend the Architecture
Architecture
Focus: MySQL
Company
Process Username Port Function
mysqld mysql 3306 Database
● DB for: user profile, course enrollment,
certificate
● Authentication and Autorization data as
well
Focus: MongoDB
Company● Easy to scale
● Storing course data
● NoSQL DB Backend
Process Username Port Function
mongodb mongo 27017 Database
Focus: Memcached
Company● High speed distributed key-value (KV)
store for object caching
● Cache user session, course structure info,
ect..
Process Username Port Function
memcached memcache 11211 KV store
Focus: Nginx
Company● Web Server.
● Provided proxied.
● Load Balanced access to static and
dynamic assets.
● Stateless and horizontally scalable.
Process Username Worker Port Function
nginx www-data 4 80 Course
nginx www-data 4 8010 Course
Manager
Focus: Gunicorn
Company● Dynamic worker management.
● Stateless and horizontally scalable.
Process Username Worker Port Function
gunicor
n
www-data 4 8000 Course
gunicor
n
www-data 4 8010 Course
Manager
Focus: RabbitMQ
Company● Large jobs are run through queue.
● Coordinated by celery
● It is a software where queues can be
defined, applications may connect to the
queue and transfer a message onto it.
Process Username Port Function
beam.smp rabbitmq * :5672 Message
Queue
beam.smp rabbitmq 15672 Message
Queue
epmd rabbitmq 4369 Port
Mapper
Extend with WEB
WebGL
WebRTC
WebSockets
SVG
MathML
MathML
WebVTT
WEBVTT


00:01.000 --> 00:04.000

Original posting to alt.sources.


00:05.000 --> 00:09.000

- Micro changes only

- Added file "patchlevel.h"
WebVR
Final
MOOC Python Web
Thank You!
Rizky Ariestiyansyah
See You!

MOOC: Python & Web as Architecture

  • 1.
    MOOC: Python andWeb as Architecture Rizky Ariestiyansyah Python Conference Malaysia 2016
  • 2.
    Hi! Mozilla Tech Speaker CTOat IndonesiaX (Indonesia’s Premier E-learning Platform) 22 Years old feel like TEEN!
  • 4.
  • 8.
    MOOC Massive Student number can be100.000+ Open Online Course Study any course, anywhere at any time Blended course Learning units in an academic subject, life skill.
  • 9.
  • 10.
    Why Python? - MinimalSetup - Hierarchical Module System - Available Libraries
  • 11.
    @app.route('/') def home(): courses_list =courses.list_courses() return render_template('index.html', courses_list = courses_list) app.py
  • 12.
    @app.route('/course/<course_id>') def course(course_id=None): course_lecs =lectures[course_id] args = { 'course_id': course_id, 'course_name': course_map[course_id], 'lectures': course_lecs, } return render_template('course.html', args = args); app.py
  • 13.
    @app.route('/course/<course_id>/<int:lec_no>') def player(course_id, lec_no): args= { 'course_name': course_map[course_id], 'course_id': course_id, 'lec_no': lec_no, 'lec_path': lectures[course_id][lec_no], 'total_lectures': len(lectures[course_id]), } return render_template('player.html', args = args) app.py
  • 14.
    def lectures(): lectures =dict() for course_id in course_map: exts = ['mp4', 'webm', 'ogg'] vid_files = [] for ext in exts: search_exp = 'static/courses/%s/*.%s' % (course_id, ext) vid_files.extend(glob(search_exp)) vid_files = sorted(vid_files) course_lecs = dict((n+1, str(x)) for n,x in enumerate(vid_files)) lectures[course_id] = course_lecs return lectures course.py
  • 15.
    def list_courses(): courses =[] for course_path in glob('static/courses/*'): course_id = os.path.basename(course_path) courses.append((course_id, course_map[course_id])) return courses course.py
  • 16.
    <body> <h1 id='brand' style="text-align:center;">PyMOOC</h1> <h3id='tagline' style="text-align:center;">Simple MOOC Platform</ h3> <p>Welcome to <b>PyMOOC</b></p> <h2>Courses</h2> <ol> {% for course_id, course_name in courses_list %} <li><a href='{{ url_for('course', course_id=course_id) }}'>{{ course_name }}</a></li> {% endfor %} </ol> index.html
  • 17.
    <body> <h1 id='course_name'>{{ args["course_name"]}}</h1> <h3>Lectures</h3> <ul id='lectures'> {% for lec_no in args["lectures"] %} <li><a href='{{ url_for('player', course_id = args["course_id"], lec_no = lec_no) }}'> Lecture {{ lec_no }} </a></li> {% endfor %} </ul> </body> course.html
  • 18.
    <body> <h3 style="text-align:center;">Lecture {{args["lec_no"] }}</h3> <h2 style="text-align:center;">{{ args["course_name"] }}</h2> <div id='player'> <video width='100%' src='/{{ args["lec_path"] }}' controls autoplay> </video> <div id='controls'> {% if args["lec_no"] > 1 %} <a href='{{ url_for("player", course_id = args["course_id"], lec_no = args["lec_no"] - 1) }}' class='navbutton' id='prev_button'>&larr; Previous</a> {% endif %} {% if args["lec_no"] < args["total_lectures"] %} <a href='{{ url_for("player", course_id = args["course_id"], lec_no = args["lec_no"] + 1) }}' class='navbutton' id='next_button'>&rarr; Next</a> {% endif %} </div> </body> player.html
  • 19.
  • 20.
  • 21.
    Focus: MySQL Company Process UsernamePort Function mysqld mysql 3306 Database ● DB for: user profile, course enrollment, certificate ● Authentication and Autorization data as well
  • 22.
    Focus: MongoDB Company● Easyto scale ● Storing course data ● NoSQL DB Backend Process Username Port Function mongodb mongo 27017 Database
  • 23.
    Focus: Memcached Company● Highspeed distributed key-value (KV) store for object caching ● Cache user session, course structure info, ect.. Process Username Port Function memcached memcache 11211 KV store
  • 24.
    Focus: Nginx Company● WebServer. ● Provided proxied. ● Load Balanced access to static and dynamic assets. ● Stateless and horizontally scalable. Process Username Worker Port Function nginx www-data 4 80 Course nginx www-data 4 8010 Course Manager
  • 25.
    Focus: Gunicorn Company● Dynamicworker management. ● Stateless and horizontally scalable. Process Username Worker Port Function gunicor n www-data 4 8000 Course gunicor n www-data 4 8010 Course Manager
  • 26.
    Focus: RabbitMQ Company● Largejobs are run through queue. ● Coordinated by celery ● It is a software where queues can be defined, applications may connect to the queue and transfer a message onto it. Process Username Port Function beam.smp rabbitmq * :5672 Message Queue beam.smp rabbitmq 15672 Message Queue epmd rabbitmq 4369 Port Mapper
  • 27.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
    WebVTT WEBVTT 
 00:01.000 --> 00:04.000
 Originalposting to alt.sources. 
 00:05.000 --> 00:09.000
 - Micro changes only
 - Added file "patchlevel.h"
  • 36.
  • 38.
  • 39.