-
Notifications
You must be signed in to change notification settings - Fork 42
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Submission export #77
Submission export #77
Conversation
The @soumyabasu , what do you think? We should either expand the definition of a protocol or reword |
print("Submissions downloaded.") | ||
if os.path.exists('export_cache.pkl'): | ||
os.remove('export_cache.pkl') | ||
sys.exit(0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer if ok.py:main
was the only function that uses exit
to abort; that way, it's easier to keep track of all the ways an abort can occur. I suggest rewriting ok.py to do something like this:
if args.export:
export.protocol...
exit(0)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with your preference, but I also don't like changing ok.py:main every time that we add a functionality like this. We should figure out how to nicely achieve both goals.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see the issue with changing ok.py:main every time we want to add an abort. Can you elaborate?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there will be a family of protocols that do something like this: make API call to the server to either fetch or update some state and then exit. I don't want to keep adding things to ok-main every time that happens since that'll get cluttered.
It might be good to then subclass things? like your GradingProcotol and models framework?
I was thinking of this as a definition: A Protocol is something that runs before a backup is taken. I think that we should have a backup flag that some protocols (e.g. this one) can turn off to indicate that no backup should be taken on this run to ok. |
Some care needs to be taken to specify which protocols are "special cases" (i.e. this protocol is explicitly mentioned in ok.py:main, whereas other protocols are just part of the |
Okay, how about a slightly different design? We have a 'NetworkProtocol' that's responsible for any server/user interaction. This protocol is one of the "special cases" you mentioned and downloading all final submissions for an assignment is just one thing that it can do. |
The |
@jathak - What do you think about this? |
That definitely makes sense. Would this still require updating ok.py:main for each new feature like this or could we make it so it looks through all available NetworkProtocols and chooses one automatically based on the command-line arguments? |
Is it better to define features like this one as protocols that run before (or in place of) the backup or as protocols that run before loading the assignment configuration? For instance, if we added a feature for students to restore to an backup, it would need to run after loading the assignment but it would still need to make network requests in place of a backup. |
Each protocol has access to command line arguments, so I think it would be fine to do it in either place. I'm preferential to ok.py:main just knowing that NetworkProtocol needs to be run and the NetworkProtocol picking the right thing to do. It's fine to just use your best judgment in cases like this and/or ping someone to talk about it.
Before the backup for precisely the reason you mentioned. Also, you could make it so that the "export all submissions" thing just downloads all of the final submissions for the assignment that was loaded into ok as well. |
Should NetworkProtocols only be available if included in the assignment configuration or should they be available regardless (provided the proper command-line argument is used)? |
I think it should be included in the assignment configuration to keep things consistent- it ultimately should be up to the instructors whether or not their students are allowed to use ok features. |
NetworkProtocols can use a mechanism similar to regular protocols to On Sat, Jun 6, 2015 at 3:04 AM, soumyabasu notifications@github.com wrote:
|
We can merge in the export protocol functionality before I rewrite the On Sat, Jun 6, 2015, 3:19 AM Albert Wu albert12132@gmail.com wrote:
|
data = None | ||
try: | ||
data = pickle.load(open("export_cache.pkl", "rb")) | ||
self.access_token = auth.authenticate(self.args.authenticate) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This authentication should probably happen before the try/except
block; it seems like you want it to happen regardless of whether or not there is an error.
pickle.dump(data, open("export_cache.pkl", "wb")) | ||
dl_left = len(data['students']) - i | ||
print("Download interrupted. Run command again to continue.") | ||
print("{0} submissions left to download".format(dl_left)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Abstract this logic away into a subroutine def abort(data, total_students, current_student):
, since you use it in multiple places.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better yet, just catch the IOError
and HTTPError
here:
except (KeyboardInterrupt, IOError, HTTPError) as e:
...
print("Download could not be completed. Run the following command to continue:")
...
Also, please include a log warning that prints the exception message and includes a stack trace:
log.warning("Incomplete download. %s: %s", type(e).__name__, str(e), exc_info=True)
import socket | ||
|
||
TIMEOUT = 500 | ||
RETRY_LIMIT = 5 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is needed anymore.
Looks good so far. Have you been able to get this working? |
I've tested this with a local server and it works. |
Great. That's all the comments I have, so I'll just wait until you're done making changes. @soumyabasu , do you have any comments? |
Nope, I'm good with the high level design and I don't have anything additional to add to your code review. |
I've resolved Albert's comments, so let me know if there's anything else that needs to be done before this can be merged. |
|
||
current_student = 0 | ||
try: | ||
if not os.path.exists('submissions'): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"submissions" should be stored in a global variable at the top of the file (e.g. SUBMISSION_DIR = 'submissions'
). You also use 'submissions' on line 82.
Should I increment the version number? |
No, I'll do that on the master branch. Merging now. |
Implements an option for course staff to export all final submissions for an assignment, as mentioned in this issue.
Adding the
--export
option to a command overrides the client's default behavior and instead downloads all final submissions for the provided assignment (the course is determined by the optional--course
parameter or selected from a list of all courses if not provided).