Metadata-Version: 2.4
Name: noimosiny
Version: 1.0.1
Summary: Python SDK for the Noimosiny API.
Project-URL: Homepage, https://github.com/noimosiny/py-sdk
Project-URL: Bug Tracker, https://github.com/noimosiny/py-sdk/issues
Author-email: Noimosiny Dev <contact@noimosiny.com>
License-Expression: MIT
License-File: LICENSE
Classifier: Development Status :: 3 - Alpha
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
Requires-Python: >=3.8
Requires-Dist: requests>=2.25.0
Description-Content-Type: text/markdown

# Noimosiny Python SDK

[![PyPI version](https://img.shields.io/pypi/v/noimosiny.svg?color=blue)](https://pypi.org/project/noimosiny/)
[![Python versions](https://img.shields.io/pypi/pyversions/noimosiny.svg)](https://pypi.org/project/noimosiny/)
[![License](https://img.shields.io/github/license/noimosiny/py-sdk.svg?color=green)](https://github.com/noimosiny/py-sdk/blob/main/LICENSE)
[![Code Style](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)

Python client library for the Noimosiny API (OSINT and reverse-lookup platform).

---

## Installation

Install the package via pip:

```bash
pip install noimosiny
```

*Note: For local development, ensure dependencies are installed via `pip install requests`.*

---

## Quick Start

Initialize the `Client` using your API token (which can be obtained from the settings page on the Noimosiny dashboard). You can retrieve your balance and perform searches within a context manager block:

```python
import os
from noimosiny import Client, NoimosinyError

def main():
    # Load API token from environment
    api_key = os.environ.get("NOIMOSINY_API_KEY", "your-api-key-here")

    try:
        # Use Client as a context manager for clean session closing
        with Client(api_key) as client:
            # Check account balances
            gold = client.get_gold_credits()
            silver = client.get_silver_credits()
            print(f"Balances: Gold={gold} credits | Silver={silver} credits")

            # Perform a reverse email lookup
            print("Running reverse email lookup...")
            results = client.search_email("user@example.com")
            print("Results:", results)
            
    except NoimosinyError as e:
        print(f"API Error occurred: {e}")

if __name__ == "__main__":
    main()
```

---

## API Reference & Endpoints

Under the hood, the Noimosiny API routes all client actions to a single endpoint (`POST https://api.noimosiny.com/v1/execute`). The SDK abstracts this payload structure entirely into clean, pythonic method calls.

### Rate Limits
- **5** simultaneous requests.
- **60** requests per minute.

---

### Account & Balances

#### `get_gold_credits() -> int`
Retrieves your current Gold credit balance. Gold credits are consumed by reverse search queries (email, phone, username).
- **Equivalent API payload method:** `getGoldCredits`
- **Example Return Value:** `1000`

#### `get_silver_credits() -> int`
Retrieves your current Silver credit balance. Silver credits are consumed by advanced tool queries.
- **Equivalent API payload method:** `getSilverCredits`
- **Example Return Value:** `5000`

---

### Reverse Search Operations

All search operations return a python dictionary matching the API's standard response format. Each query will scan several internal modules and return success statuses along with metadata from matches.

#### `search_email(email: str) -> dict`
Perform a reverse email lookup to find associated social media profiles and online registration records.
- **Equivalent API payload parameter:** `"type": "reverse_email"`
- **Response Format Example:**
  ```json
  {
      "type": "reverse_email",
      "query": "user@example.com",
      "results": [
          {
              "module": "TikTok",
              "success": true,
              "data": {
                  "id": "70397021345678",
                  "likes": 28506,
                  "region": "Australia",
                  "videos": 792,
                  "private": false,
                  "language": "en",
                  "username": "johndoe",
                  "verified": false,
                  "followers": 1029,
                  "following": 670,
                  "created_at": "2021-12-10 00:14:02",
                  "profile_url": "https://tiktok.com/@johndoe",
                  "display_name": "John Doe",
                  "social_profiles": {
                      "youtube": "John Doe"
                  }
              }
          }
      ]
  }
  ```

#### `search_phone(phone: str) -> dict`
Perform a reverse phone number search to find ownership details, carrier details, and geographical location info.
- **Equivalent API payload parameter:** `"type": "reverse_phone"`
- **Response Format Example:**
  ```json
  {
      "type": "reverse_phone",
      "query": "+1234567890",
      "results": [
          {
              "module": "PhoneUS1",
              "success": true,
              "data": {
                  "zip": "12345",
                  "city": "New York",
                  "name": "John Doe",
                  "type": "Landline",
                  "state": "NY",
                  "county": "New York",
                  "carrier": "WINDSTREAM NUVOX, INC. - FL",
                  "latitude": "40.7128",
                  "longitude": "-74.0060",
                  "risk_scale": 0.6,
                  "risk_description": "possibly unsafe caller"
              }
          }
      ]
  }
  ```

#### `search_username(username: str) -> dict`
Perform a reverse search on a username to check registry status and profiles across multiple social networks.
- **Equivalent API payload parameter:** `"type": "reverse_username"`
- **Response Format Example:**
  ```json
  {
      "type": "reverse_username",
      "query": "johndoe",
      "results": [
          {
              "module": "Instagram",
              "success": true,
              "data": {
                  "url": "https://instagram.com/johndoe",
                  "username": "johndoe",
                  "image": "https://scontent-atl3-1.cdninstagram.com/v/............",
                  "followers_count": 918,
                  "following_count": 0,
                  "posts_count": 0,
                  "is_private": true,
                  "is_verified": false,
                  "is_business": false,
                  "is_professional": false
              }
          }
      ]
  }
  ```

---

## Error Handling

All SDK-specific exceptions subclass `NoimosinyError`. Catching it handles any API or connection issue:

```python
from noimosiny import Client
from noimosiny.exceptions import (
    NoimosinyError,
    AuthenticationError,
    RateLimitError,
    InsufficientCreditsError,
    BadRequestError,
    ServerError
)

try:
    with Client("API_KEY") as client:
        client.search_email("test@example.com")
except AuthenticationError:
    print("Invalid API Key.")
except RateLimitError:
    print("Too many requests. Please throttle your queries.")
except InsufficientCreditsError:
    print("Your account is out of credits.")
except BadRequestError as e:
    print(f"Invalid query parameters: {e}")
except ServerError:
    print("An unexpected server-side error occurred on the Noimosiny API.")
except NoimosinyError as e:
    print(f"Generic SDK error: {e}")
```

### Exception Hierarchy

- `NoimosinyError` (Base exception class)
  - `AuthenticationError` (401 Unauthorized)
  - `RateLimitError` (429 Too Many Requests)
  - `APIRequestError` (Base for request validation & API responses)
    - `BadRequestError` (400 Bad Request)
    - `InsufficientCreditsError` (403 Forbidden)
    - `APITimeoutError` (408 Request Timeout)
    - `ServerError` (500+ Internal Server Error)
