+4
src/atpasser/nsid/__init__.py
+4
src/atpasser/nsid/__init__.py
+5
-5
docs/roadmap.md
+5
-5
docs/roadmap.md
···
-54
src/atpasser/did/__init__.py
-54
src/atpasser/did/__init__.py
···
+61
-17
src/atpasser/uri/handle.py
+61
-17
src/atpasser/uri/handle.py
···-raise InvalidHandleError(handle, "exceeds maximum length", f"Handle length {len(handle)} exceeds maximum allowed length of 253 characters")-raise InvalidHandleError(handle, "invalid format", "Handle must contain at least one dot separator, e.g., 'example.com'")-raise InvalidHandleError(handle, "segment length error", f"Handle segment {i+1} length {len(label)} is not in the 1-63 character range")-raise InvalidHandleError(handle, "contains invalid characters", f"Handle segment {i+1} contains invalid characters: {', '.join(invalid_chars)}")-raise InvalidHandleError(handle, "invalid format", f"Handle segment {i+1} cannot start or end with a hyphen")-raise InvalidHandleError(handle, "invalid format", "Handle's top-level domain cannot start with a digit")······-raise ResolutionError(self.handle, "DNS resolution", f"Error parsing DNS TXT record: {str(e)}")# Some websites may return incorrect Content-Type, so here we only warn without throwing an exception-raise ResolutionError(self.handle, "HTTP request", f"Error requesting well-known endpoint: {str(e)}")-raise ResolutionError(self.handle, "resolution", f"Unknown error occurred while resolving Handle: {str(e)}")
+82
-20
src/atpasser/uri/nsid.py
+82
-20
src/atpasser/uri/nsid.py
······-raise InvalidNSIDError(nsid, "contains invalid characters", "NSID must only contain ASCII characters")-raise InvalidNSIDError(nsid, "exceeds maximum length", f"NSID length {len(nsidWithoutFragment)} exceeds maximum allowed length of 317 characters")-raise InvalidNSIDError(nsid, "invalid format", f"NSID must contain at least 3 segments, currently has {len(segments)}")-raise InvalidNSIDError(nsid, "domain authority length exceeds limit", "Domain authority part length exceeds 253 characters")-raise InvalidNSIDError(nsid, "segment length error", f"Domain authority segment {i+1} length is not in the 1-63 character range")-raise InvalidNSIDError(nsid, "contains invalid characters", f"Domain authority segment {i+1} contains invalid characters: {', '.join(invalid_chars)}")-raise InvalidNSIDError(nsid, "invalid format", f"Domain authority segment {i+1} cannot start or end with a hyphen")-raise InvalidNSIDError(nsid, "invalid format", "NSID's top-level domain cannot start with a digit")···-raise InvalidNSIDError(nsid, "name length error", "NSID name cannot be empty and length cannot exceed 63 characters")-invalid_chars = set(name) - set("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")-raise InvalidNSIDError(nsid, "contains invalid characters", f"NSID name contains invalid characters: {', '.join(invalid_chars)}")-raise InvalidNSIDError(nsid, "fragment length error", "NSID fragment cannot be empty and length cannot exceed 63 characters")-invalid_chars = set(fragment) - set("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")-raise InvalidNSIDError(nsid, "contains invalid characters", f"NSID fragment contains invalid characters: {', '.join(invalid_chars)}")
-92
src/atpasser/uri/restricted.py
-92
src/atpasser/uri/restricted.py
···
-136
src/atpasser/uri/tid.py
-136
src/atpasser/uri/tid.py
···
+3
src/atpasser/uri/__init__.py
+3
src/atpasser/uri/__init__.py
-182
src/atpasser/data/decoder.py
-182
src/atpasser/data/decoder.py
···
-82
src/atpasser/data/encoder.py
-82
src/atpasser/data/encoder.py
···
-227
src/atpasser/data/hooks.py
-227
src/atpasser/data/hooks.py
···
-346
src/atpasser/data/wrapper.py
-346
src/atpasser/data/wrapper.py
···
+6
-1
.gitignore
+6
-1
.gitignore
+10
-2
README.md
+10
-2
README.md
···A simple library for the [Authenticated Transfer Protocol](https://atproto.com/specs/atp) (AT Protocol or atproto for short).···+[There's an ATProto SDK already (and used by lots of projects) by MarshalX,](https://github.com/MarshalX/atproto) and why do this exists?+The first reason is that I'm recovering the now-closed [Tietiequan](https://tangled.org/@dwn.dwnfonts.cc/bluesky-circle) app and found that some API has changed so I have to rewrite it via vanilla JS.+The second reason is that I'm a newbie in ATProto, wanting to know how ATProto is, and how this can be represented in Python.
-16
src/atpasser/blob/__init__.py
-16
src/atpasser/blob/__init__.py
···
-76
src/atpasser/data/_data.py
-76
src/atpasser/data/_data.py
···
-61
src/atpasser/data/_wrapper.py
-61
src/atpasser/data/_wrapper.py
···
-137
src/atpasser/data/cbor.py
-137
src/atpasser/data/cbor.py
···
-179
tests/_strings.py
-179
tests/_strings.py
···
+1
pyproject.toml
+1
pyproject.toml
···
+205
ARCHITECTURE_OVERVIEW.md
+205
ARCHITECTURE_OVERVIEW.md
···+ๆฌ้กน็ฎไธบ ATProto (Authenticated Transfer Protocol) ๆไพ Python ๅฎ็ฐ๏ผไธๆณจไบๆฐๆฎๆจกๅๅ Lexicon ๅฎไน็ๅค็ใๅบไบ็ฐๆ็ URI ๆจกๅๆถๆๆจกๅผ๏ผๆไพ็ฑปๅๅฎๅ จ็ๆฐๆฎ้ช่ฏใๅบๅๅๅ Lexicon ่งฃๆๅ่ฝใ+ๆฌๆถๆ่ฎพ่ฎกๆไพไบไธไธชๅฎๆดใๅฏๆฉๅฑ็ ATProto ๆฐๆฎๅค็่งฃๅณๆนๆก๏ผๅ ๅๅฉ็จไบ Python ็็ฑปๅ็ณป็ปๅ็ฐๆ็ๆ๏ผๅๆถไฟๆไบไธ ATProto ่ง่็ๅฎๅ จๅ ผๅฎนๆงใๆจกๅๅ็่ฎพ่ฎกไฝฟๅพๅไธช็ปไปถๅฏไปฅ็ฌ็ซๅผๅๅๆต่ฏ๏ผๅๆถไนไพฟไบๆชๆฅ็ๆฉๅฑๅ็ปดๆคใ
+119
examples/basic_usage.py
+119
examples/basic_usage.py
···
+11
src/atpasser/__init__.py
+11
src/atpasser/__init__.py
···
+215
src/atpasser/data/ARCHITECTURE.md
+215
src/atpasser/data/ARCHITECTURE.md
···+ๆฌๆจกๅ่ด่ดฃๅฎ็ฐ ATProto ๆฐๆฎๆจกๅ็ๅบๅๅใๅๅบๅๅๅ้ช่ฏๅ่ฝ๏ผๆฏๆ JSON ๅ DAG-CBOR ไธค็งๆ ผๅผ็ๆฐๆฎ็ผ็ ใ
+47
src/atpasser/data/__init__.py
+47
src/atpasser/data/__init__.py
···
+87
src/atpasser/data/exceptions.py
+87
src/atpasser/data/exceptions.py
···
+190
src/atpasser/data/formats.py
+190
src/atpasser/data/formats.py
···
+125
src/atpasser/data/serializer.py
+125
src/atpasser/data/serializer.py
···
+263
src/atpasser/lexicon/ARCHITECTURE.md
+263
src/atpasser/lexicon/ARCHITECTURE.md
···+ๆฌๆจกๅ่ด่ดฃ่งฃๆใ้ช่ฏๅ็ฎก็ ATProto Lexicon ๅฎไนๆไปถ๏ผๅฐ JSON Schema ่ฝฌๆขไธบๅฏๆง่ก็ Pydantic ๆจกๅ๏ผๅนถๆไพ็ฑปๅๅฎๅ จ็ๆฅๅฃใ
+71
src/atpasser/lexicon/__init__.py
+71
src/atpasser/lexicon/__init__.py
···
+125
src/atpasser/lexicon/exceptions.py
+125
src/atpasser/lexicon/exceptions.py
···
+208
src/atpasser/lexicon/parser.py
+208
src/atpasser/lexicon/parser.py
···
+114
src/atpasser/lexicon/registry.py
+114
src/atpasser/lexicon/registry.py
···
+155
src/atpasser/lexicon/types.py
+155
src/atpasser/lexicon/types.py
···