# PowerML Python Package

## Installation

    pip install powerml_app

## Authentication
You will need two keys: PowerML and OpenAI.

To get a PowerML key, go to [https://staging.powerml.co/](https://staging.powerml.co/) and log in with your email. Contact our team if you are unable to log in and we'll add you!

To get an OpenAI key, go to [https://beta.openai.com/account/api-keys](https://beta.openai.com/account/api-keys).

## Configuration
In order to use this library, first create a config file at `~/.powerml/configure.yaml` with your PowerML and OpenAI keys. Here's an example:

    powerml:
        key: "<POWERML-KEY>"
    openai:
        key: "<OPENAI-KEY>"

By default, we will use these keys for the `PowerML` class:

    from powerml import PowerML
    powerml = PowerML()

You may also configure the `PowerML` class by passing in a dictionary with the following specified format

    from powerml import PowerML
    config = {"powerml": {"key": "<POWERML-KEY>"}}
    powerml = PowerML(config)


## Usage

How to use:

You can use the member functions of the PowerML class, `fit` and `predict`, to make predictions with the model and fit data to the model to improve and customize it.

    from powerml import PowerML
    config = {"powerml": {"key": "<POWERML-KEY>"}}
    powerml = PowerML(config)
    
    # Run base model
    testPrompt = "hello there"
    response = powerml.predict(prompt=testPrompt)
    
    # Fit model to data
    data = ["item2", "item3"]
    model_details = powerml.fit(data)
    
    # Use new model
    new_model_name = model_details["model_name"]
    response = powerml.predict(prompt=testPrompt, model=new_model_name)

Note that the default model is OpenAI's `text-davinci-003`. You may specify a different model in `PowerML.fit`, such as your new fitted model

    model_details = powerml.fit(data, model="<MODEL_NAME>")


### Fit

`fit` will return a dictionary object in the following format:

    {
        "model_id":"23",
        "project_id":"None",
        "user_id":"12",
        "job_id":"89",
        "model_name":"be894276039088c5f8db3f6bfaeb19953ed9ffe55f37a847a58f9fb320d307bc",
        "job_config":"{\"type\": \"prompt_tune\", \"model_name\": \"llama\"}",
        "prompt":"item2item3{{input}}",
        "creation_time":"2022-12-20 02:19:36.519260",
        "job":{
            "job_id":"89",
            "project_id":"None",
            "user_id":"12",
            "config":"{\"type\": \"prompt_tune\", \"model_name\": \"llama\"}",
            "status":"COMPLETED",
            "name":"be894276039088c5f8db3f6bfaeb19953ed9ffe55f37a847a58f9fb320d307bc",
            "metric":"None",
            "history":"None",
            "start_time":"2022-12-20 02:19:36.369450",
            "end_time":"2022-12-20 02:19:35.837668"
        }
    }

### Predict

The PowerML class can use different models you've fitted in the predictions method `predict`:

    response = powerml.predict("test", model="<MODEL_NAME>")

Without the model parameter, the default model is OpenAI's `text-davinci-003`.

## PowerML Class

The `PowerML` class has member functions `fit` and `predict`.

`predict` accepts the following arguments:

    def predict(self,
                prompt: str,
                model: str = "",
                stop: str = "",
                max_tokens: int = 128,
                temperature: int = 0,
                ) -> str:

`fit` accepts the following arguments:

    def fit(self,
            data: list[str],
            model: str = ""):

## PowerMLTopicModel Class

The `PowerMLTopicModel` class is an example class designed to extract topics from the prompt.

### Usage

    def get_examples():
        examples_path = os.path.join(os.path.dirname(__file__), "examples.json")
        with open(examples_path) as examples_file:
            examples = json.load(examples_file)
        return examples

    def get_topics():
        return ["vscode","web","dashboard"]
    
    config = {"powerml": {"key": "<POWERML-KEY>"}}
    model = PowerMLTopicModel(get_topics(), config)
    examples = get_examples()
    model.fit(examples)
    topics = model.predict("Move invite teammates page to its own base route . per designs:   This PR just moves existing views around and adds a new base route (i.e. no new functionality)")
    print("topics:", topics)

### Methods

`__init__` is defined as follows:

    def __init__(self, topics: list[str], config={}):

`fit` is defined as follows:

    def fit(self, 
            examples: list[
                {"example": str, "labels": list[str]}
            ]):

where examples is a list of dictionaries with format `{"example": str, "labels": list[str]}`.

`predict` is defined as follows:

    def predict(self, prompt: str):

## PowerMLLearnTopics Class

The `PowerMLLearnTopics` class is an example class designed to generate topics from a list of documents.

### Usage

    model = PowerMLLearnTopics()
    model.add_data(list_of_docs)

    topics = model.get_topics()
    print(topics)

### Methods

`__init__` is defined as follows:

    def __init__(self, config={}, num_subsamples=100, sample_size=50):

`add_data` is defined as follows:

    def add_data(self, documents):

where documents is a list of strings.

`get_topics` is defined as follows:

    def get_topics(self):

and returns a set of strings

`get_filtered_topics` is defined as follows:

    def get_topics(self):

and returns a set of strings.