Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
# Conflicts:
#	pytion/models.py
  • Loading branch information
lastorel committed Apr 10, 2022
2 parents be3b013 + 40dcb4e commit c868431
Show file tree
Hide file tree
Showing 3 changed files with 242 additions and 32 deletions.
84 changes: 72 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,36 +44,96 @@ some text

`.get_parent(id_)` - Get parent object of current object if possible.

`.get_block_children(id_, limit)` - Get children Block objects of current Block object (tabulated texts) if exist
`.get_block_children(id_, limit)` - Get children Block objects of current Block object (tabulated texts) if exist.

`.get_block_children_recursive(id_, max_depth, limit, force)` - Get children Block objects of current Block object (tabulated texts) if exist recursive
`.get_block_children_recursive(id_, max_depth, limit, force)` - Get children Block objects of current Block object (tabulated texts) if exist recursive.

`.get_page_property(property_id, id_, limit)` - Retrieve a page property item.

`.db_query(id_, limit, filter_, sorts)` - Query Database
`.db_query(id_, limit, filter_, sorts)` - Query Database.

`.db_filter(...see desc...)` - Query Database
`.db_filter(...see desc...)` - Query Database.

`.db_create(database_obj, parent, properties, title)` - Create Database
`.db_create(database_obj, parent, properties, title)` - Create Database.

`.db_update(id_, title, properties)` - Update Database
`.db_update(id_, title, properties)` - Update Database.

`.page_create(page_obj, parent, properties, title)` - Create Page
`.page_create(page_obj, parent, properties, title)` - Create Page.

`.page_update(id_, properties, title, archived)` - Update Page
`.page_update(id_, properties, title, archived)` - Update Page.

`.block_update(id_, block_obj, new_text, arcived)` - Update text in Block.

`.block_append(id_, block, blocks)` - Append block or blocks children
`.block_append(id_, block, blocks)` - Append block or blocks children.

`.from_linkto(linkto)` - Creates new Element object based on LinkTo information.

`.from_object(model)` - Creates new Element object from Page, Block or Database object.
Usable while Element object contains an Array.

More details and examples of this methods you can see into func descriptions.
### pytion.models.*
There are user classmethods for models:
`RichTextArray.create()`, `Property.create()`, `PropertyValue.create()`, `Database.create()`, `Page.create()`, `Block.create()`, `LinkTo.create()`
`RichTextArray.create()`, `Property.create()`, `PropertyValue.create()`, `Database.create()`, `Page.create()`, `Block.create()`, `LinkTo.create()`, `User.create()`
### Supported block types
At present the API only supports the block types which are listed in the reference below. Any unsupported block types will continue to appear in the structure, but only contain a `type` set to `"unsupported"`.
Colors are not yet supported.

Every Block has mandatory attributes and extension attributes. There are mandatory:
- `id: str` - UUID-64 without hyphens
- `object: str` - always `"block"` (from API)
- `created_time: datetime` - from API
- `created_by: User` - from API
- `last_edited_time: datetime` - from API
- `last_edited_by: User` - from API
- `type: str` - the type of block (from API)
- `has_children: bool` - does the block have children blocks (from API)
- `archived: bool` - does the block marked as deleted (from API)
- `text: Union[str, RichTextArray]` - **main content**

Extension attributes are listed below in support matrix:

| Block Type | Description | Read support | Create support | Can have children | Extension attributes |
| --- | --- | --- | --- | --- | --- |
| `paragraph` | Simple Block with text | + | + | + | |
| `heading_1` | Heading Block with text highest level | + | - | - | |
| `heading_2` | Heading Block with text medium level | + | - | - | |
| `heading_3` | Heading Block with text lowest level | + | - | - | |
| `bulleted_list_item` | Text Block with bullet | + | - | + | |
| `numbered_list_item` | Text Block with number | + | - | + | |
| `to_do` | Text Block with checkbox | + | + | + | `checked: bool` |
| `toggle` | Text Block with toggle to children blocks | + | - | + | |
| `code` | Text Block with code style | + | + | + | `language: str`, `caption: RichTextArray` |
| `child_page` | Page inside | + | - | + | |
| `child_database` | Database inside | + | - | + | |
| `embed` | | - | - | - | |
| `image` | | - | - | - | |
| `video` | | - | - | - | |
| `file` | | - | - | - | |
| `pdf` | | - | - | - | |
| `bookmark` | Block for URL Link | + | - | - | `caption: RichTextArray` |
| `callout` | Highlighted footnote text Block | + | - | + | `icon: dict` |
| `quote` | Text Block with quote style | + | - | + | |
| `equation` | KaTeX compatible text Block | + | - | - | |
| `divider` | Simple line to divide the page | + | - | - | |
| `table_of_contents` | Block with content structure in the page | - | - | - | |
| `column` | | - | - | + | |
| `column_list` | | - | - | - | |
| `link_preview` | Same as `bookmark` | - | - | - | |
| `synced_block` | Block for synced content aka parent | - | - | + | |
| `template` | Template Block title | - | - | + | |
| `link_to_page` | Block with link to particular page `@...` | - | - | - | |
| `table` | Table Block with some attrs | - | - | + | |
| `table_row` | Children Blocks with table row content | - | - | - | |
| `breadcrumb` | Empty Block actually | + | - | - | |
| `unsupported` | Blocks unsupported by API | + | - | - | |

API converts **toggle heading** Block to simple heading Block.

## Logging
Logging is muted by default. To enable to stdout and to file:
Logging is muted by default. To enable to stdout and/or to file:
```
from pytion import setup_logging
setup_logging(level="debug", to_console=True, filename="pytion.log")
```
```
32 changes: 28 additions & 4 deletions pytion/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import pytion.envs as envs
from pytion.query import Request, Filter, Sort
from pytion.models import Database, Page, Block, BlockArray, PropertyValue, PageArray, LinkTo, RichTextArray, Property
from pytion.models import ElementArray, User


Models = Union[Database, Page, Block, BlockArray, PropertyValue, PageArray]
Expand Down Expand Up @@ -39,15 +40,15 @@ def __getattr__(self, name):


class Element(object):
class_map = {"page": Page, "database": Database, "block": Block}
class_map = {"page": Page, "database": Database, "block": Block, "user": User}

def __init__(self, api: Notion, name: str, obj: Optional[Models] = None):
self.api = api
self.name = name
self.obj = obj
logger.debug(f"Element {self!r} created")

def get(self, id_: str) -> Element:
def get(self, id_: str, _after_path: str = None) -> Element:
"""
Get Element by ID.
.query.RequestError exception if not found
Expand All @@ -57,12 +58,24 @@ def get(self, id_: str) -> Element:
result = no.databases.get("1234123412341")
result = no.pages.get("123412341234")
result = no.blocks.get("123412341234")
result = no.users.get("123412341234")
print(result.obj)
"""
if "-" in id_:
id_ = id_.replace("-", "")
raw_obj = self.api.session.method(method="get", path=self.name, id_=id_)
self.obj = self.class_map[raw_obj["object"]](**raw_obj)
if not _after_path:
raw_obj = self.api.session.method(method="get", path=self.name, id_=id_)
else:
raw_obj = self.api.session.method(method="get", path=self.name, id_=id_, after_path=_after_path)
if raw_obj["object"] == "list":
if self.name == "pages":
self.obj = PageArray(raw_obj["results"])
elif self.name == "blocks":
self.obj = BlockArray(raw_obj["results"])
else:
self.obj = ElementArray(raw_obj["results"])
else:
self.obj = self.class_map[raw_obj["object"]](**raw_obj)
return self

def get_parent(self, id_: Optional[str] = None) -> Optional[Element]:
Expand Down Expand Up @@ -106,6 +119,7 @@ def get_block_children(self, id_: Optional[str] = None, limit: int = 0) -> Optio
Paragraph
some text
"""
# todo when database is children of the block
if self.name != "blocks":
logger.warning("Only `blocks` can have children")
return None
Expand Down Expand Up @@ -467,6 +481,16 @@ def block_append(
)
return Element(api=self.api, name="blocks", obj=BlockArray(new_blocks["results"]))

def from_linkto(self, linkto: LinkTo) -> Optional[Element]:
if not linkto.uri:
logger.error("LinkTo.uri must be provided!")
return None
new_element = Element(self.api, name=linkto.uri)
return new_element.get(linkto.id, getattr(linkto, "after_path", None))

def from_object(self, model: Union[Database, Page, Block]):
return Element(self.api, model.path, model)

def __repr__(self):
if not self.obj:
return f"Notion/{self.name}/"
Expand Down
Loading

0 comments on commit c868431

Please sign in to comment.