[Tutor] Help on Software Design decisions
Juan C.
juan0christian at gmail.com
Tue Nov 29 12:17:42 EST 2016
On Tue, Nov 29, 2016 at 7:12 AM, Alan Gauld via Tutor <tutor at python.org>
wrote:
> I just noticed the last bit.
> Is this a client side API or a server side API?
> In other words are you building a set of services on the
> server or are you building a module that makes it easy
> for client side programs to access the server? I had
> assumed the first but your responses make me think it
> is probably the second.
Client side. I'm building a python package to make it easier for my
programs to get data from Moodle.
> OK, In that case you possibly want to call your class
> Users since you seem to intend to fetch all User objects at once?
> Or is the User ID doing double duty as a security token for
> the server and as a key into the data? Or should it look like:
I just need username and password to login, nothing else. I'm passing
'program_id' as an argument to make it easier for me, but I intend to
automatically get it in the future.
Here's my working code:
package moodle/
user.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from .program import Program
import requests
class User:
_AUTH_URL = 'http://lms.university.edu/moodle/login/index.php'
def __init__(self, username, password, program_id):
self.username = username
self.password = password
session = requests.session()
session.post(self._AUTH_URL, {"username": username, "password":
password})
self.program = Program(program_id=program_id, session=session)
def __str__(self):
return self.username + ':' + self.password
def __repr__(self):
return '<User %s>' % self.username
def __eq__(self, other):
if isinstance(other, self):
return self.username == other.username
else:
return False
==========
program.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from .unit import Unit
from bs4 import BeautifulSoup
class Program:
_PATH = 'http://lms.university.edu/moodle/course/index.php?categoryid='
def __init__(self, program_id, session):
response = session.get(self._PATH + str(program_id))
soup = BeautifulSoup(response.text, 'html.parser')
self.name = soup.find('ul',
class_='breadcrumb').find_all('li')[-2].text.replace('/', '').strip()
self.id = program_id
self.units = [Unit(int(item['data-categoryid']), session) for item in
soup.find_all('div', {'class': 'category'})]
def __str__(self):
return self.name
def __repr__(self):
return '<Program %s (%s)>' % (self.name, self.id)
def __eq__(self, other):
if isinstance(other, self):
return self.id == other.id
else:
return False
==========
unit.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from .course import Course
from bs4 import BeautifulSoup
class Unit:
_PATH = 'http://lms.university.edu/moodle/course/index.php?categoryid='
def __init__(self, unit_id, session):
response = session.get(self._PATH + str(unit_id))
soup = BeautifulSoup(response.text, 'html.parser')
self.name = soup.find('ul',
class_='breadcrumb').find_all('li')[-1].text.replace('/', '').strip()
self.id = unit_id
self.courses = [Course(int(item['data-courseid']), session) for item
in soup.find_all('div', {'class': 'coursebox'})]
def __str__(self):
return self.name
def __repr__(self):
return '<Unit %s (%s)>' % (self.name, self.id)
def __eq__(self, other):
if isinstance(other, self):
return self.id == other.id
else:
return False
==========
course.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from .assignment import Assignment
import re
from bs4 import BeautifulSoup
class Course:
_PATH = 'http://lms.university.edu/moodle/course/view.php?id='
def __init__(self, course_id, session):
response = session.get(self._PATH + str(course_id))
soup = BeautifulSoup(response.text, 'html.parser')
self.name = soup.find('h1').text
self.id = course_id
self.assignments = [Assignment(int(item['href'].split('id=')[-1]),
session) for item in
soup.find_all('a', href=re.compile(r'http://lms
\.university\.edu/moodle/mod/assign/view.php\?id=.*'))]
def __str__(self):
return self.name
def __repr__(self):
return '<Course %s (%s)>' % (self.name, self.id)
def __eq__(self, other):
if isinstance(other, self):
return self.id == other.id
else:
return False
==========
assignment.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from bs4 import BeautifulSoup
class Assignment:
_PATH = 'http://lms.university.edu/moodle/mod/assign/view.php?id='
def __init__(self, assignment_id, session):
response = session.get(self._PATH + str(assignment_id))
soup = BeautifulSoup(response.text, 'html.parser')
self.name = soup.find('h2').text
self.id = assignment_id
def __str__(self):
return self.name
def __repr__(self):
return '<Assignment %s (%s)>' % (self.name, self.id)
def __eq__(self, other):
if isinstance(other, self):
return self.id == other.id
else:
return False
==========
test.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from moodle.user import User
my_user = User('john.smith', '3uper$secret', 12)
print(my_user) # print: john.smith:3uper$secret
print(my_user.program) # print: Computer Science
print(my_user.program.units) # print: [<Unit Math Fundamentals (59)>,
<Unit Programming (102)>]
print(my_user.program.units[-1].courses) # print: [<Course Programming
Logic (666)>, <Course Data Modeling (667)>, <Course Python 1 (668)>,
<Course Python 2 (669)>, <Course Project (670)>]
print(my_user.program.units[-1].courses[-1].assignments) #
print: [<Assignment A1 [mandatory] (40817)>, <Assignment A2 (40824)>,
<Assignment A3 [mandatory] (40831)>, <Assignment A4 (40838)>, <Assignment
A5 [mandatory] (40845)>, <Assignment Final Assignment [mandatory] (40882)>]
More information about the Tutor
mailing list