tinkly 0.2.1__tar.gz → 0.2.2__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 (26) hide show
  1. {tinkly-0.2.1 → tinkly-0.2.2}/PKG-INFO +4 -1
  2. {tinkly-0.2.1 → tinkly-0.2.2}/README.md +3 -0
  3. {tinkly-0.2.1 → tinkly-0.2.2}/pyproject.toml +1 -1
  4. {tinkly-0.2.1 → tinkly-0.2.2}/scripts/griffe_tinkly.py +7 -15
  5. {tinkly-0.2.1 → tinkly-0.2.2}/tests/test_documentation.py +19 -3
  6. {tinkly-0.2.1 → tinkly-0.2.2}/tinkly/client.py +8 -3
  7. {tinkly-0.2.1 → tinkly-0.2.2}/tinkly.egg-info/PKG-INFO +4 -1
  8. {tinkly-0.2.1 → tinkly-0.2.2}/uv.lock +2 -2
  9. {tinkly-0.2.1 → tinkly-0.2.2}/MANIFEST.in +0 -0
  10. {tinkly-0.2.1 → tinkly-0.2.2}/doc/contributing.md +0 -0
  11. {tinkly-0.2.1 → tinkly-0.2.2}/doc/index.md +0 -0
  12. {tinkly-0.2.1 → tinkly-0.2.2}/scripts/build_docs.py +0 -0
  13. {tinkly-0.2.1 → tinkly-0.2.2}/setup.cfg +0 -0
  14. {tinkly-0.2.1 → tinkly-0.2.2}/tests/test_authentication.py +0 -0
  15. {tinkly-0.2.1 → tinkly-0.2.2}/tests/test_client.py +0 -0
  16. {tinkly-0.2.1 → tinkly-0.2.2}/tests/test_client_authentication.py +0 -0
  17. {tinkly-0.2.1 → tinkly-0.2.2}/tests/test_discovery.py +0 -0
  18. {tinkly-0.2.1 → tinkly-0.2.2}/tests/test_frame.py +0 -0
  19. {tinkly-0.2.1 → tinkly-0.2.2}/tinkly/__init__.py +0 -0
  20. {tinkly-0.2.1 → tinkly-0.2.2}/tinkly/authentication.py +0 -0
  21. {tinkly-0.2.1 → tinkly-0.2.2}/tinkly/discovery.py +0 -0
  22. {tinkly-0.2.1 → tinkly-0.2.2}/tinkly/errors.py +0 -0
  23. {tinkly-0.2.1 → tinkly-0.2.2}/tinkly/frame.py +0 -0
  24. {tinkly-0.2.1 → tinkly-0.2.2}/tinkly.egg-info/SOURCES.txt +0 -0
  25. {tinkly-0.2.1 → tinkly-0.2.2}/tinkly.egg-info/dependency_links.txt +0 -0
  26. {tinkly-0.2.1 → tinkly-0.2.2}/tinkly.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tinkly
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Summary: Low-level Twinkly discovery, authentication, HTTP, and realtime UDP transport
5
5
  Author-email: Tom Ritchford <tom@swirly.com>
6
6
  Project-URL: Documentation, https://rec.github.io/tinkly/
@@ -27,6 +27,9 @@ I re-implemented just the Twinkly communication part, and left all the other
27
27
  parts behind. In particular, there is no CLI - for that, you'll have to see my
28
28
  upcoming general project, "lyte".
29
29
 
30
+ Check out https://xled-docs.readthedocs.io/en/latest/ for more information about the
31
+ API protocol.
32
+
30
33
  ## Device communication
31
34
 
32
35
  This package provides UDP discovery, authentication, HTTP endpoint access for generation
@@ -11,6 +11,9 @@ I re-implemented just the Twinkly communication part, and left all the other
11
11
  parts behind. In particular, there is no CLI - for that, you'll have to see my
12
12
  upcoming general project, "lyte".
13
13
 
14
+ Check out https://xled-docs.readthedocs.io/en/latest/ for more information about the
15
+ API protocol.
16
+
14
17
  ## Device communication
15
18
 
16
19
  This package provides UDP discovery, authentication, HTTP endpoint access for generation
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "tinkly"
7
- version = "0.2.1"
7
+ version = "0.2.2"
8
8
  description = "Low-level Twinkly discovery, authentication, HTTP, and realtime UDP transport"
9
9
  readme = "README.md"
10
10
  authors = [{ name = "Tom Ritchford", email = "tom@swirly.com" }]
@@ -37,7 +37,7 @@ class EndpointProperties(griffe.Extension):
37
37
  """Add property labels, response types, and HTTP behavior to factory calls.
38
38
 
39
39
  Only assignments on tinkly.client.TwinklyClient are processed. Preserve
40
- any endpoint-specific attribute docstring after the generated details.
40
+ endpoint-specific descriptions; shared behavior belongs on the class.
41
41
  """
42
42
  if attr.parent is None or attr.parent.path != 'tinkly.client.TwinklyClient':
43
43
  return
@@ -61,22 +61,14 @@ class EndpointProperties(griffe.Extension):
61
61
  True,
62
62
  )
63
63
  writable = call.func.id == 'setter'
64
- description = (
65
- f'HTTP endpoint `GET {path}`.\n\n'
66
- 'Each read sends a fresh request and returns a '
67
- '`tinkly.client.TwinklyResponse` containing `http_status` and `data`.\n\n'
68
- f'Authentication is {"required" if authenticated else "not required"}.'
69
- )
64
+ description = f'`GET {path}`'
70
65
  if writable:
71
- description += (
72
- f'\n\nAssign a `dict[str, object]` JSON body to send `POST {path}`. '
73
- 'Assignment does not return the response; use `post()` when needed.'
74
- )
75
- else:
76
- description += '\n\nThis property is read-only.'
77
- description += '\n\nRequest errors propagate to the caller.'
66
+ description += f', `POST {path}`'
67
+ description += '.'
68
+ if not authenticated:
69
+ description += ' Authentication is not required.'
78
70
  if attr.docstring is not None:
79
- description += f'\n\n{attr.docstring.value}'
71
+ description = f'{attr.docstring.value}\n\n{description}'
80
72
 
81
73
  attr.labels.difference_update({'class-attribute', 'instance-attribute'})
82
74
  attr.labels.add('property')
@@ -28,15 +28,31 @@ class DocumentationTests(unittest.TestCase):
28
28
  self.assertIsNone(brightness.value)
29
29
  self.assertIn('GET led/out/brightness', brightness.docstring.value)
30
30
  self.assertIn('POST led/out/brightness', brightness.docstring.value)
31
- self.assertIn('dict[str, object]', brightness.docstring.value)
32
- self.assertIn('Authentication is required', brightness.docstring.value)
31
+ self.assertIn('dict[str, object]', client.docstring.value)
32
+ self.assertIn('Authentication is required', client.docstring.value)
33
+ self.assertIn('Request errors propagate', client.docstring.value)
34
+ self.assertIn('read-only', client.docstring.value)
35
+ self.assertIn('http_status and data', client.docstring.value)
36
+ self.assertIn('output brightness', brightness.docstring.value)
37
+ for attribute in client.attributes.values():
38
+ if 'property' in attribute.labels:
39
+ with self.subTest(property=attribute.name):
40
+ self.assertNotIn('Each read sends', attribute.docstring.value)
41
+ self.assertNotIn(
42
+ 'Authentication is required', attribute.docstring.value
43
+ )
44
+ self.assertNotIn(
45
+ 'This property is read-only', attribute.docstring.value
46
+ )
47
+ self.assertNotIn(
48
+ 'Request errors propagate', attribute.docstring.value
49
+ )
33
50
  for attribute in (firmware, status):
34
51
  with self.subTest(property=attribute.name):
35
52
  self.assertEqual(attribute.labels, {'property'})
36
53
  self.assertIn(
37
54
  'Authentication is not required', attribute.docstring.value
38
55
  )
39
- self.assertIn('read-only', attribute.docstring.value)
40
56
  self.assertIn('GET fw/version', firmware.docstring.value)
41
57
  self.assertIn('GET status', status.docstring.value)
42
58
  self.assertEqual(
@@ -81,9 +81,14 @@ class AuthToken:
81
81
  class TwinklyClient:
82
82
  """Synchronous HTTP client for a single Twinkly device.
83
83
 
84
- Endpoint properties return TwinklyResponse records on every read. Writable
85
- properties POST assigned JSON dictionaries. Authentication is automatic
86
- for protected endpoints. Each request opens and closes an HTTP connection;
84
+ Each endpoint property read sends a fresh GET request and returns a
85
+ TwinklyResponse containing http_status and data. Properties marked writable
86
+ accept a dict[str, object] JSON body and POST assignments; assignment discards
87
+ the response, so use post() when it is needed. Other properties are read-only.
88
+ Authentication is required and obtained automatically unless stated otherwise.
89
+ Request errors propagate to the caller.
90
+
91
+ Each request opens and closes an HTTP connection;
87
92
  retries, realtime frame pacing, and reconnection belong to the caller.
88
93
  Serialize all use of a client; instances are not thread-safe.
89
94
  """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tinkly
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Summary: Low-level Twinkly discovery, authentication, HTTP, and realtime UDP transport
5
5
  Author-email: Tom Ritchford <tom@swirly.com>
6
6
  Project-URL: Documentation, https://rec.github.io/tinkly/
@@ -27,6 +27,9 @@ I re-implemented just the Twinkly communication part, and left all the other
27
27
  parts behind. In particular, there is no CLI - for that, you'll have to see my
28
28
  upcoming general project, "lyte".
29
29
 
30
+ Check out https://xled-docs.readthedocs.io/en/latest/ for more information about the
31
+ API protocol.
32
+
30
33
  ## Device communication
31
34
 
32
35
  This package provides UDP discovery, authentication, HTTP endpoint access for generation
@@ -7,7 +7,7 @@ resolution-markers = [
7
7
  ]
8
8
 
9
9
  [options]
10
- exclude-newer = "2026-11-04T19:32:54.323936Z"
10
+ exclude-newer = "2026-11-04T19:41:26.290514Z"
11
11
  exclude-newer-span = "P1W"
12
12
 
13
13
  [[package]]
@@ -327,7 +327,7 @@ wheels = [
327
327
 
328
328
  [[package]]
329
329
  name = "tinkly"
330
- version = "0.2.1"
330
+ version = "0.2.2"
331
331
  source = { editable = "." }
332
332
 
333
333
  [package.dev-dependencies]
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes