uptimer-python-sdk 0.2.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.
Files changed (53) hide show
  1. uptimer_python_sdk-0.4.0/CHANGELOG.md +25 -0
  2. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/PKG-INFO +38 -2
  3. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/README.md +37 -1
  4. uptimer_python_sdk-0.4.0/Taskfile.yml +54 -0
  5. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/examples/06_create_rule.py +6 -0
  6. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/pyproject.toml +1 -1
  7. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/src/uptimer/__init__.py +1 -1
  8. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/src/uptimer/client.py +7 -2
  9. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/src/uptimer/http.py +1 -4
  10. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/src/uptimer/models/rule.py +4 -1
  11. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/tests/test_rules_endpoint.py +64 -3
  12. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/uv.lock +570 -568
  13. uptimer_python_sdk-0.2.0/CHANGELOG.md +0 -13
  14. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/.gitignore +0 -0
  15. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/.pre-commit-config.yaml +0 -0
  16. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/.vscode/extensions.json +0 -0
  17. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/.vscode/launch.json +0 -0
  18. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/.vscode/settings.json +0 -0
  19. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/.vscode/tasks.json +0 -0
  20. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/LICENSE +0 -0
  21. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/NOTICE +0 -0
  22. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/examples/01_client_setup.py +0 -0
  23. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/examples/02_list_workspaces.py +0 -0
  24. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/examples/03_list_regions.py +0 -0
  25. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/examples/04_list_rules.py +0 -0
  26. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/examples/05_get_rule.py +0 -0
  27. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/examples/07_update_rule.py +0 -0
  28. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/examples/08_delete_rule.py +0 -0
  29. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/examples/README.md +0 -0
  30. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/examples/__init__.py +0 -0
  31. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/src/uptimer/endpoints/__init__.py +0 -0
  32. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/src/uptimer/endpoints/endpoint.py +0 -0
  33. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/src/uptimer/endpoints/regions.py +0 -0
  34. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/src/uptimer/endpoints/rules.py +0 -0
  35. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/src/uptimer/endpoints/v1.py +0 -0
  36. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/src/uptimer/endpoints/workspaces.py +0 -0
  37. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/src/uptimer/errors.py +0 -0
  38. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/src/uptimer/models/__init__.py +0 -0
  39. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/src/uptimer/models/deserialize.py +0 -0
  40. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/src/uptimer/models/errors.py +0 -0
  41. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/src/uptimer/models/region.py +0 -0
  42. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/src/uptimer/models/workspace.py +0 -0
  43. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/src/uptimer/py.typed +0 -0
  44. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/tests/__init__.py +0 -0
  45. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/tests/conftest.py +0 -0
  46. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/tests/integrations/__init__.py +0 -0
  47. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/tests/integrations/conftest.py +0 -0
  48. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/tests/integrations/test_workspaces.py +0 -0
  49. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/tests/test_client.py +0 -0
  50. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/tests/test_endpoint.py +0 -0
  51. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/tests/test_regions_endpoint.py +0 -0
  52. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/tests/test_workspaces_endpoint.py +0 -0
  53. {uptimer_python_sdk-0.2.0 → uptimer_python_sdk-0.4.0}/tools/mypy-diff.sh +0 -0
@@ -0,0 +1,25 @@
1
+ ## 0.4.0 (2026-07-15)
2
+
3
+ ### Feat
4
+
5
+ - assign regions (by name) when creating or updating a rule via `rules.create`/`rules.update`; rules now expose a `regions` field
6
+
7
+ ## 0.3.0 (2025-08-19)
8
+
9
+ ### Feat
10
+
11
+ - self-hosted client now requires a base_url, added cloud client, updated docs
12
+
13
+ ## 0.2.0 (2025-08-10)
14
+
15
+ ### Feat
16
+
17
+ - create/update/delete rule methods.
18
+ - added method to get all rules
19
+ - added regions and get rule API
20
+ - added getting workspace list
21
+ - add Cursor IDE configuration for testing and development
22
+
23
+ ### Fix
24
+
25
+ - fixed dependencies in pyproject.toml
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: uptimer-python-sdk
3
- Version: 0.2.0
3
+ Version: 0.4.0
4
4
  Summary: A Python SDK for uptimer
5
5
  Project-URL: Repository, https://github.com/myuptime-info/uptimer-python-sdk
6
6
  Author-email: Roman Zadoev <zadoev@gmail.com>
@@ -13,7 +13,11 @@ Description-Content-Type: text/markdown
13
13
 
14
14
  # Uptimer Python SDK
15
15
 
16
- A Python SDK for [uptimer](https://uptimer.myuptime.info/) - a monitoring and uptime checking service.
16
+ ![Uptimer](https://static.myuptime.info/61uvxp/icon.png)
17
+
18
+ A Python SDK for uptimer - a monitoring and uptime checking service.
19
+ * [uptimer self-hosted](https://uptimer.myuptime.info)
20
+ * [myuptime.info](https://myuptime.info)
17
21
 
18
22
  ## License
19
23
 
@@ -21,8 +25,40 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
21
25
 
22
26
  For third-party license information, see the [NOTICE](NOTICE) file.
23
27
 
28
+ ## Installation
29
+
30
+ ```shell
31
+ pip install uptimer-python-sdk
32
+ ```
33
+
34
+ or
35
+ ```shell
36
+ uv add uptimer-python-sdk
37
+ ```
38
+
24
39
  ## Usage
25
40
 
41
+ ### Create client
42
+
43
+ #### self-hosted
44
+
45
+ ```python
46
+ from uptimer.client import UptimerClient
47
+ client = UptimerClient(
48
+ api_key="your-api-key-here",
49
+ base_url="http://127.0.0.1:2517/api", # or your custom base URL
50
+ )
51
+ ```
52
+
53
+ #### cloud
54
+ ```python
55
+ from uptimer.client import UptimerCloudClient
56
+ client = UptimerCloudClient(
57
+ api_key="your-api-key-here",
58
+ )
59
+ ```
60
+
61
+ ### Basic example
26
62
  ```python
27
63
  from uptimer.client import UptimerClient
28
64
  from uptimer.models.rule import CreateRuleRequest, RuleRequest, RuleResponse, RuleResponseBody
@@ -1,6 +1,10 @@
1
1
  # Uptimer Python SDK
2
2
 
3
- A Python SDK for [uptimer](https://uptimer.myuptime.info/) - a monitoring and uptime checking service.
3
+ ![Uptimer](https://static.myuptime.info/61uvxp/icon.png)
4
+
5
+ A Python SDK for uptimer - a monitoring and uptime checking service.
6
+ * [uptimer self-hosted](https://uptimer.myuptime.info)
7
+ * [myuptime.info](https://myuptime.info)
4
8
 
5
9
  ## License
6
10
 
@@ -8,8 +12,40 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
8
12
 
9
13
  For third-party license information, see the [NOTICE](NOTICE) file.
10
14
 
15
+ ## Installation
16
+
17
+ ```shell
18
+ pip install uptimer-python-sdk
19
+ ```
20
+
21
+ or
22
+ ```shell
23
+ uv add uptimer-python-sdk
24
+ ```
25
+
11
26
  ## Usage
12
27
 
28
+ ### Create client
29
+
30
+ #### self-hosted
31
+
32
+ ```python
33
+ from uptimer.client import UptimerClient
34
+ client = UptimerClient(
35
+ api_key="your-api-key-here",
36
+ base_url="http://127.0.0.1:2517/api", # or your custom base URL
37
+ )
38
+ ```
39
+
40
+ #### cloud
41
+ ```python
42
+ from uptimer.client import UptimerCloudClient
43
+ client = UptimerCloudClient(
44
+ api_key="your-api-key-here",
45
+ )
46
+ ```
47
+
48
+ ### Basic example
13
49
  ```python
14
50
  from uptimer.client import UptimerClient
15
51
  from uptimer.models.rule import CreateRuleRequest, RuleRequest, RuleResponse, RuleResponseBody
@@ -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}")
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "uptimer-python-sdk"
7
- version = "0.2.0"
7
+ version = "0.4.0"
8
8
  description = "A Python SDK for uptimer"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -1,3 +1,3 @@
1
1
  """Uptimer Python SDK."""
2
2
 
3
- __version__ = "0.1.0"
3
+ __version__ = "0.4.0"
@@ -9,8 +9,8 @@ from uptimer.http import UptimerHttpLib
9
9
  class UptimerClient:
10
10
  v1: V1Endpoint
11
11
 
12
- def __init__(self, api_key: str, base_url: str | None = None):
13
- self.set_uptimer_http_lib(UptimerHttpLib(api_key, base_url))
12
+ def __init__(self, api_key: str, base_url: str):
13
+ self._http_lib = UptimerHttpLib(api_key, base_url)
14
14
  self.v1 = V1Endpoint(self._http_lib)
15
15
 
16
16
  def version(self) -> str:
@@ -19,3 +19,8 @@ class UptimerClient:
19
19
 
20
20
  def set_uptimer_http_lib(self, http_lib: UptimerHttpLib) -> None:
21
21
  self._http_lib = http_lib
22
+
23
+
24
+ class UptimerCloudClient(UptimerClient):
25
+ def __init__(self, api_key: str):
26
+ super().__init__(api_key, "https://api.myuptime.info")
@@ -13,10 +13,7 @@ class WorkspacesEndpoint(BaseEndpoint):
13
13
 
14
14
 
15
15
  class UptimerHttpLib:
16
- def __init__(self, api_key: str, base_url: str | None = None):
17
- if base_url is None:
18
- base_url = "https://api.uptimer.com"
19
-
16
+ def __init__(self, api_key: str, base_url: str):
20
17
  self._base_url = base_url.rstrip("/")
21
18
  self._http_client = httpx.Client(
22
19
  base_url=base_url,
@@ -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)