Metadata-Version: 2.4
Name: python-scientific-os
Version: 0.1.0
Summary: FastAPI backend and CLI for Scientific OS protocol generation.
Author: Scientific OS Contributors
Requires-Python: >=3.11
Description-Content-Type: text/markdown
Requires-Dist: fastapi>=0.115.0
Requires-Dist: uvicorn[standard]>=0.30.0
Requires-Dist: pydantic>=2.8.0
Requires-Dist: python-dotenv>=1.0.1
Requires-Dist: openai>=1.99.0
Requires-Dist: tavily-python>=0.5.0
Provides-Extra: postgres
Requires-Dist: psycopg[binary]>=3.2.0; extra == "postgres"
Provides-Extra: s3
Requires-Dist: boto3>=1.34.0; extra == "s3"
Provides-Extra: all
Requires-Dist: psycopg[binary]>=3.2.0; extra == "all"
Requires-Dist: boto3>=1.34.0; extra == "all"

# Python Scientific OS

FastAPI backend equivalent of the TypeScript scientific OS server.

## Setup

```bash
python -m venv .venv
source .venv/bin/activate
pip install -e .
cp .env.example .env
```

Add `OPENAI_API_KEY` and optionally `TAVILY_API_KEY` to `.env`.

By default, local development uses SQLite and local file storage, so Docker is optional.

For the full optional stack, install extras:

```bash
pip install -e ".[all]"
```

## Package Usage

Install the package in editable mode while developing:

```bash
pip install -e .
```

Install optional Postgres/MinIO support:

```bash
pip install -e ".[postgres,s3]"
```

Build a wheel:

```bash
python -m pip wheel . --no-deps -w dist
```

Install the built wheel:

```bash
pip install dist/python_scientific_os-0.1.0-py3-none-any.whl
```

## Start the server

Start the FastAPI server from the project root:

```bash
scientific-os-server --reload --port 8000
```

The API will be available at `http://127.0.0.1:8000`.

You can also run the app directly with Uvicorn:

```bash
uvicorn scientific_os.main:app --reload --port 8000
```

## CLI Chat

With the server running, send a prompt from another terminal:

```bash
scientific-os "Create a simple protocol for extracting strawberry DNA."
```

The CLI prints the response and writes returned IDs, including `conversationId` and `jobId`, to stderr.
Use that ID to continue the same conversation:

```bash
scientific-os \
  --conversation-id 00000000-0000-0000-0000-000000000000 \
  "Make it safer for a classroom demo."
```

Replace the placeholder UUID with the real `conversationId`.

You can also pipe prompt text into the CLI:

```bash
echo "Create a protocol for testing soil pH." | scientific-os
```

Use `--pretty` to print the full JSON response:

```bash
scientific-os --pretty "List the protocol sections you generated."
```

Each chat request is tracked as a job. List recent jobs:

```bash
scientific-os --list-jobs
```

Fetch a single job:

```bash
scientific-os --job-id 00000000-0000-0000-0000-000000000000
```

Filter jobs by status:

```bash
scientific-os --list-jobs --status failed
```

If the server is running somewhere else, pass a custom base URL:

```bash
scientific-os --server http://127.0.0.1:8001 "Hello"
```

Without installing the package, the CLI still works as a module:

```bash
python -m scientific_os.cli "Hello"
```

## HTTP Chat

Send a chat request to the local server:

```bash
curl -sS http://127.0.0.1:8000/api/chat \
  -H "Content-Type: application/json" \
  -d '{
    "messages": [
      {
        "role": "user",
        "content": "Create a simple protocol for extracting strawberry DNA."
      }
    ]
  }'
```

To continue a conversation, include the `conversationId` returned by the previous response:

```bash
curl -sS http://127.0.0.1:8000/api/chat \
  -H "Content-Type: application/json" \
  -d '{
    "conversationId": "00000000-0000-0000-0000-000000000000",
    "messages": [
      {
        "role": "user",
        "content": "Make it safer for a classroom demo."
      }
    ]
  }'
```

Replace the placeholder UUID with the real `conversationId`.

Chat and protocol search requests are tracked as jobs. List recent jobs over HTTP:

```bash
curl -sS http://127.0.0.1:8000/api/jobs
```

Fetch a single job:

```bash
curl -sS http://127.0.0.1:8000/api/jobs/00000000-0000-0000-0000-000000000000
```

## Optional Docker Services

To use Postgres/pgvector and MinIO instead, set these values in `.env`:

```bash
DATABASE_URL=postgresql://myuser:mypassword@localhost:5432/mydb
STORAGE_BACKEND=s3
S3_ENDPOINT=http://localhost:9000
S3_PUBLIC_ENDPOINT=http://localhost:9000
```

Then start the backing services with `docker compose up -d`.

The compatible API routes are:

- `POST /api/chat`
- `GET /api/jobs`
- `GET /api/jobs/{job_id}`
- `GET /api/conversations`
- `GET /api/conversations/{conversation_id}`
- `GET /api/protocols/search`
- `GET /api/protocols/{protocol_id}`
