Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
name: Unit Tests

on:
pull_request:
types: [opened, synchronize, reopened]
workflow_dispatch:

jobs:
check-permissions:
runs-on: ubuntu-latest
outputs:
can-run: ${{ steps.check.outputs.can-run }}
steps:
- name: Check if user can run tests
id: check
run: |
# Check if PR author is owner, member, or collaborator
if [[ "${{ github.event.pull_request.author_association }}" == "OWNER" ]] || \
[[ "${{ github.event.pull_request.author_association }}" == "MEMBER" ]] || \
[[ "${{ github.event.pull_request.author_association }}" == "COLLABORATOR" ]]; then
echo "can-run=true" >> $GITHUB_OUTPUT
echo "✅ User has permission to run tests"
else
echo "can-run=false" >> $GITHUB_OUTPUT
echo "❌ User does not have permission to run tests"
echo "Only repository owners, members, and collaborators can run tests"
fi

test:
needs: check-permissions
if: needs.check-permissions.outputs.can-run == 'true'
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Install Poetry
run: pipx install poetry

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: 'poetry'

- name: Install dependencies
run: |
poetry env use python${{ matrix.python-version }}
poetry install --with test,lint,typing

- name: Run unit tests
run: make test

- name: Upload test results
if: always()
uses: actions/upload-artifact@v4
with:
name: test-results-${{ matrix.python-version }}
path: |
.coverage
htmlcov/
retention-days: 7

test-status:
needs: check-permissions
if: needs.check-permissions.outputs.can-run == 'false'
runs-on: ubuntu-latest
steps:
- name: Tests skipped
run: |
echo "::warning::Tests were not run because the PR author (${{ github.event.pull_request.user.login }}) is not a repository owner, member, or collaborator."
echo "Repository owners can manually trigger tests by re-running this workflow."
11 changes: 10 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
.PHONY: all format lint test tests integration_tests docker_tests help extended_tests
.PHONY: all format lint test tests integration_tests docker_tests help extended_tests install

# Default target executed when no arguments are given to make.
all: help

######################
# INSTALLATION
######################

install:
poetry env use python3.12
poetry install --with test,lint,typing

# Define a variable for the test file path.
TEST_FILE ?= tests/unit_tests/
integration_test integration_tests: TEST_FILE = tests/integration_tests/
Expand Down Expand Up @@ -56,6 +64,7 @@ check_imports: $(shell find langchain_parallel -name '*.py')

help:
@echo '----'
@echo 'install - set up Python 3.12 environment and install dependencies'
@echo 'check_imports - check imports'
@echo 'format - run code formatters'
@echo 'lint - run linters'
Expand Down
100 changes: 50 additions & 50 deletions langchain_parallel/chat_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,13 +132,13 @@ class ChatParallelWeb(BaseChatModel):
real-time web research capabilities through an OpenAI-compatible interface.

Setup:
Install ``langchain-parallel`` and set environment variable
``PARALLEL_API_KEY``.
Install `langchain-parallel` and set environment variable
`PARALLEL_API_KEY`.

.. code-block:: bash

pip install -U langchain-parallel
export PARALLEL_API_KEY="your-api-key"
```bash
pip install -U langchain-parallel
export PARALLEL_API_KEY="your-api-key"
```

Key init args — completion params:
model: str
Expand All @@ -160,62 +160,62 @@ class ChatParallelWeb(BaseChatModel):
Base URL for Parallel API. Defaults to "https://api.parallel.ai".

Instantiate:
.. code-block:: python

from langchain_parallel import ChatParallelWeb

llm = ChatParallelWeb(
model="speed",
temperature=0.7,
max_tokens=None,
timeout=None,
max_retries=2,
# api_key="...",
# other params...
)
```python
from langchain_parallel import ChatParallelWeb

llm = ChatParallelWeb(
model="speed",
temperature=0.7,
max_tokens=None,
timeout=None,
max_retries=2,
# api_key="...",
# other params...
)
```

Invoke:
.. code-block:: python

messages = [
(
"system",
"You are a helpful assistant with access to real-time web "
"information."
),
("human", "What are the latest developments in AI?"),
]
llm.invoke(messages)
```python
messages = [
(
"system",
"You are a helpful assistant with access to real-time web "
"information."
),
("human", "What are the latest developments in AI?"),
]
llm.invoke(messages)
```

Stream:
.. code-block:: python

for chunk in llm.stream(messages):
print(chunk.content, end="")
```python
for chunk in llm.stream(messages):
print(chunk.content, end="")
```

Async:
.. code-block:: python
```python
await llm.ainvoke(messages)

await llm.ainvoke(messages)
# stream:
async for chunk in llm.astream(messages):
print(chunk.content, end="")

# stream:
async for chunk in llm.astream(messages):
print(chunk.content, end="")

# batch:
await llm.abatch([messages])
# batch:
await llm.abatch([messages])
```

Token usage:
.. code-block:: python

ai_msg = llm.invoke(messages)
ai_msg.usage_metadata
```python
ai_msg = llm.invoke(messages)
ai_msg.usage_metadata
```

Response metadata:
.. code-block:: python

ai_msg = llm.invoke(messages)
ai_msg.response_metadata
```python
ai_msg = llm.invoke(messages)
ai_msg.response_metadata
```

"""

Expand Down
62 changes: 31 additions & 31 deletions langchain_parallel/extract_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,13 @@ class ParallelExtractTool(BaseTool):
Parallel Extract API.

Setup:
Install ``langchain-parallel`` and set environment variable
``PARALLEL_API_KEY``.
Install `langchain-parallel` and set environment variable
`PARALLEL_API_KEY`.

.. code-block:: bash

pip install -U langchain-parallel
export PARALLEL_API_KEY="your-api-key"
```bash
pip install -U langchain-parallel
export PARALLEL_API_KEY="your-api-key"
```

Key init args:
api_key: Optional[SecretStr]
Expand All @@ -93,35 +93,35 @@ class ParallelExtractTool(BaseTool):
Maximum characters per extracted result.

Instantiation:
.. code-block:: python

from langchain_parallel import ParallelExtractTool
```python
from langchain_parallel import ParallelExtractTool

# Basic instantiation
tool = ParallelExtractTool()
# Basic instantiation
tool = ParallelExtractTool()

# With custom API key and parameters
tool = ParallelExtractTool(
api_key="your-api-key",
max_chars_per_extract=5000
)
# With custom API key and parameters
tool = ParallelExtractTool(
api_key="your-api-key",
max_chars_per_extract=5000
)
```

Invocation:
.. code-block:: python

# Extract content from URLs
result = tool.invoke({
"urls": [
"https://example.com/article1",
"https://example.com/article2"
]
})

# Result is a list of dicts with url, title, and content
for item in result:
print(f"Title: {item['title']}")
print(f"URL: {item['url']}")
print(f"Content: {item['content'][:200]}...")
```python
# Extract content from URLs
result = tool.invoke({
"urls": [
"https://example.com/article1",
"https://example.com/article2"
]
})

# Result is a list of dicts with url, title, and content
for item in result:
print(f"Title: {item['title']}")
print(f"URL: {item['url']}")
print(f"Content: {item['content'][:200]}...")
```

Response Format:
Returns a list of dictionaries, each containing:
Expand Down
Loading
Loading