uptimer-python-sdk 0.3.0__tar.gz → 0.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/CHANGELOG.md +6 -0
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/PKG-INFO +1 -1
- uptimer_python_sdk-0.4.0/Taskfile.yml +54 -0
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/examples/06_create_rule.py +6 -0
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/pyproject.toml +1 -1
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/src/uptimer/__init__.py +1 -1
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/src/uptimer/models/rule.py +4 -1
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/tests/test_rules_endpoint.py +64 -3
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/uv.lock +569 -567
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/.gitignore +0 -0
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/.pre-commit-config.yaml +0 -0
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/.vscode/extensions.json +0 -0
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/.vscode/launch.json +0 -0
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/.vscode/settings.json +0 -0
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/.vscode/tasks.json +0 -0
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/LICENSE +0 -0
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/NOTICE +0 -0
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/README.md +0 -0
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/examples/01_client_setup.py +0 -0
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/examples/02_list_workspaces.py +0 -0
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/examples/03_list_regions.py +0 -0
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/examples/04_list_rules.py +0 -0
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/examples/05_get_rule.py +0 -0
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/examples/07_update_rule.py +0 -0
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/examples/08_delete_rule.py +0 -0
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/examples/README.md +0 -0
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/examples/__init__.py +0 -0
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/src/uptimer/client.py +0 -0
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/src/uptimer/endpoints/__init__.py +0 -0
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/src/uptimer/endpoints/endpoint.py +0 -0
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/src/uptimer/endpoints/regions.py +0 -0
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/src/uptimer/endpoints/rules.py +0 -0
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/src/uptimer/endpoints/v1.py +0 -0
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/src/uptimer/endpoints/workspaces.py +0 -0
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/src/uptimer/errors.py +0 -0
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/src/uptimer/http.py +0 -0
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/src/uptimer/models/__init__.py +0 -0
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/src/uptimer/models/deserialize.py +0 -0
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/src/uptimer/models/errors.py +0 -0
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/src/uptimer/models/region.py +0 -0
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/src/uptimer/models/workspace.py +0 -0
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/src/uptimer/py.typed +0 -0
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/tests/__init__.py +0 -0
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/tests/conftest.py +0 -0
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/tests/integrations/__init__.py +0 -0
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/tests/integrations/conftest.py +0 -0
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/tests/integrations/test_workspaces.py +0 -0
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/tests/test_client.py +0 -0
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/tests/test_endpoint.py +0 -0
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/tests/test_regions_endpoint.py +0 -0
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/tests/test_workspaces_endpoint.py +0 -0
- {uptimer_python_sdk-0.3.0 → uptimer_python_sdk-0.4.0}/tools/mypy-diff.sh +0 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# go-task runner for the uptimer Python SDK. `task --list` shows everything.
|
|
2
|
+
# All tooling goes through `uv` (deps pinned by uv.lock), so local == CI.
|
|
3
|
+
# Release/publish flow (matches the fleet rollout — release, then publish):
|
|
4
|
+
# task release # cz bump (version + CHANGELOG + tag) + push
|
|
5
|
+
# task pypi-test # validate on TestPyPI
|
|
6
|
+
# task pypi # publish to PyPI (only after the release)
|
|
7
|
+
version: '3'
|
|
8
|
+
|
|
9
|
+
tasks:
|
|
10
|
+
build:
|
|
11
|
+
desc: Build the sdist + wheel into dist/ (uv build).
|
|
12
|
+
cmds:
|
|
13
|
+
- rm -rf dist
|
|
14
|
+
- uv build
|
|
15
|
+
|
|
16
|
+
test:
|
|
17
|
+
desc: Run the test suite (uv run pytest).
|
|
18
|
+
cmds:
|
|
19
|
+
- uv run pytest
|
|
20
|
+
|
|
21
|
+
lint:
|
|
22
|
+
desc: Lint + type-check (ruff + mypy).
|
|
23
|
+
cmds:
|
|
24
|
+
- uv run ruff check .
|
|
25
|
+
- uv run mypy src
|
|
26
|
+
|
|
27
|
+
cq:
|
|
28
|
+
desc: 'Code quality gate: lint + test.'
|
|
29
|
+
cmds:
|
|
30
|
+
- task: lint
|
|
31
|
+
- task: test
|
|
32
|
+
|
|
33
|
+
release:
|
|
34
|
+
desc: 'Cut a release: cq (lint + test), then `cz bump` (version + CHANGELOG + tag) + push. Commit your changes first.'
|
|
35
|
+
cmds:
|
|
36
|
+
- task: cq
|
|
37
|
+
- cz bump --yes
|
|
38
|
+
# bump commit + the tag cz just made; --follow-tags pushes only reachable tags.
|
|
39
|
+
- git push --follow-tags
|
|
40
|
+
- 'echo ">> released v$(cz version --project) — now publish with: task pypi"'
|
|
41
|
+
|
|
42
|
+
pypi-test:
|
|
43
|
+
desc: 'Build + upload to TestPyPI (needs a token: TWINE_USERNAME=__token__ TWINE_PASSWORD=pypi-…).'
|
|
44
|
+
deps: [build]
|
|
45
|
+
cmds:
|
|
46
|
+
- uv run twine check dist/*
|
|
47
|
+
- uv run twine upload --repository-url https://test.pypi.org/legacy/ dist/*
|
|
48
|
+
|
|
49
|
+
pypi:
|
|
50
|
+
desc: 'Build + upload to PyPI (needs a token). Do this only AFTER `task release`.'
|
|
51
|
+
deps: [build]
|
|
52
|
+
cmds:
|
|
53
|
+
- uv run twine check dist/*
|
|
54
|
+
- uv run twine upload dist/*
|
|
@@ -11,6 +11,10 @@ from uptimer.models.rule import (
|
|
|
11
11
|
client = UptimerClient(api_key="your-api-key-here")
|
|
12
12
|
workspace_id = "your-workspace-id-here"
|
|
13
13
|
|
|
14
|
+
# Regions are matched by name. List them to see what's available on your instance;
|
|
15
|
+
# a rule with no regions is never checked and stays at "No Data", so assign at least one.
|
|
16
|
+
region_names = [region.name for region in client.v1.regions.all()]
|
|
17
|
+
|
|
14
18
|
# Create a new rule
|
|
15
19
|
rule = client.v1.rules.create(
|
|
16
20
|
CreateRuleRequest(
|
|
@@ -29,7 +33,9 @@ rule = client.v1.rules.create(
|
|
|
29
33
|
body=RuleResponseBody(content="expected response"),
|
|
30
34
|
kind="rule_response",
|
|
31
35
|
),
|
|
36
|
+
regions=region_names[:1], # assign the first available region
|
|
32
37
|
),
|
|
33
38
|
)
|
|
34
39
|
|
|
35
40
|
print(f"Created rule: {rule.name} (ID: {rule.id})")
|
|
41
|
+
print(f"Assigned regions: {rule.regions}")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from dataclasses import dataclass
|
|
3
|
+
from dataclasses import dataclass, field
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
@dataclass
|
|
@@ -34,6 +34,9 @@ class BaseRule:
|
|
|
34
34
|
workspace_id: str # workspace id
|
|
35
35
|
request: RuleRequest # request configuration
|
|
36
36
|
response: RuleResponse # response validation
|
|
37
|
+
# region names the rule runs in (matched by name). A rule with no regions is
|
|
38
|
+
# never checked and stays at "No Data" — assign at least one to monitor it.
|
|
39
|
+
regions: list[str] = field(default_factory=list)
|
|
37
40
|
kind: str = "rule"
|
|
38
41
|
|
|
39
42
|
|
|
@@ -314,7 +314,7 @@ def test_create_rule(
|
|
|
314
314
|
httpx_mock.add_response(
|
|
315
315
|
method="POST",
|
|
316
316
|
json=api_response(rule_result),
|
|
317
|
-
match_content=b'{"name":"My Test Rule","interval":60,"workspace_id":"03075d25-6cad-4205-ad83-2da1bd8fad9c","request":{"url":"https://example.com","method":"GET","content_type":"application/json","data":"","kind":"rule_request"},"response":{"statuses":[200],"body":{"content":"expected response","kind":"rule_response_body"},"kind":"rule_response"},"kind":"rule"}',
|
|
317
|
+
match_content=b'{"name":"My Test Rule","interval":60,"workspace_id":"03075d25-6cad-4205-ad83-2da1bd8fad9c","request":{"url":"https://example.com","method":"GET","content_type":"application/json","data":"","kind":"rule_request"},"response":{"statuses":[200],"body":{"content":"expected response","kind":"rule_response_body"},"kind":"rule_response"},"regions":[],"kind":"rule"}',
|
|
318
318
|
)
|
|
319
319
|
|
|
320
320
|
rule_object = uptimer_client.v1.rules.create(create_request)
|
|
@@ -343,6 +343,67 @@ def test_create_rule(
|
|
|
343
343
|
assert rule_object.response.kind == response_data["kind"]
|
|
344
344
|
|
|
345
345
|
|
|
346
|
+
def test_create_rule_with_regions(
|
|
347
|
+
uptimer_client: UptimerClient,
|
|
348
|
+
httpx_mock: HTTPXMock,
|
|
349
|
+
):
|
|
350
|
+
"""A rule created with regions sends them in the payload and parses them back."""
|
|
351
|
+
workspace_id = "03075d25-6cad-4205-ad83-2da1bd8fad9c"
|
|
352
|
+
rule_id = "d901834d-5768-46ae-91f5-7974b0c764b2"
|
|
353
|
+
|
|
354
|
+
create_request = CreateRuleRequest(
|
|
355
|
+
name="Regioned Rule",
|
|
356
|
+
interval=60,
|
|
357
|
+
workspace_id=workspace_id,
|
|
358
|
+
request=RuleRequest(
|
|
359
|
+
url="https://example.com",
|
|
360
|
+
method="GET",
|
|
361
|
+
content_type="application/json",
|
|
362
|
+
data="",
|
|
363
|
+
kind="rule_request",
|
|
364
|
+
),
|
|
365
|
+
response=RuleResponse(
|
|
366
|
+
statuses=[200],
|
|
367
|
+
body=RuleResponseBody(content=""),
|
|
368
|
+
kind="rule_response",
|
|
369
|
+
),
|
|
370
|
+
regions=["eu-west", "us-east"],
|
|
371
|
+
kind="rule",
|
|
372
|
+
)
|
|
373
|
+
|
|
374
|
+
rule_result = {
|
|
375
|
+
"id": rule_id,
|
|
376
|
+
"name": "Regioned Rule",
|
|
377
|
+
"interval": 60,
|
|
378
|
+
"workspace_id": workspace_id,
|
|
379
|
+
"request": {
|
|
380
|
+
"url": "https://example.com",
|
|
381
|
+
"method": "GET",
|
|
382
|
+
"content_type": "application/json",
|
|
383
|
+
"data": "",
|
|
384
|
+
"kind": "rule_request",
|
|
385
|
+
},
|
|
386
|
+
"response": {
|
|
387
|
+
"statuses": [200],
|
|
388
|
+
"body": {"content": "", "kind": "rule_response_body"},
|
|
389
|
+
"kind": "rule_response",
|
|
390
|
+
},
|
|
391
|
+
"regions": ["eu-west", "us-east"],
|
|
392
|
+
"kind": "rule",
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
httpx_mock.add_response(
|
|
396
|
+
method="POST",
|
|
397
|
+
json=api_response(rule_result),
|
|
398
|
+
match_content=b'{"name":"Regioned Rule","interval":60,"workspace_id":"03075d25-6cad-4205-ad83-2da1bd8fad9c","request":{"url":"https://example.com","method":"GET","content_type":"application/json","data":"","kind":"rule_request"},"response":{"statuses":[200],"body":{"content":"","kind":"rule_response_body"},"kind":"rule_response"},"regions":["eu-west","us-east"],"kind":"rule"}',
|
|
399
|
+
)
|
|
400
|
+
|
|
401
|
+
rule_object = uptimer_client.v1.rules.create(create_request)
|
|
402
|
+
|
|
403
|
+
assert rule_object.id == rule_id
|
|
404
|
+
assert rule_object.regions == ["eu-west", "us-east"]
|
|
405
|
+
|
|
406
|
+
|
|
346
407
|
def test_update_rule_with_rule(
|
|
347
408
|
uptimer_client: UptimerClient,
|
|
348
409
|
httpx_mock: HTTPXMock,
|
|
@@ -398,7 +459,7 @@ def test_update_rule_with_rule(
|
|
|
398
459
|
httpx_mock.add_response(
|
|
399
460
|
method="POST",
|
|
400
461
|
json=api_response(rule_result),
|
|
401
|
-
match_content=b'{"name":"Updated Rule Name","interval":120,"workspace_id":"03075d25-6cad-4205-ad83-2da1bd8fad9c","request":{"url":"https://updated-example.com","method":"POST","content_type":"application/json","data":"{\\"key2\\": \\"value\\"}","kind":"rule_request"},"response":{"statuses":[200,201],"body":{"content":"updated expected response","kind":"rule_response_body"},"kind":"rule_response"},"kind":"rule"}',
|
|
462
|
+
match_content=b'{"name":"Updated Rule Name","interval":120,"workspace_id":"03075d25-6cad-4205-ad83-2da1bd8fad9c","request":{"url":"https://updated-example.com","method":"POST","content_type":"application/json","data":"{\\"key2\\": \\"value\\"}","kind":"rule_request"},"response":{"statuses":[200,201],"body":{"content":"updated expected response","kind":"rule_response_body"},"kind":"rule_response"},"regions":[],"kind":"rule"}',
|
|
402
463
|
)
|
|
403
464
|
|
|
404
465
|
rule_object = uptimer_client.v1.rules.update(rule_id, update_request)
|
|
@@ -481,7 +542,7 @@ def test_update_rule_with_create_request(
|
|
|
481
542
|
httpx_mock.add_response(
|
|
482
543
|
method="POST",
|
|
483
544
|
json=api_response(rule_result),
|
|
484
|
-
match_content=b'{"name":"Updated Rule Name","interval":120,"workspace_id":"03075d25-6cad-4205-ad83-2da1bd8fad9c","request":{"url":"https://updated-example.com","method":"POST","content_type":"application/json","data":"{\\"key2\\": \\"value\\"}","kind":"rule_request"},"response":{"statuses":[200,201],"body":{"content":"updated expected response","kind":"rule_response_body"},"kind":"rule_response"},"kind":"rule"}',
|
|
545
|
+
match_content=b'{"name":"Updated Rule Name","interval":120,"workspace_id":"03075d25-6cad-4205-ad83-2da1bd8fad9c","request":{"url":"https://updated-example.com","method":"POST","content_type":"application/json","data":"{\\"key2\\": \\"value\\"}","kind":"rule_request"},"response":{"statuses":[200,201],"body":{"content":"updated expected response","kind":"rule_response_body"},"kind":"rule_response"},"regions":[],"kind":"rule"}',
|
|
485
546
|
)
|
|
486
547
|
|
|
487
548
|
rule_object = uptimer_client.v1.rules.update(rule_id, update_request)
|