Metadata-Version: 2.5
Name: carejobs-haystack
Version: 0.1.0
Summary: Haystack components and tools for CareJobs.Now: open US healthcare jobs, posted pay and employers
Project-URL: Homepage, https://carejobs.now
Project-URL: Documentation, https://github.com/yumaheymans/carejobs-haystack#readme
Project-URL: Issues, https://github.com/yumaheymans/carejobs-haystack/issues
Project-URL: Source, https://github.com/yumaheymans/carejobs-haystack
Project-URL: Changelog, https://github.com/yumaheymans/carejobs-haystack/blob/main/CHANGELOG.md
Author-email: "CareJobs.Now" <hello@carejobs.now>
License-Expression: MIT
License-File: LICENSE
Keywords: agent,carejobs,haystack,healthcare,jobs,mcp,nursing,tools
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: haystack-ai<4.0.0,>=3.0.0
Requires-Dist: httpx<1.0.0,>=0.27.0
Description-Content-Type: text/markdown

# carejobs-haystack

[![PyPI - Version](https://img.shields.io/pypi/v/carejobs-haystack?label=%20)](https://pypi.org/project/carejobs-haystack/#history)
[![PyPI - License](https://img.shields.io/pypi/l/carejobs-haystack)](https://opensource.org/licenses/MIT)

Haystack components and tools for [CareJobs.Now](https://carejobs.now), a free US healthcare job board.
It reads the open jobs of more than 2,000 hospitals, health systems, clinic groups and care companies:
nurses, CNAs, doctors, NPs and PAs, therapists, imaging and lab techs, pharmacy, caregivers, front
office and more.

The package gives a Haystack pipeline or Agent live access to those jobs, their posted pay, the
employers and the job-market numbers, through the public CareJobs.Now remote MCP endpoint. **No API key
or account is needed.** Every job links to its page on CareJobs.Now, where the person applies.

- [Installation](#installation)
- [Components](#components)
- [Usage](#usage)
- [Errors](#errors)
- [License](#license)

## Installation

```bash
pip install carejobs-haystack
```

The package needs Python 3.11 or later and `haystack-ai` 3.0 or later.

## Components

| Component | What it does |
| --- | --- |
| `CareJobsJobSearch` | Searches open jobs and returns one `Document` per job, with the job as `content` and its fields in `meta`. |
| `CareJobsLookup` | Calls one CareJobs.Now tool and returns its readable `text` and structured `data`: pay, job market, one state, the employer list, or one employer. |
| `CareJobsToolset` | The six CareJobs.Now tools as Haystack `Tool`s for an `Agent` or a chat generator. |

Import them from:

```python
from haystack_integrations.components.retrievers.carejobs import CareJobsJobSearch, CareJobsLookup
from haystack_integrations.tools.carejobs import CareJobsToolset
```

## Usage

### Search jobs and get Documents

```python
from haystack_integrations.components.retrievers.carejobs import CareJobsJobSearch

search = CareJobsJobSearch(kind="nurses", state="TX", top_k=3)
result = search.run(query="ICU")

print(result["total"])  # how many open jobs match
for document in result["documents"]:
    print(document.meta["title"], "|", document.meta["employer"], "|", document.meta["url"])
```

Each `Document.meta` holds `title`, `employer`, `kind`, `pay`, `schedule`, `facility`, `location`,
`listed`, `url` (the job's page, where the person applies), `employer_page`, `via` and `source`.
`run()` takes `query`, `kind`, `employer`, `state`, `remote`, `min_hourly_usd`, `sort` and `top_k`, and
`run_async()` takes the same.

`kind` is one of `nurses`, `nurse-practitioners`, `physicians`, `nursing-assistants`, `caregivers`,
`therapy-rehab`, `mental-health`, `pharmacy`, `imaging`, `lab`, `surgical-techs`, `emts-paramedics`,
`medical-assistants`, `dental`, `admin`, `allied-health` or `ai-training`. `state` is a two-letter code
(`TX`) or a name (`Texas`). `employer` is a slug such as `kaiser-permanente`, or a name.

### Use the jobs in a pipeline

```python
from haystack import Pipeline
from haystack.components.builders import PromptBuilder
from haystack_integrations.components.retrievers.carejobs import CareJobsJobSearch

pipeline = Pipeline()
pipeline.add_component("jobs", CareJobsJobSearch(kind="nursing-assistants", state="OH", top_k=3))
pipeline.add_component(
    "prompt",
    PromptBuilder(
        template="""Open jobs:
{% for doc in documents %}{{ doc.content }}

{% endfor %}
Summarize the best paying job for {{ question }}""",
        required_variables=["documents", "question"],
    ),
)
pipeline.connect("jobs.documents", "prompt.documents")

result = pipeline.run({"jobs": {"query": "night"}, "prompt": {"question": "a night-shift CNA"}})
print(result["prompt"]["prompt"])
```

Connect `prompt` to a chat generator to get an answer.

### Look up pay, the job market, a state or an employer

```python
from haystack_integrations.components.retrievers.carejobs import CareJobsLookup

pay = CareJobsLookup(tool_name="get_healthcare_pay")
result = pay.run(arguments={"kind": "nursing-assistants"})
print(result["text"])  # the readable summary
print(result["data"])  # the structured answer (a dict)

employer = CareJobsLookup(tool_name="get_healthcare_employer")
print(employer.run(arguments={"employer": "kaiser-permanente"})["text"])
```

`tool_name` is one of `search_healthcare_jobs`, `get_healthcare_pay`, `get_healthcare_job_market`,
`get_healthcare_jobs_by_state`, `list_healthcare_employers` or `get_healthcare_employer`.

### Give an Agent the tools

```python
from haystack.components.agents import Agent
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.dataclasses import ChatMessage
from haystack_integrations.tools.carejobs import CareJobsToolset

agent = Agent(chat_generator=OpenAIChatGenerator(), tools=CareJobsToolset())

result = agent.run(
    messages=[
        ChatMessage.from_user(
            "Find night-shift ICU nursing jobs in Texas that pay at least $45 an hour, "
            "and tell me which employers post the most for nurses."
        )
    ]
)
print(result["last_message"].text)
```

The toolset has `search_healthcare_jobs`, `get_healthcare_pay`, `get_healthcare_job_market`,
`get_healthcare_jobs_by_state`, `list_healthcare_employers` and `get_healthcare_employer`. Each tool
returns the service's readable summary with a link to every job. Tools run natively async.

## Errors

If CareJobs.Now cannot be reached or rejects a request (for example an unknown employer), the
components raise `CareJobsError` with the service's message. Import it from
`haystack_integrations.utils.carejobs`.

A Haystack `Tool` wraps any error in `ToolInvocationError`, whose message contains the service's
message and whose `__cause__` is the `CareJobsError`. A Haystack `Agent` hands that message back to the
model (unless `raise_on_tool_invocation_failure=True`), which can correct the call.

The first request after a quiet period can take up to about 25 seconds while the service wakes. The
default timeout is 30 seconds. To wait longer, pass `timeout=60` to a component or the toolset.

## Serialization

Components and the toolset serialize with `to_dict()` and `from_dict()`, so pipelines and Agents that
use them save and load with `dumps()` and `loads()`. The `haystack_integrations` package is on
Haystack's default allowlist for deserialization, so no extra setting is needed.

## Notes on the data

- Pay is what employers post, measured from the hourly rates open jobs state, before shift
  differentials and bonuses.
- Results cover US jobs only.
- Send people to the link in each result to apply. The tools never apply to a job.

## Privacy

The components send only the arguments of each call to `https://carejobs.now/api/mcp` and store
nothing. See the CareJobs.Now [privacy policy](https://carejobs.now/legal/privacy) and
[terms](https://carejobs.now/legal/terms).

## Development

```bash
pip install hatch
hatch run test:unit             # unit tests, no network
hatch run test:integration      # also needs network: calls the live API
hatch run fmt-check
hatch run test:types
```

## License

`carejobs-haystack` is distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license.
