# Neuwo API Python SDK
Python SDK client for the Neuwo content classification API.
[](https://pypi.org/project/neuwo-api/)
[](https://pypi.org/project/neuwo-api/)
[](https://opensource.org/licenses/MIT)
## Support
- **Neuwo**: [https://neuwo.ai](https://neuwo.ai)
- **Documentation**: [https://docs.neuwo.ai](https://docs.neuwo.ai)
- **Repository**: [GitHub](https://github.com/neuwoai/neuwo-api-sdk-python)
- **Issues**: [GitHub Issues](https://github.com/neuwoai/neuwo-api-sdk-python/issues)
- **Email Support**: [neuwo-helpdesk@neuwo.ai](mailto:neuwo-helpdesk@neuwo.ai)
## Installation
Install the package using pip:
```bash
pip install neuwo-api
```
Install with optional development dependencies:
```bash
# For development
pip install neuwo-api[dev]
# For testing
pip install neuwo-api[test]
```
## Requirements
- Python 3.8 or higher
- `requests` library (automatically installed)
## Quick Start
For more detailed examples and use cases, see the [examples folder](examples/) in the repository.
### REST API Client
```python
from neuwo_api import NeuwoRestClient
# Initialize client
client = NeuwoRestClient(
token="your-rest-api-token",
base_url="https://custom.api.com",
)
# Analyze text content
response = client.get_ai_topics(
content="Cats make wonderful pets for modern households.",
document_id="article-123",
headline="Why Cats Make Great Pets"
)
# Access results
print(f"Tags: {len(response.tags)}")
for tag in response.tags:
print(f" - {tag.value} (score: {tag.score})")
print(f"Brand Safe: {response.brand_safety.is_safe}")
print(f"IAB Categories: {len(response.marketing_categories.iab_tier_1)}")
```
### EDGE API Client
```python
from neuwo_api import NeuwoEdgeClient
# Initialize client
client = NeuwoEdgeClient(
token="your-edge-api-token",
base_url="https://custom.api.com",
origin="https://yourwebsite.com" # Optional: default origin for requests
)
# Analyze article by URL
response = client.get_ai_topics(url="https://example.com/article")
# Or wait for analysis to complete (with automatic retry)
response = client.get_ai_topics_wait(
url="https://example.com/new-article",
max_retries=10,
retry_interval=6
)
print(f"Found {len(response.tags)} tags for the article")
```
## Configuration
### REST Client Parameters
| Parameter | Type | Default | Description |
| ---------- | ----- | ------------ | ----------------------------- |
| `token` | `str` | **Required** | REST API authentication token |
| `base_url` | `str` | **Required** | Base URL for the API |
| `timeout` | `int` | `60` | Request timeout in seconds |
**Example:**
```python
client = NeuwoRestClient(
token="your-token",
base_url="https://custom.api.com",
timeout=120
)
```
### EDGE Client Parameters
| Parameter | Type | Default | Description |
| ---------- | ----- | ------------ | ---------------------------------- |
| `token` | `str` | **Required** | EDGE API authentication token |
| `base_url` | `str` | **Required** | Base URL for the API |
| `timeout` | `int` | `60` | Request timeout in seconds |
| `origin` | `str` | `None` | Default Origin header for requests |
**Example:**
```python
client = NeuwoEdgeClient(
token="your-token",
base_url="https://custom.api.com",
origin="https://yoursite.com",
timeout=90
)
```
### API Methods
#### REST API
##### Get AI Topics
```python
response = client.get_ai_topics(
content="Text to analyze", # Required
document_id="doc123", # Optional: save to database
lang="en", # Optional: ISO 639-1 code
publication_id="pub1", # Optional
headline="Article Headline", # Optional
tag_limit=15, # Optional: max tags (default: 15)
tag_min_score=0.1, # Optional: min score (default: 0.1)
marketing_limit=None, # Optional
marketing_min_score=0.3, # Optional (default: 0.3)
include_in_sim=True, # Optional (default: True)
article_url="https://example.com" # Optional
)
```
##### Get Similar Articles
```python
articles = client.get_similar(
document_id="doc123", # Required
max_rows=10, # Optional: limit results
past_days=30, # Optional: limit by date
publication_ids=["pub1", "pub2"] # Optional: filter by publication
)
```
##### Update Article
```python
from datetime import date
article = client.update_article(
document_id="doc123", # Required
published=date(2024, 1, 15), # Optional
headline="Updated Headline", # Optional
writer="Author Name", # Optional
category="News", # Optional
content="Updated content", # Optional
summary="Summary", # Optional
publication_id="pub1", # Optional
article_url="https://example.com", # Optional
include_in_sim=True # Optional
)
```
##### Train AI Topics
```python
training_tags = client.train_ai_topics(
document_id="doc123", # Required
tags=["tag1", "tag2", "tag3"], # Required
)
```
#### EDGE API
##### Get AI Topics (Single URL)
```python
response = client.get_ai_topics(
url="https://example.com/article", # Required
origin="https://yoursite.com" # Optional: override default origin
)
```
##### Get AI Topics with Auto-Retry
```python
response = client.get_ai_topics_wait(
url="https://example.com/article", # Required
origin="https://yoursite.com", # Optional
max_retries=10, # Optional (default: 10)
retry_interval=6, # Optional (default: 6s)
initial_delay=2 # Optional (default: 2s)
)
```
##### Get AI Topics (Multiple URLs)
```python
# From list
results = client.get_ai_topics_list(
urls=["https://example.com/1", "https://example.com/2"],
origin="https://yoursite.com"
)
# From file bytes
with open("urls.txt", "rb") as f:
urls_as_bytes = f.read()
result = client.get_ai_topics_list(urls_as_bytes)
```
##### Get Similar Articles
```python
articles = client.get_similar(
document_url="https://example.com/article", # Required
max_rows=10, # Optional
past_days=30, # Optional
publication_ids=["pub1", "pub2"], # Optional
origin="https://yoursite.com" # Optional
)
```
#### Raw Response Methods
All methods have `_raw` variants that return the raw `requests.Response` object:
```python
# REST
raw_response = client.get_ai_topics_raw(content="Text")
print(raw_response.status_code)
print(raw_response.text)
# EDGE
raw_response = client.get_ai_topics_raw(url="https://example.com")
print(raw_response.json())
```
## Error Handling
The SDK provides specific exceptions for different error scenarios:
```python
from neuwo_api import (
NeuwoRestClient,
ValidationError,
AuthenticationError,
NoDataAvailableError,
ContentNotAvailableError,
NetworkError
)
client = NeuwoRestClient(
token="your-token"
base_url="https://custom.api.com",
)
try:
response = client.get_ai_topics(content="Your content here")
except ValidationError as e:
print(f"Invalid input: {e}")
except AuthenticationError as e:
print(f"Authentication failed: {e}")
except NoDataAvailableError as e:
print(f"Data not yet available: {e}")
except ContentNotAvailableError as e:
print(f"Content could not be analyzed: {e}")
except NetworkError as e:
print(f"Network error: {e}")
except Exception as e:
print(f"Unexpected error: {e}")
```
### Exception Hierarchy
- `NeuwoAPIError` - Base exception for all API errors
- `AuthenticationError` - Invalid or missing token (401)
- `ForbiddenError` - Token lacks permissions (403)
- `NotFoundError` - Resource not found (404)
- `NoDataAvailableError` - URL not yet processed (404)
- `BadRequestError` - Malformed request (400)
- `ValidationError` - Request validation failed (422)
- `RateLimitError` - Rate limit exceeded (429)
- `ServerError` - Server error (5xx)
- `NetworkError` - Network communication failed
- `ContentNotAvailableError` - Content tagging failed
## Logging
The SDK uses Python's standard logging module. Enable logging to see detailed API communication:
```python
from neuwo_api import setup_logger
import logging
# Enable debug logging
setup_logger(level=logging.DEBUG)
# Or just warnings and errors (default)
setup_logger(level=logging.WARNING)
# Disable logging
from neuwo_api import disable_logger
disable_logger()
```
**Custom logging configuration:**
```python
import logging
from neuwo_api import get_logger
# Get the SDK logger
logger = get_logger()
# Add custom handler
handler = logging.FileHandler('neuwo_api.log')
handler.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
```
## Development
### Setup Development Environment
```bash
# Clone repository
git clone https://github.com/neuwoai/neuwo-api-sdk-python.git
cd neuwo-api-sdk-python
# Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install in development mode with all dependencies
pip install -e ".[dev]"
```
### Running Tests
```bash
# Run all tests
pytest
# Run with coverage
pytest --cov=neuwo_api --cov-report=html
# Run specific test file
pytest tests/test_rest_client.py
# Run with verbose output
pytest -v
```
<!-- ### Code Quality
```bash
# Format code
black neuwo_api/ tests/
# Sort imports
isort neuwo_api/ tests/
# Lint
flake8 neuwo_api/ tests/
# Type checking
mypy neuwo_api/
``` -->
### Building Distribution
```bash
# Install build tools
pip install build twine
# Build
python -m build
# Upload to PyPI
twine upload dist/*
```
## CI/CD
### Automated Testing
The [Unit Tests Coverage workflow](.github/workflows/unit-tests-coverage.yaml) automatically runs on every push to `main` or `dev` branches and on pull requests:
- **Python versions tested**: 3.8, 3.9, 3.10, 3.11, 3.12
- **Coverage reporting**: Results uploaded to Codecov
- **Test execution**: Full test suite with coverage analysis
### Publishing Pipeline
The [Publish Python Package workflow](.github/workflows/publish-sdk.yaml) enables manual deployment with the following options:
#### Workflow Features:
- Manual trigger via GitHub Actions UI
- Deploy to **TestPyPI** or **PyPI**
- Upload artifacts to **GitHub Packages**
- Auto-create **GitHub releases** with tags
- Automatic version extraction from `pyproject.toml`
#### Setup Requirements:
Add GitHub secrets for API tokens:
- `PYPI_API_TOKEN` - Production PyPI token
- `TEST_PYPI_API_TOKEN` - TestPyPI token
#### Workflow Inputs
| Input | Type | Default | Description |
| ------------------- | ------- | -------- | ---------------------------------------------- |
| `target` | choice | TestPyPI | Deploy to `TestPyPI` or `PyPI` |
| `publish_to_github` | boolean | false | Upload artifacts to GitHub |
| `create_release` | boolean | false | Create GitHub release with tag (only for PyPI) |
#### Usage:
1. **Testing release**:
- Go to Actions > Publish Python Package > Run workflow
- Select: TestPyPI
- Test: `pip install -i https://test.pypi.org/simple/ neuwo-api`
2. **Production release**:
- Update version in [pyproject.toml](pyproject.toml), [setup.py](setup.py) and [README.md](README.md)
- Commit changes to repository
- Go to Actions > Publish Python Package > Run workflow
- Select: PyPI + Publish to GitHub Packages + Create GitHub release
- Creates tag (e.g., `v0.2.0`), GitHub release, and publishes to PyPI
3. **Verify**:
- Check PyPI: https://pypi.org/project/neuwo-api/
- Check GitHub Release: https://github.com/neuwoai/neuwo-api-sdk-python/releases
- Check packages appear in repo
#### What gets created:
- PyPI package: https://pypi.org/project/neuwo-api/
- GitHub release with `.whl` and `.tar.gz` files
- Git tag following `v{VERSION}` format
- Package artifacts in GitHub Actions
**Versioning:**
Follow [Semantic Versioning](https://semver.org/) (`MAJOR.MINOR.PATCH`):
- **MAJOR**: Breaking changes
- **MINOR**: New features (backward compatible)
- **PATCH**: Bug fixes (backward compatible)
## License
This project is licensed under the MIT License - see the [LICENCE](LICENCE) file for details.
Raw data
{
"_id": null,
"home_page": "https://neuwo.ai",
"name": "neuwo-api",
"maintainer": "Grzegorz Malisz",
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": "Grzegorz Malisz <grzegorz.malisz@neuwo.ai>",
"keywords": "neuwo, api, content, classification, tagging, ai, machine-learning, iab, taxonomy, brand-safety",
"author": "Grzegorz Malisz",
"author_email": "Grzegorz Malisz <grzegorz.malisz@neuwo.ai>",
"download_url": "https://files.pythonhosted.org/packages/2f/74/8014572ff4f251edbbac95d33ec02206e92e5bedcbb9414b161df1645fa0/neuwo_api-0.2.0.tar.gz",
"platform": null,
"description": "# Neuwo API Python SDK\n\nPython SDK client for the Neuwo content classification API.\n\n[](https://pypi.org/project/neuwo-api/)\n[](https://pypi.org/project/neuwo-api/)\n[](https://opensource.org/licenses/MIT)\n\n## Support\n\n- **Neuwo**: [https://neuwo.ai](https://neuwo.ai)\n- **Documentation**: [https://docs.neuwo.ai](https://docs.neuwo.ai)\n- **Repository**: [GitHub](https://github.com/neuwoai/neuwo-api-sdk-python)\n- **Issues**: [GitHub Issues](https://github.com/neuwoai/neuwo-api-sdk-python/issues)\n- **Email Support**: [neuwo-helpdesk@neuwo.ai](mailto:neuwo-helpdesk@neuwo.ai)\n\n## Installation\n\nInstall the package using pip:\n\n```bash\npip install neuwo-api\n```\n\nInstall with optional development dependencies:\n\n```bash\n# For development\npip install neuwo-api[dev]\n\n# For testing\npip install neuwo-api[test]\n```\n\n## Requirements\n\n- Python 3.8 or higher\n- `requests` library (automatically installed)\n\n## Quick Start\n\nFor more detailed examples and use cases, see the [examples folder](examples/) in the repository.\n\n### REST API Client\n\n```python\nfrom neuwo_api import NeuwoRestClient\n\n# Initialize client\nclient = NeuwoRestClient(\n token=\"your-rest-api-token\",\n base_url=\"https://custom.api.com\",\n)\n\n# Analyze text content\nresponse = client.get_ai_topics(\n content=\"Cats make wonderful pets for modern households.\",\n document_id=\"article-123\",\n headline=\"Why Cats Make Great Pets\"\n)\n\n# Access results\nprint(f\"Tags: {len(response.tags)}\")\nfor tag in response.tags:\n print(f\" - {tag.value} (score: {tag.score})\")\n\nprint(f\"Brand Safe: {response.brand_safety.is_safe}\")\nprint(f\"IAB Categories: {len(response.marketing_categories.iab_tier_1)}\")\n```\n\n### EDGE API Client\n\n```python\nfrom neuwo_api import NeuwoEdgeClient\n\n# Initialize client\nclient = NeuwoEdgeClient(\n token=\"your-edge-api-token\",\n base_url=\"https://custom.api.com\",\n origin=\"https://yourwebsite.com\" # Optional: default origin for requests\n)\n\n# Analyze article by URL\nresponse = client.get_ai_topics(url=\"https://example.com/article\")\n\n# Or wait for analysis to complete (with automatic retry)\nresponse = client.get_ai_topics_wait(\n url=\"https://example.com/new-article\",\n max_retries=10,\n retry_interval=6\n)\n\nprint(f\"Found {len(response.tags)} tags for the article\")\n```\n\n## Configuration\n\n### REST Client Parameters\n\n| Parameter | Type | Default | Description |\n| ---------- | ----- | ------------ | ----------------------------- |\n| `token` | `str` | **Required** | REST API authentication token |\n| `base_url` | `str` | **Required** | Base URL for the API |\n| `timeout` | `int` | `60` | Request timeout in seconds |\n\n**Example:**\n\n```python\nclient = NeuwoRestClient(\n token=\"your-token\",\n base_url=\"https://custom.api.com\",\n timeout=120\n)\n```\n\n### EDGE Client Parameters\n\n| Parameter | Type | Default | Description |\n| ---------- | ----- | ------------ | ---------------------------------- |\n| `token` | `str` | **Required** | EDGE API authentication token |\n| `base_url` | `str` | **Required** | Base URL for the API |\n| `timeout` | `int` | `60` | Request timeout in seconds |\n| `origin` | `str` | `None` | Default Origin header for requests |\n\n**Example:**\n\n```python\nclient = NeuwoEdgeClient(\n token=\"your-token\",\n base_url=\"https://custom.api.com\",\n origin=\"https://yoursite.com\",\n timeout=90\n)\n```\n\n### API Methods\n\n#### REST API\n\n##### Get AI Topics\n\n```python\nresponse = client.get_ai_topics(\n content=\"Text to analyze\", # Required\n document_id=\"doc123\", # Optional: save to database\n lang=\"en\", # Optional: ISO 639-1 code\n publication_id=\"pub1\", # Optional\n headline=\"Article Headline\", # Optional\n tag_limit=15, # Optional: max tags (default: 15)\n tag_min_score=0.1, # Optional: min score (default: 0.1)\n marketing_limit=None, # Optional\n marketing_min_score=0.3, # Optional (default: 0.3)\n include_in_sim=True, # Optional (default: True)\n article_url=\"https://example.com\" # Optional\n)\n```\n\n##### Get Similar Articles\n\n```python\narticles = client.get_similar(\n document_id=\"doc123\", # Required\n max_rows=10, # Optional: limit results\n past_days=30, # Optional: limit by date\n publication_ids=[\"pub1\", \"pub2\"] # Optional: filter by publication\n)\n```\n\n##### Update Article\n\n```python\nfrom datetime import date\n\narticle = client.update_article(\n document_id=\"doc123\", # Required\n published=date(2024, 1, 15), # Optional\n headline=\"Updated Headline\", # Optional\n writer=\"Author Name\", # Optional\n category=\"News\", # Optional\n content=\"Updated content\", # Optional\n summary=\"Summary\", # Optional\n publication_id=\"pub1\", # Optional\n article_url=\"https://example.com\", # Optional\n include_in_sim=True # Optional\n)\n```\n\n##### Train AI Topics\n\n```python\ntraining_tags = client.train_ai_topics(\n document_id=\"doc123\", # Required\n tags=[\"tag1\", \"tag2\", \"tag3\"], # Required\n)\n```\n\n#### EDGE API\n\n##### Get AI Topics (Single URL)\n\n```python\nresponse = client.get_ai_topics(\n url=\"https://example.com/article\", # Required\n origin=\"https://yoursite.com\" # Optional: override default origin\n)\n```\n\n##### Get AI Topics with Auto-Retry\n\n```python\nresponse = client.get_ai_topics_wait(\n url=\"https://example.com/article\", # Required\n origin=\"https://yoursite.com\", # Optional\n max_retries=10, # Optional (default: 10)\n retry_interval=6, # Optional (default: 6s)\n initial_delay=2 # Optional (default: 2s)\n)\n```\n\n##### Get AI Topics (Multiple URLs)\n\n```python\n# From list\nresults = client.get_ai_topics_list(\n urls=[\"https://example.com/1\", \"https://example.com/2\"],\n origin=\"https://yoursite.com\"\n)\n\n# From file bytes\nwith open(\"urls.txt\", \"rb\") as f:\n urls_as_bytes = f.read()\nresult = client.get_ai_topics_list(urls_as_bytes)\n```\n\n##### Get Similar Articles\n\n```python\narticles = client.get_similar(\n document_url=\"https://example.com/article\", # Required\n max_rows=10, # Optional\n past_days=30, # Optional\n publication_ids=[\"pub1\", \"pub2\"], # Optional\n origin=\"https://yoursite.com\" # Optional\n)\n```\n\n#### Raw Response Methods\n\nAll methods have `_raw` variants that return the raw `requests.Response` object:\n\n```python\n# REST\nraw_response = client.get_ai_topics_raw(content=\"Text\")\nprint(raw_response.status_code)\nprint(raw_response.text)\n\n# EDGE\nraw_response = client.get_ai_topics_raw(url=\"https://example.com\")\nprint(raw_response.json())\n```\n\n## Error Handling\n\nThe SDK provides specific exceptions for different error scenarios:\n\n```python\nfrom neuwo_api import (\n NeuwoRestClient,\n ValidationError,\n AuthenticationError,\n NoDataAvailableError,\n ContentNotAvailableError,\n NetworkError\n)\n\nclient = NeuwoRestClient(\n token=\"your-token\"\n base_url=\"https://custom.api.com\",\n)\n\ntry:\n response = client.get_ai_topics(content=\"Your content here\")\nexcept ValidationError as e:\n print(f\"Invalid input: {e}\")\nexcept AuthenticationError as e:\n print(f\"Authentication failed: {e}\")\nexcept NoDataAvailableError as e:\n print(f\"Data not yet available: {e}\")\nexcept ContentNotAvailableError as e:\n print(f\"Content could not be analyzed: {e}\")\nexcept NetworkError as e:\n print(f\"Network error: {e}\")\nexcept Exception as e:\n print(f\"Unexpected error: {e}\")\n```\n\n### Exception Hierarchy\n\n- `NeuwoAPIError` - Base exception for all API errors\n - `AuthenticationError` - Invalid or missing token (401)\n - `ForbiddenError` - Token lacks permissions (403)\n - `NotFoundError` - Resource not found (404)\n - `NoDataAvailableError` - URL not yet processed (404)\n - `BadRequestError` - Malformed request (400)\n - `ValidationError` - Request validation failed (422)\n - `RateLimitError` - Rate limit exceeded (429)\n - `ServerError` - Server error (5xx)\n - `NetworkError` - Network communication failed\n - `ContentNotAvailableError` - Content tagging failed\n\n## Logging\n\nThe SDK uses Python's standard logging module. Enable logging to see detailed API communication:\n\n```python\nfrom neuwo_api import setup_logger\nimport logging\n\n# Enable debug logging\nsetup_logger(level=logging.DEBUG)\n\n# Or just warnings and errors (default)\nsetup_logger(level=logging.WARNING)\n\n# Disable logging\nfrom neuwo_api import disable_logger\ndisable_logger()\n```\n\n**Custom logging configuration:**\n\n```python\nimport logging\nfrom neuwo_api import get_logger\n\n# Get the SDK logger\nlogger = get_logger()\n\n# Add custom handler\nhandler = logging.FileHandler('neuwo_api.log')\nhandler.setLevel(logging.DEBUG)\nformatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')\nhandler.setFormatter(formatter)\nlogger.addHandler(handler)\n```\n\n## Development\n\n### Setup Development Environment\n\n```bash\n# Clone repository\ngit clone https://github.com/neuwoai/neuwo-api-sdk-python.git\ncd neuwo-api-sdk-python\n\n# Create virtual environment\npython -m venv venv\nsource venv/bin/activate # On Windows: venv\\Scripts\\activate\n\n# Install in development mode with all dependencies\npip install -e \".[dev]\"\n```\n\n### Running Tests\n\n```bash\n# Run all tests\npytest\n\n# Run with coverage\npytest --cov=neuwo_api --cov-report=html\n\n# Run specific test file\npytest tests/test_rest_client.py\n\n# Run with verbose output\npytest -v\n```\n\n<!-- ### Code Quality\n\n```bash\n# Format code\nblack neuwo_api/ tests/\n\n# Sort imports\nisort neuwo_api/ tests/\n\n# Lint\nflake8 neuwo_api/ tests/\n\n# Type checking\nmypy neuwo_api/\n``` -->\n\n### Building Distribution\n\n```bash\n# Install build tools\npip install build twine\n\n# Build\npython -m build\n\n# Upload to PyPI\ntwine upload dist/*\n```\n\n## CI/CD\n\n### Automated Testing\n\nThe [Unit Tests Coverage workflow](.github/workflows/unit-tests-coverage.yaml) automatically runs on every push to `main` or `dev` branches and on pull requests:\n\n- **Python versions tested**: 3.8, 3.9, 3.10, 3.11, 3.12\n- **Coverage reporting**: Results uploaded to Codecov\n- **Test execution**: Full test suite with coverage analysis\n\n### Publishing Pipeline\n\nThe [Publish Python Package workflow](.github/workflows/publish-sdk.yaml) enables manual deployment with the following options:\n\n#### Workflow Features:\n\n- Manual trigger via GitHub Actions UI\n- Deploy to **TestPyPI** or **PyPI**\n- Upload artifacts to **GitHub Packages**\n- Auto-create **GitHub releases** with tags\n- Automatic version extraction from `pyproject.toml`\n\n#### Setup Requirements:\n\nAdd GitHub secrets for API tokens:\n\n- `PYPI_API_TOKEN` - Production PyPI token\n- `TEST_PYPI_API_TOKEN` - TestPyPI token\n\n#### Workflow Inputs\n\n| Input | Type | Default | Description |\n| ------------------- | ------- | -------- | ---------------------------------------------- |\n| `target` | choice | TestPyPI | Deploy to `TestPyPI` or `PyPI` |\n| `publish_to_github` | boolean | false | Upload artifacts to GitHub |\n| `create_release` | boolean | false | Create GitHub release with tag (only for PyPI) |\n\n#### Usage:\n\n1. **Testing release**:\n\n - Go to Actions > Publish Python Package > Run workflow\n - Select: TestPyPI\n - Test: `pip install -i https://test.pypi.org/simple/ neuwo-api`\n\n2. **Production release**:\n - Update version in [pyproject.toml](pyproject.toml), [setup.py](setup.py) and [README.md](README.md)\n - Commit changes to repository\n - Go to Actions > Publish Python Package > Run workflow\n - Select: PyPI + Publish to GitHub Packages + Create GitHub release\n - Creates tag (e.g., `v0.2.0`), GitHub release, and publishes to PyPI\n\n3. **Verify**:\n - Check PyPI: https://pypi.org/project/neuwo-api/\n - Check GitHub Release: https://github.com/neuwoai/neuwo-api-sdk-python/releases\n - Check packages appear in repo\n\n#### What gets created:\n\n- PyPI package: https://pypi.org/project/neuwo-api/\n- GitHub release with `.whl` and `.tar.gz` files\n- Git tag following `v{VERSION}` format\n- Package artifacts in GitHub Actions\n\n**Versioning:**\n\nFollow [Semantic Versioning](https://semver.org/) (`MAJOR.MINOR.PATCH`):\n\n- **MAJOR**: Breaking changes\n- **MINOR**: New features (backward compatible)\n- **PATCH**: Bug fixes (backward compatible)\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENCE](LICENCE) file for details.\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Neuwo API SDK - Python SDK client for the Neuwo content classification API.",
"version": "0.2.0",
"project_urls": {
"Documentation": "https://docs.neuwo.ai",
"Homepage": "https://neuwo.ai",
"Repository": "https://github.com/neuwoai/neuwo-api-sdk-python"
},
"split_keywords": [
"neuwo",
" api",
" content",
" classification",
" tagging",
" ai",
" machine-learning",
" iab",
" taxonomy",
" brand-safety"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "e58e33f7f4c17cb1fed93d0b2464335ccf1a94115fda3b4db729eb0d3ae1c1df",
"md5": "1f8806617ec8214bb274611e5199dc57",
"sha256": "169b233835bc500e8b7d615985002eba276ba6dc0a6ff0bddb03b92015842637"
},
"downloads": -1,
"filename": "neuwo_api-0.2.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "1f8806617ec8214bb274611e5199dc57",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 25820,
"upload_time": "2025-10-27T13:10:01",
"upload_time_iso_8601": "2025-10-27T13:10:01.147339Z",
"url": "https://files.pythonhosted.org/packages/e5/8e/33f7f4c17cb1fed93d0b2464335ccf1a94115fda3b4db729eb0d3ae1c1df/neuwo_api-0.2.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "2f748014572ff4f251edbbac95d33ec02206e92e5bedcbb9414b161df1645fa0",
"md5": "efb2e20ae252f92cabf6c0210a3d372e",
"sha256": "c26fa9757f7fe6c62bdf0eeee4ff3b5ecc310ddcfbe4bdc5e369109b9448f538"
},
"downloads": -1,
"filename": "neuwo_api-0.2.0.tar.gz",
"has_sig": false,
"md5_digest": "efb2e20ae252f92cabf6c0210a3d372e",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 45616,
"upload_time": "2025-10-27T13:10:01",
"upload_time_iso_8601": "2025-10-27T13:10:01.969800Z",
"url": "https://files.pythonhosted.org/packages/2f/74/8014572ff4f251edbbac95d33ec02206e92e5bedcbb9414b161df1645fa0/neuwo_api-0.2.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-27 13:10:01",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "neuwoai",
"github_project": "neuwo-api-sdk-python",
"github_not_found": true,
"lcname": "neuwo-api"
}