Skip to content

Commit

Permalink
api/discoverer refactor: tests passing with (discoverer requires a li…
Browse files Browse the repository at this point in the history
…veserver)
  • Loading branch information
vsudilov committed Jan 7, 2015
1 parent f80365c commit 1ec85e3
Show file tree
Hide file tree
Showing 16 changed files with 348 additions and 268 deletions.
2 changes: 2 additions & 0 deletions adsws/api/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from flask import jsonify

from views import StatusView,Bootstrap,ProtectedView
from discoverer import discover

def create_app(**kwargs_config):

Expand All @@ -20,6 +21,7 @@ def create_app(**kwargs_config):
api.add_resource(StatusView,'/status')
api.add_resource(ProtectedView,'/protected')
api.add_resource(Bootstrap,'/bootstrap')
discover(app)

# Register custom error handlers
if not app.config.get('DEBUG'):
Expand Down
45 changes: 45 additions & 0 deletions adsws/api/config.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
import os
import logging

LOG_LEVEL=logging.DEBUG
LOG_FILE='logs/adsws.log' #Relative to here
#Set DEBUG=True to log to stderr, which is useful for development only.
#Note that this will also print the traceback in the response to the client, which is not desirable in production.
DEBUG=False


BOOTSTRAP_SCOPES = ['ads:default']
BOOTSTRAP_USER_EMAIL = 'anonymous@adslabs.org'
OAUTH2_CLIENT_ID_SALT_LEN = 40
BOOTSTRAP_TOKEN_EXPIRES = 3600*24 #1 day
OAUTH2_CACHE_TYPE='simple'

EXTENSIONS = ['adsws.ext.menu',
'adsws.ext.sqlalchemy',
Expand All @@ -23,3 +34,37 @@
'CACHE_KEY_PREFIX':'api_',
}
RATELIMITER_BACKEND = 'flaskcacheredis'

WEBSERVICES_PUBLISH_ENDPOINT = 'resources'
WEBSERVICES = {
# uri : deploy_path
'http://localhost:4000/': '/vis',
'http://localhost:1233/citation_helper/':'/citation_helper',
'http://localhost:1233/graphics/':'/graphics',
'http://localhost:1233/metrics/':'/metrics',
'http://localhost:1233/recommender/':'/recommender',
'adsws.solr.app':'/solr',
'adsws.graphics.app':'/graphics',
}


SOLR_SEARCH_HANDLER = 'http://localhost:8983/solr/select'
SOLR_QTREE_HANDLER = 'http://localhost:8983/solr/qtree'
SOLR_UPDATE_HANDLER = 'http://localhost:8983/solr/update'
SOLR_TVRH_HANDLER = 'http://localhost:8983/solr/tvrh'

SECRET_KEY = 'fake'
ACCOUNT_VERIFICATION_SECRET = 'fake'

FALL_BACK_ADS_CLASSIC_LOGIN = True
CLASSIC_LOGIN_URL = 'http://adsabs.harvard.edu/cgi-bin/maint/manage_account/credentials'
SITE_SECURE_URL = 'http://0.0.0.0:5000'

# Flask-Sqlalchemy: http://packages.python.org/Flask-SQLAlchemy/config.html
SQLALCHEMY_ECHO = False
SQLALCHEMY_DATABASE_URI = 'sqlite:////adsws/adsws.sqlite'

# Stuff that should be added for every application
CORE_PACKAGES = []

HTTPS_ONLY=False
Binary file removed adsws/api/db
Binary file not shown.
1 change: 1 addition & 0 deletions adsws/api/discoverer/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from utils import discover
46 changes: 10 additions & 36 deletions adsws/discoverer/app.py → adsws/api/discoverer/utils.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,12 @@
# -*- coding: utf-8 -*-
"""
adsws.discoverer
~~~~~~~~~~~~~~~~~~
"""
import os
from .. import factory
import requests
from flask import current_app, request
from views import ProxyView, StatusView
from flask.ext.restful import Api
from flask.ext.cors import CORS
from views import ProxyView
from adsws.modules.oauth2server.provider import oauth2
from urlparse import urljoin
import traceback
from importlib import import_module
from flask.ext.ratelimiter import RateLimiter, ratelimit
from flask.ext.cache import Cache
from flask.ext.ratelimiter import ratelimit


def bootstrap_local_module(service_uri,deploy_path,app):
Expand Down Expand Up @@ -96,33 +86,17 @@ def bootstrap_remote_service(service_uri,deploy_path,app):


def discover(app):
#Query each third-party service defined in the config for a route ('resources' by default)
#This route is expected to be present in all web-services, and describes which routes are present
#therein.
for service_uri, deploy_path in app.config.get('WEBSERVICES',{}).iteritems():
'''Query each third-party service defined in the config for a route ('resources' by default)
This route is expected to be present in all web-services, and describes which routes are present
therein.'''
WEBSERVICES = app.config.get('WEBSERVICES')
if not WEBSERVICES:
WEBSERVICES = {}
for service_uri, deploy_path in WEBSERVICES.iteritems():
try:
if service_uri.startswith('http'):
bootstrap_remote_service(service_uri,deploy_path,app)
else:
bootstrap_local_module(service_uri,deploy_path,app)
except:
app.logger.warning("Problem discovering %s, skipping this service entirely: %s" % (service_uri,traceback.format_exc()))


def create_app(**kwargs_config):
app = factory.create_app(__name__.replace('.app',''),**kwargs_config)

api = Api(app)
ratelimiter = RateLimiter(app=app)
cors = CORS(app,origins=app.config.get('CORS_DOMAINS'), headers=app.config.get('CORS_HEADERS'))
cache = Cache(app,config=app.config['CACHE'])

api.add_resource(StatusView,'/status')
discover(app)

return app


if __name__ == '__main__':
app = Flask(__name__)
app.run('0.0.0.0',5000,debug=True)
app.logger.warning("Problem discovering %s, skipping this service entirely: %s" % (service_uri,traceback.format_exc()))
7 changes: 1 addition & 6 deletions adsws/discoverer/views.py → adsws/api/discoverer/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,14 @@
from urlparse import urljoin
import requests
import time
from adsws.modules.oauth2server.provider import oauth2

blueprint = Blueprint(
'discoverer',
__name__,
static_folder=None,
)

class StatusView(Resource):
'''Returns the status of this app'''
def get(self):
return {'app':current_app.name,'status': 'online'}, 200

class ProxyView(Resource):
'''Proxies a request to a webservice'''

Expand All @@ -33,7 +29,6 @@ def _dispatcher(self,**kwargs):
return self.__getattribute__(request.method.lower())(ep,request)

def get(self,ep,request,**kwargs):
print "enter discoverer.get on %s" % ep
r = requests.get(ep)
return jsonify(r.json())

Expand Down
3 changes: 0 additions & 3 deletions adsws/discoverer/__init__.py

This file was deleted.

39 changes: 0 additions & 39 deletions adsws/discoverer/config.py

This file was deleted.

49 changes: 27 additions & 22 deletions adsws/tests/api_base.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

import os
import logging
import json
Expand All @@ -16,36 +15,31 @@
except ImportError:
from urllib.parse import urlparse

os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = 'True'

#logging.basicConfig(level=logging.DEBUG)


class ApiTestCase(FlaskAppTestCase):
'''Authenticate users using ADS Classic (if necessary)'''

def create_app(self):
os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = 'True'

app = api.create_app(
SQLALCHEMY_BINDS=None,
SQLALCHEMY_DATABASE_URI='sqlite://',
WTF_CSRF_ENABLED = False,
TESTING = False,
SITE_SECURE_URL='http://localhost',
SECURITY_POST_LOGIN_VIEW='/postlogin'
)

# def create_app(self):

@app.route('/postlogin')
def username():
if current_user.is_authenticated():
return current_user.email
return u'Anonymous'
# app = api.create_app(
# SQLALCHEMY_BINDS=None,
# SQLALCHEMY_DATABASE_URI='sqlite://',
# WTF_CSRF_ENABLED = False,
# TESTING = False,
# SITE_SECURE_URL='http://localhost',
# SECURITY_POST_LOGIN_VIEW='/postlogin',
# WEBSERVICES = {},
# )

@app.errorhandler(404)
def handle_404(e):
raise e

db.create_all(app=app)
return app

# db.create_all(app=app)
# return app

def parse_redirect(self, location, parse_fragment=False):
from werkzeug.urls import url_parse, url_decode, url_unparse
Expand All @@ -56,6 +50,17 @@ def parse_redirect(self, location, parse_fragment=False):
)

def setUp(self):
@self.app.route('/postlogin')
def username():
if current_user.is_authenticated():
return current_user.email
return u'Anonymous'

@self.app.errorhandler(404)
def handle_404(e):
raise e
db.create_all(app=self.app)

FlaskAppTestCase.setUp(self)

user = user_manipulator.create(email='montysolr', password='montysolr', active=True)
Expand Down
1 change: 1 addition & 0 deletions adsws/tests/stubdata_liveserver/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from app import *
93 changes: 93 additions & 0 deletions adsws/tests/stubdata_liveserver/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
from flask import Flask, jsonify, request

class Stubdata:

resources_route = {
"/GET": {
"description": "desc for resc1",
"methods": [
"GET"
],
"scopes": [],
"rate_limit": [1000,60*60*24],
},
"/POST": {
"description": "desc for resc2",
"methods": [
"POST"
],
"scopes": [],
"rate_limit": [1000,60*60*24],

},
"/GETPOST": {
"description": "desc for resc3",
"methods": [
"GET",
"POST",
],
"scopes": [],
"rate_limit": [1000,60*60*24],

},
"/SCOPED": {
"description": "desc for resc3",
"methods": [
"GET",
],
"scopes": ['this-scope-shouldnt-exist'],
"rate_limit": [1000,60*60*24],

},
"/resources": {
"description": "Overview of available resources",
"methods": [
"GET"
],
"scopes": [],
"rate_limit": [1000,60*60*24],
}
}

GET = {'resource': 'GET'}
POST = {'resource': 'POST'}
GETPOST = {
'GET': {'resource': 'GETPOST','method':'get'},
'POST': {'resource': 'GETPOST','method':'post'},
}




def create_app():
app = Flask(__name__)

@app.route('/resources')
def resources():
return jsonify(Stubdata.resources_route)

@app.route('/GET',methods=['GET'])
def get_():
return jsonify(Stubdata.GET)

@app.route('/POST',methods=['POST'])
def post_():
return jsonify(Stubdata.POST)

@app.route('/GETPOST',methods=['GET','POST'])
def getpost():
if request.method=='GET':
return jsonify(Stubdata.GETPOST['GET'])
if request.method=='POST':
return jsonify(Stubdata.GETPOST['POST'])

return app



def run():
app = create_app()
app.run(host='127.0.0.1',port=5005,processes=5,debug=False)

if __name__ == "__main__":
run()
Loading

0 comments on commit 1ec85e3

Please sign in to comment.