better-notion 1.8.3__py3-none-any.whl → 1.8.5__py3-none-any.whl

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.
@@ -10,6 +10,7 @@ from better_notion._api.properties.number import Number
10
10
  from better_notion._api.properties.url import URL
11
11
  from better_notion._api.properties.email import Email
12
12
  from better_notion._api.properties.phone import Phone
13
+ from better_notion._api.properties.relation import Relation
13
14
 
14
15
  __all__ = [
15
16
  "Property",
@@ -27,4 +28,5 @@ __all__ = [
27
28
  "URL",
28
29
  "Email",
29
30
  "Phone",
31
+ "Relation",
30
32
  ]
@@ -0,0 +1,27 @@
1
+ """Relation property builder."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ from better_notion._api.properties.base import Property
8
+
9
+
10
+ class Relation(Property):
11
+ """Builder for relation properties."""
12
+
13
+ def __init__(self, page_ids: list[str]) -> None:
14
+ """Initialize a relation property.
15
+
16
+ Args:
17
+ page_ids: List of related page IDs.
18
+ """
19
+ super().__init__("Relation")
20
+ self._page_ids = page_ids
21
+
22
+ def to_dict(self) -> dict[str, Any]:
23
+ """Convert to Notion API format."""
24
+ return {
25
+ "type": "relation",
26
+ "relation": [{"id": page_id} for page_id in self._page_ids]
27
+ }
@@ -61,15 +61,20 @@ class RichText(Property):
61
61
  if self._code:
62
62
  annotations["code"] = True
63
63
 
64
- rich_text_obj: dict[str, Any] = {
64
+ # Build the inner text object
65
+ inner_text_obj: dict[str, Any] = {
65
66
  "type": "text",
66
67
  "text": text_obj,
67
68
  }
68
69
 
69
70
  if annotations:
70
- rich_text_obj["annotations"] = annotations
71
+ inner_text_obj["annotations"] = annotations
71
72
 
72
- return rich_text_obj
73
+ # Return proper rich_text property format
74
+ return {
75
+ "type": "rich_text",
76
+ "rich_text": [inner_text_obj]
77
+ }
73
78
 
74
79
 
75
80
  class Text(Property):
@@ -12,15 +12,82 @@ with caching support through the plugin system.
12
12
 
13
13
  from __future__ import annotations
14
14
 
15
- from typing import TYPE_CHECKING, Any
15
+ from typing import TYPE_CHECKING, Any, AsyncIterator
16
16
 
17
17
  from better_notion._sdk.base.entity import BaseEntity
18
18
 
19
19
  if TYPE_CHECKING:
20
20
  from better_notion._sdk.client import NotionClient
21
+ from better_notion._sdk.models.block import Block
22
+ from better_notion._sdk.models.database import Database
23
+ from better_notion._sdk.models.page import Page
21
24
 
22
25
 
23
- class Organization(BaseEntity):
26
+ class DatabasePageEntityMixin:
27
+ """Mixin providing BaseEntity abstract method implementations for database pages.
28
+
29
+ This mixin provides parent() and children() implementations for entities
30
+ that are pages in databases (like Organization, Project, etc.).
31
+ """
32
+
33
+ async def parent(self) -> "Database | Page | None":
34
+ """Get parent object (database for entity pages).
35
+
36
+ Returns:
37
+ Parent Database or Page or None
38
+ """
39
+ from better_notion._sdk.models.database import Database
40
+
41
+ # Get parent from data
42
+ parent_data = self._data.get("parent")
43
+ if not parent_data:
44
+ return None
45
+
46
+ # Check cache
47
+ cached = self._cache_get("parent")
48
+ if cached:
49
+ return cached
50
+
51
+ # Database parent
52
+ if parent_data.get("type") == "database_id":
53
+ db_id = parent_data.get("database_id")
54
+ parent = await Database.get(db_id, client=self._client)
55
+ self._cache_set("parent", parent)
56
+ return parent
57
+
58
+ # Page parent
59
+ if parent_data.get("type") == "page_id":
60
+ from better_notion._sdk.models.page import Page
61
+ page_id = parent_data.get("page_id")
62
+ parent = await Page.get(page_id, client=self._client)
63
+ self._cache_set("parent", parent)
64
+ return parent
65
+
66
+ return None
67
+
68
+ async def children(self) -> AsyncIterator["Block"]:
69
+ """Iterate over child blocks.
70
+
71
+ Yields:
72
+ Block objects that are direct children
73
+ """
74
+ from better_notion._api.utils.pagination import AsyncPaginatedIterator
75
+ from better_notion._sdk.models.block import Block
76
+
77
+ async def _get_blocks(offset: str | None = None) -> dict[str, Any]:
78
+ return await self._client._request(
79
+ "GET",
80
+ f"/blocks/{self.id}/children",
81
+ params={"start_cursor": offset} if offset else None
82
+ )
83
+
84
+ iterator = AsyncPaginatedIterator(_get_blocks, lambda data: data.get("results", []))
85
+
86
+ async for block_data in iterator:
87
+ yield Block(self._client, block_data)
88
+
89
+
90
+ class Organization(DatabasePageEntityMixin, BaseEntity):
24
91
  """
25
92
  Organization entity representing a company or team.
26
93
 
@@ -348,7 +415,7 @@ class Organization(BaseEntity):
348
415
  return [Project(self._client, page_data) for page_data in response.get("results", [])]
349
416
 
350
417
 
351
- class Project(BaseEntity):
418
+ class Project(DatabasePageEntityMixin, BaseEntity):
352
419
  """
353
420
  Project entity representing a software project.
354
421
 
@@ -634,7 +701,7 @@ class Project(BaseEntity):
634
701
  return [Version(self._client, page_data) for page_data in response.get("results", [])]
635
702
 
636
703
 
637
- class Version(BaseEntity):
704
+ class Version(DatabasePageEntityMixin, BaseEntity):
638
705
  """
639
706
  Version entity representing a project version/release.
640
707
 
@@ -874,7 +941,7 @@ class Version(BaseEntity):
874
941
  return [Task(self._client, page_data) for page_data in response.get("results", [])]
875
942
 
876
943
 
877
- class Task(BaseEntity):
944
+ class Task(DatabasePageEntityMixin, BaseEntity):
878
945
  """
879
946
  Task entity representing a work task.
880
947
 
@@ -1190,7 +1257,7 @@ class Task(BaseEntity):
1190
1257
  return True
1191
1258
 
1192
1259
 
1193
- class Idea(BaseEntity):
1260
+ class Idea(DatabasePageEntityMixin, BaseEntity):
1194
1261
  """
1195
1262
  Idea entity representing an improvement opportunity discovered during work.
1196
1263
 
@@ -1577,7 +1644,7 @@ class Idea(BaseEntity):
1577
1644
  )
1578
1645
 
1579
1646
 
1580
- class WorkIssue(BaseEntity):
1647
+ class WorkIssue(DatabasePageEntityMixin, BaseEntity):
1581
1648
  """
1582
1649
  Work Issue entity representing a development-time problem.
1583
1650
 
@@ -1938,7 +2005,7 @@ class WorkIssue(BaseEntity):
1938
2005
  return idea
1939
2006
 
1940
2007
 
1941
- class Incident(BaseEntity):
2008
+ class Incident(DatabasePageEntityMixin, BaseEntity):
1942
2009
  """
1943
2010
  Incident entity representing a production incident.
1944
2011
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: better-notion
3
- Version: 1.8.3
3
+ Version: 1.8.5
4
4
  Summary: A high-level Python SDK for the Notion API with developer experience in mind.
5
5
  Project-URL: Homepage, https://github.com/nesalia-inc/better-notion
6
6
  Project-URL: Documentation, https://github.com/nesalia-inc/better-notion#readme
@@ -15,14 +15,15 @@ better_notion/_api/entities/comment.py,sha256=li4bZEA0Q4VwpeSSvg1QJRfIKZL_h79LNT
15
15
  better_notion/_api/entities/database.py,sha256=MsR7AjBihzgo6oGLubECJ0rmeFOxMxa3S-0oESAKAQg,1753
16
16
  better_notion/_api/entities/page.py,sha256=7Xi1IES6dE6gASB1RLHOGLvaUk5yYy98gkRgLHavgns,4595
17
17
  better_notion/_api/entities/user.py,sha256=EVjwvj3ksSoOVIbMlR6Ez3j0PtzNRchvTb8rr5aNJ-s,1145
18
- better_notion/_api/properties/__init__.py,sha256=fdnuzzh3BerMh0GZni-HPjqN_opQ0VXimCgT2-UemOk,926
18
+ better_notion/_api/properties/__init__.py,sha256=WH4hLn4aQuPFFMjGE7N0iawidEcOHaIRrIAnWu2che4,1002
19
19
  better_notion/_api/properties/base.py,sha256=3lSkj50Zm9smlbSANx1ngrjP82ygXnfux3tG02aeFms,895
20
20
  better_notion/_api/properties/checkbox.py,sha256=DTJjq3KxOukoPlpQ7UB173Sf9WHDlND5-7QSwydL7Pc,691
21
21
  better_notion/_api/properties/date.py,sha256=E2rIMcgTMuPf8rS5AdT8M0UyYEDobJ8zJRYoBaFSR9s,2372
22
22
  better_notion/_api/properties/email.py,sha256=JaWHUNJoO837PqGGNPQ7fixG7al3U7i7Ipap7wTLOok,659
23
23
  better_notion/_api/properties/number.py,sha256=6XpDOpnU5D4_Fr7DOX7IoGOk4o9ggyMbcZua-UDL0Kk,671
24
24
  better_notion/_api/properties/phone.py,sha256=EDKKUku51RK86rPt92sbuobJgbhvPhuYe9IlfHzSnI4,678
25
- better_notion/_api/properties/rich_text.py,sha256=4pyHK56nGFRCoZ8Qla5wM8PsjYkU9-3GXL6VcTDr7LQ,3466
25
+ better_notion/_api/properties/relation.py,sha256=e0VKMNhCyoxaqPkTGRZP4D22eNatDvej5Rz726FskpI,708
26
+ better_notion/_api/properties/rich_text.py,sha256=yqdr-snhTQYAcaNs881-OptNkbz2-1N-eTg6fauRO80,3629
26
27
  better_notion/_api/properties/select.py,sha256=5NMzj6dykXiH6xCWx8xWP3eeyUvQICScdTPjJJOQZ_c,1347
27
28
  better_notion/_api/properties/title.py,sha256=SmcSXmiPtnM05hBH7EnJeJW7SYfGrOoPO9cIw1Zs-Jo,815
28
29
  better_notion/_api/properties/url.py,sha256=1_vHKHENevN1b8F3b6pYsZboQXGAPOfsEMgjCe6HXKM,632
@@ -117,7 +118,7 @@ better_notion/plugins/official/agents_schema.py,sha256=NQRAJFoBAXRuxB9_9Eaf-4tVt
117
118
  better_notion/plugins/official/productivity.py,sha256=_-whP4pYA4HufE1aUFbIdhrjU-O9njI7xUO_Id2M1J8,8726
118
119
  better_notion/plugins/official/agents_sdk/__init__.py,sha256=luQBzZLsJ7fC5U0jFu8dfzMviiXj2SBZXcTohM53wkQ,725
119
120
  better_notion/plugins/official/agents_sdk/managers.py,sha256=0zMZPu63zhdyqiudO2gKsmM3YOJh0nFAR9FrMlwkV2A,31186
120
- better_notion/plugins/official/agents_sdk/models.py,sha256=qrgu6E80wJq_lLEHh3jVJfuJ8uwmBA8aypKeLP4P4E8,80341
121
+ better_notion/plugins/official/agents_sdk/models.py,sha256=vWe1cut11VmQSd_vDG0ijs5EXYvYvQ1xgbkii61rL8Q,82919
121
122
  better_notion/plugins/official/agents_sdk/plugin.py,sha256=bs9O8Unv6SARGj4lBU5Gj9HGbLTUNqTacJ3RLUhdbI4,4479
122
123
  better_notion/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
123
124
  better_notion/utils/helpers.py,sha256=HgFuUQlG_HzBOB0z2GA9RxPLoXgwRc0DIxa9Fg6C-Jk,2337
@@ -132,8 +133,8 @@ better_notion/utils/agents/rbac.py,sha256=8ZA8Y7wbOiVZDbpjpH7iC35SZrZ0jl4fcJ3xWC
132
133
  better_notion/utils/agents/schemas.py,sha256=eHfGhY90FAPXA3E8qE6gP75dgNzn-9z5Ju1FMwBKnQQ,22120
133
134
  better_notion/utils/agents/state_machine.py,sha256=xUBEeDTbU1Xq-rsRo2sbr6AUYpYrV9DTHOtZT2cWES8,6699
134
135
  better_notion/utils/agents/workspace.py,sha256=Uy8bqLsT_VFGYAPoiQJNuCvGdjMceaSiVGbR9saMpoU,16558
135
- better_notion-1.8.3.dist-info/METADATA,sha256=KU9Yunh85byLx9y_lw6uNtP4UPmHlC6tzEOphJNQDe0,11096
136
- better_notion-1.8.3.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
137
- better_notion-1.8.3.dist-info/entry_points.txt,sha256=D0bUcP7Z00Zyjxw7r2p29T95UrwioDO0aGDoHe9I6fo,55
138
- better_notion-1.8.3.dist-info/licenses/LICENSE,sha256=BAdN3JpgMY_y_fWqZSCFSvSbC2mTHP-BKDAzF5FXQAI,1069
139
- better_notion-1.8.3.dist-info/RECORD,,
136
+ better_notion-1.8.5.dist-info/METADATA,sha256=aP3q-b0_38YX28OaYWBxtCZsgrFiNuSeZHe71ct9j5Q,11096
137
+ better_notion-1.8.5.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
138
+ better_notion-1.8.5.dist-info/entry_points.txt,sha256=D0bUcP7Z00Zyjxw7r2p29T95UrwioDO0aGDoHe9I6fo,55
139
+ better_notion-1.8.5.dist-info/licenses/LICENSE,sha256=BAdN3JpgMY_y_fWqZSCFSvSbC2mTHP-BKDAzF5FXQAI,1069
140
+ better_notion-1.8.5.dist-info/RECORD,,