Skip to content
This repository was archived by the owner on Jun 28, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"python.venvFolders": ["/home/seve/w/seam/seamapi-python/.venv"]
// "python.venvFolders": ["/home/seve/w/seam/seamapi-python/.venv"]
}
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ seam.locks.lock_door(some_lock)

This project uses [poetry](https://github.com/python-poetry/poetry)

- To setup the project and install dependencies run `poetry install`
- To run tests, run `poetry run pytest`
- To build the project for publishing, run `poetry build`
- To publish the project run `poetry build`
Expand All @@ -39,3 +40,10 @@ Our tests use a seam sandbox environment given by the environment
variables `SEAM_SANDBOX_API_KEY`. If you want to run the tests, you should
first create a sandbox workspace [on your dashboard](https://dashboard.getseam.com)
then create a sandbox workspace.

> NOTE: For installation on m1 mac, you may need to export the following lines
> prior to `poetry install`...
>
> `export CPPFLAGS="-I/opt/homebrew/opt/openssl@1.1/include"`
>
> `export LDFLAGS="-L/opt/homebrew/opt/openssl@1.1/lib -L${HOME}/.pyenv/versions/3.8.10/lib"`
2 changes: 1 addition & 1 deletion seamapi/connect_webviews.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def list(self) -> List[ConnectWebview]:
]

def get(self, connect_webview_id: str) -> ConnectWebview:
res = requests.post(
res = requests.get(
f"{self.seam.api_url}/connect_webviews/get",
headers={"Authorization": f"Bearer {self.seam.api_key}"},
params={"connect_webview_id": connect_webview_id},
Expand Down
14 changes: 11 additions & 3 deletions seamapi/devices.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,20 @@ def list(
devices = res.json()["devices"]
return [Device.from_dict(d) for d in devices]

def get(self, device: Union[DeviceId, Device]) -> Device:
device_id = to_device_id(device)
def get(
self,
device: Optional[Union[DeviceId, Device]] = None,
name: Optional[str] = None,
) -> Device:
params = {}
if device:
params["device_id"] = to_device_id(device)
if name:
params["name"] = name
res = requests.get(
f"{self.seam.api_url}/devices/get",
headers={"Authorization": f"Bearer {self.seam.api_key}"},
params={"device_id": device_id},
params=params,
)
if not res.ok:
raise Exception(res.text)
Expand Down
14 changes: 11 additions & 3 deletions seamapi/locks.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,20 @@ def list(
json_locks = res.json()["devices"]
return [Device.from_dict(d) for d in json_locks]

def get(self, device: Union[DeviceId, Device]) -> Device:
device_id = to_device_id(device)
def get(
self,
device: Optional[Union[DeviceId, Device]] = None,
name: Optional[str] = None,
) -> Device:
params = {}
if device:
params["device_id"] = to_device_id(device)
if name:
params["name"] = name
res = requests.post(
f"{self.seam.api_url}/locks/get",
headers={"Authorization": f"Bearer {self.seam.api_key}"},
params={"device_id": device_id},
params=params,
)
if not res.ok:
raise Exception(res.text)
Expand Down
7 changes: 5 additions & 2 deletions seamapi/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
AcceptedProvider = str # e.g. august or noiseaware


@dataclass_json
@dataclass
class Device:
device_id: DeviceId
Expand Down Expand Up @@ -151,7 +150,11 @@ def list(self) -> List[Device]:
raise NotImplementedError

@abc.abstractmethod
def get(self, device: Union[DeviceId, Device]) -> Device:
def get(
self,
device: Optional[Union[DeviceId, Device]] = None,
name: Optional[str] = None,
) -> Device:
raise NotImplementedError


Expand Down
11 changes: 6 additions & 5 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from dotenv import load_dotenv
from typing import Any
from dataclasses import dataclass
import sys
from testcontainers.postgres import PostgresContainer
from testcontainers.core.container import DockerContainer
from testcontainers.core.waiting_utils import wait_for_logs
Expand All @@ -21,7 +22,7 @@ class SeamBackend:
sandbox_api_key: str


@pytest.fixture
@pytest.fixture(scope="session")
def seam_backend():
with PostgresContainer("postgres:13", dbname="postgres") as pg:
db_host = "host.docker.internal" if sys.platform == "darwin" else "172.17.0.1"
Expand All @@ -34,18 +35,18 @@ def seam_backend():
).with_env("DATABASE_NAME", "seam_api").with_env("NODE_ENV", "test").with_env(
"POSTGRES_HOST", db_host
).with_env(
"SERVER_BASE_URL", "http://localhost:3021"
"SERVER_BASE_URL", "http://localhost:3000"
).with_env(
"SEAMTEAM_ADMIN_PASSWORD", "1234"
).with_bind_ports(
3000, 4020
3000, 3000
).with_command(
"start:for-integration-testing"
) as sc_container:
wait_for_logs(sc_container, r"started server", timeout=20)
requests.get("http://localhost:4020/health")
requests.get("http://localhost:3000/health")
yield SeamBackend(
url="http://localhost:4020",
url="http://localhost:3000",
sandbox_api_key="seam_sandykey_0000000000000000000sand",
)

Expand Down
7 changes: 7 additions & 0 deletions tests/connect_webviews/test_connect_webviews.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from seamapi import Seam


def test_connect_webviews(seam: Seam):
webview = seam.connect_webviews.create(accepted_providers=["schlage"])

assert webview.url is not None
13 changes: 13 additions & 0 deletions tests/devices/test_devices.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from seamapi import Seam
from tests.fixtures.login_via_schlage import login_via_schlage
from seamapi.utils.deep_attr_dict import DeepAttrDict


def test_devices(seam: Seam):
login_via_schlage(seam)

devices = seam.devices.list()
assert len(devices) > 0

some_device = seam.devices.get(name="FRONT DOOR")
assert some_device.properties.name == "FRONT DOOR"
1 change: 1 addition & 0 deletions tests/fixtures/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .login_via_schlage import login_via_schlage
22 changes: 22 additions & 0 deletions tests/fixtures/login_via_schlage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from seamapi import Seam
import time
import requests


def login_via_schlage(seam: Seam):
webview = seam.connect_webviews.create(accepted_providers=["schlage"])

# This is an internal endpoint that will be removed, don't use it, see how
# it says "internal" there? It's not going to stick around.
schlage_login_res = requests.post(
f"{seam.api_url}/internal/schlage/login",
json={
"email": "jane@example.com",
"password": "1234",
"connect_webview_id": webview.connect_webview_id,
},
).json()

# We've completed a webview login, which will load devices into this
# workspace
pass
8 changes: 1 addition & 7 deletions tests/test_init_seam.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
from seamapi import Seam


# def test_init_seam():
# seam = Seam()
# assert seam.api_key
# assert seam.api_url


def test_init_seam_with_fixture(seam: Seam):
assert seam.api_key
assert seam.api_url
assert "https" in seam.api_url and "localhost" in seam.api_url
assert "http" in seam.api_url and "localhost" in seam.api_url
7 changes: 7 additions & 0 deletions tests/utils/test_deep_attr_dict.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from seamapi.utils.deep_attr_dict import DeepAttrDict


def test_deep_attr_dict():
attrdict = DeepAttrDict({"a": {"b": {"c": 5}}})

assert attrdict.a.b.c == 5
1 change: 0 additions & 1 deletion tests/workspaces/test_workspaces_get.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,4 @@

def test_workspaces_get(seam: Seam):
ws = seam.workspaces.get()
assert ws.name == "PythonLibrarySandbox"
assert ws.is_sandbox == True