Metadata-Version: 2.4
Name: azulene-opal
Version: 0.4.0
Summary: A CLI and Python library to interact with Azulene Opal
Author-email: Azulene Labs <contact@azulenelabs.com>
Project-URL: Homepage, https://www.azulenelabs.com/
Project-URL: Repository, https://github.com/Azulene-Labs/opal-cli
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: typer
Requires-Dist: httpx
Requires-Dist: supabase
Requires-Dist: rich
Dynamic: license-file

# Azulene-Opal

- [Quickstart.md](Quickstart.md)
- [API_Reference.md](API_Reference.md)
- [Job_Types.md](Job_Types.md)


This guide shows how to:

1. Log in
2. Submit a job
3. Inspect and filter jobs
4. Get / cancel a specific job
5. Poll running jobs
6. Check service health & job types
7. Submit a batch of jobs

Each section has **Python** and **CLI** examples.

---

## How to download OPAL CLI

```shellscript
pip install azulene-opal
```

## 0. Imports (Python)

```python
from opal import auth, jobs
```

---

## 1. Log in

### Python

```python
from opal import auth

res = auth.login(email="test@example.com", password="pass123")
print(res)  # {"ok": True, "message": "Logged in successfully!"}
```

### CLI

```bash
# Recommended: let the CLI prompt you (password hidden)
python -m opal.main login
# Your email:    test@example.com
# Your password: *****
```

You stay logged in via locally stored tokens until you explicitly log out.

---

## 2. Check who you are

### Python

```python
from opal import auth

res = auth.whoami()
print(res)
# {
#   "ok": True,
#   "user": { ... full user object ... },
#   "slim": {
#       "email": "...",
#       "role": "...",
#       "approved": True,
#       ...
#   }
# }
```

### CLI

```bash
python -m opal.main whoami
```

If your account isn’t approved yet, the API will tell you and block job access.

---

## 3. Submit a single job

Example job type: `generate_conformers` with a SMILES and number of conformers.

### Python

```python
from opal import jobs

res = jobs.submit(
    job_type="generate_conformers",
    input_data={"smiles": "CCO", "num_conformers": 5},  # dict
)
print(res)
# {"ok": True, "data": {"job_id": "...", "status": "submitted", ...}}
```

(You *can* also pass a JSON string instead of a dict if you want.)

### CLI

```bash
python -m opal.main jobs submit \
  --job-type generate_conformers \
  --input-data '{"smiles": "CCO", "num_conformers": 5}'
```

Each call submits **one** job.

---

## 4. List and filter jobs

By default, the server returns **the last 5 jobs** for the current user.
You can ask for all jobs, limit, or filter by job_type, status, or date range.

### Python

```python
from opal import jobs

# Last 5 jobs (default)
print(jobs.get_jobs())

# All jobs
print(jobs.get_jobs(all_jobs=True))

# Last 10 jobs
print(jobs.get_jobs(limit=10))

# Filter by job_type and status
print(
    jobs.get_jobs(
        job_type="generate_conformers",
        status="completed",
    )
)

# Filter by created_at date range (ISO timestamps)
print(
    jobs.get_jobs(
        start_date="2025-12-01T00:00:00Z",
        end_date="2025-12-05T00:00:00Z",
    )
)
```

Each call returns something like:

```python
{"ok": True, "data": [ { "id": "...", "job_type": "...", ... }, ... ]}
```

### CLI

```bash
# Last 5 jobs
python -m opal.main jobs get-jobs

# All jobs
python -m opal.main jobs get-jobs --all

# Last 10 jobs
python -m opal.main jobs get-jobs --limit 10

# Filter by job_type + status
python -m opal.main jobs get-jobs \
  --job-type generate_conformers \
  --status completed

# Filter by date range
python -m opal.main jobs get-jobs \
  --start-date 2025-12-01T00:00:00Z \
  --end-date   2025-12-05T00:00:00Z
```

---

## 5. Get a specific job

Once you have a `job_id`, you can fetch that job’s details.

### Python

```python
from opal import jobs

res = jobs.get(job_id="YOUR_JOB_ID")
print(res)
# {"ok": True, "data": { "id": "...", "status": "...", "input_data": {...}, "results": {...}, ... }}
```

### CLI

```bash
python -m opal.main jobs get --job-id YOUR_JOB_ID
```

---

## 6. Cancel a job

If a job is still running, you can cancel it.

### Python

```python
from opal import jobs

res = jobs.cancel(job_id="YOUR_JOB_ID")
print(res)
# {"ok": True, "data": {...}}
```

### CLI

```bash
python -m opal.main jobs cancel --job-id YOUR_JOB_ID
```

---

## 7. Poll running jobs

This endpoint checks any currently running jobs and update their statuses.

### Python

```python
from opal import jobs

res = jobs.check_running_jobs()
print(res)
# {"ok": True, "data": {...}}  # depends on your backend payload
```

### CLI

```bash
python -m opal.main jobs check-running-jobs
```


---

## 8. Health check

Check that the Opal backend is reachable.

### Python

```python
from opal import jobs

res = jobs.check_health()
print(res)
# {"ok": True, "data": {...}}  on success
```

### CLI

```bash
python -m opal.main jobs check-health
```

---

## 9. Discover available job types

List job types supported by the current backend.

### Python

```python
from opal import jobs

res = jobs.get_job_types()
print(res)
# {"ok": True, "data": ["generate_conformers", "absolute_solvation_energy_aqueous", ...]}
```

### CLI

```bash
python -m opal.main jobs get-job-types
```

The CLI version prints a prettier, less noisy summary.

---

## 10. Submit a batch of jobs (same job_type, many inputs)

You can submit **multiple jobs at once** for a single `job_type`.
Each entry in the list becomes a **separate job** under the hood.

### Python

```python
from opal import jobs

small_input_list = [
    {"smiles": "CCO",   "num_conformers": 5},
    {"smiles": "CCCO",  "num_conformers": 3},
    {"smiles": "CCcndO","num_conformers": 2},
]

res = jobs.submit_batch_jobs(
    job_type="generate_conformers",
    input_data=small_input_list,
)
print(res)
# {
#   "ok": True,
#   "results": [
#       {
#         "index": 0,
#         "input": {...},
#         "response": {
#             "ok": True,
#             "data": {
#                 "job_id": "...",
#                 "status": "submitted",
#                 "message": "Job submitted successfully",
#                 ...
#             }
#         }
#       },
#       ...
#   ]
# }
```

### CLI

Same thing from the command line, using a JSON list:

```bash
python -m opal.main jobs submit-batch-jobs \
  --job-type generate_conformers \
  --input-data '[{"smiles": "CCO", "num_conformers": 5}, {"smiles": "CCCO", "num_conformers": 3}, {"smiles": "CCcndO", "num_conformers": 2}]'
```

The CLI will print a summary like:

* Total jobs
* Number of successes / failures
* Per-job `job_id` and status

---

## 11. Log out

When you’re done, you can clear the local tokens.

### Python

```python
from opal import auth

res = auth.logout()
print(res)  # {"ok": True}
```

### CLI

```bash
python -m opal.main logout
```

---

## TL;DR minimal workflows

### Python minimal workflow

```python
from opal import auth, jobs

# 1) Log in
auth.login(email="test@example.com", password="pass123")

# 2) Submit a job
submit_res = jobs.submit(
    job_type="generate_conformers",
    input_data={"smiles": "CCO", "num_conformers": 5},
)
print(submit_res)

# 3) List recent jobs
print(jobs.get_jobs())

# 4) Fetch that job by ID
job_id = submit_res["data"]["job_id"]
print(jobs.get(job_id=job_id))
```

### CLI minimal workflow

```bash
# 1) Log in
python -m opal.main login

# 2) Submit one job
python -m opal.main jobs submit \
  --job-type generate_conformers \
  --input-data '{"smiles": "CCO", "num_conformers": 5}'

# 3) See your last 5 jobs
python -m opal.main jobs get-jobs

# 4) Get a specific job
python -m opal.main jobs get --job-id YOUR_JOB_ID
```

### Help Commands

```bash
python -m opal.main --help

python -m opal.main jobs --help

python -m opal.main jobs submit --help
```

## Next

For more details and examples, see:

- [Quickstart.md](Quickstart.md)
- [API_Reference.md](API_Reference.md)
- [Job_Types.md](Job_Types.md)



**All Rights Reserved**
