Metadata-Version: 2.4
Name: hacksmith
Version: 1.0.0
Summary: Official Python SDK for the HackSmith AI API — chat, image generation, and multi-key management.
Author: codeleabwithosman
License: MIT
Project-URL: Homepage, https://github.com/codeleabwithosman
Project-URL: Repository, https://github.com/codeleabwithosman
Keywords: ai,hacksmith,llm,chat,image-generation,gpt,gemini
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.8
Description-Content-Type: text/markdown
Requires-Dist: requests>=2.28.0

# HackSmith Python SDK

Official Python SDK for the HackSmith AI API.

Access every model — GPT, Gemini, DeepSeek, Grok, Claude, Mistral, and more — plus AI image generation, from a single clean library. No juggling raw HTTP requests. No exposing your full codebase.

---

## Installation

```bash
pip install hacksmith
```

---

## Authentication

Every request requires an API token from your HackSmith dashboard. Tokens begin with `thenoob-`.

---

## Quickstart

### All-in-one client

```python
from hacksmith import HackSmithClient

client = HackSmithClient("thenoob-your-key-here")

# Chat
reply = client.chat("Explain what a transformer model is.")
print(reply.text)

# Generate an image
job = client.generate_image("A futuristic city at dusk, cinematic lighting")
urls = job.wait()
print(urls[0])

# Generate a logo
job = client.generate_logo("A wolf head esports mascot", style="3D Logo")
urls = job.wait()
print(urls[0])

# List all available models
client.models().display()
```

---

## Chat Only

```python
from hacksmith.chat import ChatClient

client = ChatClient("thenoob-your-key")

reply = client.send("What is the capital of Ghana?")
print(reply.text)
print(reply.provider)    # e.g. "Starnest"
print(reply.model_label) # e.g. "GPT-4o"

# Choose a specific model
reply = client.send("Write a haiku about rain.", model="gemini_3_pro")
print(reply.text)

# Attach a file
reply = client.send("Summarise this document.", file_path="report.pdf")
print(reply.text)
```

---

## Image Generation Only

```python
from hacksmith.image import ImageClient

client = ImageClient("thenoob-your-key")

# General image
job = client.generate("A cyberpunk cat on a neon-lit rooftop")
urls = job.wait()

# Nano style (faster, lighter)
job = client.generate("Abstract geometric mountains", style="Nano Banana")
urls = job.wait()

# Logo
job = client.logo("A minimalist coffee shop brand", style="Elegant Logo")
urls = job.wait()

# Remix (image-to-image)
job = client.generate(
    prompt="Turn this into a watercolour painting",
    seed_image_path="photo.jpg"
)
urls = job.wait()

# See all available logo styles
print(ImageClient.logo_styles())
```

---

## Available Models

```python
from hacksmith import HackSmithClient

client = HackSmithClient("thenoob-your-key")
client.models().display()
```

This prints a formatted table of every available model slug and label.

**Model groups include:** GPT, Gemini, DeepSeek, Grok, Claude, Mistral, o-series, Perplexity.

---

## Multiple API Keys

You can register multiple keys in one client and route requests to the right key by alias.

```python
from hacksmith import HackSmithClient

client = HackSmithClient("thenoob-primary-key")

client.add_key("thenoob-second-key", alias="project-b")
client.add_key("thenoob-third-key",  alias="analytics")

# Use a specific key
reply = client.chat("Hello", key="project-b")

# Remove a key when done
client.remove_key("analytics")

# See all registered keys
print(client.list_keys())
```

---

## System Prompts

You can set a custom system prompt per client, per key, or per message.

**Disclaimer:** A system prompt set here is fully isolated to your code. It does NOT read from or write to the global workspace persona configured in the HackSmith dashboard. If you do not provide a system prompt, the server automatically applies your workspace persona.

```python
# Client-level: applied to every request from this client
client = HackSmithClient(
    "thenoob-your-key",
    system_prompt="You are a senior Python engineer. Be concise and precise."
)

# Key-level: per registered key
client.add_key(
    "thenoob-second-key",
    alias="analyst",
    system_prompt="You are a financial data analyst. Use clear bullet points."
)

# Per-request override (stacks on top of client/key-level prompt)
reply = client.chat(
    "Explain compound interest.",
    key="analyst",
    system_prompt="Limit your answer to three sentences."
)

# Update a key's system prompt at any time
client.set_system_prompt("You are a helpful assistant.", key="analyst")

# Clear the system prompt (falls back to workspace persona)
client.set_system_prompt(None, key="analyst")
```

---

## Error Handling

```python
from hacksmith import HackSmithClient
from hacksmith.exceptions import (
    AuthenticationError,
    TokenExpiredError,
    TokenRevokedError,
    RateLimitError,
    NSFWError,
    APIError,
)

client = HackSmithClient("thenoob-your-key")

try:
    reply = client.chat("Hello!")
    print(reply.text)

except TokenExpiredError:
    print("Your token has expired. Log in to HackSmith to check your plan.")

except TokenRevokedError:
    print("Token was revoked. Generate a new one from the dashboard.")

except AuthenticationError as e:
    print(f"Auth error: {e}")

except RateLimitError as e:
    print(f"Rate limit hit. Try again after: {e.reset_at}")

except NSFWError:
    print("Prompt rejected for containing disallowed content.")

except APIError as e:
    print(f"API error ({e.status_code}): {e}")
```

---

## Image Job Status

If you need non-blocking image polling:

```python
job = client.generate_image("A mountain landscape at sunrise")

# Non-blocking: check status manually
status = client.image.status(job.record_id)
print(status["status"])  # "QUEUED", "DONE", or "FAILED"

# Blocking: wait until done (default: polls every 3s, max 180s)
urls = job.wait(poll_interval=3.0, max_wait=180.0)
```

---

## Logo Styles

```python
from hacksmith.image import ImageClient
print(ImageClient.logo_styles())
```

Available: Minimalistic Logo, Monogram Logo, Futuristic Logo, Elegant Logo, Gradient Logo, 3D Logo, Epic Logo, Combination Logo, Emblem Logo, Abstract Logo, Mascots Logo, Geometric Logo, Hand-drawn Logo, Grunge Logo — plus numbered variants for each.

---

## License

MIT — Copyright codeleabwithosman
