boarddata 6.3.1__tar.gz → 6.4.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 (60) hide show
  1. {boarddata-6.3.1 → boarddata-6.4.2}/PKG-INFO +1 -1
  2. {boarddata-6.3.1 → boarddata-6.4.2}/__init__.py +1 -1
  3. {boarddata-6.3.1 → boarddata-6.4.2}/_assemblies.py +19 -3
  4. {boarddata-6.3.1 → boarddata-6.4.2}/_esg.py +66 -1
  5. {boarddata-6.3.1 → boarddata-6.4.2}/boarddata.egg-info/PKG-INFO +1 -1
  6. {boarddata-6.3.1 → boarddata-6.4.2}/pyproject.toml +1 -1
  7. {boarddata-6.3.1 → boarddata-6.4.2}/tests/test_esg.py +26 -0
  8. {boarddata-6.3.1 → boarddata-6.4.2}/CLAUDE.md +0 -0
  9. {boarddata-6.3.1 → boarddata-6.4.2}/README.md +0 -0
  10. {boarddata-6.3.1 → boarddata-6.4.2}/_auditors.py +0 -0
  11. {boarddata-6.3.1 → boarddata-6.4.2}/_base.py +0 -0
  12. {boarddata-6.3.1 → boarddata-6.4.2}/_comex.py +0 -0
  13. {boarddata-6.3.1 → boarddata-6.4.2}/_companies.py +0 -0
  14. {boarddata-6.3.1 → boarddata-6.4.2}/_criteria.py +0 -0
  15. {boarddata-6.3.1 → boarddata-6.4.2}/_directors.py +0 -0
  16. {boarddata-6.3.1 → boarddata-6.4.2}/_documents.py +0 -0
  17. {boarddata-6.3.1 → boarddata-6.4.2}/_indexes.py +0 -0
  18. {boarddata-6.3.1 → boarddata-6.4.2}/_persons.py +0 -0
  19. {boarddata-6.3.1 → boarddata-6.4.2}/_sentinel.py +0 -0
  20. {boarddata-6.3.1 → boarddata-6.4.2}/_utilities.py +0 -0
  21. {boarddata-6.3.1 → boarddata-6.4.2}/boarddata.egg-info/SOURCES.txt +0 -0
  22. {boarddata-6.3.1 → boarddata-6.4.2}/boarddata.egg-info/dependency_links.txt +0 -0
  23. {boarddata-6.3.1 → boarddata-6.4.2}/boarddata.egg-info/requires.txt +0 -0
  24. {boarddata-6.3.1 → boarddata-6.4.2}/boarddata.egg-info/top_level.txt +0 -0
  25. {boarddata-6.3.1 → boarddata-6.4.2}/cache.py +0 -0
  26. {boarddata-6.3.1 → boarddata-6.4.2}/client.py +0 -0
  27. {boarddata-6.3.1 → boarddata-6.4.2}/errors.py +0 -0
  28. {boarddata-6.3.1 → boarddata-6.4.2}/py.typed +0 -0
  29. {boarddata-6.3.1 → boarddata-6.4.2}/setup.cfg +0 -0
  30. {boarddata-6.3.1 → boarddata-6.4.2}/tests/__init__.py +0 -0
  31. {boarddata-6.3.1 → boarddata-6.4.2}/tests/conftest.py +0 -0
  32. {boarddata-6.3.1 → boarddata-6.4.2}/tests/test_assemblies.py +0 -0
  33. {boarddata-6.3.1 → boarddata-6.4.2}/tests/test_auditors.py +0 -0
  34. {boarddata-6.3.1 → boarddata-6.4.2}/tests/test_base.py +0 -0
  35. {boarddata-6.3.1 → boarddata-6.4.2}/tests/test_build_payload.py +0 -0
  36. {boarddata-6.3.1 → boarddata-6.4.2}/tests/test_cache.py +0 -0
  37. {boarddata-6.3.1 → boarddata-6.4.2}/tests/test_comex.py +0 -0
  38. {boarddata-6.3.1 → boarddata-6.4.2}/tests/test_companies.py +0 -0
  39. {boarddata-6.3.1 → boarddata-6.4.2}/tests/test_config.py +0 -0
  40. {boarddata-6.3.1 → boarddata-6.4.2}/tests/test_criteria.py +0 -0
  41. {boarddata-6.3.1 → boarddata-6.4.2}/tests/test_directors.py +0 -0
  42. {boarddata-6.3.1 → boarddata-6.4.2}/tests/test_documents.py +0 -0
  43. {boarddata-6.3.1 → boarddata-6.4.2}/tests/test_exports.py +0 -0
  44. {boarddata-6.3.1 → boarddata-6.4.2}/tests/test_indexes.py +0 -0
  45. {boarddata-6.3.1 → boarddata-6.4.2}/tests/test_persons.py +0 -0
  46. {boarddata-6.3.1 → boarddata-6.4.2}/tests/test_sentinel.py +0 -0
  47. {boarddata-6.3.1 → boarddata-6.4.2}/tests/test_utilities.py +0 -0
  48. {boarddata-6.3.1 → boarddata-6.4.2}/types/__init__.py +0 -0
  49. {boarddata-6.3.1 → boarddata-6.4.2}/types/assemblies.py +0 -0
  50. {boarddata-6.3.1 → boarddata-6.4.2}/types/auditors.py +0 -0
  51. {boarddata-6.3.1 → boarddata-6.4.2}/types/comex.py +0 -0
  52. {boarddata-6.3.1 → boarddata-6.4.2}/types/companies.py +0 -0
  53. {boarddata-6.3.1 → boarddata-6.4.2}/types/core.py +0 -0
  54. {boarddata-6.3.1 → boarddata-6.4.2}/types/criteria.py +0 -0
  55. {boarddata-6.3.1 → boarddata-6.4.2}/types/directors.py +0 -0
  56. {boarddata-6.3.1 → boarddata-6.4.2}/types/documents.py +0 -0
  57. {boarddata-6.3.1 → boarddata-6.4.2}/types/esg.py +0 -0
  58. {boarddata-6.3.1 → boarddata-6.4.2}/types/indexes.py +0 -0
  59. {boarddata-6.3.1 → boarddata-6.4.2}/types/persons.py +0 -0
  60. {boarddata-6.3.1 → boarddata-6.4.2}/types/sentinel.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boarddata
3
- Version: 6.3.1
3
+ Version: 6.4.2
4
4
  Summary: Python SDK for the BoardData V2 REST API
5
5
  License: MIT
6
6
  Classifier: Development Status :: 4 - Beta
@@ -6,7 +6,7 @@ from .cache import FileTokenCache, ScalewaySecretTokenCache
6
6
  from .client import BoardDataClient
7
7
  from .errors import BoardDataError, ExportTooLargeError
8
8
 
9
- __version__ = "6.3.1"
9
+ __version__ = "6.4.2"
10
10
  __all__ = [
11
11
  "Base",
12
12
  "BoardDataClient",
@@ -410,15 +410,31 @@ class AssemblyMixin:
410
410
  assembly_date_from / assembly_date_to: str (YYYY-MM-DD) — filter
411
411
  by parent assembly's ``assembly_date``.
412
412
  assembly_id: str — comma-separated UUIDs; returns questions whose
413
- parent assembly is in the list. Use to batch-fetch questions
414
- for many assemblies in one round-trip instead of N calls to
415
- ``list_assembly_questions``.
413
+ parent assembly is in the list. For batch-fetching questions
414
+ across many assemblies, prefer ``list_questions_batch`` it
415
+ hits a sibling endpoint that drops the ``-created_at`` sort
416
+ (unindexed, dominates query time) in favor of the FK-indexed
417
+ ``(assembly, position)`` ordering.
416
418
  page, page_size: pagination.
417
419
 
418
420
  Any key accepted by ``QuestionListFilterSet`` is forwarded verbatim.
419
421
  """
420
422
  return self._get("questions/", **params) # type: ignore[attr-defined]
421
423
 
424
+ def list_questions_batch(self, **params: Any) -> PaginatedResponse:
425
+ """List questions optimized for assembly-id batch fetches.
426
+
427
+ Hits ``GET /api/questions-batch/``.
428
+
429
+ Same payload shape and filter set as ``list_questions``, but uses
430
+ the model's default ``(assembly, position)`` ordering — FK-index
431
+ backed — instead of ``-created_at`` (unindexed). For ``assembly_id``
432
+ scans of 50+ UUIDs this collapses per-call latency from 6-10s to
433
+ sub-second; for unfiltered LexisNexis-style exports prefer
434
+ ``list_questions`` so rows arrive newest-first.
435
+ """
436
+ return self._get("questions-batch/", **params) # type: ignore[attr-defined]
437
+
422
438
  def create_questions(
423
439
  self,
424
440
  assembly_uid: str,
@@ -4,7 +4,7 @@ from __future__ import annotations
4
4
 
5
5
  from typing import Any
6
6
 
7
- from .types.core import FieldSourcePayload, PaginatedResponse
7
+ from .types.core import FieldSourcePayload, PaginatedResponse, UpsertResult
8
8
  from .types.esg import (
9
9
  ESGBenchmarkExportItem,
10
10
  ESGBenchmarkStats,
@@ -397,3 +397,68 @@ class ESGMixin:
397
397
  BoardDataError: On non-2xx API response.
398
398
  """
399
399
  return self._get("companies/benchmark/stats/", **params) # type: ignore[attr-defined,return-value]
400
+
401
+ # ------------------------------------------------------------------
402
+ # EU Taxonomy
403
+ # ------------------------------------------------------------------
404
+
405
+ def upsert_taxonomy(
406
+ self,
407
+ *,
408
+ company: str,
409
+ report_year: int,
410
+ company_type: str,
411
+ metrics: dict[str, Any] | None = None,
412
+ sector_specific: dict[str, Any] | None = None,
413
+ by_objective: list[dict[str, Any]] | None = None,
414
+ field_sources: list[FieldSourcePayload] | None = None,
415
+ validation_status: str = "unknown",
416
+ validation_warnings: list[str] | None = None,
417
+ validation_errors: list[str] | None = None,
418
+ meta: dict[str, Any] | None = None,
419
+ annex_xii: dict[str, Any] | None = None,
420
+ ) -> UpsertResult:
421
+ """Upsert a company's EU-Taxonomy disclosure (server upserts by company+report_year).
422
+
423
+ The backend route is ``POST /api/taxonomy-reports/``. It upserts by
424
+ ``(company, report_year)``: returns HTTP 200 on update and HTTP 201 on create.
425
+ Envelope field names map 1:1 to the v3.8 ``composed.json`` schema.
426
+
427
+ Args:
428
+ company: Company UUID.
429
+ report_year: Fiscal year the disclosure covers (e.g. ``2024``).
430
+ company_type: Reporting entity type. One of ``"INDUSTRIAL"``,
431
+ ``"BANK"``, ``"INSURANCE"``, ``"ASSET_MANAGER"``.
432
+ metrics: Top-level KPI metrics dict (v3.8 schema).
433
+ sector_specific: Sector-specific metrics dict (v3.8 schema).
434
+ by_objective: Per-objective breakdown list (v3.8 schema).
435
+ field_sources: Field source entries for traceability.
436
+ validation_status: Pipeline validation outcome
437
+ (e.g. ``"valid"``, ``"warning"``, ``"error"``, ``"unknown"``).
438
+ validation_warnings: Non-blocking validation messages.
439
+ validation_errors: Blocking validation messages.
440
+ meta: Arbitrary pipeline metadata (extraction run ID, model, etc.).
441
+ annex_xii: Annex XII disclosure block (v3.8 addition).
442
+
443
+ Returns:
444
+ ``UpsertResult`` with ``id`` (UUID), ``action`` (``"created"`` or
445
+ ``"updated"``), and optional ``flag``.
446
+
447
+ Raises:
448
+ BoardDataError: On non-2xx API response.
449
+ """
450
+ payload: dict[str, Any] = {
451
+ "company": company,
452
+ "report_year": report_year,
453
+ "company_type": company_type,
454
+ "metrics": metrics or {},
455
+ "sector_specific": sector_specific or {},
456
+ "by_objective": by_objective or [],
457
+ "field_sources": field_sources or [],
458
+ "validation_status": validation_status,
459
+ "validation_warnings": validation_warnings or [],
460
+ "validation_errors": validation_errors or [],
461
+ "meta": meta or {},
462
+ "annex_xii": annex_xii or {},
463
+ }
464
+ return self._post("taxonomy-reports/", payload) # type: ignore[attr-defined]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boarddata
3
- Version: 6.3.1
3
+ Version: 6.4.2
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 = "6.3.1"
7
+ version = "6.4.2"
8
8
  description = "Python SDK for the BoardData V2 REST API"
9
9
  readme = "README.md"
10
10
  license = {text = "MIT"}
@@ -74,3 +74,29 @@ class TestGetEsgBenchmarkStats:
74
74
  }
75
75
  assert result["total_iros"] == 23
76
76
  assert result["count"] == 42
77
+
78
+
79
+ class TestUpsertTaxonomy:
80
+ def test_upsert_taxonomy_posts_envelope(self):
81
+ c = make_client()
82
+ c._request.return_value = {
83
+ "id": "tax-uuid-1234",
84
+ "action": "created",
85
+ }
86
+ c.upsert_taxonomy(
87
+ company="comp-uuid-abcd",
88
+ report_year=2025,
89
+ company_type="BANK",
90
+ annex_xii={"is_disclosed": True},
91
+ )
92
+ args, kwargs = c._request.call_args
93
+ assert args == ("POST", "taxonomy-reports/")
94
+ payload = kwargs["json"]
95
+ assert payload["company"] == "comp-uuid-abcd"
96
+ assert payload["report_year"] == 2025
97
+ assert payload["company_type"] == "BANK"
98
+ assert payload["annex_xii"] == {"is_disclosed": True}
99
+ # defaults are populated
100
+ assert payload["metrics"] == {}
101
+ assert payload["by_objective"] == []
102
+ assert payload["validation_status"] == "unknown"
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