Skip to content

Commit

Permalink
Merge pull request #15 from parea-ai/update-pkg
Browse files Browse the repository at this point in the history
update naming and imports
  • Loading branch information
jalexanderII committed Jul 24, 2023
2 parents e5f3223 + ec4b2e6 commit 26650da
Show file tree
Hide file tree
Showing 11 changed files with 153 additions and 136 deletions.
1 change: 1 addition & 0 deletions .env.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
API_KEY=<API_KEY>
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ Building a new version of the application contains steps:
with [`safety`](https://github.com/pyupio/safety) and [`bandit`](https://github.com/PyCQA/bandit)
- Testing with [`pytest`](https://docs.pytest.org/en/latest/).
-

Ready-to-use [`.editorconfig`](https://github.com/parea-ai/parea-sdk/blob/master/.editorconfig), [`.dockerignore`](https://github.com/parea-ai/parea-sdk/blob/master/.dockerignore),
and [`.gitignore`](https://github.com/parea-ai/parea-sdk/blob/master/.gitignore). You don't have to worry about those
things.
Expand All @@ -131,8 +132,10 @@ things.
### Open source community features

-

Ready-to-use [Pull Requests templates](https://github.com/parea-ai/parea-sdk/blob/master/.github/PULL_REQUEST_TEMPLATE.md)
and several [Issue templates](https://github.com/parea-ai/parea-sdk/tree/master/.github/ISSUE_TEMPLATE).

- Files such as: `LICENSE`, `CONTRIBUTING.md`, `CODE_OF_CONDUCT.md`, and `SECURITY.md` are generated automatically.
- [`Stale bot`](https://github.com/apps/stale) that closes abandoned issues after a period of inactivity. (You will
only [need to setup free plan](https://github.com/marketplace/stale)). Configuration
Expand All @@ -143,13 +146,13 @@ and several [Issue templates](https://github.com/parea-ai/parea-sdk/tree/master/
## Installation

```bash
pip install -U parea-sdk
pip install -U parea
```

or install with `Poetry`

```bash
poetry add parea-sdk
poetry add parea
```

### Makefile usage
Expand Down
12 changes: 11 additions & 1 deletion parea/__init__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
# type: ignore[attr-defined]
"""Parea python sdk"""
# flake8: noqa

"""
Parea API SDK
The Parea SDK allows you to interact with Parea from your product or service.
To install the official [Python SDK](https://pypi.org/project/parea/),
run the following command: ```bash pip install parea ```.
"""

from importlib import metadata as importlib_metadata

from parea.client import Parea


def get_version() -> str:
try:
Expand Down
71 changes: 71 additions & 0 deletions parea/api_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
from typing import Any, Optional

import httpx


class HTTPClient:
_instance = None
base_url = "http://localhost:8000/api/parea/v1"

def __new__(cls, *args, **kwargs):
if cls._instance is None:
cls._instance = super().__new__(cls)
cls._instance.sync_client = httpx.Client(base_url=cls.base_url, timeout=60 * 3.0)
cls._instance.async_client = httpx.AsyncClient(base_url=cls.base_url, timeout=60 * 3.0)
return cls._instance

def request(
self,
method: str,
endpoint: str,
data: Optional[dict[str, Any]] = None,
params: Optional[dict[str, Any]] = None,
authorization: Optional[str] = None,
) -> httpx.Response:
"""
Makes an HTTP request to the specified endpoint.
"""
headers = {"Authorization": f"Bearer {authorization}"} if authorization else None
response = self.sync_client.request(method, endpoint, json=data, headers=headers, params=params)
response.raise_for_status()
return response

async def request_async(
self,
method: str,
endpoint: str,
data: Optional[dict[str, Any]] = None,
params: Optional[dict[str, Any]] = None,
authorization: Optional[str] = None,
) -> httpx.Response:
"""
Makes an asynchronous HTTP request to the specified endpoint.
"""
headers = {"Authorization": f"Bearer {authorization}"} if authorization else None
response = await self.async_client.request(method, endpoint, json=data, headers=headers, params=params)
response.raise_for_status()
return response

def close(self):
"""
Closes the synchronous HTTP client.
"""
self.sync_client.close()

async def close_async(self):
"""
Closes the asynchronous HTTP client.
"""
await self.async_client.aclose()

def __enter__(self):
return self

def __exit__(self, exc_type, exc_val, exc_tb):
self.close()

async def __aenter__(self):
return self

async def __aexit__(self, exc_type, exc_val, exc_tb):
await self.close_async()
125 changes: 49 additions & 76 deletions parea/client.py
Original file line number Diff line number Diff line change
@@ -1,76 +1,49 @@
from typing import Any, Optional

import os

import httpx
from dotenv import load_dotenv

load_dotenv()


class HTTPClient:
_instance = None
base_url = os.getenv("PAREA_API_URL")

def __new__(cls, *args, **kwargs):
if cls._instance is None:
cls._instance = super().__new__(cls)
cls._instance.sync_client = httpx.Client(base_url=cls.base_url, timeout=60 * 3.0)
cls._instance.async_client = httpx.AsyncClient(base_url=cls.base_url, timeout=60 * 3.0)
return cls._instance

def request(
self,
method: str,
endpoint: str,
data: Optional[dict[str, Any]] = None,
params: Optional[dict[str, Any]] = None,
authorization: Optional[str] = None,
) -> httpx.Response:
"""
Makes an HTTP request to the specified endpoint.
"""
headers = {"Authorization": f"Bearer {authorization}"} if authorization else None
response = self.sync_client.request(method, endpoint, json=data, headers=headers, params=params)
response.raise_for_status()
return response

async def request_async(
self,
method: str,
endpoint: str,
data: Optional[dict[str, Any]] = None,
params: Optional[dict[str, Any]] = None,
authorization: Optional[str] = None,
) -> httpx.Response:
"""
Makes an asynchronous HTTP request to the specified endpoint.
"""
headers = {"Authorization": f"Bearer {authorization}"} if authorization else None
response = await self.async_client.request(method, endpoint, json=data, headers=headers, params=params)
response.raise_for_status()
return response

def close(self):
"""
Closes the synchronous HTTP client.
"""
self.sync_client.close()

async def close_async(self):
"""
Closes the asynchronous HTTP client.
"""
await self.async_client.aclose()

def __enter__(self):
return self

def __exit__(self, exc_type, exc_val, exc_tb):
self.close()

async def __aenter__(self):
return self

async def __aexit__(self, exc_type, exc_val, exc_tb):
await self.close_async()
from attrs import asdict, define, field

from parea.api_client import HTTPClient
from parea.schemas.models import Completion, CompletionResponse, UseDeployedPrompt, UseDeployedPromptResponse

COMPLETION_ENDPOINT = "/completion"
DEPLOYED_PROMPT_ENDPOINT = "/deployed-prompt"


@define
class Parea:
api_key: str = field(init=True, default="")
_client: HTTPClient = field(init=False, default=HTTPClient())

def completion(self, data: Completion) -> CompletionResponse:
r = self._client.request(
"POST",
COMPLETION_ENDPOINT,
data=asdict(data),
authorization=self.api_key,
)
return CompletionResponse(**r.json())

async def acompletion(self, data: Completion) -> CompletionResponse:
r = await self._client.request_async(
"POST",
COMPLETION_ENDPOINT,
data=asdict(data),
authorization=self.api_key,
)
return CompletionResponse(**r.json())

def get_prompt(self, data: UseDeployedPrompt) -> UseDeployedPromptResponse:
r = self._client.request(
"POST",
DEPLOYED_PROMPT_ENDPOINT,
data=asdict(data),
authorization=self.api_key,
)
return UseDeployedPromptResponse(**r.json())

async def aget_prompt(self, data: UseDeployedPrompt) -> UseDeployedPromptResponse:
r = await self._client.request_async(
"POST",
DEPLOYED_PROMPT_ENDPOINT,
data=asdict(data),
authorization=self.api_key,
)
return UseDeployedPromptResponse(**r.json())
13 changes: 9 additions & 4 deletions parea/main.py → parea/example.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,21 @@

from dotenv import load_dotenv

from parea.parea import Parea
from parea.client import Parea
from parea.schemas.models import Completion, UseDeployedPrompt

load_dotenv()

p = Parea(api_key=os.getenv("DEV_API_KEY"))
p = Parea(api_key=os.getenv("API_KEY"))

deployment_id = os.getenv("DEV_DEPLOYMENT_ID")
# You will find this deployment_id in the Parea dashboard
deployment_id = "p-qsefFeFEICnxqJ_yLjji"
# Assuming my deployed prompt's message is:
# {"role": "user", "content": "Write a hello world program using {{x}} and the {{y}} framework."}
inputs = {"inputs": {"x": "Golang", "y": "Fiber"}}
test_completion = Completion(**{"prompt_deployment_id": deployment_id, "llm_inputs": inputs, "metadata": {"purpose": "testing"}})
test_completion = Completion(**{"deployment_id": deployment_id, "llm_inputs": inputs, "metadata": {"purpose": "testing"}})
# By passing in my inputs, instead of unfilled variables {{x}} and {{y}}, we will also have the filled in prompt:
# {"role": "user", "content": "Write a hello world program using Golang and the Fiber framework."}
test_get_prompt = UseDeployedPrompt(deployment_id, inputs)


Expand Down
49 changes: 0 additions & 49 deletions parea/parea.py

This file was deleted.

4 changes: 2 additions & 2 deletions parea/schemas/models.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Any, Dict, List, Optional, Union
from typing import Any, Optional, Union

from enum import Enum

Expand Down Expand Up @@ -45,7 +45,7 @@ class LLMInputs:
class Completion:
llm_inputs: LLMInputs
end_user_identifier: Optional[str] = None
prompt_deployment_id: Optional[str] = None
deployment_id: Optional[str] = None
name: Optional[str] = None
eval_metric_id: Optional[int] = None
metadata: Optional[dict] = None
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ build-backend = "poetry.core.masonry.api"

[tool.poetry]
name = "parea"
version = "0.1.0"
version = "0.1.1a0"
description = "Parea python sdk"
readme = "README.md"
authors = ["parea-ai <[email protected]>"]
Expand Down
3 changes: 3 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
attrs
httpx
python-dotenv
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""Tests for hello function."""
import pytest

from parea.main import hello
from parea.example import hello


@pytest.mark.parametrize(
Expand Down

0 comments on commit 26650da

Please sign in to comment.