Skip to content

Commit 34fc281

Browse files
committed
feat: export
1 parent 7151d75 commit 34fc281

File tree

14 files changed

+411
-68
lines changed

14 files changed

+411
-68
lines changed

src/apmodel/_initial/_rebuild.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from typing import Annotated, List, Optional, Union # noqa: F401
22

3-
from pydantic import BeforeValidator # noqa: F401
3+
from pydantic import BeforeValidator, PlainSerializer # noqa: F401
44

55
from ..core.activity import Activity
66
from ..core.collection import (
@@ -19,7 +19,11 @@
1919
from ..extra.cid import DataIntegrityProof, Multikey # noqa: F401
2020
from ..extra.schema import PropertyValue # noqa: F401
2121
from ..extra.security import CryptographicKey # noqa: F401
22-
from ..helpers import get_value_from_array, parse_ld_context # noqa: F401
22+
from ..helpers import ( # noqa: F401
23+
get_value_from_array,
24+
parse_ld_context,
25+
to_jld,
26+
)
2327

2428
# Nodeinfo
2529
from ..nodeinfo.nodeinfo import (
@@ -34,6 +38,8 @@
3438
)
3539
from ..types import aliases # noqa: F401
3640
from ..types.aliases import ( # noqa: F401
41+
ID_OPT_STR,
42+
ID_OPT_STR_OR_OBJECT_OR_LINK,
3743
OPT_STR_OR_LINK,
3844
OPT_STR_OR_OBJECT_OR_LINK,
3945
)

src/apmodel/_jsonld/__init__.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,11 @@ def get_schema(path: str) -> dict:
3737
return full_data.get("schema", {})
3838

3939

40-
@lru_cache(maxsize=100)
40+
#@lru_cache(maxsize=100)
4141
def cached_loader(
42-
requests_loader: Callable[[str, dict], dict], url, options_str: str
42+
requests_loader: Callable[[str, dict], dict], url, options={}
4343
):
44-
options = json.loads(options_str)
44+
#options = json.loads(options_str)
4545
if "headers" not in options:
4646
options["headers"] = {}
4747
options["headers"]["Accept"] = (
@@ -85,7 +85,8 @@ def loader(url, options={}):
8585
{"url": url},
8686
)
8787

88-
options_str = json.dumps(options, sort_keys=True)
89-
return cached_loader(requests_loader, url, options_str)
88+
89+
#options_str = json.dumps(options, sort_keys=True)
90+
return cached_loader(requests_loader, url, options)
9091

9192
return loader

src/apmodel/context.py

Lines changed: 66 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from __future__ import annotations
22

33
from typing import Any, Dict, List, TypeVar, Union, overload
4+
from urllib.parse import urlparse, urlunparse
45

56
from pydantic_core import core_schema
67

@@ -112,9 +113,7 @@ def __get_pydantic_core_schema__(
112113
"""
113114
Defines how Pydantic should handle the LDContext type.
114115
"""
115-
from_any_schema = core_schema.no_info_plain_validator_function(
116-
cls
117-
)
116+
from_any_schema = core_schema.no_info_plain_validator_function(cls)
118117

119118
to_full_context_serializer = (
120119
core_schema.plain_serializer_function_ser_schema(
@@ -127,3 +126,67 @@ def __get_pydantic_core_schema__(
127126
python_schema=from_any_schema,
128127
serialization=to_full_context_serializer,
129128
)
129+
130+
131+
def _get_namespace_base(uri: str) -> Union[str, None]:
132+
parsed_uri = urlparse(uri)
133+
134+
if parsed_uri.fragment:
135+
base_url = urlunparse(parsed_uri._replace(fragment=""))
136+
137+
if not base_url.endswith("#") and not base_url.endswith("/"):
138+
return base_url + "#"
139+
140+
return base_url
141+
142+
elif parsed_uri.path and parsed_uri.path != "/":
143+
path_segments = parsed_uri.path.rstrip("/").split("/")
144+
local_name = path_segments[-1]
145+
146+
if len(path_segments) > 1:
147+
namespace_base_path = parsed_uri.path[: -len(local_name)]
148+
base_url = urlunparse(
149+
parsed_uri._replace(
150+
path=namespace_base_path, params="", query="", fragment=""
151+
)
152+
)
153+
154+
if base_url and not (
155+
base_url.endswith("/") or base_url.endswith("#")
156+
):
157+
return base_url + "/"
158+
159+
return base_url
160+
161+
return None
162+
163+
def generate_context_from_expanded(expanded_json_ld: List[Dict[str, Any]], orig_context: LDContext = LDContext()) -> Dict[str, List[Union[str, Dict[str, Any]]]]:
164+
uris_to_process = set()
165+
166+
for item in expanded_json_ld:
167+
entity_id = item.get("@id")
168+
for key in item.keys():
169+
if key in ("@id", "@type", "@context"):
170+
continue
171+
uris_to_process.add(key)
172+
173+
if isinstance(item[key], list):
174+
for sub_item in item[key]:
175+
if isinstance(sub_item, dict) and "@id" in sub_item and "://" in sub_item["@id"]:
176+
sub_id = sub_item["@id"]
177+
178+
if "@type" in item:
179+
for type_uri in item["@type"]:
180+
if "://" in type_uri:
181+
uris_to_process.add(type_uri)
182+
183+
context_obj = LDContext()
184+
185+
for uri in uris_to_process:
186+
base_url = _get_namespace_base(uri)
187+
188+
if base_url:
189+
context_obj.add(base_url)
190+
191+
context_obj = context_obj + orig_context
192+
return {"@context": context_obj.full_context}

src/apmodel/core/link.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
from pydantic import BeforeValidator, Field
66

7-
from apmodel.types.aliases import OPT_STR, OPT_STR_OR_OBJECT_OR_LINK
7+
from apmodel.types.aliases import ID_OPT_STR_OR_OBJECT_OR_LINK, OPT_STR
88

99
from ..context import LDContext
1010
from ..helpers import generate_aliases, parse_ld_context
@@ -24,7 +24,7 @@ class Link(ActivityPubModel):
2424
)
2525
AS_URI: ClassVar[str] = "https://www.w3.org/ns/activitystreams#Link"
2626

27-
id: OPT_STR_OR_OBJECT_OR_LINK = Field(
27+
id: ID_OPT_STR_OR_OBJECT_OR_LINK = Field(
2828
validation_alias="@id", serialization_alias="@id"
2929
)
3030
name: OPT_STR = Field(default=None, **generate_aliases("name", "as2"))

src/apmodel/core/object.py

Lines changed: 41 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,18 @@
22

33
from typing import TYPE_CHECKING, Annotated, List, Optional, TypeVar, Union
44

5-
from pydantic import BeforeValidator, Field
5+
from pydantic import AliasChoices, BeforeValidator, Field, PlainSerializer
66

77
from apmodel.types.aliases import (
8+
ID_OPT_STR,
89
JSONLD_CONTEXT,
910
OPT_DATETIME,
1011
OPT_STR,
1112
OPT_STR_OR_LINK,
1213
)
1314

1415
from ..context import LDContext
15-
from ..helpers import generate_aliases, get_value_from_array
16+
from ..helpers import generate_aliases, get_value_from_array, to_jld
1617

1718
# from ..dumper import _serialize_model_to_json
1819
from ..types import ActivityPubModel
@@ -39,17 +40,15 @@ class Object(ActivityPubModel):
3940
)
4041
AS_URI = "https://www.w3.org/ns/activitystreams#Object"
4142

42-
id: OPT_STR = Field(
43-
validation_alias="@id", serialization_alias="@id", default=None
43+
id: ID_OPT_STR = Field(
44+
validation_alias=AliasChoices("id", "@id"),
45+
serialization_alias="@id",
46+
default=None,
4447
)
4548
name: OPT_STR = Field(default=None, **generate_aliases("name", "as2"))
4649
content: OPT_STR = Field(default=None, **generate_aliases("content", "as2"))
47-
summary: OPT_STR = Field(
48-
default=None, **generate_aliases("summary", "as2")
49-
)
50-
url: OPT_STR_OR_LINK = Field(
51-
default=None, **generate_aliases("url", "as2")
52-
)
50+
summary: OPT_STR = Field(default=None, **generate_aliases("summary", "as2"))
51+
url: OPT_STR_OR_LINK = Field(default=None, **generate_aliases("url", "as2"))
5352
published: OPT_DATETIME = Field(
5453
alias="https://www.w3.org/ns/activitystreams#published", default=None
5554
)
@@ -59,74 +58,98 @@ class Object(ActivityPubModel):
5958
attributed_to: Annotated[
6059
Optional[Union[str, "Actor", List[Union[str, "Actor"]]]],
6160
BeforeValidator(get_value_from_array),
61+
PlainSerializer(to_jld()),
6262
] = Field(
6363
alias="https://www.w3.org/ns/activitystreams#attributedTo", default=None
6464
)
6565
audience: Annotated[
6666
Optional[Union[str, "Object", List[Union[str, "Object"]]]],
6767
BeforeValidator(get_value_from_array),
68+
PlainSerializer(to_jld()),
6869
] = Field(
6970
alias="https://www.w3.org/ns/activitystreams#audience", default=None
7071
)
7172
to: Annotated[
7273
Optional[Union[str, "Object", List[Union[str, "Object"]]]],
7374
BeforeValidator(get_value_from_array),
75+
PlainSerializer(to_jld()),
7476
] = Field(alias="https://www.w3.org/ns/activitystreams#to", default=None)
7577
bto: Annotated[
7678
Optional[Union[str, "Object", List[Union[str, "Object"]]]],
7779
BeforeValidator(get_value_from_array),
80+
PlainSerializer(to_jld()),
7881
] = Field(alias="https://www.w3.org/ns/activitystreams#bto", default=None)
7982
cc: Annotated[
8083
Optional[Union[str, "Object", List[Union[str, "Object"]]]],
8184
BeforeValidator(get_value_from_array),
85+
PlainSerializer(to_jld()),
8286
] = Field(alias="https://www.w3.org/ns/activitystreams#cc", default=None)
8387
bcc: Annotated[
8488
Optional[Union[str, "Object", List[Union[str, "Object"]]]],
8589
BeforeValidator(get_value_from_array),
90+
PlainSerializer(to_jld()),
8691
] = Field(alias="https://www.w3.org/ns/activitystreams#bcc", default=None)
8792
generator: Annotated[
88-
Optional["Object"], BeforeValidator(get_value_from_array)
93+
Optional["Object"],
94+
BeforeValidator(get_value_from_array),
95+
PlainSerializer(to_jld()),
8996
] = Field(
9097
alias="https://www.w3.org/ns/activitystreams#generator", default=None
9198
)
9299
icon: Annotated[
93-
Optional["Image"], BeforeValidator(get_value_from_array)
100+
Optional["Image"],
101+
BeforeValidator(get_value_from_array),
102+
PlainSerializer(to_jld()),
94103
] = Field(alias="https://www.w3.org/ns/activitystreams#icon", default=None)
95104
image: Annotated[
96-
Optional["Image"], BeforeValidator(get_value_from_array)
105+
Optional["Image"],
106+
BeforeValidator(get_value_from_array),
107+
PlainSerializer(to_jld()),
97108
] = Field(alias="https://www.w3.org/ns/activitystreams#image", default=None)
98109
in_reply_to: Annotated[
99-
Optional["Object"], BeforeValidator(get_value_from_array)
110+
Optional["Object"],
111+
BeforeValidator(get_value_from_array),
112+
PlainSerializer(to_jld()),
100113
] = Field(
101114
alias="https://www.w3.org/ns/activitystreams#inReplyTo", default=None
102115
)
103116
location: Annotated[
104-
Optional["Object"], BeforeValidator(get_value_from_array)
117+
Optional["Object"],
118+
BeforeValidator(get_value_from_array),
119+
PlainSerializer(to_jld()),
105120
] = Field(
106121
alias="https://www.w3.org/ns/activitystreams#location", default=None
107122
)
108123
preview: Annotated[
109-
Optional["Object"], BeforeValidator(get_value_from_array)
124+
Optional["Object"],
125+
BeforeValidator(get_value_from_array),
126+
PlainSerializer(to_jld()),
110127
] = Field(
111128
alias="https://www.w3.org/ns/activitystreams#preview", default=None
112129
)
113130
replies: Annotated[
114-
Optional["Collection"], BeforeValidator(get_value_from_array)
131+
Optional["Collection"],
132+
BeforeValidator(get_value_from_array),
133+
PlainSerializer(to_jld()),
115134
] = Field(
116135
alias="https://www.w3.org/ns/activitystreams#replies", default=None
117136
)
118137
scope: Annotated[
119-
Optional["Object"], BeforeValidator(get_value_from_array)
138+
Optional["Object"],
139+
BeforeValidator(get_value_from_array),
140+
PlainSerializer(to_jld()),
120141
] = Field(alias="https://www.w3.org/ns/activitystreams#scope", default=None)
121142
tag: Annotated[
122143
List[Union["Object", "Hashtag", "Emoji"]],
123144
BeforeValidator(get_value_from_array),
145+
PlainSerializer(to_jld()),
124146
] = Field(
125147
alias="https://www.w3.org/ns/activitystreams#tag", default_factory=list
126148
)
127149
attachment: Annotated[
128150
List[Union["Object", "PropertyValue"]],
129151
BeforeValidator(get_value_from_array),
152+
PlainSerializer(to_jld()),
130153
] = Field(
131154
alias="https://www.w3.org/ns/activitystreams#attachment",
132155
default_factory=list,

0 commit comments

Comments
 (0)