Polyaxon users can use the service abstraction to move from trained ML models to internal production-grade prediction APIs or to test their APIs before moving to a production framework.

This guide demonstrates how to create a simple Flask service and schedule it with Polyaxon.

Install the libraries

Your container needs to have the Flask dependencies:

pip install flask gunicorn

Creating a simple API

The following code is a simple Flask program:

from flask import Flask

app = Flask(__name__)

@app.route('/')
def index():
    return 'Index Page'

@app.route('/hello')
def hello():
    return 'Hello, World'

Polyaxon service

By default, Polyaxon exposes services with a base url following this pattern: /services/v1/namespace/owner/project/runs/uuid. In order to leverage the service kind in Polyaxon with Flask, the easiest to avoid handling base urls is by enabling the rewritePath: true flag to rewrite the path and remove that part.

Polyaxon component

This is a simple API component, the component can be more complex if it requires to initialize code, artifacts, or if it defines inputs.

version: 1.1
kind: component
name: flask-service
tags: ["flask", "api"]
run:
  kind: service
  ports: [5000]
  rewritePath: true
  container:
    image: polyaxon/polyaxon-examples:ml-serving
    command: ["sh", "-c"]
    args: ["flask run --host=0.0.0.0"]

If you need to schedule a more robust API with a production wsgi you can use gunicorn:

version: 1.1
kind: component
name: flask-service
tags: ["flask", "api"]
run:
  kind: service
  ports: [8000]
  rewritePath: true
  container:
    image: polyaxon/polyaxon-examples:ml-serving
    command: ["sh", "-c"]
    args: ["gunicorn --preload -t 60 --bind 0.0.0.0:8000 app:app"]

Example as an executable component

This inline example is intended to make it easy to execute this component without download or cloning any repo, this not intended as production pattern.

version: 1.1
kind: component
name: flask-service
tags: ["flask", "api"]
run:
  kind: service
  ports: [8000]
  rewritePath: true
  init:
    - file:
        filename: app.py
        content: |
          from flask import Flask

          app = Flask(__name__)
          
          @app.route('/')
          def index():
              return 'Index Page'
          
          @app.route('/hello')
          def hello():
              return 'Hello, World'
  container:
    image: polyaxon/polyaxon-examples:ml-serving
    workingDir: "{{ globals.artifacts_path }}"
    command: ["sh", "-c"]
    args: ["gunicorn --preload -t 60 --bind 0.0.0.0:8000 app:app"]

Scheduling the example

To schedule this component you can copy/past it to the UI and use the default values.

You can also schedule it with CLI:

polyaxon run -f api.yaml

Interacting with the API

The API can be tested directly from the UI, you also can get the url by clicking fullscreen or you can execute this CLI command to get the external service url:

polyaxon ops service --external --url

To test the endpoint using a browser the index returns a Index Page, you can also append /hello to get a different response Hello, World.

To test the endpoint using curl:

curl HOST:PORT/rewrite-services/v1/NAMESPACE/ORG/PROJECT/runs/UUID/hello --request GET \
    --header "Content-Type: application/json"

Hello, World

Authentication

For users on Polyaxon EE or Polyaxon Cloud, you will need to use:

  • A browser session with an authenticated user.
  • Add the auth header with a valid auth token: --header "Authorization: token AUTH_TOKEN".

Complete example

For a complete example from training to serving, please check the serving tutorial