def wsgi_app(self, environ, start_response): """Execute this instance as a WSGI application. See the PEP for the meaning of parameters. The separation of __call__ and wsgi_app eases the insertion of middlewares. """ original_response = Response.from_app(self.wrapped_app, environ) # We send relative locations to play nice with reverse proxies # but Werkzeug by default turns them into absolute ones. original_response.autocorrect_location_header = False if self.DIGEST_HEADER not in original_response.headers: return original_response digest = original_response.headers.pop(self.DIGEST_HEADER) filename = original_response.headers.pop(self.FILENAME_HEADER, None) mimetype = original_response.mimetype try: fobj = self.file_cacher.get_file(digest) size = self.file_cacher.get_size(digest) except KeyError: return NotFound() except TombstoneError: return ServiceUnavailable() request = Request(environ) request.encoding_errors = "strict" response = Response() response.status_code = 200 response.mimetype = mimetype if filename is not None: response.headers.add( "Content-Disposition", "attachment", filename=filename) response.set_etag(digest) response.cache_control.max_age = SECONDS_IN_A_YEAR response.cache_control.private = True response.response = \ wrap_file(environ, fobj, buffer_size=FileCacher.CHUNK_SIZE) response.direct_passthrough = True try: # This takes care of conditional and partial requests. response.make_conditional( request, accept_ranges=True, complete_length=size) except HTTPException as exc: return exc return response
def _get_job_log(self, id): # pragma: no cover logger.debug('getting logs for validation id {}'.format(id)) # if we got no BEARER_TOKEN, we use local config if self.BEARER_TOKEN is None: config.load_kube_config() else: config.load_incluster_config() _client = client.CoreV1Api() try: # 1. lets get the pod that ran our job _resp = _client.list_namespaced_pod( namespace=THOTH_DEPENDENCY_MONKEY_NAMESPACE ) # , label_selector='job-name=validation-id-'+str(id)) for pod in _resp.items: if 'job-name' in pod.metadata.labels.keys(): logger.debug('found a Validation Job: {}'.format( pod.metadata.labels['job-name'])) # TODO this may be more than one Pod (because it failed or so...) if pod.metadata.labels['job-name'].endswith(str(id)): _log = _client.read_namespaced_pod_log( pod.metadata.name, namespace=THOTH_DEPENDENCY_MONKEY_NAMESPACE, pretty=True) return _log except client.rest.ApiException as e: logger.error(e) if e.status == 403: raise ServiceUnavailable('OpenShift auth failed') raise ServiceUnavailable('OpenShift')
def _get_all_scheduled_validation_job(self): # pragma: no cover logger.debug('looking for all validations') result = [] # if we got no BEARER_TOKEN, we use local config if self.BEARER_TOKEN is None: config.load_kube_config() else: config.load_incluster_config() _client = client.CoreV1Api() _api = client.BatchV1Api() try: _resp = _api.list_namespaced_job( namespace=THOTH_DEPENDENCY_MONKEY_NAMESPACE) # if we got a none empty list of jobs, lets filter the ones out that belong to us... if not _resp.items is None: for job in _resp.items: if job.metadata.name.startswith(VALIDATION_JOB_PREFIX): result.append(job) except client.rest.ApiException as e: logger.error(e) if e.status == 403: raise ServiceUnavailable('OpenShift auth failed') raise ServiceUnavailable('OpenShift') except IndexError as e: logger.debug('we got no jobs...') return [] return result
def user_suggested(username): """ Returns movie suggestions. The algorithm returns a list of 3 top ranked movies that the user has not yet booked. :param username: :return: Suggested movies """ print 'user_suggested' response = requests.get('http://localhost:5001/movies/rank/{}'.format(username)) print 'responsed' if response.status_code == 200: return nice_json(response.json()) else: raise ServiceUnavailable("The Movies Service is unavailable")
def destroy_db(): conn = connection() curr = conn.cursor() blacklist = """DROP TABLE IF EXISTS blacklist CASCADE; """ users = """DROP TABLE IF EXISTS users CASCADE; """ queries = [blacklist, users] try: for query in queries: curr.execute(query) conn.commit() except: raise ServiceUnavailable( "OOPS!! We cannot reach the database server at the moment")
def get_summary_data(mbid): """Fetches the lowlevel and highlevel features from abz database for the specified MBID.""" summary = {} mbid = str(mbid) conn = psycopg2.connect(current_app.config['PG_CONNECT']) cur = conn.cursor() try: cur.execute("SELECT data FROM lowlevel WHERE mbid = %s", (mbid, )) if not cur.rowcount: raise NoDataFoundException( "No data for the track in acousticbrainz database") row = cur.fetchone() lowlevel = row[0] if 'artist' not in lowlevel['metadata']['tags']: lowlevel['metadata']['tags']['artist'] = ["[unknown]"] if 'release' not in lowlevel['metadata']['tags']: lowlevel['metadata']['tags']['release'] = ["[unknown]"] if 'title' not in lowlevel['metadata']['tags']: lowlevel['metadata']['tags']['title'] = ["[unknown]"] # Format track length readably (mm:ss) lowlevel['metadata']['audio_properties']['length_formatted'] = \ time.strftime("%M:%S", time.gmtime(lowlevel['metadata']['audio_properties']['length'])) summary['lowlevel'] = lowlevel cur.execute( "SELECT hlj.data " "FROM highlevel hl, highlevel_json hlj " "WHERE hl.data = hlj.id " "AND hl.mbid = %s", (mbid, )) if cur.rowcount: row = cur.fetchone() highlevel = row[0] summary['highlevel'] = highlevel try: summary['genres'], summary['moods'], summary[ 'other'] = interpret_high_level(highlevel) except KeyError: pass return summary except psycopg2.IntegrityError as e: raise BadRequest(e) except psycopg2.OperationalError as e: raise ServiceUnavailable(e) return InternalServerError("whoops!")
def get(self): ''' return a list of all users with details about them ''' try: users = User.query.all() except: raise ServiceUnavailable('Database error') user_list = [self.user_details(user.username) for user in users] response = make_response(json.dumps(user_list, cls=DecimalEncoder)) response.headers['content-type'] = 'application/json' return response
def user_bookings(username): """ Gets booking information from the 'Bookings Service' for the user, and movie ratings etc. from the 'Movie Service' and returns a list. :param username: :return: List of Users bookings """ if username not in users: raise NotFound("User '{}' not found.".format(username)) try: users_bookings = requests.get("http://127.0.0.1:5003/bookings/{}".format(username)) except requests.exceptions.ConnectionError: raise ServiceUnavailable("The Bookings service is unavailable.") if users_bookings.status_code == 404: raise NotFound("No bookings were found for {}".format(username)) users_bookings = users_bookings.json() # For each booking, get the rating and the movie title result = {} for date, movies in users_bookings.iteritems(): result[date] = [] for movieid in movies: try: movies_resp = requests.get("http://127.0.0.1:5001/movies/{}".format(movieid)) except requests.exceptions.ConnectionError: raise ServiceUnavailable("The Movie service is unavailable.") movies_resp = movies_resp.json() result[date].append({ "title": movies_resp["title"], "rating": movies_resp["rating"], "uri": movies_resp["uri"] }) return nice_json(result)
def _process(self, action, comment): confirm_editable_changes(self.revision, session.user, action, comment) service_url = editing_settings.get(self.event, 'service_url') publish = True if service_url: try: resp = service_handle_review_editable(self.editable, session.user, action, self.revision) publish = resp.get('publish', True) except ServiceRequestFailed: raise ServiceUnavailable(_('Failed processing review, please try again later.')) if publish and action == EditingConfirmationAction.accept: publish_editable_revision(self.revision) return '', 204
def handle_error(response): if response.status_code == BadRequest.code: raise BadRequest(_get_response_message(response)) elif response.status_code == Forbidden.code: raise Forbidden(_get_response_message(response)) elif response.status_code == InternalServerError.code: raise InternalServerError(_get_response_message(response)) elif response.status_code == NotFound.code: raise NotFound(_get_response_message(response)) elif response.status_code == ServiceUnavailable.code: raise ServiceUnavailable(_get_response_message(response)) elif response.status_code == Unauthorized.code: raise Unauthorized(_get_response_message(response)) response.raise_for_status()
def count_lowlevel(mbid): """Count number of stored datasets for a specified MBID.""" conn = psycopg2.connect(current_app.config['PG_CONNECT']) cur = conn.cursor() try: cur.execute("SELECT count(*) FROM lowlevel WHERE mbid = %s", (str(mbid), )) return cur.fetchone()[0] except psycopg2.IntegrityError as e: raise BadRequest(e) except psycopg2.OperationalError as e: raise ServiceUnavailable(e) return InternalServerError("Ouch!")
def movie_remove(): if request.method == 'POST': record = request.form['mid'] data = { 'db': request.form['db'], 'tn': request.form['tn'], 'id': record } print("posting :" + str(data)) try: r = requests.post("http://127.0.0.1:5000/deletebyid", data=data) except requests.exceptions.ConnectionError: raise ServiceUnavailable("The Movie service is unavailable.") return r.text return render_template("removmovie.html")
def user_bookings(user_id) -> Dict: """ This endpoint request the bookings microservices to fetch bookings done by pass user and further requests movies microservices to fetch movie details :param user_id: :return: Dict user bookings """ try: bookings_resp = requests.get( 'http://127.0.0.1:5001/bookings/{user}'.format(user=user_id)) except requests.exceptions.ConnectionError: raise ServiceUnavailable('Bookings service is not available') if bookings_resp.status_code == 404: raise NotFound('No bookings found for this user') bookings_data = bookings_resp.json() show_result = {} for date, movies in bookings_data.items(): show_result[date] = [] for movie_id in movies: try: movies_resp = requests.get( 'http://127.0.0.1:5002/movies/{movie}'.format( movie=movie_id)) except requests.exceptions.ConnectionError: raise ServiceUnavailable('Movies service is not available') movie_data = movies_resp.json() show_result[date].append({ "title": movie_data["title"], "rating": movie_data["rating"], "director": movie_data["director"] }) return json.dumps(show_result, indent=4)
def ws_drink(drink): mixer = app.mixer if app.options.must_login_to_dispense and not current_user.is_authenticated( ): return "login required" recipe = {} for arg in request.args: recipe[arg] = int(request.args.get(arg)) if mixer.make_drink(drink, recipe): return "ok\n" else: raise ServiceUnavailable("Error: %s (%d)" % (mixer.get_error(), ret))
def ordermovie(): record = str( {request.form['mid'], request.form['uid'], request.form['date']}) data = { 'db': request.form['db'], 'tn': request.form['tn'], 'record': record } try: print(data) r = requests.post("http://127.0.0.1:5000/add_record", data=data) print(r.reason) except requests.exceptions.ConnectionError: raise ServiceUnavailable("The Movie service is unavailable.") return r.text
def __post__(self, xml): http = httplib2.Http() http.add_credentials(self.username, self.pw) response, content = http.request( self.endpoint, method="POST", headers={'Content-type': 'application/xml'}, body=xml) if response['status'] != '201': raise ServiceUnavailable( 'Mayolink service unavailable, please re-try later') result = self._xml_to_dict(content) return result
def ws_make_drink(drink, speed): recipe = {} for arg in request.args: disp = int(arg[5:]) recipe[disp] = int(request.args.get(arg)) if app.mixer.get_state() == STATE_ERROR: raise InternalServerError try: err = app.mixer.make_drink(drink, recipe, speed) if not err: return "ok\n" else: raise BadRequest(err) except mixer.BartendroBusyError: raise ServiceUnavailable("busy")
def _process(self): args = parser.parse({ 'files': EditingFilesField(self.event, self.contrib, self.editable_type, allow_claimed_files=True, required=True) }) service_url = editing_settings.get(self.event, 'service_url') new_revision = create_submitter_revision(self.revision, session.user, args['files']) if service_url: try: service_handle_review_editable(self.editable, session.user, EditingReviewAction.update, self.revision, new_revision) except ServiceRequestFailed: raise ServiceUnavailable(_('Failed processing review, please try again later.')) return '', 204
def login(): if request.method == 'POST': p = " names = '"+request.form['uname']+"' and pass = '******'pass']+"'" data = {'db': request.form['db'], 'tn': request.form['tn'],'pr': p} print(data) try: r = requests.post("http://127.0.0.1:5000/dologin",data=data) print(r.text) if r.text == str(True): session['uname'] = request.form['uname'] return redirect(url_for('save')) else: return "wrong credintials" except requests.exceptions.ConnectionError: raise ServiceUnavailable("The Movie service is unavailable.") return render_template("login.html")
def add(): """Endpoint for adding new mappings to Spotify. Only connection to albums on Spotify is supported right now. JSON parameters: user: UUID of the user who is adding new mapping. mbid: MusicBrainz ID of an entity that is being connected. spotify_uri: Spotify URI of an album that is being connected. """ user = request.json["user"] if not validate_uuid(user): raise BadRequest("Incorrect user ID (UUID).") mbid = request.json["mbid"] if not validate_uuid(mbid): raise BadRequest("Incorrect MBID (UUID).") uri = request.json["spotify_uri"] if not uri.startswith("spotify:album:"): raise BadRequest( "Incorrect Spotify URI. Only albums are supported right now.") conn = psycopg2.connect(**current_app.config["PG_INFO"]) cur = conn.cursor() try: # Checking if mapping is already created cur.execute( "SELECT id FROM mapping " "WHERE is_deleted = FALSE " "AND mbid = %s " "AND spotify_uri = %s", (mbid, uri)) if not cur.rowcount: # and if it's not, adding it cur.execute( "INSERT INTO mapping (mbid, spotify_uri, cb_user, is_deleted)" "VALUES (%s, %s, %s, FALSE)", (mbid, uri, user)) conn.commit() except psycopg2.IntegrityError as e: raise BadRequest(str(e)) except psycopg2.OperationalError as e: raise ServiceUnavailable(str(e)) response = Response() response.headers["Access-Control-Allow-Origin"] = "*" return response
def create(musicbrainz_id): try: connection = psycopg2.connect(current_app.config['PG_CONNECT']) cursor = connection.cursor() # TODO(roman): Do we need to make sure that musicbrainz_id is case insensitive? cursor.execute( 'INSERT INTO "user" (musicbrainz_id) VALUES (%s) RETURNING id', (musicbrainz_id, )) connection.commit() new_id = cursor.fetchone()[0] except psycopg2.ProgrammingError as e: raise BadRequest(e) except psycopg2.IntegrityError as e: raise BadRequest(e) except psycopg2.OperationalError as e: raise ServiceUnavailable(e) return new_id
def add_movie(): if request.method == 'POST': record = str({ request.form['title'], request.form['director'], request.form['rating'] }) data = { 'db': request.form['db'], 'tn': request.form['tn'], 'record': record } print("posting :" + str(data)) try: r = requests.post("http://127.0.0.1:5000/add_record", data=data) except requests.exceptions.ConnectionError: raise ServiceUnavailable("The Movie service is unavailable.") return r.text return render_template("addmovie.html")
def _process(self): if self.editable: raise UserValueError(_('Editable already exists')) args = parser.parse({ 'files': EditingFilesField(self.event, self.contrib, self.editable_type, required=True) }) service_url = editing_settings.get(self.event, 'service_url') initial_state = InitialRevisionState.new if service_url else InitialRevisionState.ready_for_review editable = create_new_editable(self.contrib, self.editable_type, session.user, args['files'], initial_state) if service_url: try: service_handle_new_editable(editable, session.user) except ServiceRequestFailed: raise ServiceUnavailable(_('Submission failed, please try again later.')) return '', 201
def db_session() -> scoped_session: """Provide a transactional scope around a series of operations.""" try: yield db.session db.session.commit() except SQLAlchemyError as e: db.session.rollback() print_exc_info() if isinstance(e, IntegrityError): raise AbortError(HTTPStatus.UNPROCESSABLE_ENTITY, "Conflicts with existing entry or " "constraint condition not met") else: raise ServiceUnavailable() finally: db.session.close()
def publish_transaction(channel, tr_type, payload): conf_db = get_conf_db() if tr_type not in ["insert", "delete"]: raise ValueError("Unknown transaction type", tr_type) subscribed = conf_db.scard("Subscriptions:%s:ActiveAnalytics" % channel) if subscribed == 0: raise NotFound(("Channel not found", "Channel '%(channel)s' is not found or has 0 " "subscriptions" % locals())) listened = conf_db.publish( channel, '{' ' "tr_type" : "' + tr_type + '", ' ' "payload" : ' + payload + '}') if listened != subscribed: raise ServiceUnavailable( ("Subscription-Listened mismatch", "Listened count = %d doesn't match Subscribed count = %d" % (listened, subscribed)))
def get(self): ''' return a list of all billing plans available to users ''' try: billingPlans = BillingPlan.query.all() except: raise ServiceUnavailable('Database error') billing_plan_list = [{ column.name: str(getattr(bp, column.name)) for column in bp.__table__.columns } for bp in billingPlans] response = make_response( json.dumps(billing_plan_list, cls=DecimalEncoder)) response.headers['content-type'] = 'application/json' return response
def put(self, username): ''' edit data regarding the user with username "username" body of request should contain: - "password" (string, optional) - "email" (string, optional) - "is_admin" (bool, optional) - "quota" (int, optional) ''' args = self.parser.parse_args() password = args['password'] email = args['email'] is_admin = args['is_admin'] quota = args['quota'] try: # check if user exists user = User.query.filter_by(username=username).first() # update user fields updated_fields = {} if password is not None: user.password = password updated_fields['password (hash)'] = user.password_hash.decode( 'ascii') if email is not None: user.email = email updated_fields['email'] = email if is_admin is not None: user.is_admin = is_admin updated_fields['is_admin'] = is_admin if quota is not None: user.max_quota = quota updated_fields['max quota'] = quota db.session.commit() except: db.session.rollback() raise ServiceUnavailable('Database error') return make_response({ 'username': username, 'updated fields': updated_fields })
def error_router(self, original_handler, e): logger = log.getLogger() if isinstance(e, HTTPException): logger.error(str(e)) elif isinstance(e, OperationalError): logger.error(str(e)) raise ServiceUnavailable( "Request canceled due to statement timeout") else: logger.exception("Unhandled exception occurred") # Handle all exceptions using handle_error, not only for owned routes try: return self.handle_error(e) except Exception: logger.exception("Exception from handle_error occurred") pass # If something went wrong - fallback to original behavior return super().error_router(original_handler, e)
def postTransaction(fromAccNum, toAccNum, amount): try: url = TRANSACTIONS_SERVICE_URL + 'transactions' payload = { 'fromAccNum': fromAccNum, 'toAccNum': toAccNum, 'amount': amount } res = requests.post(url, json=payload) except ConnectionError as e: raise ServiceUnavailable("Transactions service connection error: %s." % e) if res.status_code != codes.ok: raise NotFound("Cannot post a transaction from " + \ "%s to %s amount %s, resp %s, status code %s" \ % (fromAccNum, toAccNum, amount, res.text, res.status_code)) else: return res.json()['number']
def users(name, email): if not name and not email: abort( 422, messages={ 'name': ['name or email must be provided'], 'email': ['name or email must be provided'], }, ) if current_app.config['SKIP_LOGIN']: res = [x for x in _generate_fake_users() if _match(x, name, email)] total, data = len(res), res[:10] elif not current_app.config['MULTIPASS_IDENTITY_PROVIDER_SEARCH']: raise ServiceUnavailable('Search is not available') else: total, data = search_users(name, email, 10) return { 'total': total, 'users': UserSearchResultSchema(many=True).dump(data), }