malloryapi 0.2.3.post1.dev0__tar.gz → 0.2.5__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 (42) hide show
  1. {malloryapi-0.2.3.post1.dev0 → malloryapi-0.2.5}/.github/workflows/publish.yml +10 -1
  2. {malloryapi-0.2.3.post1.dev0 → malloryapi-0.2.5}/PKG-INFO +1 -1
  3. {malloryapi-0.2.3.post1.dev0 → malloryapi-0.2.5}/src/malloryapi/_version.py +2 -2
  4. {malloryapi-0.2.3.post1.dev0 → malloryapi-0.2.5}/src/malloryapi/client.py +43 -0
  5. malloryapi-0.2.5/src/malloryapi/resources/user.py +31 -0
  6. {malloryapi-0.2.3.post1.dev0 → malloryapi-0.2.5}/.github/workflows/ci.yml +0 -0
  7. {malloryapi-0.2.3.post1.dev0 → malloryapi-0.2.5}/.gitignore +0 -0
  8. {malloryapi-0.2.3.post1.dev0 → malloryapi-0.2.5}/LICENSE +0 -0
  9. {malloryapi-0.2.3.post1.dev0 → malloryapi-0.2.5}/README.md +0 -0
  10. {malloryapi-0.2.3.post1.dev0 → malloryapi-0.2.5}/pyproject.toml +0 -0
  11. {malloryapi-0.2.3.post1.dev0 → malloryapi-0.2.5}/src/malloryapi/__init__.py +0 -0
  12. {malloryapi-0.2.3.post1.dev0 → malloryapi-0.2.5}/src/malloryapi/_http.py +0 -0
  13. {malloryapi-0.2.3.post1.dev0 → malloryapi-0.2.5}/src/malloryapi/_pagination.py +0 -0
  14. {malloryapi-0.2.3.post1.dev0 → malloryapi-0.2.5}/src/malloryapi/_types.py +0 -0
  15. {malloryapi-0.2.3.post1.dev0 → malloryapi-0.2.5}/src/malloryapi/cli.py +0 -0
  16. {malloryapi-0.2.3.post1.dev0 → malloryapi-0.2.5}/src/malloryapi/exceptions.py +0 -0
  17. {malloryapi-0.2.3.post1.dev0 → malloryapi-0.2.5}/src/malloryapi/resources/__init__.py +0 -0
  18. {malloryapi-0.2.3.post1.dev0 → malloryapi-0.2.5}/src/malloryapi/resources/_base.py +0 -0
  19. {malloryapi-0.2.3.post1.dev0 → malloryapi-0.2.5}/src/malloryapi/resources/attack_patterns.py +0 -0
  20. {malloryapi-0.2.3.post1.dev0 → malloryapi-0.2.5}/src/malloryapi/resources/breaches.py +0 -0
  21. {malloryapi-0.2.3.post1.dev0 → malloryapi-0.2.5}/src/malloryapi/resources/content_chunks.py +0 -0
  22. {malloryapi-0.2.3.post1.dev0 → malloryapi-0.2.5}/src/malloryapi/resources/detection_signatures.py +0 -0
  23. {malloryapi-0.2.3.post1.dev0 → malloryapi-0.2.5}/src/malloryapi/resources/exploitations.py +0 -0
  24. {malloryapi-0.2.3.post1.dev0 → malloryapi-0.2.5}/src/malloryapi/resources/exploits.py +0 -0
  25. {malloryapi-0.2.3.post1.dev0 → malloryapi-0.2.5}/src/malloryapi/resources/malware.py +0 -0
  26. {malloryapi-0.2.3.post1.dev0 → malloryapi-0.2.5}/src/malloryapi/resources/mentions.py +0 -0
  27. {malloryapi-0.2.3.post1.dev0 → malloryapi-0.2.5}/src/malloryapi/resources/organizations.py +0 -0
  28. {malloryapi-0.2.3.post1.dev0 → malloryapi-0.2.5}/src/malloryapi/resources/products.py +0 -0
  29. {malloryapi-0.2.3.post1.dev0 → malloryapi-0.2.5}/src/malloryapi/resources/references.py +0 -0
  30. {malloryapi-0.2.3.post1.dev0 → malloryapi-0.2.5}/src/malloryapi/resources/search.py +0 -0
  31. {malloryapi-0.2.3.post1.dev0 → malloryapi-0.2.5}/src/malloryapi/resources/sources.py +0 -0
  32. {malloryapi-0.2.3.post1.dev0 → malloryapi-0.2.5}/src/malloryapi/resources/stories.py +0 -0
  33. {malloryapi-0.2.3.post1.dev0 → malloryapi-0.2.5}/src/malloryapi/resources/technology_product_advisories.py +0 -0
  34. {malloryapi-0.2.3.post1.dev0 → malloryapi-0.2.5}/src/malloryapi/resources/threat_actors.py +0 -0
  35. {malloryapi-0.2.3.post1.dev0 → malloryapi-0.2.5}/src/malloryapi/resources/vulnerabilities.py +0 -0
  36. {malloryapi-0.2.3.post1.dev0 → malloryapi-0.2.5}/src/malloryapi/resources/weaknesses.py +0 -0
  37. {malloryapi-0.2.3.post1.dev0 → malloryapi-0.2.5}/tests/conftest.py +0 -0
  38. {malloryapi-0.2.3.post1.dev0 → malloryapi-0.2.5}/tests/test_cli.py +0 -0
  39. {malloryapi-0.2.3.post1.dev0 → malloryapi-0.2.5}/tests/test_client.py +0 -0
  40. {malloryapi-0.2.3.post1.dev0 → malloryapi-0.2.5}/tests/test_http.py +0 -0
  41. {malloryapi-0.2.3.post1.dev0 → malloryapi-0.2.5}/tests/test_vulnerabilities.py +0 -0
  42. {malloryapi-0.2.3.post1.dev0 → malloryapi-0.2.5}/uv.lock +0 -0
@@ -50,7 +50,10 @@ jobs:
50
50
  run: git fetch --tags --force
51
51
 
52
52
  - name: Verify version
53
- run: git describe --tags
53
+ run: |
54
+ echo "Git describe: $(git describe --tags)"
55
+ echo "Release tag: ${{ github.event.release.tag_name }}"
56
+ echo "Package version: ${GITHUB_REF_NAME#v}"
54
57
 
55
58
  - name: Install uv
56
59
  uses: astral-sh/setup-uv@v4
@@ -58,7 +61,13 @@ jobs:
58
61
  - name: Set up Python
59
62
  run: uv python install 3.12
60
63
 
64
+ - name: Extract version from tag
65
+ id: version
66
+ run: echo "version=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT"
67
+
61
68
  - name: Build package
69
+ env:
70
+ SETUPTOOLS_SCM_PRETEND_VERSION: ${{ steps.version.outputs.version }}
62
71
  run: |
63
72
  uv venv
64
73
  uv pip install build
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: malloryapi
3
- Version: 0.2.3.post1.dev0
3
+ Version: 0.2.5
4
4
  Summary: Official Python client for the Mallory threat intelligence API
5
5
  Project-URL: Homepage, https://mallory.ai
6
6
  Project-URL: Documentation, https://docs.mallory.ai
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '0.2.3.post1.dev0'
32
- __version_tuple__ = version_tuple = (0, 2, 3, 'post1', 'dev0')
31
+ __version__ = version = '0.2.5'
32
+ __version_tuple__ = version_tuple = (0, 2, 5)
33
33
 
34
34
  __commit_id__ = commit_id = None
@@ -2,6 +2,8 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ from typing import Any
6
+
5
7
  from malloryapi._http import (
6
8
  DEFAULT_BASE_URL,
7
9
  DEFAULT_TIMEOUT,
@@ -48,6 +50,7 @@ from malloryapi.resources.threat_actors import (
48
50
  AsyncThreatActors,
49
51
  ThreatActors,
50
52
  )
53
+ from malloryapi.resources.user import AsyncUser, User
51
54
  from malloryapi.resources.vulnerabilities import (
52
55
  AsyncVulnerabilities,
53
56
  Vulnerabilities,
@@ -104,6 +107,26 @@ class MalloryApi:
104
107
  self.mentions = Mentions(self._http)
105
108
  self.search = Search(self._http)
106
109
 
110
+ # Account
111
+ self.user = User(self._http)
112
+
113
+ def health(self) -> dict[str, Any]:
114
+ """Check API health (unauthenticated).
115
+
116
+ Returns ``{"message": "OK", "status": "HEALTHY"}`` when the
117
+ API is reachable and operational.
118
+ """
119
+ return self._http.get("/health")
120
+
121
+ def whoami(self) -> dict[str, Any]:
122
+ """Return the current authenticated user's information.
123
+
124
+ Shortcut for ``client.user.me()``. Verifies that the
125
+ configured API key is valid and returns user details
126
+ (uuid, email, first_name, last_name).
127
+ """
128
+ return self.user.me()
129
+
107
130
  def close(self) -> None:
108
131
  """Close the underlying HTTP connection."""
109
132
  self._http.close()
@@ -165,6 +188,26 @@ class AsyncMalloryApi:
165
188
  self.mentions = AsyncMentions(self._http)
166
189
  self.search = AsyncSearch(self._http)
167
190
 
191
+ # Account
192
+ self.user = AsyncUser(self._http)
193
+
194
+ async def health(self) -> dict[str, Any]:
195
+ """Check API health (unauthenticated).
196
+
197
+ Returns ``{"message": "OK", "status": "HEALTHY"}`` when the
198
+ API is reachable and operational.
199
+ """
200
+ return await self._http.get("/health")
201
+
202
+ async def whoami(self) -> dict[str, Any]:
203
+ """Return the current authenticated user's information.
204
+
205
+ Shortcut for ``client.user.me()``. Verifies that the
206
+ configured API key is valid and returns user details
207
+ (uuid, email, first_name, last_name).
208
+ """
209
+ return await self.user.me()
210
+
168
211
  async def aclose(self) -> None:
169
212
  """Close the underlying HTTP connection."""
170
213
  await self._http.aclose()
@@ -0,0 +1,31 @@
1
+ """User resource – current authenticated user info."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ from malloryapi.resources._base import AsyncResource, SyncResource
8
+
9
+
10
+ class User(SyncResource):
11
+ _path = "/user"
12
+
13
+ def me(self) -> dict[str, Any]:
14
+ """Get the current authenticated user's information.
15
+
16
+ Returns the user's UUID, email, first name, and last name.
17
+ Requires a valid API key or Clerk token.
18
+ """
19
+ return self._http.get(self._path)
20
+
21
+
22
+ class AsyncUser(AsyncResource):
23
+ _path = "/user"
24
+
25
+ async def me(self) -> dict[str, Any]:
26
+ """Get the current authenticated user's information.
27
+
28
+ Returns the user's UUID, email, first name, and last name.
29
+ Requires a valid API key or Clerk token.
30
+ """
31
+ return await self._http.get(self._path)