예제 #1
0
    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)
예제 #2
0
    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)
예제 #3
0
    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)
예제 #4
0
    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)
예제 #5
0
 def configure_logging(self) -> None:
     configure_logging(self.app)
예제 #6
0
    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 ""
예제 #7
0
 def configure_logging(self, log_payloads: bool = False) -> None:
     configure_logging(self.app, log_payloads=log_payloads)