Metadata-Version: 2.4
Name: appliku
Version: 0.2.2
Summary: Python CLI and SDK for Appliku
Project-URL: Homepage, https://github.com/appliku/appliku-cli
Project-URL: Documentation, https://github.com/appliku/appliku-cli#readme
Project-URL: Issues, https://github.com/appliku/appliku-cli/issues
Author-email: Appliku <dev@appliku.com>
License-Expression: MIT
License-File: LICENSE
Keywords: appliku,cli,deployment,paas,sdk
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Internet
Requires-Python: >=3.10
Requires-Dist: attrs>=26.1.0
Requires-Dist: httpx>=0.27.0
Requires-Dist: pydantic[email]>=2.6.0
Requires-Dist: python-dateutil>=2.8.0
Requires-Dist: rich>=13.7.0
Requires-Dist: tomli-w>=1.0.0
Requires-Dist: tomli>=2.0.0; python_version < '3.11'
Requires-Dist: typer>=0.12.0
Provides-Extra: dev
Requires-Dist: httpx>=0.27.0; extra == 'dev'
Requires-Dist: mypy>=1.8.0; extra == 'dev'
Requires-Dist: pytest-httpx>=0.30.0; extra == 'dev'
Requires-Dist: pytest>=8.0.0; extra == 'dev'
Requires-Dist: ruff>=0.3.0; extra == 'dev'
Description-Content-Type: text/markdown

# appliku

[![PyPI version](https://badge.fury.io/py/appliku.svg)](https://pypi.org/project/appliku/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/downloads/)

Python CLI and SDK for the [Appliku](https://appliku.com) platform.

This package gives you:

- a CLI for common Appliku workflows
- a Python SDK for scripting and integrations

## Install uv

This project uses [uv](https://docs.astral.sh/uv/) for local development and is easiest to use with uv for both the CLI and SDK examples below.

macOS and Linux:

```bash
curl -LsSf https://astral.sh/uv/install.sh | sh
```

Windows PowerShell:

```powershell
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
```

After installation, restart your shell or verify:

```bash
uv --version
```

## Install appliku

For CLI usage, install the package as a tool:

```bash
uv tool install appliku
```

Then verify:

```bash
appliku --help
```

For SDK usage inside a Python project:

```bash
uv add appliku
```

If you prefer `pip`, this also works:

```bash
pip install appliku
```

## Authentication

The CLI supports two login methods:

1. Browser-based device flow:

```bash
appliku login
```

2. Direct token login:

```bash
appliku login --token YOUR_API_TOKEN
```

Useful auth commands:

```bash
appliku whoami
appliku logout
```

The SDK resolves credentials in this order:

1. `Appliku(token="...")`
2. `APPLIKU_TOKEN` environment variable
3. `~/.config/appliku/config.toml`

Example environment variable setup:

```bash
export APPLIKU_TOKEN=YOUR_API_TOKEN
```

## CLI Quick Start

List your teams:

```bash
appliku teams list
```

Inspect one team:

```bash
appliku teams get my-team
```

List applications in a team:

```bash
appliku apps list --team my-team
```

Show the latest deployment for an app:

```bash
appliku deployments latest --team my-team --app 42
```

List domains for an app:

```bash
appliku domains list --team my-team --app 42
```

List datastores for an app:

```bash
appliku datastores list --team my-team --app 42
```

Every list-style command also supports JSON output:

```bash
appliku apps list --team my-team --output json
```

## CLI Command Reference

### teams

Manage your Appliku teams.

```bash
appliku teams list
appliku teams get my-team
```

### apps

Manage applications and fetch logs.

```bash
# List apps in a team
appliku apps list --team my-team

# Fetch application-level logs (async, polls until ready)
appliku apps logs --team my-team --app 42 --process web
appliku apps logs --team my-team --app 42 --process web --process celery --tail 200

# Fetch service logs directly
appliku apps service-logs --team my-team --app 42 --service web --tail 100

# Fetch nginx access logs for a domain
appliku apps nginx-logs --team my-team --app 42 --domain example.com --tail 100

# Fetch load balancer logs for a domain
appliku apps load-balancer-logs --team my-team --app 42 --domain example.com --tail 100
```

### deployments

Inspect deployments and their logs.

```bash
# List deployments for an app
appliku deployments list --team my-team --app 42

# Show the latest deployment
appliku deployments latest --team my-team --app 42

# Fetch logs for a specific deployment
appliku deployments logs --team my-team --id 1234
```

### domains

Manage custom domains.

```bash
appliku domains list   --team my-team --app 42
appliku domains create --team my-team --app 42 --domain example.com
appliku domains delete --team my-team --app 42 --id 7
appliku domains check-dns --team my-team --app 42 --domain example.com
```

### datastores

Manage attached datastores (databases, caches, etc.).

```bash
appliku datastores list    --team my-team --app 42
appliku datastores start   --team my-team --app 42 --id 5
appliku datastores stop    --team my-team --app 42 --id 5
appliku datastores restart --team my-team --app 42 --id 5
appliku datastores delete  --team my-team --app 42 --id 5
```

### volumes

Manage persistent volumes.

```bash
appliku volumes list   --team my-team --app 42
appliku volumes delete --team my-team --app 42 --id 3
```

### crons

Manage cron jobs.

```bash
appliku crons list   --team my-team --app 42
appliku crons delete --team my-team --app 42 --id 8
```

### clusters

Manage Docker Swarm clusters.

```bash
appliku clusters list   --team my-team
appliku clusters delete --team my-team --id 2
```

### servers

Inspect servers.

```bash
appliku servers list --team my-team
appliku servers get  --team my-team --id 10
```

### invites

Manage team invitations.

```bash
appliku invites list   --team my-team
appliku invites delete --team my-team --id 4
```

### migrations

Manage and inspect database migrations.

```bash
appliku migrations list --team my-team
appliku migrations logs --team my-team --id 99
```

## SDK Quick Start

Create a client using a saved token or `APPLIKU_TOKEN`:

```python
from appliku import Appliku

client = Appliku()
```

Or pass the token explicitly:

```python
from appliku import Appliku

client = Appliku(token="YOUR_API_TOKEN")
```

List teams:

```python
from appliku import Appliku

client = Appliku()

for team in client.teams.list():
    print(team.team_path, team.plan)
```

Get one team and list its apps:

```python
from appliku import Appliku

client = Appliku()
team = client.teams.get("my-team")
apps = client.apps.list("my-team")

print(team.name)
for app in apps:
    print(app.id, app.name, app.last_deployment_status)
```

Get the latest deployment and fetch its logs:

```python
from appliku import Appliku

client = Appliku()
latest = client.deployments.latest("my-team", 42)
logs = client.deployments.logs("my-team", latest.id)

print(latest.status)
for entry in logs:
    print(entry.log)
```

Work with domains and datastores:

```python
from appliku import Appliku

client = Appliku()

domains = client.domains.list("my-team", 42)
datastores = client.datastores.list("my-team", 42)

print([d.domain for d in domains])
print([db.name for db in datastores])
```

## SDK Reference

All resources are accessed as properties on the `Appliku` instance.

### apps

```python
client.apps.list("my-team")
client.apps.get("my-team", app_id=42)
client.apps.create("my-team", name="my-app", branch="main")
client.apps.update("my-team", app_id=42, branch="develop")
client.apps.delete("my-team", app_id=42)
client.apps.deploy("my-team", app_id=42)

# Config vars
vars = client.apps.get_config_vars("my-team", app_id=42)
client.apps.set_config_vars("my-team", app_id=42, vars={"DEBUG": "false"})

# Application-level logs (async fetch)
logs = client.apps.get_logs("my-team", app_id=42, process="web", tail=100)
print(logs)

# Service logs (direct fetch)
logs = client.apps.get_service_logs("my-team", app_id=42, service="web", tail=100)

# Nginx / load balancer logs
logs = client.apps.get_nginx_logs("my-team", app_id=42, domain="example.com", tail=100)
logs = client.apps.get_load_balancer_logs("my-team", app_id=42, domain="example.com", tail=100)
```

### deployments

```python
client.deployments.list("my-team", app_id=42)
client.deployments.get("my-team", app_id=42, deployment_id=1234)
client.deployments.latest("my-team", app_id=42)
client.deployments.logs("my-team", deployment_id=1234)
```

### domains

```python
client.domains.list("my-team", app_id=42)
client.domains.get("my-team", app_id=42, domain_id=7)
client.domains.create("my-team", app_id=42, domain="example.com")
client.domains.delete("my-team", app_id=42, domain_id=7)

result = client.domains.check_dns("my-team", app_id=42, domain="example.com")
print(result.status)
```

### datastores

```python
client.datastores.list("my-team", app_id=42)
client.datastores.get("my-team", app_id=42, datastore_id=5)
client.datastores.create("my-team", app_id=42, name="mydb", kind="postgresql")
client.datastores.delete("my-team", app_id=42, datastore_id=5)
client.datastores.start("my-team", app_id=42, datastore_id=5)
client.datastores.stop("my-team", app_id=42, datastore_id=5)
client.datastores.restart("my-team", app_id=42, datastore_id=5)
```

### volumes

```python
client.volumes.list("my-team", app_id=42)
client.volumes.get("my-team", app_id=42, volume_id=3)
client.volumes.create("my-team", app_id=42, name="uploads", mount_path="/app/uploads")
client.volumes.update("my-team", app_id=42, volume_id=3, mount_path="/app/media")
client.volumes.delete("my-team", app_id=42, volume_id=3)
```

### cron_jobs

```python
client.cron_jobs.list("my-team", app_id=42)
client.cron_jobs.create("my-team", app_id=42, schedule="0 * * * *", command="python manage.py clearsessions")
client.cron_jobs.update("my-team", app_id=42, cron_id=8, schedule="30 2 * * *")
client.cron_jobs.delete("my-team", app_id=42, cron_id=8)
```

### clusters

```python
client.clusters.list("my-team")
client.clusters.get("my-team", cluster_id=2)
client.clusters.create("my-team", name="prod-cluster")
client.clusters.delete("my-team", cluster_id=2)
```

### servers

```python
client.servers.list("my-team")
client.servers.get("my-team", server_id=10)
```

### invites

```python
client.invites.list("my-team")
client.invites.create("my-team", email="colleague@example.com")
client.invites.delete("my-team", invite_id=4)
```

### migrations

```python
client.migrations.list("my-team")
client.migrations.run("my-team", app_id=42, command="python manage.py migrate")
client.migrations.logs("my-team", migration_id=99)
```

## Error Handling

The SDK raises typed exceptions:

```python
from appliku import Appliku, AuthenticationError, NotFoundError

client = Appliku()

try:
    client.teams.get("missing-team")
except AuthenticationError:
    print("Invalid or missing token")
except NotFoundError as exc:
    print(exc)
```

Main exception types:

- `AplikuError`
- `AuthenticationError`
- `AuthorizationError`
- `NotFoundError`
- `ValidationError`
- `RateLimitError`
- `ServerError`

## Development

Create or sync the local environment:

```bash
uv sync
```

Run tests:

```bash
UV_CACHE_DIR=/tmp/uv-cache uv run pytest
```

Run the CLI from the repo:

```bash
UV_CACHE_DIR=/tmp/uv-cache uv run appliku --help
```

Regenerate models and generated client code from the OpenAPI schema:

```bash
./scripts/codegen.sh
```

## License

MIT
