Skip to content
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

Merged
merged 9 commits into from
Jun 17, 2015

Conversation

jathak
Copy link
Contributor

@jathak jathak commented Jun 6, 2015

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).

@albert12132
Copy link
Contributor

The ExportProtocol doesn't fit the behavior of a Protocol, as far as I know; I thought the original intention of a Protocol was a routine that runs before network communication. In this case, ExportProtocol runs in place of network communication.

@soumyabasu , what do you think? We should either expand the definition of a protocol or reword ExportProtocol as something else.

print("Submissions downloaded.")
if os.path.exists('export_cache.pkl'):
os.remove('export_cache.pkl')
sys.exit(0)
Copy link
Contributor

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)

Copy link
Contributor

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.

Copy link
Contributor

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?

Copy link
Contributor

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?

@soumyabasu
Copy link
Contributor

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.

@albert12132
Copy link
Contributor

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 for protocol in protocols section). In this particular case, the ExportProtocol would also want to prevent other protocols from running.

@soumyabasu
Copy link
Contributor

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.

@albert12132
Copy link
Contributor

The NetworkProtocol idea sounds better to me. We can have a switch statement in ok.py that selects what sort of network protocol to run based on command-line arguments.

@soumyabasu
Copy link
Contributor

@jathak - What do you think about this?

@jathak
Copy link
Contributor Author

jathak commented Jun 6, 2015

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?

@jathak
Copy link
Contributor Author

jathak commented Jun 6, 2015

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.

@soumyabasu
Copy link
Contributor

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?

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.

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?

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.

@jathak
Copy link
Contributor Author

jathak commented Jun 6, 2015

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)?

@soumyabasu
Copy link
Contributor

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.

@albert12132
Copy link
Contributor

NetworkProtocols can use a mechanism similar to regular protocols to
determine which one should be used; that way, ok.py:main won't have to be
modified every time. I can work on setting up the NetworkProtocol framework
in the next few days.

On Sat, Jun 6, 2015 at 3:04 AM, soumyabasu notifications@github.com wrote:

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.


Reply to this email directly or view it on GitHub
#77 (comment)
.

@albert12132
Copy link
Contributor

We can merge in the export protocol functionality before I rewrite the
network protocol stuff, since I won't be able to work on it for a couple of
days.

On Sat, Jun 6, 2015, 3:19 AM Albert Wu albert12132@gmail.com wrote:

NetworkProtocols can use a mechanism similar to regular protocols to
determine which one should be used; that way, ok.py:main won't have to be
modified every time. I can work on setting up the NetworkProtocol framework
in the next few days.

On Sat, Jun 6, 2015 at 3:04 AM, soumyabasu notifications@github.com
wrote:

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.


Reply to this email directly or view it on GitHub
#77 (comment)
.

data = None
try:
data = pickle.load(open("export_cache.pkl", "rb"))
self.access_token = auth.authenticate(self.args.authenticate)
Copy link
Contributor

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))
Copy link
Contributor

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.

Copy link
Contributor

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
Copy link
Contributor

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.

@albert12132
Copy link
Contributor

Looks good so far. Have you been able to get this working?

@jathak
Copy link
Contributor Author

jathak commented Jun 16, 2015

I've tested this with a local server and it works.

@albert12132
Copy link
Contributor

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?

@soumyabasu
Copy link
Contributor

Nope, I'm good with the high level design and I don't have anything additional to add to your code review.

@jathak
Copy link
Contributor Author

jathak commented Jun 17, 2015

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'):
Copy link
Contributor

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.

@jathak
Copy link
Contributor Author

jathak commented Jun 17, 2015

Should I increment the version number?

@albert12132
Copy link
Contributor

No, I'll do that on the master branch. Merging now.

albert12132 added a commit that referenced this pull request Jun 17, 2015
@albert12132 albert12132 merged commit 06a28cd into okpy:master Jun 17, 2015
@jathak jathak deleted the enhancement/jathak/submission-export branch June 18, 2015 03:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants