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 URL prefix support #1803

Merged
merged 4 commits into from
Aug 30, 2017
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
1 change: 1 addition & 0 deletions digits/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
server_name,
store_option,
tensorflow,
url_prefix,
)


Expand Down
8 changes: 8 additions & 0 deletions digits/config/url_prefix.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
from __future__ import absolute_import

import os

from . import option_list

option_list['url_prefix'] = os.environ.get('DIGITS_URL_PREFIX', '')
2 changes: 1 addition & 1 deletion digits/static/js/PretrainedModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ PretrainedModel.Actions = function(props) {
var parent = !_.isUndefined(props.parent) ? props.parent : props;

self.uploadArchive = function(file) {
var upload_url = '/pretrained_models/upload_archive';
var upload_url = URL_PREFIX + '/pretrained_models/upload_archive';
parent.heading({classed: false, text: 'Uploading archive, one moment...'});

var formData = new FormData();
Expand Down
12 changes: 6 additions & 6 deletions digits/static/js/home_app.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ try {
$scope.add_job = function(job_id) {
$http({
method: 'GET',
url: '/jobs/' + job_id + '/table_data.json',
url: URL_PREFIX + '/jobs/' + job_id + '/table_data.json',
}).then(function success(response) {
var job = response.data.job;
for (var i = 0; i < $scope.jobs.length; i++) {
Expand Down Expand Up @@ -69,7 +69,7 @@ try {
$scope.load_jobs = function() {
$http({
method: 'GET',
url: '/completed_jobs.json',
url: URL_PREFIX + '/completed_jobs.json',
}).then(function success(response) {
// Find the dataset reference count
var count = {};
Expand Down Expand Up @@ -393,7 +393,7 @@ try {
'<br><br>All related files will be permanently removed.'),
function(result) {
if (result)
$.ajax('/jobs',
$.ajax(URL_PREFIX + '/jobs',
{
type: 'DELETE',
data: {'job_ids': job_ids},
Expand All @@ -419,7 +419,7 @@ try {
(job_ids.length == 1 ? 'job?' : job_ids.length + ' jobs?')),
function(result) {
if (result)
$.ajax('/abort_jobs',
$.ajax(URL_PREFIX + '/abort_jobs',
{
type: 'POST',
data: {'job_ids': job_ids},
Expand Down Expand Up @@ -456,7 +456,7 @@ try {
// Case the user enters 'Ungrouped', change it to ''
if (result == 'Ungrouped')
result = '';
$.ajax('/group',
$.ajax(URL_PREFIX + '/group',
{
type: 'POST',
data: {
Expand Down Expand Up @@ -719,7 +719,7 @@ try {
restrict: 'AE',
replace: true,
template: ('<span>' +
' <a href="/jobs/{[ job.id ]}" title="{[job.name]}">' +
' <a href="' + URL_PREFIX + '/jobs/{[ job.id ]}" title="{[job.name]}">' +
' {[ job.name | major_name ]}' +
' </a>' +
' <small>' +
Expand Down
4 changes: 2 additions & 2 deletions digits/static/js/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
'use strict';
var app = angular.module('modelStore', []);
app.controller('ModelListController', function($scope, $http) {
var end_point = '/store/models';
var end_point = URL_PREFIX + '/store/models';
var get_model_list = function(refresh) {
$http({
method: 'GET',
Expand All @@ -27,7 +27,7 @@
$scope.download = function(id) {
$http({
method: 'GET',
url: '/store/push?id=' + id,
url: URL_PREFIX + '/store/push?id=' + id,
}).then(function successCallback(response) {
// nothing
}, function errorCallback(response) {
Expand Down
2 changes: 1 addition & 1 deletion digits/templates/home.html
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ <h4>
ng-keydown="keydown($event)"
ng-class="{selected:job.selected}">
<td>
<a href="/jobs/{[ job.id ]}" title="{[job.name]}">
<a href="{{config['URL_PREFIX']}}/jobs/{[ job.id ]}" title="{[job.name]}">
{[ job.name | major_name ]}
</a>
<small>
Expand Down
9 changes: 6 additions & 3 deletions digits/templates/layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
<link rel="stylesheet" href="{{ url_for('static', filename='css/c3.min.css', ver=dir_hash) }}">
<title>{% block title %}DIGITS{% endblock %}</title>

<script type="text/javascript">
var URL_PREFIX = "{{config['URL_PREFIX']}}";
</script>
<script src="{{ url_for('static', filename='js/3rdparty/jquery-1.11.1.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/3rdparty/bootstrap-3.3.6.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/3rdparty/bootbox-4.3.0.min.js') }}"></script>
Expand All @@ -34,7 +37,7 @@
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="/">DIGITS</a>
<a class="navbar-brand" href="{{ url_for("digits.views.home") }}">DIGITS</a>
</div>
<ul class="nav navbar-nav">
{% block nav %}
Expand All @@ -44,9 +47,9 @@
<li>
<p class="navbar-text">
{% if username %}
{{username}} (<a class="navbar-link" href="/logout">Logout</a>)
{{username}} (<a class="navbar-link" href="{{ url_for("digits.views.logout") }}">Logout</a>)
{% else %}
<a class="navbar-link" href="/login">Login</a>
<a class="navbar-link" href="{{ url_for("digits.views.login") }}">Login</a>
{% endif %}
</p>
</li>
Expand Down
2 changes: 1 addition & 1 deletion digits/templates/models/images/classification/new.html
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ <h4 style="display:inline-block;">Python Layers</h4>

$("#dataset").change(function() {
if ($(this).val()) {
$.ajax("/datasets/summary?job_id=" + $(this).val(),
$.ajax("{{url_for('digits.dataset.views.summary')}}" + "?job_id=" + $(this).val(),
{
type: "GET",
}
Expand Down
2 changes: 1 addition & 1 deletion digits/templates/models/images/classification/show.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ <h4 class='text-center'>Dataset</h4>
<div id="dataset-summary"></div>
{% if job.dataset %}
<script>
$.ajax("/datasets/summary?job_id={{ job.dataset.id() }}",
$.ajax("{{url_for('digits.dataset.views.summary', job_id=job.dataset.id())}}",
{
type: "GET",
}
Expand Down
2 changes: 1 addition & 1 deletion digits/templates/models/images/generic/new.html
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ <h4 style="display:inline-block;">Python Layers</h4>

$("#dataset").change(function() {
if ($(this).val()) {
$.ajax("/datasets/summary?job_id=" + $(this).val(),
$.ajax("{{url_for('digits.dataset.views.summary')}}" + "?job_id=" + $(this).val(),
{
type: "GET",
}
Expand Down
4 changes: 2 additions & 2 deletions digits/templates/models/images/generic/show.html
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ <h4 class='text-center'>Dataset</h4>
<div id="dataset-summary"></div>
{% if job.dataset %}
<script>
$.ajax("/datasets/summary?job_id={{ job.dataset.id() }}",
$.ajax("{{url_for('digits.dataset.views.summary', job_id=job.dataset.id())}}",
{
type: "GET",
}
Expand Down Expand Up @@ -178,7 +178,7 @@ <h3>Visualization Options</h3>
<script>
$("#view_extension_id").change(function() {
if ($(this).val()) {
$.ajax("/models/view-config/" + $(this).val(),
$.ajax("{{config['URL_PREFIX']}}/models/view-config/" + $(this).val(),
{
type: "GET",
}
Expand Down
2 changes: 1 addition & 1 deletion digits/templates/partials/home/datasets_pane.html
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@
ng-keydown="keydown($event)"
ng-class="{selected:job.selected}">
<td>
<a href="/jobs/{[ job.id ]}" title="{[job.name]}">
<a href="{{config['URL_PREFIX']}}/jobs/{[ job.id ]}" title="{[job.name]}">
{[ job.name | major_name ]}
</a>
<small>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<script type="text/javascript" src="{{ url_for('static', filename='js/PretrainedModel.js', ver=dir_hash) }}"></script>

{% set size = 500 %}
{% set url = "/pretrained_models/new" %}
{% set url = url_for('digits.pretrained_model.views.new') %}

<style>
.closeButton {
Expand Down
7 changes: 5 additions & 2 deletions digits/templates/socketio.html
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
{# Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. #}

<!-- Scripts for communicating with the SocketIO server -->
<script type="text/javascript" src="/static/js/3rdparty/socket.io-1.4.5.min.js"></script>
<script type="text/javascript" src="{{ url_for('static', filename='js/3rdparty/socket.io-1.4.5.min.js', ver=dir_hash) }}"></script>
<script>
var socket = io.connect('http://' + document.domain + ':' + location.port + "{{namespace}}");
var socket = io.connect(
'http://' + document.domain + ':' + location.port + "{{namespace}}",
{path: "{{config['URL_PREFIX']}}/socket.io"}
);

$(window).bind("beforeunload", function() {
socket.emit('leave');
Expand Down
2 changes: 1 addition & 1 deletion digits/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def job_exists(cls, job_id, job_type='jobs'):
"""
url = '/%s/%s' % (job_type, job_id)
rv = cls.app.get(url, follow_redirects=True)
assert rv.status_code in [200, 404], 'got status code "%s" from "%s"' % (rv.status_code, url)
assert rv.status_code in [200, 404], 'got status code "%s" from "%s"\n%s' % (rv.status_code, url, rv.data)
return rv.status_code == 200

@classmethod
Expand Down
41 changes: 27 additions & 14 deletions digits/webapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,16 @@

# Create Flask, Scheduler and SocketIO objects

app = flask.Flask(__name__)
url_prefix = config_value('url_prefix')
app = flask.Flask(__name__, static_url_path=url_prefix+'/static')
app.config['DEBUG'] = True
# Disable CSRF checking in WTForms
app.config['WTF_CSRF_ENABLED'] = False
# This is still necessary for SocketIO
app.config['SECRET_KEY'] = os.urandom(12).encode('hex')
app.url_map.redirect_defaults = False
socketio = SocketIO(app, async_mode='gevent')
app.config['URL_PREFIX'] = url_prefix
socketio = SocketIO(app, async_mode='gevent', path=url_prefix+'/socket.io')
app.config['store_cache'] = StoreCache()
app.config['store_url_list'] = config_value('model_store')['url_list']
scheduler = digits.scheduler.Scheduler(config_value('gpu_list'), True)
Expand All @@ -45,30 +47,41 @@
app.jinja_env.lstrip_blocks = True

import digits.views # noqa
app.register_blueprint(digits.views.blueprint)
app.register_blueprint(digits.views.blueprint,
url_prefix=url_prefix)
import digits.dataset.views # noqa
app.register_blueprint(digits.dataset.views.blueprint, url_prefix='/datasets')
app.register_blueprint(digits.dataset.views.blueprint,
url_prefix=url_prefix+'/datasets')
import digits.dataset.generic.views # noqa
app.register_blueprint(digits.dataset.generic.views.blueprint, url_prefix='/datasets/generic')
app.register_blueprint(digits.dataset.generic.views.blueprint,
url_prefix=url_prefix+'/datasets/generic')
import digits.dataset.images.views # noqa
app.register_blueprint(digits.dataset.images.views.blueprint, url_prefix='/datasets/images')
app.register_blueprint(digits.dataset.images.views.blueprint,
url_prefix=url_prefix+'/datasets/images')
import digits.dataset.images.classification.views # noqa
app.register_blueprint(digits.dataset.images.classification.views.blueprint,
url_prefix='/datasets/images/classification')
url_prefix=url_prefix+'/datasets/images/classification')
import digits.dataset.images.generic.views # noqa
app.register_blueprint(digits.dataset.images.generic.views.blueprint, url_prefix='/datasets/images/generic')
app.register_blueprint(digits.dataset.images.generic.views.blueprint,
url_prefix=url_prefix+'/datasets/images/generic')
import digits.model.views # noqa
app.register_blueprint(digits.model.views.blueprint, url_prefix='/models')
app.register_blueprint(digits.model.views.blueprint,
url_prefix=url_prefix+'/models')
import digits.model.images.views # noqa
app.register_blueprint(digits.model.images.views.blueprint, url_prefix='/models/images')
app.register_blueprint(digits.model.images.views.blueprint,
url_prefix=url_prefix+'/models/images')
import digits.model.images.classification.views # noqa
app.register_blueprint(digits.model.images.classification.views.blueprint, url_prefix='/models/images/classification')
app.register_blueprint(digits.model.images.classification.views.blueprint,
url_prefix=url_prefix+'/models/images/classification')
import digits.model.images.generic.views # noqa
app.register_blueprint(digits.model.images.generic.views.blueprint, url_prefix='/models/images/generic')
app.register_blueprint(digits.model.images.generic.views.blueprint,
url_prefix=url_prefix+'/models/images/generic')
import digits.pretrained_model.views # noqa
app.register_blueprint(digits.pretrained_model.views.blueprint, url_prefix='/pretrained_models')
app.register_blueprint(digits.pretrained_model.views.blueprint,
url_prefix=url_prefix+'/pretrained_models')
import digits.store.views # noqa
app.register_blueprint(digits.store.views.blueprint, url_prefix='/store')
app.register_blueprint(digits.store.views.blueprint,
url_prefix=url_prefix+'/store')


def username_decorator(f):
Expand Down
1 change: 1 addition & 0 deletions docs/Configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ DIGITS uses environment variables for configuration.
| `DIGITS_LOGFILE_LEVEL` | DEBUG | Minimum log message level to be saved (DEBUG/INFO/WARNING/ERROR/CRITICAL). Default is INFO. |
| `DIGITS_SERVER_NAME` | The Big One | The name of the server (accessible in the UI under "Info"). Default is the system hostname. |
| `DIGITS_MODEL_STORE_URL` | http://localhost/modelstore | A list of URL's, separated by comma. Default is the official NVIDIA store. |
| `DIGITS_URL_PREFIX` | /custom-prefix | A path to prepend before every URL. Sets the home-page to be at "http://localhost/custom-prefix" instead of "http://localhost/"/ |