Skip to content

Commit 5e104ce

Browse files
authored
Feat/prepare release (#5)
* chore: update version * feat: make lab svc simpler * docs: update docs
1 parent 17f75d5 commit 5e104ce

File tree

8 files changed

+134
-27
lines changed

8 files changed

+134
-27
lines changed

README.md

Lines changed: 69 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,45 +7,104 @@ Allows you to spin up versioned Appwrite deployments for easy testing via CLI of
77
```sh
88
pip install appwrite-lab
99
```
10-
## Appwrite Lab features (in progress)
10+
## Appwrite Lab features
1111
- [x] Spin up ephemeral Appwrite instances with Docker/Podman
1212
- [x] Automatically grab API keys (for programmatic access)
13-
- [x] Environment syncing
13+
- [x] Environment syncing (with `appwrite.json`)
1414
- [x] Clean teardowns
15+
- [x] Test suite
1516

16-
## Appwrite Lab in progress features
17-
- [ ] Test suite
17+
## Appwrite Lab (in progress)
1818
- [ ] Appwrite data population
1919

2020
## CLI Usage
2121
### Help with appwrite-lab CLI
2222
```sh
2323
appwrite-lab --help
2424
```
25+
or
26+
```sh
27+
awlab --help
28+
```
29+
30+
### To get started spinning up a lab instance, use:
2531

26-
To get started spinning up a lab instance, use:
32+
```sh
33+
awlab new lab test --version 1.7.4
34+
```
35+
#### Example of additional args:
36+
Additional arguments can be found here.
37+
```sh
38+
awlab new lab --help
39+
```
2740

2841
```sh
29-
appwrite-lab new lab test-lab --version 1.7.4
42+
awlab new lab test --version 1.7.4 --port 8005 --email test@example.com --password xxxxxxx12
3043
```
3144

32-
To teardown,
45+
### To teardown
3346

3447
```sh
35-
appwrite-lab stop test-lab
48+
awlab stop test
49+
```
50+
### Listing Appwrite Labs
51+
```sh
52+
awlab list labs
3653
```
3754

3855
### Sync an Appwrite lab from your prod lab schema
3956
Run in the same folder where your `appwrite.json` is located to sync `all` resources:
4057
```sh
41-
appwrite-lab sync test-lab
58+
awlab sync test
4259
```
4360
or sync a specific resource:
4461

4562
```sh
46-
appwrite-lab sync test-lab --resource functions
63+
awlab sync test --resource functions
4764
```
4865

66+
## Python usage
67+
68+
### Creating a lab
69+
```py
70+
from appwrite_lab import Labs
71+
from appwrite_lab.models import AppwriteLabCreation
72+
73+
labs = Labs()
74+
lab_res = labs.new(
75+
name="test",
76+
version="1.7.4",
77+
auth=AppwriteLabCreation(
78+
admin_email="test@example.com",
79+
admin_password="xxxxxxx12",
80+
project_id=None, # for auto gen
81+
project_name=None, # for auto gen
82+
)
83+
port=8005
84+
)
85+
86+
assert lab_res.data
87+
```
88+
89+
#### Random generation that's compliant
90+
```py
91+
from appwrite_lab.models import AppwriteLabCreation
92+
93+
auth = AppwriteLabCreation.generate()
94+
```
95+
96+
### Syncing a lab
97+
```py
98+
from appwrite_lab import Labs
99+
from appwrite_lab.automations.models import Expiration
100+
101+
Labs().sync_with_appwrite_config(
102+
name="test",
103+
appwrite_json="appwrite.json", # if not directly in folder
104+
sync_type="all",
105+
expiration=Expiration.THIRTY_DAYS,
106+
)
107+
```
49108
## Known Troubleshooting
50109
### Podman support and Selinux
51110
Since I am mimicking the `compose` file that Appwrite provides, it was not designed to work rootless, but I have adjusted to work also on Fedora. You will need to turn `selinux` off for now to use.

appwrite_lab/_orchestrator.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@
66
import tempfile
77
from pathlib import Path
88

9-
from appwrite_lab.automations.models import BaseVarModel, AppwriteAPIKeyCreation
9+
from appwrite_lab.automations.models import (
10+
BaseVarModel,
11+
AppwriteAPIKeyCreation,
12+
AppwriteUserCreation,
13+
)
1014
from ._state import State
1115
from dataclasses import dataclass
1216
from .models import Lab, Automation, Project
@@ -162,7 +166,7 @@ def deploy_appwrite_lab(
162166
name: str,
163167
version: str,
164168
port: int,
165-
meta: dict[str, str],
169+
auth: AppwriteUserCreation | None = None,
166170
**kwargs: dict[str, str],
167171
):
168172
"""
@@ -172,11 +176,11 @@ def deploy_appwrite_lab(
172176
name: The name to give to the deployment/project.
173177
version: The version of the service to deploy.
174178
port: The port to use for the Appwrite service. Must not be in use by another service.
175-
meta: Extra metadata to pass to the deployment.
179+
auth: The authentication credentials.
176180
177181
"""
178182
# sync
179-
appwrite_config = meta.get("appwrite_config", {})
183+
appwrite_config = asdict(auth) if auth else {}
180184

181185
pods_by_project = self.get_pods_by_project(name)
182186
if len(pods_by_project) > 0:
Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,19 @@
11
from .common import AppwriteCLI
22
from .utils import PlaywrightAutomationError
3+
from .models import (
4+
AppwriteLabCreation,
5+
AppwriteUserCreation,
6+
AppwriteProjectCreation,
7+
AppwriteSyncProject,
8+
AppwriteAPIKeyCreation,
9+
)
310

4-
__all__ = ("AppwriteCLI", "PlaywrightAutomationError")
11+
__all__ = (
12+
"AppwriteCLI",
13+
"PlaywrightAutomationError",
14+
"AppwriteLabCreation",
15+
"AppwriteUserCreation",
16+
"AppwriteProjectCreation",
17+
"AppwriteSyncProject",
18+
"AppwriteAPIKeyCreation",
19+
)

appwrite_lab/automations/models.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,32 @@ class AppwriteAPIKeyCreation(BaseVarModel):
6969
key_expiry: Expiration
7070

7171

72+
@dataclass
73+
class AppwriteLabCreation(BaseVarModel):
74+
admin_email: str | None = None
75+
admin_password: str | None = None
76+
project_id: str | None = None
77+
project_name: str | None = None
78+
url: str | None = None
79+
80+
def generate(self):
81+
"""Generate random data for model"""
82+
random_key = str(uuid.uuid4())
83+
password = random_key[:16]
84+
last_six = random_key[-6:]
85+
admin_password = password
86+
admin_email = f"admin{last_six}@local.dev"
87+
project_id = random_key
88+
project_name = f"test-project-{last_six}"
89+
90+
return AppwriteUserCreation(
91+
admin_email=admin_email,
92+
admin_password=admin_password,
93+
project_id=project_id,
94+
project_name=project_name,
95+
)
96+
97+
7298
@dataclass
7399
class AppwriteUserCreation(BaseVarModel):
74100
url: str

appwrite_lab/cli/list_menu.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
labs = get_global_labs()
99

1010

11-
@list_menu.command(name="labs")
11+
@list_menu.command(name="labs", help="List resources.")
1212
def get_labs():
1313
"""List all ephemeral Appwrite instances."""
1414
headers, pods = labs.orchestrator.get_formatted_labs(collapsed=True)

appwrite_lab/cli/new_menu.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import typer
22
from appwrite_lab.utils import console
33
from appwrite_lab import get_global_labs
4-
from appwrite_lab.automations.models import Expiration
4+
from appwrite_lab.automations.models import Expiration, AppwriteUserCreation
55

66
new_menu = typer.Typer(name="new", help="Create a new resource.")
77

@@ -59,18 +59,18 @@ def new_lab(
5959
with console.status(
6060
f"Creating lab '{name}'{extra_str}...", spinner="dots"
6161
) as status:
62-
creds = {
63-
"admin_email": email,
64-
"admin_password": password,
65-
"project_id": project_id,
66-
"project_name": project_name,
67-
}
62+
creds = AppwriteUserCreation(
63+
admin_email=email,
64+
admin_password=password,
65+
project_id=project_id,
66+
project_name=project_name,
67+
)
6868

6969
labs.new(
7070
name=name,
7171
version=version,
7272
port=port,
73-
meta={"appwrite_config": creds},
73+
auth=creds,
7474
just_deploy=just_deploy,
7575
)
7676
status.update(f"Creating lab '{name}'... done")

appwrite_lab/labs.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from ._orchestrator import ServiceOrchestrator, Response
44
from .models import Automation, Lab
55
from appwrite_lab.automations.models import (
6+
AppwriteLabCreation,
67
AppwriteProjectCreation,
78
AppwriteSyncProject,
89
AppwriteAPIKeyCreation,
@@ -25,7 +26,7 @@ def new(
2526
name: str,
2627
version: str,
2728
port: int,
28-
meta: dict[str, str] = {},
29+
auth: AppwriteLabCreation | None = None,
2930
just_deploy: bool = False,
3031
):
3132
"""
@@ -35,9 +36,11 @@ def new(
3536
name: The name of the lab.
3637
version: The version of the lab.
3738
port: The port of the lab.
39+
auth: The authentication credentials.
40+
just_deploy: Deploy the lab without creating an API key or project.
3841
"""
3942
return self.orchestrator.deploy_appwrite_lab(
40-
name, version, port, meta, just_deploy=just_deploy
43+
name, version, port, auth, just_deploy=just_deploy
4144
)
4245

4346
def get_lab(self, name: str) -> Lab | None:

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "appwrite-lab"
7-
version = "0.0.7"
7+
version = "0.1.0"
88
description = "Zero-click Appwrite test environments."
99
readme = "README.md"
1010
requires-python = ">=3.11"

0 commit comments

Comments
 (0)