boarddata 4.4.4__tar.gz → 4.4.8__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 (59) hide show
  1. {boarddata-4.4.4 → boarddata-4.4.8}/PKG-INFO +1 -1
  2. {boarddata-4.4.4 → boarddata-4.4.8}/__init__.py +1 -1
  3. {boarddata-4.4.4 → boarddata-4.4.8}/_auditors.py +21 -1
  4. {boarddata-4.4.4 → boarddata-4.4.8}/_directors.py +42 -0
  5. {boarddata-4.4.4 → boarddata-4.4.8}/boarddata.egg-info/PKG-INFO +1 -1
  6. {boarddata-4.4.4 → boarddata-4.4.8}/pyproject.toml +1 -1
  7. {boarddata-4.4.4 → boarddata-4.4.8}/tests/test_auditors.py +20 -0
  8. {boarddata-4.4.4 → boarddata-4.4.8}/tests/test_directors.py +52 -0
  9. {boarddata-4.4.4 → boarddata-4.4.8}/types/directors.py +16 -0
  10. {boarddata-4.4.4 → boarddata-4.4.8}/CLAUDE.md +0 -0
  11. {boarddata-4.4.4 → boarddata-4.4.8}/README.md +0 -0
  12. {boarddata-4.4.4 → boarddata-4.4.8}/_assemblies.py +0 -0
  13. {boarddata-4.4.4 → boarddata-4.4.8}/_base.py +0 -0
  14. {boarddata-4.4.4 → boarddata-4.4.8}/_comex.py +0 -0
  15. {boarddata-4.4.4 → boarddata-4.4.8}/_companies.py +0 -0
  16. {boarddata-4.4.4 → boarddata-4.4.8}/_criteria.py +0 -0
  17. {boarddata-4.4.4 → boarddata-4.4.8}/_documents.py +0 -0
  18. {boarddata-4.4.4 → boarddata-4.4.8}/_esg.py +0 -0
  19. {boarddata-4.4.4 → boarddata-4.4.8}/_indexes.py +0 -0
  20. {boarddata-4.4.4 → boarddata-4.4.8}/_persons.py +0 -0
  21. {boarddata-4.4.4 → boarddata-4.4.8}/_sentinel.py +0 -0
  22. {boarddata-4.4.4 → boarddata-4.4.8}/_utilities.py +0 -0
  23. {boarddata-4.4.4 → boarddata-4.4.8}/boarddata.egg-info/SOURCES.txt +0 -0
  24. {boarddata-4.4.4 → boarddata-4.4.8}/boarddata.egg-info/dependency_links.txt +0 -0
  25. {boarddata-4.4.4 → boarddata-4.4.8}/boarddata.egg-info/requires.txt +0 -0
  26. {boarddata-4.4.4 → boarddata-4.4.8}/boarddata.egg-info/top_level.txt +0 -0
  27. {boarddata-4.4.4 → boarddata-4.4.8}/cache.py +0 -0
  28. {boarddata-4.4.4 → boarddata-4.4.8}/client.py +0 -0
  29. {boarddata-4.4.4 → boarddata-4.4.8}/errors.py +0 -0
  30. {boarddata-4.4.4 → boarddata-4.4.8}/py.typed +0 -0
  31. {boarddata-4.4.4 → boarddata-4.4.8}/setup.cfg +0 -0
  32. {boarddata-4.4.4 → boarddata-4.4.8}/tests/__init__.py +0 -0
  33. {boarddata-4.4.4 → boarddata-4.4.8}/tests/conftest.py +0 -0
  34. {boarddata-4.4.4 → boarddata-4.4.8}/tests/test_assemblies.py +0 -0
  35. {boarddata-4.4.4 → boarddata-4.4.8}/tests/test_base.py +0 -0
  36. {boarddata-4.4.4 → boarddata-4.4.8}/tests/test_build_payload.py +0 -0
  37. {boarddata-4.4.4 → boarddata-4.4.8}/tests/test_cache.py +0 -0
  38. {boarddata-4.4.4 → boarddata-4.4.8}/tests/test_comex.py +0 -0
  39. {boarddata-4.4.4 → boarddata-4.4.8}/tests/test_companies.py +0 -0
  40. {boarddata-4.4.4 → boarddata-4.4.8}/tests/test_config.py +0 -0
  41. {boarddata-4.4.4 → boarddata-4.4.8}/tests/test_criteria.py +0 -0
  42. {boarddata-4.4.4 → boarddata-4.4.8}/tests/test_documents.py +0 -0
  43. {boarddata-4.4.4 → boarddata-4.4.8}/tests/test_esg.py +0 -0
  44. {boarddata-4.4.4 → boarddata-4.4.8}/tests/test_indexes.py +0 -0
  45. {boarddata-4.4.4 → boarddata-4.4.8}/tests/test_persons.py +0 -0
  46. {boarddata-4.4.4 → boarddata-4.4.8}/tests/test_sentinel.py +0 -0
  47. {boarddata-4.4.4 → boarddata-4.4.8}/tests/test_utilities.py +0 -0
  48. {boarddata-4.4.4 → boarddata-4.4.8}/types/__init__.py +0 -0
  49. {boarddata-4.4.4 → boarddata-4.4.8}/types/assemblies.py +0 -0
  50. {boarddata-4.4.4 → boarddata-4.4.8}/types/auditors.py +0 -0
  51. {boarddata-4.4.4 → boarddata-4.4.8}/types/comex.py +0 -0
  52. {boarddata-4.4.4 → boarddata-4.4.8}/types/companies.py +0 -0
  53. {boarddata-4.4.4 → boarddata-4.4.8}/types/core.py +0 -0
  54. {boarddata-4.4.4 → boarddata-4.4.8}/types/criteria.py +0 -0
  55. {boarddata-4.4.4 → boarddata-4.4.8}/types/documents.py +0 -0
  56. {boarddata-4.4.4 → boarddata-4.4.8}/types/esg.py +0 -0
  57. {boarddata-4.4.4 → boarddata-4.4.8}/types/indexes.py +0 -0
  58. {boarddata-4.4.4 → boarddata-4.4.8}/types/persons.py +0 -0
  59. {boarddata-4.4.4 → boarddata-4.4.8}/types/sentinel.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boarddata
3
- Version: 4.4.4
3
+ Version: 4.4.8
4
4
  Summary: Python SDK for the BoardData V2 REST API
5
5
  License: MIT
6
6
  Classifier: Development Status :: 4 - Beta
@@ -7,7 +7,7 @@ from .errors import BoardDataError
7
7
 
8
8
  from . import types as types # noqa: F401 — makes types accessible as boarddata.types
9
9
 
10
- __version__ = "4.4.4"
10
+ __version__ = "4.4.8"
11
11
  __all__ = [
12
12
  "Base",
13
13
  "BoardDataClient",
@@ -5,7 +5,7 @@ from __future__ import annotations
5
5
  import logging
6
6
  from typing import Any
7
7
 
8
- from .types.auditors import AuditorCompensationItem, AuditorCreateResponse, AuditorDetail
8
+ from .types.auditors import AuditorCompanyItem, AuditorCompensationItem, AuditorCreateResponse, AuditorDetail
9
9
  from .types.core import FieldSourcePayload, PaginatedResponse
10
10
 
11
11
  logger = logging.getLogger("boarddata")
@@ -153,6 +153,26 @@ class AuditorMixin:
153
153
  """
154
154
  return self._get("auditor-companies/", **params) # type: ignore[attr-defined]
155
155
 
156
+ def create_auditor_company(
157
+ self,
158
+ name: str,
159
+ country: str = "",
160
+ ) -> AuditorCompanyItem:
161
+ """Create an auditor company (get-or-create on the server).
162
+
163
+ Args:
164
+ name: Audit firm name (e.g. ``"Deloitte & Associés"``).
165
+ country: ISO 3166-1 alpha-2 country code (e.g. ``"FR"``).
166
+
167
+ Returns:
168
+ AuditorCompanyItem with id, name, and country.
169
+
170
+ Raises:
171
+ BoardDataError: On non-2xx API response.
172
+ """
173
+ payload = self._build_payload(name=name, country=country) # type: ignore[attr-defined]
174
+ return self._post("auditor-companies/", payload) # type: ignore[attr-defined]
175
+
156
176
  # ------------------------------------------------------------------
157
177
  # Auditor compensations
158
178
  # ------------------------------------------------------------------
@@ -103,6 +103,10 @@ class DirectorMixin:
103
103
  valid_to: str | None = None,
104
104
  is_independent: bool | None = None,
105
105
  is_executive: bool | None = None,
106
+ is_chairman: bool | None = None,
107
+ is_lead_independent: bool | None = None,
108
+ is_employee_representative: bool | None = None,
109
+ is_employee_shareholder_representative: bool | None = None,
106
110
  appointment_method: str | None = None,
107
111
  entity_type: str | None = None,
108
112
  representative_name: str | None = None,
@@ -119,6 +123,12 @@ class DirectorMixin:
119
123
  valid_to: End date (``"YYYY-MM-DD"``) or None if current.
120
124
  is_independent: Whether the director is independent.
121
125
  is_executive: Whether the director is executive.
126
+ is_chairman: Whether the director is Chairman of the Board.
127
+ is_lead_independent: Whether the director is Lead Independent Director.
128
+ is_employee_representative: Whether the director represents employees
129
+ (appointed by works council / employee vote).
130
+ is_employee_shareholder_representative: Whether the director represents
131
+ employee shareholders (AG-elected, distinct from employee reps).
122
132
  appointment_method: How they were appointed.
123
133
  entity_type: Entity type (physical, legal).
124
134
  representative_name: Name of legal entity representative.
@@ -139,6 +149,10 @@ class DirectorMixin:
139
149
  valid_to=valid_to,
140
150
  is_independent=is_independent,
141
151
  is_executive=is_executive,
152
+ is_chairman=is_chairman,
153
+ is_lead_independent=is_lead_independent,
154
+ is_employee_representative=is_employee_representative,
155
+ is_employee_shareholder_representative=is_employee_shareholder_representative,
142
156
  appointment_method=appointment_method,
143
157
  entity_type=entity_type,
144
158
  representative_name=representative_name,
@@ -156,6 +170,10 @@ class DirectorMixin:
156
170
  valid_to: str | None = None,
157
171
  is_independent: bool | None = None,
158
172
  is_executive: bool | None = None,
173
+ is_chairman: bool | None = None,
174
+ is_lead_independent: bool | None = None,
175
+ is_employee_representative: bool | None = None,
176
+ is_employee_shareholder_representative: bool | None = None,
159
177
  appointment_method: str | None = None,
160
178
  entity_type: str | None = None,
161
179
  representative_name: str | None = None,
@@ -171,6 +189,12 @@ class DirectorMixin:
171
189
  valid_to: End date (``"YYYY-MM-DD"``).
172
190
  is_independent: Whether the director is independent.
173
191
  is_executive: Whether the director is executive.
192
+ is_chairman: Whether the director is Chairman of the Board.
193
+ is_lead_independent: Whether the director is Lead Independent Director.
194
+ is_employee_representative: Whether the director represents employees
195
+ (appointed by works council / employee vote).
196
+ is_employee_shareholder_representative: Whether the director represents
197
+ employee shareholders (AG-elected, distinct from employee reps).
174
198
  appointment_method: How they were appointed.
175
199
  entity_type: Entity type.
176
200
  representative_name: Name of legal entity representative.
@@ -189,6 +213,10 @@ class DirectorMixin:
189
213
  valid_to=valid_to,
190
214
  is_independent=is_independent,
191
215
  is_executive=is_executive,
216
+ is_chairman=is_chairman,
217
+ is_lead_independent=is_lead_independent,
218
+ is_employee_representative=is_employee_representative,
219
+ is_employee_shareholder_representative=is_employee_shareholder_representative,
192
220
  appointment_method=appointment_method,
193
221
  entity_type=entity_type,
194
222
  representative_name=representative_name,
@@ -443,6 +471,10 @@ class DirectorMixin:
443
471
  valid_to: str | None = None,
444
472
  is_independent: bool | None = None,
445
473
  is_executive: bool | None = None,
474
+ is_chairman: bool | None = None,
475
+ is_lead_independent: bool | None = None,
476
+ is_employee_representative: bool | None = None,
477
+ is_employee_shareholder_representative: bool | None = None,
446
478
  appointment_method: str | None = None,
447
479
  entity_type: str | None = None,
448
480
  representative_name: str | None = None,
@@ -459,6 +491,12 @@ class DirectorMixin:
459
491
  valid_to: End date (``"YYYY-MM-DD"``).
460
492
  is_independent: Whether the director is independent.
461
493
  is_executive: Whether the director is executive.
494
+ is_chairman: Whether the director is Chairman of the Board.
495
+ is_lead_independent: Whether the director is Lead Independent Director.
496
+ is_employee_representative: Whether the director represents employees
497
+ (appointed by works council / employee vote).
498
+ is_employee_shareholder_representative: Whether the director represents
499
+ employee shareholders (AG-elected, distinct from employee reps).
462
500
  appointment_method: How they were appointed.
463
501
  entity_type: Entity type.
464
502
  representative_name: Name of legal entity representative.
@@ -490,6 +528,10 @@ class DirectorMixin:
490
528
  valid_to=valid_to,
491
529
  is_independent=is_independent,
492
530
  is_executive=is_executive,
531
+ is_chairman=is_chairman,
532
+ is_lead_independent=is_lead_independent,
533
+ is_employee_representative=is_employee_representative,
534
+ is_employee_shareholder_representative=is_employee_shareholder_representative,
493
535
  appointment_method=appointment_method,
494
536
  entity_type=entity_type,
495
537
  representative_name=representative_name,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boarddata
3
- Version: 4.4.4
3
+ Version: 4.4.8
4
4
  Summary: Python SDK for the BoardData V2 REST API
5
5
  License: MIT
6
6
  Classifier: Development Status :: 4 - Beta
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "boarddata"
7
- version = "4.4.4"
7
+ version = "4.4.8"
8
8
  description = "Python SDK for the BoardData V2 REST API"
9
9
  readme = "README.md"
10
10
  license = {text = "MIT"}
@@ -38,6 +38,26 @@ class TestCreateAuditor:
38
38
  assert payload["auditor_type"] == "PRINCIPAL"
39
39
 
40
40
 
41
+ class TestCreateAuditorCompany:
42
+ def test_sends_name_and_country(self):
43
+ c = make_client()
44
+ c._request.return_value = {"id": "ac1", "name": "Deloitte", "country": "FR"}
45
+ result = c.create_auditor_company("Deloitte", "FR")
46
+ _, kwargs = c._request.call_args
47
+ payload = kwargs["json"]
48
+ assert payload["name"] == "Deloitte"
49
+ assert payload["country"] == "FR"
50
+ assert result["id"] == "ac1"
51
+
52
+ def test_country_defaults_to_empty(self):
53
+ c = make_client()
54
+ c._request.return_value = {"id": "ac2", "name": "KPMG", "country": ""}
55
+ c.create_auditor_company("KPMG")
56
+ _, kwargs = c._request.call_args
57
+ payload = kwargs["json"]
58
+ assert payload["country"] == ""
59
+
60
+
41
61
  class TestCreateAuditorCompensation:
42
62
  def test_sends_audit_fields(self):
43
63
  c = make_client()
@@ -61,3 +61,55 @@ class TestUpsertDirector:
61
61
  result = c.upsert_director("comp-uuid", "pers-uuid", title="Director")
62
62
  assert result["action"] == "created"
63
63
  assert result["id"] == "new-uuid"
64
+
65
+ def test_sends_board_classification_flags(self):
66
+ c = make_client()
67
+ c._request.side_effect = [
68
+ {"count": 0, "results": []},
69
+ {"id": "new-uuid"},
70
+ ]
71
+ c.upsert_director(
72
+ "comp-uuid",
73
+ "pers-uuid",
74
+ title="Chairman & CEO",
75
+ is_chairman=True,
76
+ is_lead_independent=False,
77
+ is_employee_representative=False,
78
+ is_employee_shareholder_representative=False,
79
+ )
80
+ _, kwargs = c._request.call_args
81
+ payload = kwargs["json"]
82
+ assert payload["is_chairman"] is True
83
+ assert payload["is_lead_independent"] is False
84
+ assert payload["is_employee_representative"] is False
85
+ assert payload["is_employee_shareholder_representative"] is False
86
+
87
+ def test_omits_unset_classification_flags(self):
88
+ c = make_client()
89
+ c._request.side_effect = [
90
+ {"count": 0, "results": []},
91
+ {"id": "new-uuid"},
92
+ ]
93
+ c.upsert_director("comp-uuid", "pers-uuid", title="Director")
94
+ _, kwargs = c._request.call_args
95
+ payload = kwargs["json"]
96
+ assert "is_chairman" not in payload
97
+ assert "is_lead_independent" not in payload
98
+ assert "is_employee_representative" not in payload
99
+ assert "is_employee_shareholder_representative" not in payload
100
+
101
+
102
+ class TestUpdateDirector:
103
+ def test_sends_board_classification_flags(self):
104
+ c = make_client()
105
+ c._request.return_value = {"id": "dir-uuid"}
106
+ c.update_director(
107
+ "dir-uuid",
108
+ is_lead_independent=True,
109
+ is_employee_representative=True,
110
+ )
111
+ _, kwargs = c._request.call_args
112
+ payload = kwargs["json"]
113
+ assert payload["is_lead_independent"] is True
114
+ assert payload["is_employee_representative"] is True
115
+ assert "is_chairman" not in payload
@@ -114,6 +114,10 @@ class DirectorListItem(TypedDict):
114
114
  valid_to: str | None
115
115
  is_independent: bool
116
116
  is_executive: bool
117
+ is_chairman: bool
118
+ is_lead_independent: bool
119
+ is_employee_representative: bool
120
+ is_employee_shareholder_representative: bool
117
121
  appointment_method: str
118
122
  entity_type: str
119
123
  representative_name: str
@@ -137,6 +141,10 @@ class DirectorDetail(TypedDict):
137
141
  cause_end: str
138
142
  is_independent: bool
139
143
  is_executive: bool
144
+ is_chairman: bool
145
+ is_lead_independent: bool
146
+ is_employee_representative: bool
147
+ is_employee_shareholder_representative: bool
140
148
  appointment_method: str
141
149
  entity_type: str
142
150
  representative_name: str
@@ -154,6 +162,10 @@ class CreateDirectorPayload(TypedDict):
154
162
  valid_to: NotRequired[str | None]
155
163
  is_independent: NotRequired[bool]
156
164
  is_executive: NotRequired[bool]
165
+ is_chairman: NotRequired[bool]
166
+ is_lead_independent: NotRequired[bool]
167
+ is_employee_representative: NotRequired[bool]
168
+ is_employee_shareholder_representative: NotRequired[bool]
157
169
  appointment_method: NotRequired[str]
158
170
  entity_type: NotRequired[str]
159
171
  representative_name: NotRequired[str]
@@ -167,6 +179,10 @@ class UpdateDirectorPayload(TypedDict, total=False):
167
179
  valid_to: str | None
168
180
  is_independent: bool
169
181
  is_executive: bool
182
+ is_chairman: bool
183
+ is_lead_independent: bool
184
+ is_employee_representative: bool
185
+ is_employee_shareholder_representative: bool
170
186
  appointment_method: str
171
187
  entity_type: str
172
188
  representative_name: str
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
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
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