Skip to content

Commit 8f0207a

Browse files
committed
Initial commit: Plexe Python client library
0 parents  commit 8f0207a

7 files changed

Lines changed: 291 additions & 0 deletions

File tree

‎.gitignore‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
__pycache__/
2+
*.py[cod]
3+
*$py.class
4+
*.so
5+
.Python
6+
build/
7+
develop-eggs/
8+
dist/
9+
downloads/
10+
eggs/
11+
.eggs/
12+
lib/
13+
lib64/
14+
parts/
15+
sdist/
16+
var/
17+
wheels/
18+
*.egg-info/
19+
.installed.cfg
20+
*.egg
21+
MANIFEST
22+
.env
23+
.venv
24+
env/
25+
venv/
26+
ENV/
27+
env.bak/
28+
venv.bak/
29+
.idea/
30+
.vscode/
31+
plexe/__pycache__

‎Makefile‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
.PHONY: install clean build publish
2+
3+
install:
4+
pip install -e .
5+
6+
clean:
7+
rm -rf build/ dist/ *.egg-info __pycache__
8+
find . -type d -name __pycache__ -exec rm -rf {} +
9+
10+
build: clean
11+
python -m build
12+
13+
publish: build
14+
python -m twine upload dist/*
15+
16+
# Update version like: make version VERSION=0.1.1
17+
version:
18+
sed -i 's/version="[0-9.]*"/version="$(VERSION)"/' setup.py

‎README.md‎

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Plexe
2+
3+
Create ML models from natural language descriptions.
4+
5+
## Installation
6+
7+
```bash
8+
pip install plexe
9+
```
10+
11+
## Usage
12+
13+
First, set your API key:
14+
```bash
15+
export PLEXE_API_KEY=your_api_key_here
16+
```
17+
18+
Then use it in your code:
19+
20+
```python
21+
import plexe
22+
23+
# Create a model
24+
model_id, version, desc = plexe.create(
25+
"Create a model that predicts sentiment from text"
26+
)
27+
28+
# Make predictions
29+
result = plexe.run(
30+
model_id=model_id,
31+
text_input="This product is amazing!"
32+
)
33+
print(result)
34+
35+
# Batch predictions
36+
results = plexe.batch_run(
37+
model_id=model_id,
38+
inputs=[
39+
{"text": "This is great"},
40+
{"text": "This is terrible"}
41+
]
42+
)
43+
44+
# Async support
45+
async def main():
46+
model_id, version, desc = await plexe.acreate(
47+
"Create a classifier for text"
48+
)
49+
result = await plexe.arun(model_id, text_input="Test")
50+
```

‎plexe/__init__.py‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
from .client import PlexeClient
2+
3+
def create(task_description: str, api_key: str = "") -> tuple[str, int, str]:
4+
"""Create a new ML model."""
5+
client = PlexeClient(api_key=api_key)
6+
return client.create(task_description=task_description)
7+
8+
async def acreate(task_description: str, api_key: str = "") -> tuple[str, int, str]:
9+
"""Create a new ML model asynchronously."""
10+
client = PlexeClient(api_key=api_key)
11+
return await client.acreate(task_description=task_description)
12+
13+
def run(model_id: str, text_input: str = "", version: int = -1, api_key: str = "") -> dict:
14+
"""Run predictions using a model."""
15+
client = PlexeClient(api_key=api_key)
16+
return client.run(model_id=model_id, text_input=text_input, version=version)
17+
18+
async def arun(model_id: str, text_input: str = "", version: int = -1, api_key: str = "") -> dict:
19+
"""Run predictions using a model asynchronously."""
20+
client = PlexeClient(api_key=api_key)
21+
return await client.arun(model_id=model_id, text_input=text_input, version=version)
22+
23+
def batch_run(model_id: str, inputs: list, version: int = -1, api_key: str = "") -> list:
24+
"""Run batch predictions."""
25+
client = PlexeClient(api_key=api_key)
26+
return client.batch_run(model_id=model_id, inputs=inputs, version=version)
27+
28+
__all__ = ['PlexeClient', 'create', 'acreate', 'run', 'arun', 'batch_run']

‎plexe/client.py‎

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
import asyncio
2+
from typing import Any, Dict, List, Optional, Union
3+
4+
import httpx
5+
6+
class PlexeClient:
7+
def __init__(self, api_key: Optional[str] = None, timeout: float = 120.0):
8+
self.api_key = api_key
9+
if not api_key:
10+
import os
11+
self.api_key = os.environ.get("PLEXE_API_KEY")
12+
if not self.api_key:
13+
raise ValueError("PLEXE_API_KEY must be provided or set as environment variable")
14+
15+
self.base_url = "https://api.plexe.ai/v1"
16+
self.client = httpx.Client(timeout=timeout)
17+
self.async_client = httpx.AsyncClient(timeout=timeout)
18+
19+
def _headers(self):
20+
return {
21+
"Authorization": f"Bearer {self.api_key}",
22+
"Content-Type": "application/json",
23+
}
24+
25+
def create(self, task_description: str) -> tuple[str, int, str]:
26+
"""Create a new ML model from a task description.
27+
28+
Args:
29+
task_description: Description of what the model should do
30+
31+
Returns:
32+
Tuple of (model_id, version, description)
33+
"""
34+
if not task_description:
35+
raise ValueError("Task description must be provided")
36+
37+
response = self.client.post(
38+
f"{self.base_url}/create",
39+
json={"description": task_description},
40+
headers=self._headers()
41+
)
42+
response.raise_for_status()
43+
data = response.json()
44+
return data["model_id"], data["version"], data["description"]
45+
46+
async def acreate(self, task_description: str) -> tuple[str, int, str]:
47+
"""Async version of create()"""
48+
if not task_description:
49+
raise ValueError("Task description must be provided")
50+
51+
response = await self.async_client.post(
52+
f"{self.base_url}/create",
53+
json={"description": task_description},
54+
headers=self._headers()
55+
)
56+
response.raise_for_status()
57+
data = response.json()
58+
return data["model_id"], data["version"], data["description"]
59+
60+
def run(self, model_id: str, text_input: str = "", version: int = -1) -> Dict[str, Any]:
61+
"""Run predictions using a model.
62+
63+
Args:
64+
model_id: ID of the model to use
65+
text_input: Input text for the model
66+
version: Model version to use (-1 for latest)
67+
68+
Returns:
69+
Dictionary containing prediction results
70+
"""
71+
response = self.client.post(
72+
f"{self.base_url}/run",
73+
json={
74+
"model_id": model_id,
75+
"text": text_input,
76+
"version": version
77+
},
78+
headers=self._headers()
79+
)
80+
response.raise_for_status()
81+
return response.json()
82+
83+
async def arun(self, model_id: str, text_input: str = "", version: int = -1) -> Dict[str, Any]:
84+
"""Async version of run()"""
85+
response = await self.async_client.post(
86+
f"{self.base_url}/run",
87+
json={
88+
"model_id": model_id,
89+
"text": text_input,
90+
"version": version
91+
},
92+
headers=self._headers()
93+
)
94+
response.raise_for_status()
95+
return response.json()
96+
97+
def batch_run(self, model_id: str, inputs: List[Dict[str, Any]], version: int = -1) -> List[Dict[str, Any]]:
98+
"""Run batch predictions.
99+
100+
Args:
101+
model_id: ID of the model to use
102+
inputs: List of input dictionaries
103+
version: Model version to use (-1 for latest)
104+
105+
Returns:
106+
List of prediction results
107+
"""
108+
async def run_batch():
109+
tasks = [
110+
self.arun(model_id=model_id, text_input=x.get("text", ""), version=version)
111+
for x in inputs
112+
]
113+
return await asyncio.gather(*tasks)
114+
115+
return asyncio.run(run_batch())

‎setup.cfg‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[tool:pytest]
2+
testpaths = tests
3+
python_files = test_*.py
4+
addopts = -v --cov=plexe --cov-report=term-missing
5+
6+
[coverage:run]
7+
source = plexe
8+
omit = tests/*
9+
10+
[coverage:report]
11+
exclude_lines =
12+
pragma: no cover
13+
def __repr__
14+
raise NotImplementedError
15+
if __name__ == .__main__.:
16+
pass
17+
raise ImportError

‎setup.py‎

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
from setuptools import setup, find_packages
2+
3+
setup(
4+
name="plexe",
5+
version="0.1.0",
6+
packages=find_packages(),
7+
install_requires=[
8+
"httpx>=0.24.0",
9+
"asyncio>=3.4.3",
10+
],
11+
author="Plexe AI",
12+
author_email="support@plexe.ai",
13+
description="Create ML models from natural language descriptions",
14+
long_description=open("README.md").read(),
15+
long_description_content_type="text/markdown",
16+
url="https://github.com/plexe-ai/plexe",
17+
classifiers=[
18+
"Programming Language :: Python :: 3",
19+
"License :: OSI Approved :: MIT License",
20+
"Operating System :: OS Independent",
21+
],
22+
python_requires=">=3.7",
23+
extras_require={
24+
"dev": [
25+
"pytest>=7.0",
26+
"pytest-asyncio>=0.20.0",
27+
"pytest-cov>=4.0.0",
28+
"black>=22.0.0",
29+
"isort>=5.0.0",
30+
]
31+
},
32+
)

0 commit comments

Comments
 (0)