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
75 changes: 75 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Generated by seam-plop
name: Python Test
on:
push:
workflow_dispatch:
inputs:
sdkSha:
description: "SHA of the seamapi-python commit to run against"
type: string
required: false
connectSha:
description: "SHA of the seam-connect commit to run against"
type: string
required: false
prRepo:
description: "Repository of PR context (needed when leaving comments)"
type: string
required: false
prNumber:
description: "PR number (needed when leaving comments)"
type: string

jobs:
test:
runs-on: ubuntu-latest
env:
CONTAINER_REGISTRY: "registry.digitalocean.com"
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
steps:
- name: Checkout
uses: actions/checkout@v2
with:
ref: ${{ github.event.inputs.sdkSha }}
- name: Login to DO container registry
uses: docker/login-action@v1
with:
registry: ${{ env.CONTAINER_REGISTRY }}
username: ${{ secrets.DIGITAL_OCEAN_TOKEN }}
password: ${{ secrets.DIGITAL_OCEAN_TOKEN }}
- name: Pre-pull Seam Connect image
run: docker pull ${{ env.CONTAINER_REGISTRY }}/seam/seam-connect:${{ github.event.inputs.connectSha || 'latest' }}
- uses: actions/setup-python@v2
with:
python-version: 3.8
- name: Install Poetry
uses: snok/install-poetry@v1
- if: ${{ github.event.inputs.prNumber }}
uses: marocchino/sticky-pull-request-comment@v2
with:
number: ${{ github.event.inputs.prNumber }}
repo: ${{ github.event.inputs.prRepo }}
GITHUB_TOKEN: ${{ secrets.BOT_GH_TOKEN }}
message: |
⌛️ [running Python SDK tests](${{ env.RUN_URL }})...
- run: poetry install
- run: poetry run pytest -s
- name: Comment on failure
if: ${{ github.event.inputs.prNumber && failure() }}
uses: marocchino/sticky-pull-request-comment@v2
with:
number: ${{ github.event.inputs.prNumber }}
repo: ${{ github.event.inputs.prRepo }}
GITHUB_TOKEN: ${{ secrets.BOT_GH_TOKEN }}
message: |
⛔️ [Python SDK tests failed](${{ env.RUN_URL }}).

- name: Comment on success
if: ${{ github.event.inputs.prNumber && success() }}
uses: marocchino/sticky-pull-request-comment@v2
with:
number: ${{ github.event.inputs.prNumber }}
repo: ${{ github.event.inputs.prRepo }}
GITHUB_TOKEN: ${{ secrets.BOT_GH_TOKEN }}
message: |
✅ [Python SDK tests passed](${{ env.RUN_URL }}).
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,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 run tests, run `poetry run pytest -s`
- To build the project for publishing, run `poetry build`

Commits to `main` following [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) will automatically be published to PyPI.
Expand Down
1 change: 0 additions & 1 deletion seamapi/access_codes.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,6 @@ def update(
success_res: Any = action_attempt.result
return AccessCode.from_dict(success_res["access_code"])


def delete(
self,
access_code: Union[AccessCodeId, AccessCode],
Expand Down
2 changes: 1 addition & 1 deletion seamapi/connect_webviews.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def list(self) -> List[ConnectWebview]:
A list of connect webviews
"""

res = requests.post(
res = requests.get(
f"{self.seam.api_url}/connect_webviews/list",
headers={"Authorization": f"Bearer {self.seam.api_key}"},
)
Expand Down
2 changes: 1 addition & 1 deletion seamapi/connected_accounts.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def list(self) -> List[ConnectedAccount]:
A list of connected accounts.
"""

res = requests.post(
res = requests.get(
f"{self.seam.api_url}/connected_accounts/list",
headers={"Authorization": f"Bearer {self.seam.api_key}"},
)
Expand Down
2 changes: 2 additions & 0 deletions seamapi/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ class AccessCode:
starts_at: Optional[str] = None
ends_at: Optional[str] = None
name: Optional[str] = ""
status: Optional[str] = None


class AbstractActionAttempts(abc.ABC):
Expand Down Expand Up @@ -149,6 +150,7 @@ def update(
code: Optional[str] = None,
starts_at: Optional[str] = None,
ends_at: Optional[str] = None,
status: Optional[str] = None,
) -> AccessCode:
raise NotImplementedError

Expand Down
5 changes: 2 additions & 3 deletions seamapi/workspaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def list(
Workspace
"""

workspace_id = to_workspace_id(workspace)
workspace_id = None if workspace is None else to_workspace_id(workspace)
res = requests.get(
f"{self.seam.api_url}/workspaces/list",
params={"workspace_id": workspace_id},
Expand Down Expand Up @@ -102,8 +102,7 @@ def get(
------
Workspace
"""

workspace_id = to_workspace_id(workspace)
workspace_id = None if workspace is None else to_workspace_id(workspace)
res = requests.get(
f"{self.seam.api_url}/workspaces/get",
params={"workspace_id": workspace_id},
Expand Down
9 changes: 6 additions & 3 deletions tests/access_codes/test_access_codes.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
from seamapi import Seam
from tests.fixtures.login_via_schlage import login_via_schlage
from tests.fixtures.run_august_factory import run_august_factory


def test_access_codes(seam: Seam):
login_via_schlage(seam)
run_august_factory(seam)

some_device = seam.devices.list()[0]

created_access_code = seam.access_codes.create(some_device.device_id, "Test code", "4444")
created_access_code = seam.access_codes.create(
some_device.device_id, "Test code", "4444"
)
assert created_access_code.name == "Test code"
assert created_access_code.status == "setting"

access_codes = seam.access_codes.list(some_device.device_id)
assert len(access_codes) == 1
Expand Down
8 changes: 5 additions & 3 deletions tests/action_attempts/test_action_attempts.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
from seamapi import Seam
from tests.fixtures.login_via_schlage import login_via_schlage
from tests.fixtures.run_august_factory import run_august_factory


def test_action_attempts(seam: Seam):
login_via_schlage(seam)
run_august_factory(seam)

some_device = seam.devices.list()[0]
created_access_code = seam.access_codes.create(some_device.device_id, "Test code", "4444")
created_access_code = seam.access_codes.create(
some_device.device_id, "Test code", "4444"
)
delete_action_attempt = seam.access_codes.delete(created_access_code)

action_attempt = seam.action_attempts.get(delete_action_attempt)
Expand Down
12 changes: 8 additions & 4 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,21 @@ class SeamBackend:
sandbox_api_key: str


@pytest.fixture(scope="session")
# TODO this should use scope="session", but there's some issue, this would
# dramatically reduce test time to switch
@pytest.fixture(scope="function")
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"
db_url = f"postgresql://test:test@{db_host}:{pg.get_exposed_port(pg.port_to_expose)}/seam_api"
with DockerContainer("seam-connect").with_env(
db_url = f"postgresql://test:test@{db_host}:{pg.get_exposed_port(pg.port_to_expose)}/postgres"
with DockerContainer("registry.digitalocean.com/seam/seam-connect").with_env(
"DATABASE_URL",
# TODO on mac us docker.host.internal instead of 172.17.0.1 when someone
# with a mac needs to run tests
db_url,
).with_env("DATABASE_NAME", "seam_api").with_env("NODE_ENV", "test").with_env(
).with_env("POSTGRES_DATABASE", "postgres").with_env(
"NODE_ENV", "test"
).with_env(
"POSTGRES_HOST", db_host
).with_env(
"SERVER_BASE_URL", "http://localhost:3020"
Expand Down
4 changes: 2 additions & 2 deletions tests/connected_accounts/test_connected_accounts.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from seamapi import Seam
from tests.fixtures.login_via_schlage import login_via_schlage
from tests.fixtures.run_august_factory import run_august_factory


def test_connected_accounts(seam: Seam):
login_via_schlage(seam)
run_august_factory(seam)

connected_accounts = seam.connected_accounts.list()
assert len(connected_accounts) > 0
Expand Down
17 changes: 9 additions & 8 deletions tests/devices/test_devices.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,29 @@
from seamapi import Seam
from tests.fixtures.login_via_schlage import login_via_schlage
from tests.fixtures.run_august_factory import run_august_factory
from seamapi.utils.deep_attr_dict import DeepAttrDict


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

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

some_device = seam.devices.get(name="FRONT DOOR")
assert some_device.properties.name == "FRONT DOOR"
some_device = seam.devices.get(name="Generated Lock 0")
assert some_device.properties.name == "Generated Lock 0"

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

some_lock = seam.locks.get(device=(some_device))
assert some_lock.device_id == some_device.device_id

assert some_lock.properties.locked == False
seam.locks.lock_door(device=(some_device))
some_locked_lock = seam.locks.get(device=(some_device))
assert some_locked_lock.properties.locked == True
assert some_lock.properties.locked == True

seam.locks.unlock_door(device=(some_device.device_id))
some_unlocked_lock = seam.locks.get(device=(some_device))
assert some_unlocked_lock.properties.locked == False

seam.locks.lock_door(device=(some_device))
some_locked_lock = seam.locks.get(device=(some_device))
assert some_locked_lock.properties.locked == True
2 changes: 1 addition & 1 deletion tests/fixtures/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
from .login_via_schlage import login_via_schlage
from .run_august_factory import run_august_factory
22 changes: 0 additions & 22 deletions tests/fixtures/login_via_schlage.py

This file was deleted.

17 changes: 17 additions & 0 deletions tests/fixtures/run_august_factory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from seamapi import Seam
import time
import requests


def run_august_factory(seam: Seam):
factory_res = requests.post(
f"{seam.api_url}/internal/scenarios/factories/load",
json={
"factory_name": "create_august_devices",
"input": {"num": 1},
"sync": True,
},
headers={
"Authorization": f"Bearer {seam.api_key}",
},
)
4 changes: 2 additions & 2 deletions tests/workspaces/test_workspaces.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from seamapi import Seam
from tests.fixtures.login_via_schlage import login_via_schlage
from tests.fixtures.run_august_factory import run_august_factory


def test_workspaces(seam: Seam):
login_via_schlage(seam)
run_august_factory(seam)

ws = seam.workspaces.get()
assert ws.is_sandbox == True
Expand Down