def __init__(self, name: str = "tasks"): super().__init__(name) configure_logging(self) @self.route("/", methods=["GET"]) def tasks(): tasks = get_tasks() return flask.jsonify(tasks)
def __init__(self, name: str = "info"): super().__init__(name) configure_logging(self) cache = Cache(config={"CACHE_TYPE": "simple"}) cache.init_app(self) # We'll re-use a single HTTP Session to make all of the info requests to our # our model endpoints. # We set `pool_maxsize` to 100 so that the pool can handle all of the model # requests concurrently, potentially from several different incoming requests # at once. self.session = Session() adapter = adapters.HTTPAdapter(pool_maxsize=100) self.session.mount("https://", adapter) @self.route("/", methods=["GET"]) @cache.cached(timeout=10) def info(): client = kubernetes.client.ExtensionsV1beta1Api() resp = client.list_ingress_for_all_namespaces( label_selector="app=allennlp-demo") # Gather endpoints. endpoints: List[Endpoint] = [] info_requests: List[grequests.AsyncRequest] = [] for ingress in resp.items: endpoint = ingress.metadata.labels.get("endpoint") # We only really want information about the model endpoints, so skip everything # else. if (endpoint == "info" or endpoint == "tasks" or endpoint == "model-cards" or endpoint == "permalinks"): continue endpoint = Endpoint.from_ingress(ingress) if endpoint is not None: endpoints.append(endpoint) info_requests.append( grequests.request("GET", endpoint.url, session=self.session)) # Now join the info HTTP requests concurrently. for endpoint, info_resp in zip( endpoints, grequests.map(info_requests, exception_handler=self.exception_handler), ): if not info_resp: continue endpoint.info = info_resp.json() return flask.jsonify(endpoints)
def __init__(self, name: str = "model-cards"): super().__init__(name) configure_logging(self) # We call this once and cache the results. It takes a little memory (~4 MB) but makes # everything a lot faster. self.cards_by_id = get_pretrained_models() @self.route("/", methods=["GET"]) def all_model_cards(): cards: Dict[str, Dict] = {} for id, card in self.cards_by_id.items(): cards[id] = card.to_dict() return flask.jsonify(cards)
def __init__(self, name: str = "tasks"): super().__init__(name) configure_logging(self) @self.route("/", methods=["GET"]) def tasks(): params = { "id": "ner", "name": "Negation", "description": "Negation is the tasks of detecting a negation keyword and its corresponding scope.", "expected_inputs": "The task expects an input sentence.", "expected_outputs": "The output is all the identified named entities (which can be one or more words) in the text.", "scope_and_limitations": None, "examples": [{ "sentence": "This shirt was bought at Grandpa Joe's in downtown Deep Learning." }, { "sentence": "AllenNLP is a PyTorch-based natural language processing library developed at the Allen Institute for Artificial Intelligence in Seattle." }, { "sentence": "Did Uriah honestly think he could beat The Legend of Zelda in under three hours?" }, { "sentence": "Michael Jordan is a professor at Berkeley." }, { "sentence": "My preferred candidate is Cary Moon, but she won't be the next mayor of Seattle." }, { "sentence": "If you like Paul McCartney you should listen to the first Wings album." }, { "sentence": "When I told John that I wanted to move to Alaska, he warned me that I'd have trouble finding a Starbucks there." }, { "sentence": "This is a negation sentence for the demo, wait, no it isn't. Hi Michael Jordan." }], } tasks = get_tasks() nerparams = Params(params) tasks['ner'] = TaskCard.from_params(nerparams) return flask.jsonify(tasks)
def configure_logging(self) -> None: configure_logging(self.app)
def __init__(self, name: str = "permalinks", db: Optional[DemoDatabase] = None): super().__init__(name) configure_logging(self) self.db = db if db is None: self.logger.warning("No database, permalinks are disabled.") @self.errorhandler(BadRequest) def handle_400(err: BadRequest): return jsonify({"error": str(err)}), 400 @self.errorhandler(InternalServerError) def handle_500(err: InternalServerError) -> Response: self.logger.error(err) return jsonify({"error": "Something went wrong."}), 500 @self.route("/", methods=["GET"]) def info(): """ The simplest of info routes. We can add more here later. """ return jsonify({"id": "permalinks"}) @self.route("/<string:slug>") def get_permalink(slug: str) -> Response: """ Find a permalink by slug. """ # If we don't have a database configured, there are no permalinks. if self.db is None: raise BadRequest("Permalinks are not enabled") link_id = slug_to_int(slug) if link_id is None: # Malformed slug raise BadRequest(f"Unrecognized permalink: {slug}") # Fetch the results from the database. try: link = self.db.get_result(link_id) except psycopg2.Error: self.logger.exception( f"Unable to get results from database: {link_id}") raise InternalServerError("Database error") if link is None: raise NotFound(f"Permalink not found: {slug}") return jsonify(link._asdict()) @self.route("/", methods=["POST"]) def create_permalink() -> Response: """ Creates a new permalink. """ # If we don't have a database configured, there are no permalinks. if self.db is None: raise BadRequest("Permalinks are not enabled") request_data = request.json.get("request_data") if not request_data: raise BadRequest("Invalid request_data") # Old models send this field. New models do not. # TODO: Remove this once all models use the new serving mechanism. model_name = request.json.get("model_name") # New models send these fields, but old models do not. # TODO: Once all models are served via the new mechanism these should be required. model_id = request.json.get("model_id") task_name = request.json.get("task_name") try: id = self.db.insert_request( model_name=model_name, request_data=request_data, model_id=model_id, task_name=task_name, ) return jsonify(int_to_slug(id)) except psycopg2.Error as err: self.logger.exception("Error saving permalink: %s", err) raise InternalServerError("Unable to create permalink") # noop post for image upload, we need an endpoint, but we don't need to save the image @self.route("/noop", methods=["POST"]) def noop(): return ""
def configure_logging(self, log_payloads: bool = False) -> None: configure_logging(self.app, log_payloads=log_payloads)