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

Add basic login functionality #463

Merged
merged 3 commits into from
Jan 7, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions digits/dataset/images/classification/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from digits import utils
from digits.utils.forms import fill_form_if_cloned, save_form_to_job
from digits.utils.routing import request_wants_json, job_from_request
from digits.webapp import app, scheduler, autodoc
from digits.webapp import app, scheduler
from digits.dataset import tasks
from forms import ImageClassificationDatasetForm
from job import ImageClassificationDatasetJob
Expand Down Expand Up @@ -254,7 +254,7 @@ def from_files(job, form):


@app.route(NAMESPACE + '/new', methods=['GET'])
@autodoc('datasets')
@utils.auth.requires_login
def image_classification_dataset_new():
"""
Returns a form for a new ImageClassificationDatasetJob
Expand All @@ -268,7 +268,7 @@ def image_classification_dataset_new():

@app.route(NAMESPACE + '.json', methods=['POST'])
@app.route(NAMESPACE, methods=['POST'])
@autodoc(['datasets', 'api'])
@utils.auth.requires_login(redirect=False)
def image_classification_dataset_create():
"""
Creates a new ImageClassificationDatasetJob
Expand All @@ -289,6 +289,7 @@ def image_classification_dataset_create():
job = None
try:
job = ImageClassificationDatasetJob(
username = utils.auth.get_username(),
name = form.dataset_name.data,
image_dims = (
int(form.resize_height.data),
Expand Down Expand Up @@ -328,7 +329,6 @@ def show(job):
return flask.render_template('datasets/images/classification/show.html', job=job)

@app.route(NAMESPACE + '/summary', methods=['GET'])
@autodoc('datasets')
def image_classification_dataset_summary():
"""
Return a short HTML summary of a DatasetJob
Expand Down Expand Up @@ -364,7 +364,6 @@ def entries(self):
yield item

@app.route(NAMESPACE + '/explore', methods=['GET'])
@autodoc('datasets')
def image_classification_dataset_explore():
"""
Returns a gallery consisting of the images of one of the dbs
Expand Down
13 changes: 7 additions & 6 deletions digits/dataset/images/generic/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@

import flask

from digits import utils
from digits.utils.forms import fill_form_if_cloned, save_form_to_job
from digits.utils.routing import request_wants_json, job_from_request
from digits.webapp import app, scheduler, autodoc
from digits.webapp import app, scheduler
from digits.dataset import tasks
from forms import GenericImageDatasetForm
from job import GenericImageDatasetJob

NAMESPACE = '/datasets/images/generic'

@app.route(NAMESPACE + '/new', methods=['GET'])
@autodoc('datasets')
@utils.auth.requires_login
def generic_image_dataset_new():
"""
Returns a form for a new GenericImageDatasetJob
Expand All @@ -26,7 +27,7 @@ def generic_image_dataset_new():

@app.route(NAMESPACE + '.json', methods=['POST'])
@app.route(NAMESPACE, methods=['POST'])
@autodoc(['datasets', 'api'])
@utils.auth.requires_login(redirect=False)
def generic_image_dataset_create():
"""
Creates a new GenericImageDatasetJob
Expand All @@ -47,8 +48,9 @@ def generic_image_dataset_create():
job = None
try:
job = GenericImageDatasetJob(
name = form.dataset_name.data,
mean_file = form.prebuilt_mean_file.data.strip(),
username = utils.auth.get_username(),
name = form.dataset_name.data,
mean_file = form.prebuilt_mean_file.data.strip(),
)

if form.method.data == 'prebuilt':
Expand Down Expand Up @@ -118,7 +120,6 @@ def show(job):
return flask.render_template('datasets/images/generic/show.html', job=job)

@app.route(NAMESPACE + '/summary', methods=['GET'])
@autodoc('datasets')
def generic_image_dataset_summary():
"""
Return a short HTML summary of a DatasetJob
Expand Down
3 changes: 1 addition & 2 deletions digits/dataset/images/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,13 @@

import digits
from digits import utils
from digits.webapp import app, autodoc
from digits.webapp import app
import classification.views
import generic.views

NAMESPACE = '/datasets/images'

@app.route(NAMESPACE + '/resize-example', methods=['POST'])
@autodoc('datasets')
def image_dataset_resize_example():
"""
Resizes the example image, and returns it as a string of png data
Expand Down
3 changes: 1 addition & 2 deletions digits/dataset/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import flask
import werkzeug.exceptions

from digits.webapp import app, scheduler, autodoc
from digits.webapp import app, scheduler
from digits.utils.routing import request_wants_json
import images.views
import images as dataset_images
Expand All @@ -12,7 +12,6 @@

@app.route(NAMESPACE + '<job_id>.json', methods=['GET'])
@app.route(NAMESPACE + '<job_id>', methods=['GET'])
@autodoc(['datasets', 'api'])
def datasets_show(job_id):
"""
Show a DatasetJob
Expand Down
6 changes: 5 additions & 1 deletion digits/job.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,19 @@ def load(cls, job_id):
task.detect_snapshots()
return job

def __init__(self, name):
def __init__(self, name, username):
"""
Arguments:
name -- name of this job
username -- creator of this job
"""
super(Job, self).__init__()

# create a unique ID
self._id = '%s-%s' % (time.strftime('%Y%m%d-%H%M%S'), os.urandom(2).encode('hex'))
self._dir = os.path.join(config_value('jobs_dir'), self._id)
self._name = name
self.username = username
self.pickver_job = PICKLE_VERSION
self.tasks = []
self.exception = None
Expand All @@ -76,6 +78,8 @@ def __setstate__(self, state):
"""
Used when loading a pickle file
"""
if 'username' not in state:
state['username'] = None
self.__dict__ = state

def json_dict(self, detailed=False):
Expand Down
11 changes: 4 additions & 7 deletions digits/model/images/classification/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from digits.config import config_value
from digits import utils
from digits.utils.routing import request_wants_json, job_from_request
from digits.webapp import app, scheduler, autodoc
from digits.webapp import app, scheduler
from digits.dataset import ImageClassificationDatasetJob
from digits import frameworks
from forms import ImageClassificationModelForm
Expand All @@ -24,7 +24,7 @@
NAMESPACE = '/models/images/classification'

@app.route(NAMESPACE + '/new', methods=['GET'])
@autodoc('models')
@utils.auth.requires_login
def image_classification_model_new():
"""
Return a form for a new ImageClassificationModelJob
Expand All @@ -50,7 +50,7 @@ def image_classification_model_new():

@app.route(NAMESPACE + '.json', methods=['POST'])
@app.route(NAMESPACE, methods=['POST'])
@autodoc(['models', 'api'])
@utils.auth.requires_login(redirect=False)
def image_classification_model_create():
"""
Create a new ImageClassificationModelJob
Expand Down Expand Up @@ -88,6 +88,7 @@ def image_classification_model_create():
job = None
try:
job = ImageClassificationModelJob(
username = utils.auth.get_username(),
name = form.model_name.data,
dataset_id = datasetJob.id(),
)
Expand Down Expand Up @@ -235,7 +236,6 @@ def show(job):
return flask.render_template('models/images/classification/show.html', job=job, framework_ids = [fw.get_id() for fw in frameworks.get_frameworks()])

@app.route(NAMESPACE + '/large_graph', methods=['GET'])
@autodoc('models')
def image_classification_model_large_graph():
"""
Show the loss/accuracy graph, but bigger
Expand All @@ -246,7 +246,6 @@ def image_classification_model_large_graph():

@app.route(NAMESPACE + '/classify_one.json', methods=['POST'])
@app.route(NAMESPACE + '/classify_one', methods=['POST', 'GET'])
@autodoc(['models', 'api'])
def image_classification_model_classify_one():
"""
Classify one image and return the top 5 classifications
Expand Down Expand Up @@ -304,7 +303,6 @@ def image_classification_model_classify_one():

@app.route(NAMESPACE + '/classify_many.json', methods=['POST'])
@app.route(NAMESPACE + '/classify_many', methods=['POST', 'GET'])
@autodoc(['models', 'api'])
def image_classification_model_classify_many():
"""
Classify many images and return the top 5 classifications for each
Expand Down Expand Up @@ -389,7 +387,6 @@ def image_classification_model_classify_many():
)

@app.route(NAMESPACE + '/top_n', methods=['POST'])
@autodoc('models')
def image_classification_model_top_n():
"""
Classify many images and show the top N images per category by confidence
Expand Down
10 changes: 4 additions & 6 deletions digits/model/images/generic/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from digits import utils
from digits.utils.routing import request_wants_json, job_from_request
from digits.utils.forms import fill_form_if_cloned, save_form_to_job
from digits.webapp import app, scheduler, autodoc
from digits.webapp import app, scheduler
from digits.dataset import GenericImageDatasetJob
from forms import GenericImageModelForm
from job import GenericImageModelJob
Expand All @@ -22,7 +22,7 @@
NAMESPACE = '/models/images/generic'

@app.route(NAMESPACE + '/new', methods=['GET'])
@autodoc('models')
@utils.auth.requires_login
def generic_image_model_new():
"""
Return a form for a new GenericImageModelJob
Expand All @@ -47,7 +47,7 @@ def generic_image_model_new():

@app.route(NAMESPACE + '.json', methods=['POST'])
@app.route(NAMESPACE, methods=['POST'])
@autodoc(['models', 'api'])
@utils.auth.requires_login(redirect=False)
def generic_image_model_create():
"""
Create a new GenericImageModelJob
Expand Down Expand Up @@ -84,6 +84,7 @@ def generic_image_model_create():
job = None
try:
job = GenericImageModelJob(
username = utils.auth.get_username(),
name = form.model_name.data,
dataset_id = datasetJob.id(),
)
Expand Down Expand Up @@ -218,7 +219,6 @@ def show(job):
return flask.render_template('models/images/generic/show.html', job=job)

@app.route(NAMESPACE + '/large_graph', methods=['GET'])
@autodoc('models')
def generic_image_model_large_graph():
"""
Show the loss/accuracy graph, but bigger
Expand All @@ -229,7 +229,6 @@ def generic_image_model_large_graph():

@app.route(NAMESPACE + '/infer_one.json', methods=['POST'])
@app.route(NAMESPACE + '/infer_one', methods=['POST', 'GET'])
@autodoc(['models', 'api'])
def generic_image_model_infer_one():
"""
Infer one image
Expand Down Expand Up @@ -280,7 +279,6 @@ def generic_image_model_infer_one():

@app.route(NAMESPACE + '/infer_many.json', methods=['POST'])
@app.route(NAMESPACE + '/infer_many', methods=['POST', 'GET'])
@autodoc(['models', 'api'])
def generic_image_model_infer_many():
"""
Infer many images
Expand Down
8 changes: 1 addition & 7 deletions digits/model/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@


import digits
from digits.webapp import app, scheduler, autodoc
from digits.webapp import app, scheduler
from digits.utils import time_filters
from digits.utils.routing import request_wants_json
from . import ModelJob
Expand All @@ -25,7 +25,6 @@
NAMESPACE = '/models/'

@app.route(NAMESPACE, methods=['GET'])
@autodoc(['models'])
def models_index():
column_attrs = list(get_column_attrs())
raw_jobs = [j for j in scheduler.jobs.values() if isinstance(j, ModelJob)]
Expand Down Expand Up @@ -82,7 +81,6 @@ def models_index():

@app.route(NAMESPACE + '<job_id>.json', methods=['GET'])
@app.route(NAMESPACE + '<job_id>', methods=['GET'])
@autodoc(['models', 'api'])
def models_show(job_id):
"""
Show a ModelJob
Expand All @@ -106,7 +104,6 @@ def models_show(job_id):
'Invalid job type')

@app.route(NAMESPACE + 'customize', methods=['POST'])
@autodoc('models')
def models_customize():
"""
Returns a customized file for the ModelJob based on completed form fields
Expand Down Expand Up @@ -147,7 +144,6 @@ def models_customize():
})

@app.route(NAMESPACE + 'visualize-network', methods=['POST'])
@autodoc('models')
def models_visualize_network():
"""
Returns a visualization of the custom network as a string of PNG data
Expand All @@ -162,7 +158,6 @@ def models_visualize_network():
return ret

@app.route(NAMESPACE + 'visualize-lr', methods=['POST'])
@autodoc('models')
def models_visualize_lr():
"""
Returns a JSON object of data used to create the learning rate graph
Expand Down Expand Up @@ -217,7 +212,6 @@ def models_visualize_lr():
defaults={'extension': 'tar.gz'})
@app.route(NAMESPACE + '<job_id>/download.<extension>',
methods=['GET', 'POST'])
@autodoc('models')
def models_download(job_id, extension):
"""
Return a tarball of all files required to run the model
Expand Down
12 changes: 8 additions & 4 deletions digits/templates/job.html
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,9 @@
<div class="row">
<div id="show-job-name" class="col-sm-12">
<h2 style="display:inline;">{{ job.name() }}</h2>
{% if job | has_permission('edit') %}
<a href=# onClick="$('#show-job-name').hide(); $('#edit-job-name').show(); return false;"><span class="glyphicon glyphicon-edit"></span></a>
{% endif %}
</div>
<div id="edit-job-name" class="col-sm-4" style="display:none;">
<script>
Expand All @@ -116,15 +118,17 @@ <h2 style="display:inline;">{{ job.name() }}</h2>
<a href=# class="btn btn-info" onClick="$('#edit-job-name').hide(); $('#show-job-name').show(); return false;">Cancel</a>
</div>
</div>
<small>{{ job.job_type() }}</small>
{% if job.username %}
<small>Owner: {{job.username}}</small>
{% endif %}
<div class="pull-right">
{% if job.form_data is defined %}
<a id="clone-job" class="btn btn-info" href="{{url_for('clone_job', clone=job.id())}}">Clone Job</a>
{% else %}
<a id="clone-job" class="btn btn-info " disabled>Clone Job</a>
<a id="clone-job" class="btn btn-info" disabled>Clone Job</a>
{% endif %}
<a id="abort-job" class="btn btn-warning{{ ' hidden' if not job.status.is_running() }}">Abort Job</a>
<a id="delete-job" class="btn btn-danger">Delete Job</a>
<a id="abort-job" class="btn btn-warning {{ 'hidden' if not job.status.is_running() }} {{'disabled' if not (job | has_permission('abort'))}}">Abort Job</a>
<a id="delete-job" class="btn btn-danger {{'disabled' if not (job | has_permission('delete'))}}">Delete Job</a>
</div>
</div>
<script>
Expand Down
4 changes: 3 additions & 1 deletion digits/templates/job_item.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
{# Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved. #}
<li id="job-{{job.id()}}" class="list-group-item">
<a class="btn btn-xs btn-danger pull-right" onClick="return deleteJob('{{job.id()}}');">Delete</a>
{% if job | has_permission('delete') %}
<a class="btn btn-xs btn-danger pull-right" onClick="return deleteJob('{{job.id()}}');">Delete</a>
{% endif %}
<h4 class="list-group-item-heading"><a href="{{ url_for(show_func, job_id=job.id()) }}">{{ job.name() }}</a> &nbsp; <span class="badge">{{badge}}</span></h4>
<p class="list-group-item-text">
<b>Submitted:</b> {{job.status_history[0][1]|print_time}}
Expand Down
Loading