valentina-python-client 1.20.1__tar.gz → 1.22.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.
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/PKG-INFO +13 -1
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/README.md +12 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/pyproject.toml +1 -1
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/__init__.py +5 -1
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_codegen.py +5 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_sync/__init__.py +2 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_sync/client.py +15 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_sync/registry.py +24 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_sync/services/__init__.py +2 -0
- valentina_python_client-1.22.0/src/vclient/_sync/services/_audit_params.py +63 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_sync/services/companies.py +204 -2
- valentina_python_client-1.22.0/src/vclient/_sync/services/global_admin.py +406 -0
- valentina_python_client-1.22.0/src/vclient/_sync/services/user_lookup.py +68 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/client.py +15 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/constants.py +19 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/endpoints.py +5 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/models/__init__.py +10 -0
- valentina_python_client-1.22.0/src/vclient/models/audit_logs.py +55 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/models/companies.py +5 -0
- valentina_python_client-1.22.0/src/vclient/models/user_lookup.py +22 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/registry.py +24 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/services/__init__.py +2 -0
- valentina_python_client-1.22.0/src/vclient/services/_audit_params.py +64 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/services/companies.py +207 -3
- valentina_python_client-1.22.0/src/vclient/services/global_admin.py +429 -0
- valentina_python_client-1.22.0/src/vclient/services/user_lookup.py +67 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/testing/__init__.py +6 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/testing/_factories.py +22 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/testing/_router.py +9 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/testing/_routes.py +8 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/validate_constants.py +2 -0
- valentina_python_client-1.20.1/src/vclient/_sync/services/global_admin.py +0 -199
- valentina_python_client-1.20.1/src/vclient/services/global_admin.py +0 -217
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/LICENSE +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_sync/services/base.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_sync/services/campaign_book_chapters.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_sync/services/campaign_books.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_sync/services/campaigns.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_sync/services/character_autogen.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_sync/services/character_blueprint.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_sync/services/character_traits.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_sync/services/characters.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_sync/services/developers.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_sync/services/dicerolls.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_sync/services/dictionary.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_sync/services/options.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_sync/services/system.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_sync/services/users.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_sync/testing/__init__.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_sync/testing/_client.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/config.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/exceptions.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/models/books.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/models/campaigns.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/models/chapters.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/models/character_autogen.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/models/character_blueprint.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/models/character_trait.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/models/characters.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/models/developers.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/models/diceroll.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/models/dictionary.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/models/full_sheet.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/models/global_admin.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/models/pagination.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/models/shared.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/models/system.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/models/users.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/py.typed +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/services/base.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/services/campaign_book_chapters.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/services/campaign_books.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/services/campaigns.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/services/character_autogen.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/services/character_blueprint.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/services/character_traits.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/services/characters.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/services/developers.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/services/dicerolls.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/services/dictionary.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/services/options.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/services/system.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/services/users.py +0 -0
- {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/testing/_client.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: valentina-python-client
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.22.0
|
|
4
4
|
Summary: Async Python client library for the Valentina Noir API
|
|
5
5
|
Author: Nate Landau
|
|
6
6
|
Author-email: Nate Landau <github@natenate.org>
|
|
@@ -47,6 +47,18 @@ This client is a supported and up-to-date reference implementation for the [Vale
|
|
|
47
47
|
|
|
48
48
|
The full documentation is available at https://natelandau.github.io/valentina-python-client/.
|
|
49
49
|
|
|
50
|
+
## Claude Code Skill
|
|
51
|
+
|
|
52
|
+
This repo includes a [Claude Code skill](https://docs.anthropic.com/en/docs/claude-code/skills) that gives Claude deep knowledge of vclient's services, models, constants, and testing utilities. Install it so Claude can help you build applications against the Valentina API.
|
|
53
|
+
|
|
54
|
+
### Install
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
claude install-skill /path/to/valentina-python-client/vclient-guide-skill
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Once installed, Claude will automatically activate the skill when you're working with vclient imports, Valentina API endpoints, or FakeVClient testing.
|
|
61
|
+
|
|
50
62
|
## Development Tools
|
|
51
63
|
|
|
52
64
|
### Validate Constants
|
|
@@ -18,6 +18,18 @@ This client is a supported and up-to-date reference implementation for the [Vale
|
|
|
18
18
|
|
|
19
19
|
The full documentation is available at https://natelandau.github.io/valentina-python-client/.
|
|
20
20
|
|
|
21
|
+
## Claude Code Skill
|
|
22
|
+
|
|
23
|
+
This repo includes a [Claude Code skill](https://docs.anthropic.com/en/docs/claude-code/skills) that gives Claude deep knowledge of vclient's services, models, constants, and testing utilities. Install it so Claude can help you build applications against the Valentina API.
|
|
24
|
+
|
|
25
|
+
### Install
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
claude install-skill /path/to/valentina-python-client/vclient-guide-skill
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Once installed, Claude will automatically activate the skill when you're working with vclient imports, Valentina API endpoints, or FakeVClient testing.
|
|
32
|
+
|
|
21
33
|
## Development Tools
|
|
22
34
|
|
|
23
35
|
### Validate Constants
|
|
@@ -49,6 +49,7 @@ from vclient._sync import ( # noqa: E402
|
|
|
49
49
|
sync_global_admin_service,
|
|
50
50
|
sync_options_service,
|
|
51
51
|
sync_system_service,
|
|
52
|
+
sync_user_lookup_service,
|
|
52
53
|
sync_users_service,
|
|
53
54
|
)
|
|
54
55
|
from vclient.client import VClient # noqa: E402
|
|
@@ -67,6 +68,7 @@ from vclient.registry import ( # noqa: E402
|
|
|
67
68
|
global_admin_service,
|
|
68
69
|
options_service,
|
|
69
70
|
system_service,
|
|
71
|
+
user_lookup_service,
|
|
70
72
|
users_service,
|
|
71
73
|
)
|
|
72
74
|
|
|
@@ -100,9 +102,11 @@ __all__ = (
|
|
|
100
102
|
"sync_global_admin_service",
|
|
101
103
|
"sync_options_service",
|
|
102
104
|
"sync_system_service",
|
|
105
|
+
"sync_user_lookup_service",
|
|
103
106
|
"sync_users_service",
|
|
104
107
|
"system_service",
|
|
108
|
+
"user_lookup_service",
|
|
105
109
|
"users_service",
|
|
106
110
|
)
|
|
107
111
|
|
|
108
|
-
__version__ = "1.
|
|
112
|
+
__version__ = "1.22.0"
|
|
@@ -28,6 +28,7 @@ RENAME_CLASSES: dict[str, str] = {
|
|
|
28
28
|
"GlobalAdminService": "SyncGlobalAdminService",
|
|
29
29
|
"OptionsService": "SyncOptionsService",
|
|
30
30
|
"SystemService": "SyncSystemService",
|
|
31
|
+
"UserLookupService": "SyncUserLookupService",
|
|
31
32
|
"UsersService": "SyncUsersService",
|
|
32
33
|
"VClient": "SyncVClient",
|
|
33
34
|
"FakeVClient": "SyncFakeVClient",
|
|
@@ -49,6 +50,7 @@ FACTORY_RENAMES: dict[str, str] = {
|
|
|
49
50
|
"dicerolls_service": "sync_dicerolls_service",
|
|
50
51
|
"options_service": "sync_options_service",
|
|
51
52
|
"character_autogen_service": "sync_character_autogen_service",
|
|
53
|
+
"user_lookup_service": "sync_user_lookup_service",
|
|
52
54
|
"configure_default_client": "sync_configure_default_client",
|
|
53
55
|
"clear_default_client": "sync_clear_default_client",
|
|
54
56
|
"default_client": "sync_default_client",
|
|
@@ -73,6 +75,7 @@ IMPORT_REWRITES: dict[str, str] = {
|
|
|
73
75
|
"vclient.services.dicerolls": "vclient._sync.services.dicerolls",
|
|
74
76
|
"vclient.services.options": "vclient._sync.services.options",
|
|
75
77
|
"vclient.services.character_autogen": "vclient._sync.services.character_autogen",
|
|
78
|
+
"vclient.services.user_lookup": "vclient._sync.services.user_lookup",
|
|
76
79
|
"vclient.registry": "vclient._sync.registry",
|
|
77
80
|
"vclient.testing._client": "vclient._sync.testing._client",
|
|
78
81
|
}
|
|
@@ -307,6 +310,7 @@ def _write_sync_init(path: Path) -> None:
|
|
|
307
310
|
" sync_global_admin_service,",
|
|
308
311
|
" sync_options_service,",
|
|
309
312
|
" sync_system_service,",
|
|
313
|
+
" sync_user_lookup_service,",
|
|
310
314
|
" sync_users_service,",
|
|
311
315
|
")",
|
|
312
316
|
"",
|
|
@@ -329,6 +333,7 @@ def _write_sync_init(path: Path) -> None:
|
|
|
329
333
|
' "sync_global_admin_service",',
|
|
330
334
|
' "sync_options_service",',
|
|
331
335
|
' "sync_system_service",',
|
|
336
|
+
' "sync_user_lookup_service",',
|
|
332
337
|
' "sync_users_service",',
|
|
333
338
|
"]",
|
|
334
339
|
"",
|
{valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_sync/__init__.py
RENAMED
|
@@ -19,6 +19,7 @@ from vclient._sync.registry import (
|
|
|
19
19
|
sync_global_admin_service,
|
|
20
20
|
sync_options_service,
|
|
21
21
|
sync_system_service,
|
|
22
|
+
sync_user_lookup_service,
|
|
22
23
|
sync_users_service,
|
|
23
24
|
)
|
|
24
25
|
|
|
@@ -41,5 +42,6 @@ __all__ = [
|
|
|
41
42
|
"sync_global_admin_service",
|
|
42
43
|
"sync_options_service",
|
|
43
44
|
"sync_system_service",
|
|
45
|
+
"sync_user_lookup_service",
|
|
44
46
|
"sync_users_service",
|
|
45
47
|
]
|
{valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_sync/client.py
RENAMED
|
@@ -37,6 +37,7 @@ if TYPE_CHECKING:
|
|
|
37
37
|
SyncGlobalAdminService,
|
|
38
38
|
SyncOptionsService,
|
|
39
39
|
SyncSystemService,
|
|
40
|
+
SyncUserLookupService,
|
|
40
41
|
SyncUsersService,
|
|
41
42
|
)
|
|
42
43
|
|
|
@@ -147,6 +148,7 @@ class SyncVClient:
|
|
|
147
148
|
self._developer: SyncDeveloperService | None = None
|
|
148
149
|
self._global_admin: SyncGlobalAdminService | None = None
|
|
149
150
|
self._system: SyncSystemService | None = None
|
|
151
|
+
self._user_lookup: SyncUserLookupService | None = None
|
|
150
152
|
if set_as_default:
|
|
151
153
|
from vclient._sync.registry import sync_configure_default_client
|
|
152
154
|
|
|
@@ -278,6 +280,19 @@ class SyncVClient:
|
|
|
278
280
|
self._system = SyncSystemService(self)
|
|
279
281
|
return self._system
|
|
280
282
|
|
|
283
|
+
@property
|
|
284
|
+
def user_lookup(self) -> "SyncUserLookupService":
|
|
285
|
+
"""Access the User Lookup service for cross-company user discovery.
|
|
286
|
+
|
|
287
|
+
Returns:
|
|
288
|
+
The SyncUserLookupService instance for user lookup operations.
|
|
289
|
+
"""
|
|
290
|
+
if self._user_lookup is None:
|
|
291
|
+
from vclient._sync.services.user_lookup import SyncUserLookupService
|
|
292
|
+
|
|
293
|
+
self._user_lookup = SyncUserLookupService(self)
|
|
294
|
+
return self._user_lookup
|
|
295
|
+
|
|
281
296
|
def users(self, company_id: str | None = None) -> "SyncUsersService":
|
|
282
297
|
"""Get a SyncUsersService scoped to a specific company.
|
|
283
298
|
|
{valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_sync/registry.py
RENAMED
|
@@ -38,6 +38,7 @@ if TYPE_CHECKING:
|
|
|
38
38
|
SyncGlobalAdminService,
|
|
39
39
|
SyncOptionsService,
|
|
40
40
|
SyncSystemService,
|
|
41
|
+
SyncUserLookupService,
|
|
41
42
|
SyncUsersService,
|
|
42
43
|
)
|
|
43
44
|
_default_client: "SyncVClient | None" = None
|
|
@@ -189,6 +190,29 @@ def sync_system_service() -> "SyncSystemService":
|
|
|
189
190
|
return SyncSystemService(sync_default_client())
|
|
190
191
|
|
|
191
192
|
|
|
193
|
+
def sync_user_lookup_service() -> "SyncUserLookupService":
|
|
194
|
+
"""Create a SyncUserLookupService using the default client.
|
|
195
|
+
|
|
196
|
+
Discover which companies a person has a user record in by searching
|
|
197
|
+
via email, Discord ID, Google ID, or GitHub ID.
|
|
198
|
+
|
|
199
|
+
Returns:
|
|
200
|
+
SyncUserLookupService: A service instance for cross-company user lookup.
|
|
201
|
+
|
|
202
|
+
Raises:
|
|
203
|
+
RuntimeError: If no default client has been configured.
|
|
204
|
+
|
|
205
|
+
Example:
|
|
206
|
+
```python
|
|
207
|
+
lookup = sync_user_lookup_service()
|
|
208
|
+
results = await lookup.by_email("alice@example.com")
|
|
209
|
+
```
|
|
210
|
+
"""
|
|
211
|
+
from vclient._sync.services.user_lookup import SyncUserLookupService
|
|
212
|
+
|
|
213
|
+
return SyncUserLookupService(sync_default_client())
|
|
214
|
+
|
|
215
|
+
|
|
192
216
|
def sync_users_service(company_id: str | None = None) -> "SyncUsersService":
|
|
193
217
|
"""Create a SyncUsersService scoped to a specific company using the default client.
|
|
194
218
|
|
|
@@ -16,6 +16,7 @@ from .dictionary import SyncDictionaryService
|
|
|
16
16
|
from .global_admin import SyncGlobalAdminService
|
|
17
17
|
from .options import SyncOptionsService
|
|
18
18
|
from .system import SyncSystemService
|
|
19
|
+
from .user_lookup import SyncUserLookupService
|
|
19
20
|
from .users import SyncUsersService
|
|
20
21
|
|
|
21
22
|
__all__ = [
|
|
@@ -34,5 +35,6 @@ __all__ = [
|
|
|
34
35
|
"SyncGlobalAdminService",
|
|
35
36
|
"SyncOptionsService",
|
|
36
37
|
"SyncSystemService",
|
|
38
|
+
"SyncUserLookupService",
|
|
37
39
|
"SyncUsersService",
|
|
38
40
|
]
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# AUTO-GENERATED — do not edit. Run 'uv run duty generate_sync' to regenerate.
|
|
2
|
+
"""Shared query parameter builder for audit log endpoints."""
|
|
3
|
+
|
|
4
|
+
from collections.abc import Sequence
|
|
5
|
+
from datetime import datetime
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def _build_audit_params(
|
|
9
|
+
*,
|
|
10
|
+
acting_user_id: str | None = None,
|
|
11
|
+
user_id: str | None = None,
|
|
12
|
+
campaign_id: str | None = None,
|
|
13
|
+
book_id: str | None = None,
|
|
14
|
+
chapter_id: str | None = None,
|
|
15
|
+
character_id: str | None = None,
|
|
16
|
+
entity_type: str | None = None,
|
|
17
|
+
operation: str | None = None,
|
|
18
|
+
date_from: datetime | None = None,
|
|
19
|
+
date_to: datetime | None = None,
|
|
20
|
+
include: Sequence[str] | None = None,
|
|
21
|
+
company_id: str | None = None,
|
|
22
|
+
) -> dict[str, str]:
|
|
23
|
+
"""Build query parameter dict from audit log filter kwargs.
|
|
24
|
+
|
|
25
|
+
Only include non-None values. Serialize datetimes to ISO 8601 and
|
|
26
|
+
join include lists with commas.
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
acting_user_id: Filter by the user who performed the action.
|
|
30
|
+
user_id: Filter by the user affected by the action.
|
|
31
|
+
campaign_id: Filter by campaign ID.
|
|
32
|
+
book_id: Filter by book ID.
|
|
33
|
+
chapter_id: Filter by chapter ID.
|
|
34
|
+
character_id: Filter by character ID.
|
|
35
|
+
entity_type: Filter by entity type (e.g., "CAMPAIGN", "CHARACTER").
|
|
36
|
+
operation: Filter by operation type (CREATE, UPDATE, DELETE).
|
|
37
|
+
date_from: Return logs on or after this datetime (ISO 8601 serialized).
|
|
38
|
+
date_to: Return logs on or before this datetime (ISO 8601 serialized).
|
|
39
|
+
include: Additional data to include (e.g., ("request_details",)).
|
|
40
|
+
company_id: Filter by company ID (used for global admin endpoint).
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
A dict of query parameters with only non-None values included.
|
|
44
|
+
"""
|
|
45
|
+
string_params: dict[str, str | None] = {
|
|
46
|
+
"acting_user_id": acting_user_id,
|
|
47
|
+
"user_id": user_id,
|
|
48
|
+
"campaign_id": campaign_id,
|
|
49
|
+
"book_id": book_id,
|
|
50
|
+
"chapter_id": chapter_id,
|
|
51
|
+
"character_id": character_id,
|
|
52
|
+
"entity_type": entity_type,
|
|
53
|
+
"operation": operation,
|
|
54
|
+
"company_id": company_id,
|
|
55
|
+
}
|
|
56
|
+
params: dict[str, str] = {k: v for k, v in string_params.items() if v is not None}
|
|
57
|
+
if date_from is not None:
|
|
58
|
+
params["date_from"] = date_from.isoformat()
|
|
59
|
+
if date_to is not None:
|
|
60
|
+
params["date_to"] = date_to.isoformat()
|
|
61
|
+
if include is not None:
|
|
62
|
+
params["include"] = ",".join(include)
|
|
63
|
+
return params
|
|
@@ -1,12 +1,21 @@
|
|
|
1
1
|
# AUTO-GENERATED — do not edit. Run 'uv run duty generate_sync' to regenerate.
|
|
2
2
|
"""Service for interacting with the Companies API."""
|
|
3
3
|
|
|
4
|
-
from collections.abc import Iterator
|
|
4
|
+
from collections.abc import Iterator, Sequence
|
|
5
|
+
from datetime import datetime
|
|
5
6
|
|
|
6
7
|
from vclient._sync.services.base import SyncBaseService
|
|
7
|
-
from vclient.constants import
|
|
8
|
+
from vclient.constants import (
|
|
9
|
+
DEFAULT_PAGE_LIMIT,
|
|
10
|
+
AuditEntityType,
|
|
11
|
+
AuditLogInclude,
|
|
12
|
+
AuditOperation,
|
|
13
|
+
PermissionLevel,
|
|
14
|
+
)
|
|
8
15
|
from vclient.endpoints import Endpoints
|
|
9
16
|
from vclient.models import (
|
|
17
|
+
AuditLog,
|
|
18
|
+
AuditLogDetail,
|
|
10
19
|
Company,
|
|
11
20
|
CompanyCreate,
|
|
12
21
|
CompanyPermissions,
|
|
@@ -16,6 +25,7 @@ from vclient.models import (
|
|
|
16
25
|
RollStatistics,
|
|
17
26
|
_GrantAccess,
|
|
18
27
|
)
|
|
28
|
+
from vclient.services._audit_params import _build_audit_params
|
|
19
29
|
|
|
20
30
|
|
|
21
31
|
class SyncCompaniesService(SyncBaseService):
|
|
@@ -216,3 +226,195 @@ class SyncCompaniesService(SyncBaseService):
|
|
|
216
226
|
params={"num_top_traits": num_top_traits},
|
|
217
227
|
)
|
|
218
228
|
return RollStatistics.model_validate(response.json())
|
|
229
|
+
|
|
230
|
+
def get_audit_log_page(
|
|
231
|
+
self,
|
|
232
|
+
company_id: str,
|
|
233
|
+
*,
|
|
234
|
+
limit: int = DEFAULT_PAGE_LIMIT,
|
|
235
|
+
offset: int = 0,
|
|
236
|
+
acting_user_id: str | None = None,
|
|
237
|
+
user_id: str | None = None,
|
|
238
|
+
campaign_id: str | None = None,
|
|
239
|
+
book_id: str | None = None,
|
|
240
|
+
chapter_id: str | None = None,
|
|
241
|
+
character_id: str | None = None,
|
|
242
|
+
entity_type: AuditEntityType | None = None,
|
|
243
|
+
operation: AuditOperation | None = None,
|
|
244
|
+
date_from: datetime | None = None,
|
|
245
|
+
date_to: datetime | None = None,
|
|
246
|
+
include: Sequence[AuditLogInclude] | None = None,
|
|
247
|
+
) -> PaginatedResponse[AuditLog] | PaginatedResponse[AuditLogDetail]:
|
|
248
|
+
"""Retrieve a paginated page of audit log entries for a company.
|
|
249
|
+
|
|
250
|
+
Use filter parameters to narrow results by entity, operation, user, or time range.
|
|
251
|
+
Pass ``include=["request_details"]`` to receive full HTTP request forensics in each
|
|
252
|
+
entry (returns AuditLogDetail instead of AuditLog).
|
|
253
|
+
|
|
254
|
+
Args:
|
|
255
|
+
company_id: The ID of the company whose audit logs to retrieve.
|
|
256
|
+
limit: Maximum number of items to return (0-100, default 10).
|
|
257
|
+
offset: Number of items to skip from the beginning (default 0).
|
|
258
|
+
acting_user_id: Filter by the user who performed the action.
|
|
259
|
+
user_id: Filter by the user affected by the action.
|
|
260
|
+
campaign_id: Filter by campaign ID.
|
|
261
|
+
book_id: Filter by book ID.
|
|
262
|
+
chapter_id: Filter by chapter ID.
|
|
263
|
+
character_id: Filter by character ID.
|
|
264
|
+
entity_type: Filter by entity type (e.g., "CAMPAIGN", "CHARACTER").
|
|
265
|
+
operation: Filter by operation type (CREATE, UPDATE, DELETE).
|
|
266
|
+
date_from: Return logs on or after this datetime.
|
|
267
|
+
date_to: Return logs on or before this datetime.
|
|
268
|
+
include: Additional data to include. Pass ["request_details"] for HTTP forensics.
|
|
269
|
+
|
|
270
|
+
Returns:
|
|
271
|
+
A PaginatedResponse containing AuditLog (or AuditLogDetail) objects.
|
|
272
|
+
|
|
273
|
+
Raises:
|
|
274
|
+
NotFoundError: If the company does not exist.
|
|
275
|
+
AuthorizationError: If you don't have access to the company.
|
|
276
|
+
"""
|
|
277
|
+
model = AuditLogDetail if include and "request_details" in include else AuditLog
|
|
278
|
+
params = _build_audit_params(
|
|
279
|
+
acting_user_id=acting_user_id,
|
|
280
|
+
user_id=user_id,
|
|
281
|
+
campaign_id=campaign_id,
|
|
282
|
+
book_id=book_id,
|
|
283
|
+
chapter_id=chapter_id,
|
|
284
|
+
character_id=character_id,
|
|
285
|
+
entity_type=entity_type,
|
|
286
|
+
operation=operation,
|
|
287
|
+
date_from=date_from,
|
|
288
|
+
date_to=date_to,
|
|
289
|
+
include=include,
|
|
290
|
+
)
|
|
291
|
+
return self._get_paginated_as(
|
|
292
|
+
Endpoints.COMPANY_AUDIT_LOGS.format(company_id=company_id),
|
|
293
|
+
model,
|
|
294
|
+
limit=limit,
|
|
295
|
+
offset=offset,
|
|
296
|
+
params=params,
|
|
297
|
+
)
|
|
298
|
+
|
|
299
|
+
def list_all_audit_logs(
|
|
300
|
+
self,
|
|
301
|
+
company_id: str,
|
|
302
|
+
*,
|
|
303
|
+
acting_user_id: str | None = None,
|
|
304
|
+
user_id: str | None = None,
|
|
305
|
+
campaign_id: str | None = None,
|
|
306
|
+
book_id: str | None = None,
|
|
307
|
+
chapter_id: str | None = None,
|
|
308
|
+
character_id: str | None = None,
|
|
309
|
+
entity_type: AuditEntityType | None = None,
|
|
310
|
+
operation: AuditOperation | None = None,
|
|
311
|
+
date_from: datetime | None = None,
|
|
312
|
+
date_to: datetime | None = None,
|
|
313
|
+
include: Sequence[AuditLogInclude] | None = None,
|
|
314
|
+
) -> list[AuditLog] | list[AuditLogDetail]:
|
|
315
|
+
"""Retrieve all audit log entries for a company.
|
|
316
|
+
|
|
317
|
+
Automatically paginates through all results. Use ``get_audit_log_page()`` for
|
|
318
|
+
paginated access or ``iter_all_audit_logs()`` for memory-efficient streaming.
|
|
319
|
+
|
|
320
|
+
Args:
|
|
321
|
+
company_id: The ID of the company whose audit logs to retrieve.
|
|
322
|
+
acting_user_id: Filter by the user who performed the action.
|
|
323
|
+
user_id: Filter by the user affected by the action.
|
|
324
|
+
campaign_id: Filter by campaign ID.
|
|
325
|
+
book_id: Filter by book ID.
|
|
326
|
+
chapter_id: Filter by chapter ID.
|
|
327
|
+
character_id: Filter by character ID.
|
|
328
|
+
entity_type: Filter by entity type (e.g., "CAMPAIGN", "CHARACTER").
|
|
329
|
+
operation: Filter by operation type (CREATE, UPDATE, DELETE).
|
|
330
|
+
date_from: Return logs on or after this datetime.
|
|
331
|
+
date_to: Return logs on or before this datetime.
|
|
332
|
+
include: Additional data to include. Pass ["request_details"] for HTTP forensics.
|
|
333
|
+
|
|
334
|
+
Returns:
|
|
335
|
+
A list of all AuditLog (or AuditLogDetail) objects.
|
|
336
|
+
|
|
337
|
+
Raises:
|
|
338
|
+
NotFoundError: If the company does not exist.
|
|
339
|
+
AuthorizationError: If you don't have access to the company.
|
|
340
|
+
"""
|
|
341
|
+
return [
|
|
342
|
+
log
|
|
343
|
+
for log in self.iter_all_audit_logs(
|
|
344
|
+
company_id,
|
|
345
|
+
acting_user_id=acting_user_id,
|
|
346
|
+
user_id=user_id,
|
|
347
|
+
campaign_id=campaign_id,
|
|
348
|
+
book_id=book_id,
|
|
349
|
+
chapter_id=chapter_id,
|
|
350
|
+
character_id=character_id,
|
|
351
|
+
entity_type=entity_type,
|
|
352
|
+
operation=operation,
|
|
353
|
+
date_from=date_from,
|
|
354
|
+
date_to=date_to,
|
|
355
|
+
include=include,
|
|
356
|
+
)
|
|
357
|
+
]
|
|
358
|
+
|
|
359
|
+
def iter_all_audit_logs(
|
|
360
|
+
self,
|
|
361
|
+
company_id: str,
|
|
362
|
+
*,
|
|
363
|
+
limit: int = 100,
|
|
364
|
+
acting_user_id: str | None = None,
|
|
365
|
+
user_id: str | None = None,
|
|
366
|
+
campaign_id: str | None = None,
|
|
367
|
+
book_id: str | None = None,
|
|
368
|
+
chapter_id: str | None = None,
|
|
369
|
+
character_id: str | None = None,
|
|
370
|
+
entity_type: AuditEntityType | None = None,
|
|
371
|
+
operation: AuditOperation | None = None,
|
|
372
|
+
date_from: datetime | None = None,
|
|
373
|
+
date_to: datetime | None = None,
|
|
374
|
+
include: Sequence[AuditLogInclude] | None = None,
|
|
375
|
+
) -> Iterator[AuditLog] | Iterator[AuditLogDetail]:
|
|
376
|
+
"""Iterate through all audit log entries for a company.
|
|
377
|
+
|
|
378
|
+
Yields individual audit log entries, automatically fetching subsequent pages
|
|
379
|
+
until all matching entries have been retrieved.
|
|
380
|
+
|
|
381
|
+
Args:
|
|
382
|
+
company_id: The ID of the company whose audit logs to retrieve.
|
|
383
|
+
limit: Items per page (default 100 for efficiency).
|
|
384
|
+
acting_user_id: Filter by the user who performed the action.
|
|
385
|
+
user_id: Filter by the user affected by the action.
|
|
386
|
+
campaign_id: Filter by campaign ID.
|
|
387
|
+
book_id: Filter by book ID.
|
|
388
|
+
chapter_id: Filter by chapter ID.
|
|
389
|
+
character_id: Filter by character ID.
|
|
390
|
+
entity_type: Filter by entity type (e.g., "CAMPAIGN", "CHARACTER").
|
|
391
|
+
operation: Filter by operation type (CREATE, UPDATE, DELETE).
|
|
392
|
+
date_from: Return logs on or after this datetime.
|
|
393
|
+
date_to: Return logs on or before this datetime.
|
|
394
|
+
include: Additional data to include. Pass ["request_details"] for HTTP forensics.
|
|
395
|
+
|
|
396
|
+
Yields:
|
|
397
|
+
Individual AuditLog (or AuditLogDetail) objects.
|
|
398
|
+
|
|
399
|
+
Raises:
|
|
400
|
+
NotFoundError: If the company does not exist.
|
|
401
|
+
AuthorizationError: If you don't have access to the company.
|
|
402
|
+
"""
|
|
403
|
+
model = AuditLogDetail if include and "request_details" in include else AuditLog
|
|
404
|
+
params = _build_audit_params(
|
|
405
|
+
acting_user_id=acting_user_id,
|
|
406
|
+
user_id=user_id,
|
|
407
|
+
campaign_id=campaign_id,
|
|
408
|
+
book_id=book_id,
|
|
409
|
+
chapter_id=chapter_id,
|
|
410
|
+
character_id=character_id,
|
|
411
|
+
entity_type=entity_type,
|
|
412
|
+
operation=operation,
|
|
413
|
+
date_from=date_from,
|
|
414
|
+
date_to=date_to,
|
|
415
|
+
include=include,
|
|
416
|
+
)
|
|
417
|
+
for item in self._iter_all_pages(
|
|
418
|
+
Endpoints.COMPANY_AUDIT_LOGS.format(company_id=company_id), limit=limit, params=params
|
|
419
|
+
):
|
|
420
|
+
yield model.model_validate(item)
|