Skip to content

Commit

Permalink
chore: add Flask openai example (#941)
Browse files Browse the repository at this point in the history
* 'Refactored by Sourcery'

* chore: add Flask html example

* chore: add Flask openai example

* sourcery refactor integration tests

* fix: Flask package install set to optional

---------

Co-authored-by: Sourcery AI <>
  • Loading branch information
aloha-fim authored Feb 19, 2024
1 parent 66945fd commit 53928a5
Show file tree
Hide file tree
Showing 13 changed files with 252 additions and 257 deletions.
47 changes: 47 additions & 0 deletions examples/templates/sample_flask_salaries.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{% block content %}

<!DOCTYPE html>
<html lang="en">
<head>
<title>Pandas AI</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
</head>
<body>

<div class="container">
<h2>Pandas AI</h2>
<br>
<form class="form-horizontal" action="/pandasai" method="POST" enctype="multipart/form-data">
<div class="form-group">
<label class="control-label col-sm-2" for="query">Input:</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="query" placeholder="Enter Query" name="query" required>
</div>
</div>
<br>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" value="Submit" class="btn btn-default">Submit</button>
</div>
</div>
</form>
{% if response %}
<div class="card border-info mb-3" style="max-width: 18rem;">
<div class="card-header">
Pandas AI Discovery
</div>
<div class="card-body text-info">
<p class="card-text">{{ response }}</p>
</div>
</div>
{% endif %}
</div>

</body>
</html>

{% endblock %}
64 changes: 64 additions & 0 deletions examples/using_flask.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
"""
Example of using displaying PandasAI charts in Flask
Usage:
flask –-app using_flask.py run
"""
import pandas as pd
from flask import Flask, render_template, request

from pandasai import SmartDatalake
from pandasai.llm import OpenAI
from pandasai.responses.response_parser import ResponseParser

app = Flask(__name__)


# This class overrides default behaviour how dataframe is returned
# By Default PandasAI returns the SmartDataFrame
class PandasDataFrame(ResponseParser):
def __init__(self, context) -> None:
super().__init__(context)

def format_dataframe(self, result):
# Returns Pandas Dataframe instead of SmartDataFrame
return result["value"]


employees_df = pd.DataFrame(
{
"EmployeeID": [1, 2, 3, 4, 5],
"Name": ["John", "Emma", "Liam", "Olivia", "William"],
"Department": ["HR", "Sales", "IT", "Marketing", "Finance"],
}
)

salaries_df = pd.DataFrame(
{
"EmployeeID": [1, 2, 3, 4, 5],
"Salary": [5000, 6000, 4500, 7000, 5500],
}
)

llm = OpenAI("OPENAI-KEY")
dl = SmartDatalake(
[employees_df, salaries_df],
config={"llm": llm, "verbose": True, "response_parser": PandasDataFrame},
)


@app.route("/pandasai", methods=["GET", "POST"])
def pandasai():
if request.method == "POST":
# prompt question such as "Return a dataframe of name against salaries"
query = request.form["query"]
response = dl.chat(query)

# Returns the response as Pandas DataFrame object in html
return render_template("sample_flask_salaries.html", response=response)

return render_template("sample_flask_salaries.html")


if __name__ == "__main__":
app.run()
2 changes: 1 addition & 1 deletion pandasai/connectors/airtable.py
Original file line number Diff line number Diff line change
Expand Up @@ -271,5 +271,5 @@ def column_hash(self):
if not isinstance(self._instance, pd.DataFrame):
self._instance = self.execute()
columns_str = "|".join(self._instance.columns)
columns_str += "WHERE" + self._build_formula()
columns_str += f"WHERE{self._build_formula()}"
return hashlib.sha256(columns_str.encode("utf-8")).hexdigest()
2 changes: 1 addition & 1 deletion pandasai/helpers/anonymizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def _generate_random_email() -> str:
domain = random.choice(domains)
letters = string.ascii_lowercase + string.digits + "-_"
username = "".join(random.choice(letters) for _ in range(name_length))
return f"{username}@" + domain
return f"{username}@{domain}"

@staticmethod
def _generate_random_phone_number(original: str) -> str:
Expand Down
2 changes: 1 addition & 1 deletion pandasai/helpers/code_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ def execute_code(self, code: str, context: CodeExecutionContext) -> Any:
code,
logger=self._logger,
file_name="temp_chart",
save_charts_path_str=find_project_root() + "/exports/charts",
save_charts_path_str=f"{find_project_root()}/exports/charts",
)

# Reset used skills
Expand Down
2 changes: 1 addition & 1 deletion pandasai/helpers/df_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ def _df_to_list_of_dict(self, df: DataFrameType, dataframe_type: str) -> List[Di
Returns:
list of dict of dataframe rows
"""
if dataframe_type in ("pandas", "modin"):
if dataframe_type in {"pandas", "modin"}:
return df.to_dict(orient="records")
elif dataframe_type == "polars":
return df.to_dicts()
Expand Down
2 changes: 1 addition & 1 deletion pandasai/skills/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ def _make_skill(skill_fn: Callable) -> Skill:
elif len(args) == 1 and callable(args[0]):
# Example: @skill
return _make_skill_with_name(args[0].__name__)(args[0])
elif len(args) == 0:
elif not args:
# Covers the case in which a function is decorated with "@skill()"
# with the intended behavior of "@skill"
def _func_wrapper(fn: Callable) -> Skill:
Expand Down
13 changes: 6 additions & 7 deletions pandasai/smart_dataframe/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
```python
from pandasai.smart_dataframe import SmartDataframe
from pandasai.llm.openai import OpenAI
df = pd.read_csv("examples/data/Loan payments data.csv")
llm = OpenAI()
df = SmartDataframe(df, config={"llm": llm})
response = df.chat("What is the average loan amount?")
print(response)
Expand All @@ -20,7 +20,6 @@

import hashlib
import uuid
import warnings
from functools import cached_property
from io import StringIO
from typing import Any, List, Optional, Union
Expand Down Expand Up @@ -398,7 +397,7 @@ def _truncate_head_columns(self, df: DataFrameType, max_size=25) -> DataFrameTyp
if df[col].dtype == "object":
first_val = df[col].iloc[0]
if isinstance(first_val, str) and len(first_val) > max_size:
df_trunc[col] = df_trunc[col].str.slice(0, max_size - 3) + "..."
df_trunc[col] = f"{df_trunc[col].str.slice(0, max_size - 3)}..."
elif engine == "polars":
try:
import polars as pl
Expand All @@ -409,9 +408,9 @@ def _truncate_head_columns(self, df: DataFrameType, max_size=25) -> DataFrameTyp
if df[col].dtype == pl.Utf8:
first_val = df[col][0]
if isinstance(first_val, str) and len(df_trunc[col]) > max_size:
df_trunc[col] = (
df_trunc[col].str.slice(0, max_size - 3) + "..."
)
df_trunc[
col
] = f"{df_trunc[col].str.slice(0, max_size - 3)}..."
except ImportError as e:
raise ImportError(
"Polars is not installed. "
Expand Down
Loading

0 comments on commit 53928a5

Please sign in to comment.