Metadata-Version: 2.5
Name: sweetconnect-api
Version: 0.3.0
Summary: A SweetConnect API library for Python
Project-URL: Homepage, https://github.com/sweetconnect/sweetconnect-api-client-python
Project-URL: Repository, https://github.com/sweetconnect/sweetconnect-api-client-python
Project-URL: Issues, https://github.com/sweetconnect/sweetconnect-api-client-python/issues
Project-URL: Changelog, https://github.com/sweetconnect/sweetconnect-api-client-python/releases
Author-email: Kai Clauß <kc@sweetconnect.io>, Eduardo Melgarejo <eduardo.melgarejo@sollich.com>, Felix Weisenfeld <felix.weisenfeld@w-u-d.com>
License: Apache-2.0
License-File: LICENSE
License-File: NOTICE
Requires-Python: >=3.10
Requires-Dist: click>=8.0.1
Requires-Dist: loguru>=0.6.0
Requires-Dist: pydantic<2.0.0,>=1.9.1
Requires-Dist: requests>=2.25.0
Description-Content-Type: text/markdown

# SweetConnect API Library

<!-- Uncomment once published / once CI and docs hosting exist
[![PyPI](https://img.shields.io/pypi/v/sweetconnect-api.svg)][pypi_]
[![Tests](https://github.com/sweetconnect/sweetconnect-api-client-python/actions/workflows/ci.yml/badge.svg)][tests]
 -->

[![Status](https://img.shields.io/badge/status-Alpha-orange)][status]
[![License](https://img.shields.io/badge/license-Apache_2.0-green)][license]
[![Python Version](https://img.shields.io/badge/python-%3E%3D%203.8-blue)][python version]
[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)][pre-commit]
[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)][ruff]

<!-- [pypi_]: https://pypi.org/project/sweetconnect-api/
[tests]: https://github.com/sweetconnect/sweetconnect-api-client-python/actions/workflows/ci.yml
 -->

[status]: https://pypi.org/project/sweetconnect-api/
[python version]: https://pypi.org/project/sweetconnect-api
[pre-commit]: https://github.com/pre-commit/pre-commit
[ruff]: https://github.com/astral-sh/ruff

## Installation

You can install _SweetConnect API Library_ via [pip] from [PyPI]:

```console
$ pip install sweetconnect-api
```

## Quick Start

Here's a simple example to get you started with the SweetConnect API:

```python
from sweetconnect_api import Assets, SweetConnectSession, SystemInfo
from sweetconnect_api.models.sc_assets import AddMachine, AlterMachine, Machine
from sweetconnect_api.models.sweetconnect_types import AssetView

# The base URL comes from the system you pick, not from a parameter.
# SystemInfo.production is the default; test and development also exist.
with SweetConnectSession("your_username", "your_password", SystemInfo.production) as s:
    # Read-only calls are static methods and take the session first.
    tree = Assets.get_asset_tree(s, AssetView.published)
    for node in tree:
        print(f"{node.name} ({node.id})")

    # create() and update() need a typed accessor, built from the
    # add model, the alter model and the asset model.
    machines = Assets(AddMachine, AlterMachine, Machine)

    # Calls return an (object, meta) tuple and raise on failure.
    machine, meta = machines.create(
        s,
        AddMachine(
            name="MyMachine",
            serialNumber="Machine No. 1",
            constructionYear="2026",
        ),
    )
    print(f"created {machine.name} ({machine.id})")
```

The session renews its access token automatically before it expires, so a
long-running script does not need to log in again.

## Error handling

Every call goes through the session, which raises `SweetConnectHTTPError` when
the platform answers outside the 2xx range. The exception carries the status
code and the error body the API sent:

```python
from sweetconnect_api import Assets, SweetConnectHTTPError

try:
    asset, _ = Assets.get(s, asset_id)
except SweetConnectHTTPError as error:
    print(error.status_code)  # 404
    print(error.detail)  # {"message": "asset not found"}
```

`SweetConnectError` is the base class, so a single `except SweetConnectError`
catches everything the library raises, including `SweetConnectAuthError` from
token handling. There is no need to import `requests` to handle errors.

> **Changed in 0.3.0.** Before this release the API methods returned `None` on
> failure and logged the error body, so a server error was indistinguishable
> from an empty result. Code that checked for `None` can drop the check; code
> that relied on the silence has to catch `SweetConnectHTTPError`.

For a fuller walkthrough, see the [examples/](examples/) directory.

## Development

This project uses [uv] for dependency management. To set up a development environment:

```console
# Install uv (if not already installed)
$ curl -LsSf https://astral.sh/uv/install.sh | sh

# Clone the repository
$ git clone https://github.com/sweetconnect/sweetconnect-api-client-python.git
$ cd sweetconnect-api-client-python

# Install dependencies
$ uv sync

# Run tests
$ uv run pytest

# Run linting checks (same as CI pipeline)
$ ./lint.sh

# Or run linting manually
$ uv run ruff check .
$ uv run ruff format .
```

[uv]: https://github.com/astral-sh/uv

### Testing Local Builds

Before creating a release, you can test your local changes:

```console
# Build the package locally
$ uv build

# Install the local build in a test environment
$ pip install dist/sweetconnect_api-*.whl

# Or test in an isolated environment
$ python -m venv test-env
$ source test-env/bin/activate  # On Windows: test-env\Scripts\activate
$ pip install dist/sweetconnect_api-*.whl

# Verify the installation
$ python -c "import sweetconnect_api; print(sweetconnect_api.__version__)"

# Clean up when done
$ deactivate
$ rm -rf test-env
```

### Code Quality Notes

**Linting:** This project uses [Ruff](https://github.com/astral-sh/ruff) for linting and formatting.

**Pre-commit Hooks:** This project uses pre-commit hooks to ensure code quality before commits.

To set up pre-commit hooks:

```console
# Install pre-commit hooks (one-time setup)
$ uv run pre-commit install

# Run hooks manually on all files
$ uv run pre-commit run --all-files

# Run hooks on staged files only (happens automatically on commit)
$ git commit
```

The pre-commit hooks will automatically check:

- **Ruff**: Code linting and formatting
- **File checks**: Large files, TOML/YAML syntax, trailing whitespace
- **Secret detection**: Prevents committing passwords, API keys, and private keys
- **Prettier**: Formats JSON/YAML/Markdown files

**Design Decisions:**

- **API Naming**: Models use `mixedCase` (e.g., `assetId`, `tenantId`) to match the SweetConnect REST API convention
- **Examples**: Star imports (`from module import *`) used in example files for brevity
- **Docstrings**: Optional for internal APIs (following project conventions)

**Areas for Future Improvement:**

- Add specific exception handling for bare `except` clauses
- Expand API documentation coverage

### Versioning

This project uses [hatch-vcs](https://github.com/ofek/hatch-vcs) for automatic version management based on Git tags, following [Semantic Versioning](https://semver.org/) (SemVer) with [PEP 440](https://peps.python.org/pep-0440/) compliance:

**Version Format:** `MAJOR.MINOR.PATCH`

- **MAJOR**: Breaking changes (not backwards compatible)
- **MINOR**: New features (backwards compatible)
- **PATCH**: Bug fixes (backwards compatible)

**Version Types:**

- **Stable releases** (e.g., `0.1.0`): Created from Git tags (e.g., `v0.1.0`)
- **Development versions** (e.g., `0.1.1.dev4`): Automatically generated between releases
- **Alpha versions** (e.g., `0.2.0a1`): Early testing (tag: `v0.2.0a1`)
- **Beta versions** (e.g., `0.2.0b1`): Feature-complete testing (tag: `v0.2.0b1`)
- **Release candidates** (e.g., `0.2.0rc1`): Pre-release testing (tag: `v0.2.0rc1`)

**Version Increment Guide:**

- **Patch (v0.1.1)**: Bug fixes only
- **Minor (v0.2.0)**: New features, backwards compatible
- **Major (v1.0.0)**: Breaking changes

**Deployment Workflows:**

The version is automatically determined from Git history - no manual version updates needed in `pyproject.toml`.

<details>
<summary><strong>📦 Creating a Pre-Release (Alpha/Beta/RC)</strong></summary>

Use pre-releases for testing new features before a stable release:

```console
# 1. Ensure your changes are committed and pushed to main
$ git checkout main
$ git pull origin main

# 2. Create and push a pre-release tag
$ git tag v0.2.0a1        # Alpha release
$ git push origin v0.2.0a1

# 3. The Release workflow automatically:
#    - Runs linting checks and tests
#    - Builds the package and verifies the version matches the tag
#    - Publishes to PyPI (after approval, if the environment requires it)

# 4. Test the pre-release
$ pip install sweetconnect-api==0.2.0a1

# 5. If issues found, fix them and create next pre-release
$ git tag v0.2.0a2
$ git push origin v0.2.0a2

# 6. Progress through testing phases
$ git tag v0.2.0b1        # Beta (feature complete)
$ git push origin v0.2.0b1

$ git tag v0.2.0rc1       # Release Candidate (final testing)
$ git push origin v0.2.0rc1
```

</details>

<details>
<summary><strong>🚀 Creating a Stable Release</strong></summary>

When all testing is complete and you're ready for production:

```console
# 1. Ensure main branch is ready
$ git checkout main
$ git pull origin main

# 2. Create and push the release tag
$ git tag v0.2.0
$ git push origin v0.2.0

# 3. The Release workflow automatically:
#    - Runs linting checks and tests
#    - Builds the package and verifies the version matches the tag
#    - Publishes to PyPI (after approval, if the environment requires it)

# 4. Verify the release on PyPI
$ pip install --upgrade sweetconnect-api

# 5. Update documentation/changelog if needed
```

</details>

### Continuous Integration

This project uses GitHub Actions. There are two workflows:

**`.github/workflows/ci.yml`** — runs on pushes to `main` and on pull requests:

- **Lint & format**: every pre-commit hook, which covers `ruff check` and
  `ruff format --check` for Python plus `prettier`, secret scanning and the
  file hygiene checks for everything else
- **Test**: pytest on Python 3.10 through 3.14, covering the floor declared in
  `requires-python` and the newest CPython release
- **Build & install check**: builds the wheel, installs it in a clean environment
  without dev dependencies, and imports every module. This catches runtime
  imports that are missing from `[project.dependencies]`.

Type checking is not enforced: mypy is configured strict but currently reports
errors that need to be addressed first.

**`.github/workflows/release.yml`** — runs only when a `v*` tag is pushed:

- Repeats lint and tests, then builds the package
- **Refuses to publish** if the built version does not exactly match the tag,
  which guards against shallow clones or missing tags silently producing a
  `.dev` version
- Publishes to PyPI via trusted publishing

Supported tag forms: `v0.2.0` (stable), `v0.2.0a1` (alpha), `v0.2.0b1` (beta),
`v0.2.0rc1` (release candidate). Pushing to `main` never publishes.

**Setup Requirements:**

Publishing uses [trusted publishing][trusted publishing] (OIDC) — there is no
PyPI token stored in this repository. It needs a one-time setup on PyPI:

1. Go to the `sweetconnect-api` project → Manage → Publishing
2. Add a GitHub publisher: owner `sweetconnect`, repository
   `sweetconnect-api-client-python`, workflow `release.yml`, environment `pypi`

Optionally add required reviewers to the `pypi` environment under
Settings → Environments to require a manual approval before each release.

[trusted publishing]: https://docs.pypi.org/trusted-publishers/

## Usage

See [Quick Start](#quick-start) above and the [examples/](examples/) directory.

### API Documentation

SweetConnect API documentation is available for different environments:

- **Production**: <https://doc.api.my.sweetconnect.io/> - Stable API for production use
- **Test**: <https://doc.api.test.sweetconnect.io/> - Testing environment for integration testing
- **Development**: <https://doc.api.dev.sweetconnect.io/> - Development environment with latest features

## Contributing

Contributions are very welcome! Here's how you can help:

1. **Report Issues**: [File an issue] with bug reports or feature requests
2. **Submit Pull Requests**: Fork the repository and submit PRs
3. **Improve Documentation**: Help expand the documentation
4. **Code Review**: Review and comment on open PRs

For detailed guidelines, see the [Contributor Guide].

**Development Setup:**

```console
# Fork and clone the repository
$ git clone https://github.com/<your-username>/sweetconnect-api-client-python.git
$ cd sweetconnect-api-client-python

# Set up development environment
$ uv sync
$ uv run pre-commit install

# Run tests and linting before committing
$ uv run pytest
$ ./lint.sh
```

This project was generated from [@cjolowicz]'s [Hypermodern Python Cookiecutter] template. For more details see [Hypermodern Python documentation]

## License

Distributed under the terms of the [Apache 2.0 license][license],
_SweetConnect API Library_ is free and open source software.

## Issues

If you encounter any problems,
please [file an issue] along with a detailed description.

[@cjolowicz]: https://github.com/cjolowicz
[pypi]: https://pypi.org/
[hypermodern python cookiecutter]: https://github.com/cjolowicz/cookiecutter-hypermodern-python
[hypermodern python documentation]: https://cookiecutter-hypermodern-python.readthedocs.io/
[file an issue]: https://github.com/sweetconnect/sweetconnect-api-client-python/issues/new
[pip]: https://pip.pypa.io/

<!-- github-only -->

[license]: https://github.com/sweetconnect/sweetconnect-api-client-python/blob/main/LICENSE
[contributor guide]: https://github.com/sweetconnect/sweetconnect-api-client-python/blob/main/CONTRIBUTING.md
