diff --git a/.gitignore b/.gitignore index 2a814190..6610fea4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ .DS_Store .idea +.vscode .run *.iml .env diff --git a/docs/source/atproto/atproto_client.models.rst b/docs/source/atproto/atproto_client.models.rst index 17ce3266..864bb1ca 100644 --- a/docs/source/atproto/atproto_client.models.rst +++ b/docs/source/atproto/atproto_client.models.rst @@ -29,6 +29,7 @@ Submodules atproto_client.models.dot_dict atproto_client.models.languages atproto_client.models.models_loader + atproto_client.models.string_formats atproto_client.models.type_conversion atproto_client.models.unknown_type atproto_client.models.utils diff --git a/docs/source/atproto/atproto_client.models.string_formats.rst b/docs/source/atproto/atproto_client.models.string_formats.rst new file mode 100644 index 00000000..a8fdcf81 --- /dev/null +++ b/docs/source/atproto/atproto_client.models.string_formats.rst @@ -0,0 +1,7 @@ +string\_formats +====================================== + +.. automodule:: atproto_client.models.string_formats + :members: + :undoc-members: + :show-inheritance: \ No newline at end of file diff --git a/examples/advanced_usage/validate_string_formats.py b/examples/advanced_usage/validate_string_formats.py new file mode 100644 index 00000000..323d8f12 --- /dev/null +++ b/examples/advanced_usage/validate_string_formats.py @@ -0,0 +1,30 @@ +from atproto_client.models import string_formats +from pydantic import TypeAdapter, ValidationError + +some_good_handle = 'test.bsky.social' +some_bad_handle = 'invalid@ @handle' + +strict_validation_context = {'strict_string_format': True} +HandleTypeAdapter = TypeAdapter(string_formats.Handle) + +assert string_formats._OPT_IN_KEY == 'strict_string_format' # noqa: S101 + +# values will not be validated if not opting in +sneaky_bad_handle = HandleTypeAdapter.validate_python(some_bad_handle) + +assert sneaky_bad_handle == some_bad_handle # noqa: S101 + +print(f'{sneaky_bad_handle=}\n\n') + +# values will be validated if opting in +validated_good_handle = HandleTypeAdapter.validate_python(some_good_handle, context=strict_validation_context) + +assert validated_good_handle == some_good_handle # noqa: S101 + +print(f'{validated_good_handle=}\n\n') + +try: + print('Trying to validate a bad handle with strict validation...') + HandleTypeAdapter.validate_python(some_bad_handle, context=strict_validation_context) +except ValidationError as e: + print(e) diff --git a/packages/atproto_client/models/app/bsky/actor/defs.py b/packages/atproto_client/models/app/bsky/actor/defs.py index ded9a970..f567d0cd 100644 --- a/packages/atproto_client/models/app/bsky/actor/defs.py +++ b/packages/atproto_client/models/app/bsky/actor/defs.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -18,11 +20,11 @@ class ProfileViewBasic(base.ModelBase): """Definition model for :obj:`app.bsky.actor.defs`.""" - did: str #: Did. - handle: str #: Handle. + did: string_formats.Did #: Did. + handle: string_formats.Handle #: Handle. associated: t.Optional['models.AppBskyActorDefs.ProfileAssociated'] = None #: Associated. - avatar: t.Optional[str] = None #: Avatar. - created_at: t.Optional[str] = None #: Created at. + avatar: t.Optional[string_formats.Uri] = None #: Avatar. + created_at: t.Optional[string_formats.DateTime] = None #: Created at. display_name: t.Optional[str] = Field(default=None, max_length=640) #: Display name. labels: t.Optional[t.List['models.ComAtprotoLabelDefs.Label']] = None #: Labels. viewer: t.Optional['models.AppBskyActorDefs.ViewerState'] = None #: Viewer. @@ -35,14 +37,14 @@ class ProfileViewBasic(base.ModelBase): class ProfileView(base.ModelBase): """Definition model for :obj:`app.bsky.actor.defs`.""" - did: str #: Did. - handle: str #: Handle. + did: string_formats.Did #: Did. + handle: string_formats.Handle #: Handle. associated: t.Optional['models.AppBskyActorDefs.ProfileAssociated'] = None #: Associated. - avatar: t.Optional[str] = None #: Avatar. - created_at: t.Optional[str] = None #: Created at. + avatar: t.Optional[string_formats.Uri] = None #: Avatar. + created_at: t.Optional[string_formats.DateTime] = None #: Created at. description: t.Optional[str] = Field(default=None, max_length=2560) #: Description. display_name: t.Optional[str] = Field(default=None, max_length=640) #: Display name. - indexed_at: t.Optional[str] = None #: Indexed at. + indexed_at: t.Optional[string_formats.DateTime] = None #: Indexed at. labels: t.Optional[t.List['models.ComAtprotoLabelDefs.Label']] = None #: Labels. viewer: t.Optional['models.AppBskyActorDefs.ViewerState'] = None #: Viewer. @@ -54,17 +56,17 @@ class ProfileView(base.ModelBase): class ProfileViewDetailed(base.ModelBase): """Definition model for :obj:`app.bsky.actor.defs`.""" - did: str #: Did. - handle: str #: Handle. + did: string_formats.Did #: Did. + handle: string_formats.Handle #: Handle. associated: t.Optional['models.AppBskyActorDefs.ProfileAssociated'] = None #: Associated. - avatar: t.Optional[str] = None #: Avatar. - banner: t.Optional[str] = None #: Banner. - created_at: t.Optional[str] = None #: Created at. + avatar: t.Optional[string_formats.Uri] = None #: Avatar. + banner: t.Optional[string_formats.Uri] = None #: Banner. + created_at: t.Optional[string_formats.DateTime] = None #: Created at. description: t.Optional[str] = Field(default=None, max_length=2560) #: Description. display_name: t.Optional[str] = Field(default=None, max_length=640) #: Display name. followers_count: t.Optional[int] = None #: Followers count. follows_count: t.Optional[int] = None #: Follows count. - indexed_at: t.Optional[str] = None #: Indexed at. + indexed_at: t.Optional[string_formats.DateTime] = None #: Indexed at. joined_via_starter_pack: t.Optional['models.AppBskyGraphDefs.StarterPackViewBasic'] = ( None #: Joined via starter pack. ) @@ -106,10 +108,10 @@ class ViewerState(base.ModelBase): """Definition model for :obj:`app.bsky.actor.defs`. Metadata about the requesting account's relationship with the subject account. Only has meaningful content for authed requests.""" blocked_by: t.Optional[bool] = None #: Blocked by. - blocking: t.Optional[str] = None #: Blocking. + blocking: t.Optional[string_formats.AtUri] = None #: Blocking. blocking_by_list: t.Optional['models.AppBskyGraphDefs.ListViewBasic'] = None #: Blocking by list. - followed_by: t.Optional[str] = None #: Followed by. - following: t.Optional[str] = None #: Following. + followed_by: t.Optional[string_formats.AtUri] = None #: Followed by. + following: t.Optional[string_formats.AtUri] = None #: Following. known_followers: t.Optional['models.AppBskyActorDefs.KnownFollowers'] = None #: Known followers. muted: t.Optional[bool] = None #: Muted. muted_by_list: t.Optional['models.AppBskyGraphDefs.ListViewBasic'] = None #: Muted by list. @@ -168,7 +170,9 @@ class ContentLabelPref(base.ModelBase): visibility: t.Union[ t.Literal['ignore'], t.Literal['show'], t.Literal['warn'], t.Literal['hide'], str ] #: Visibility. - labeler_did: t.Optional[str] = None #: Which labeler does this preference apply to? If undefined, applies globally. + labeler_did: t.Optional[string_formats.Did] = ( + None #: Which labeler does this preference apply to? If undefined, applies globally. + ) py_type: t.Literal['app.bsky.actor.defs#contentLabelPref'] = Field( default='app.bsky.actor.defs#contentLabelPref', alias='$type', frozen=True @@ -201,8 +205,8 @@ class SavedFeedsPrefV2(base.ModelBase): class SavedFeedsPref(base.ModelBase): """Definition model for :obj:`app.bsky.actor.defs`.""" - pinned: t.List[str] #: Pinned. - saved: t.List[str] #: Saved. + pinned: t.List[string_formats.AtUri] #: Pinned. + saved: t.List[string_formats.AtUri] #: Saved. timeline_index: t.Optional[int] = None #: Timeline index. py_type: t.Literal['app.bsky.actor.defs#savedFeedsPref'] = Field( @@ -213,7 +217,7 @@ class SavedFeedsPref(base.ModelBase): class PersonalDetailsPref(base.ModelBase): """Definition model for :obj:`app.bsky.actor.defs`.""" - birth_date: t.Optional[str] = None #: The birth date of account owner. + birth_date: t.Optional[string_formats.DateTime] = None #: The birth date of account owner. py_type: t.Literal['app.bsky.actor.defs#personalDetailsPref'] = Field( default='app.bsky.actor.defs#personalDetailsPref', alias='$type', frozen=True @@ -280,7 +284,7 @@ class MutedWord(base.ModelBase): actor_target: t.Optional[t.Union[t.Literal['all'], t.Literal['exclude-following'], str]] = ( 'all' #: Groups of users to apply the muted word to. If undefined, applies to all users. ) - expires_at: t.Optional[str] = ( + expires_at: t.Optional[string_formats.DateTime] = ( None #: The date and time at which the muted word will expire and no longer be applied. ) id: t.Optional[str] = None #: Id. @@ -303,7 +307,7 @@ class MutedWordsPref(base.ModelBase): class HiddenPostsPref(base.ModelBase): """Definition model for :obj:`app.bsky.actor.defs`.""" - items: t.List[str] #: A list of URIs of posts the account owner has hidden. + items: t.List[string_formats.AtUri] #: A list of URIs of posts the account owner has hidden. py_type: t.Literal['app.bsky.actor.defs#hiddenPostsPref'] = Field( default='app.bsky.actor.defs#hiddenPostsPref', alias='$type', frozen=True @@ -323,7 +327,7 @@ class LabelersPref(base.ModelBase): class LabelerPrefItem(base.ModelBase): """Definition model for :obj:`app.bsky.actor.defs`.""" - did: str #: Did. + did: string_formats.Did #: Did. py_type: t.Literal['app.bsky.actor.defs#labelerPrefItem'] = Field( default='app.bsky.actor.defs#labelerPrefItem', alias='$type', frozen=True @@ -364,7 +368,7 @@ class Nux(base.ModelBase): data: t.Optional[str] = Field( default=None, max_length=3000 ) #: Arbitrary data for the NUX. The structure is defined by the NUX itself. Limited to 300 characters. - expires_at: t.Optional[str] = ( + expires_at: t.Optional[string_formats.DateTime] = ( None #: The date and time at which the NUX will expire and should be considered completed. ) diff --git a/packages/atproto_client/models/app/bsky/actor/get_profile.py b/packages/atproto_client/models/app/bsky/actor/get_profile.py index 6d8acb97..83327070 100644 --- a/packages/atproto_client/models/app/bsky/actor/get_profile.py +++ b/packages/atproto_client/models/app/bsky/actor/get_profile.py @@ -7,14 +7,14 @@ import typing as t -from atproto_client.models import base +from atproto_client.models import base, string_formats class Params(base.ParamsModelBase): """Parameters model for :obj:`app.bsky.actor.getProfile`.""" - actor: str #: Handle or DID of account to fetch profile of. + actor: string_formats.Handle #: Handle or DID of account to fetch profile of. class ParamsDict(t.TypedDict): - actor: str #: Handle or DID of account to fetch profile of. + actor: string_formats.Handle #: Handle or DID of account to fetch profile of. diff --git a/packages/atproto_client/models/app/bsky/actor/get_profiles.py b/packages/atproto_client/models/app/bsky/actor/get_profiles.py index 8508c29b..dbb58f79 100644 --- a/packages/atproto_client/models/app/bsky/actor/get_profiles.py +++ b/packages/atproto_client/models/app/bsky/actor/get_profiles.py @@ -9,6 +9,8 @@ from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -17,11 +19,11 @@ class Params(base.ParamsModelBase): """Parameters model for :obj:`app.bsky.actor.getProfiles`.""" - actors: t.List[str] = Field(max_length=25) #: Actors. + actors: t.List[string_formats.Handle] = Field(max_length=25) #: Actors. class ParamsDict(t.TypedDict): - actors: t.List[str] #: Actors. + actors: t.List[string_formats.Handle] #: Actors. class Response(base.ResponseModelBase): diff --git a/packages/atproto_client/models/app/bsky/actor/profile.py b/packages/atproto_client/models/app/bsky/actor/profile.py index b49ab215..d9dab15b 100644 --- a/packages/atproto_client/models/app/bsky/actor/profile.py +++ b/packages/atproto_client/models/app/bsky/actor/profile.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models.blob_ref import BlobRef @@ -23,7 +25,7 @@ class Record(base.RecordModelBase): None #: Small image to be displayed next to posts from account. AKA, 'profile picture'. ) banner: t.Optional['BlobRef'] = None #: Larger horizontal image to display behind profile view. - created_at: t.Optional[str] = None #: Created at. + created_at: t.Optional[string_formats.DateTime] = None #: Created at. description: t.Optional[str] = Field(default=None, max_length=2560) #: Free-form profile description text. display_name: t.Optional[str] = Field(default=None, max_length=640) #: Display name. joined_via_starter_pack: t.Optional['models.ComAtprotoRepoStrongRef.Main'] = None #: Joined via starter pack. diff --git a/packages/atproto_client/models/app/bsky/embed/external.py b/packages/atproto_client/models/app/bsky/embed/external.py index e1e74bb5..227b7611 100644 --- a/packages/atproto_client/models/app/bsky/embed/external.py +++ b/packages/atproto_client/models/app/bsky/embed/external.py @@ -9,6 +9,8 @@ from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models.blob_ref import BlobRef @@ -28,7 +30,7 @@ class External(base.ModelBase): description: str #: Description. title: str #: Title. - uri: str #: Uri. + uri: string_formats.Uri #: Uri. thumb: t.Optional['BlobRef'] = None #: Thumb. py_type: t.Literal['app.bsky.embed.external#external'] = Field( @@ -51,8 +53,8 @@ class ViewExternal(base.ModelBase): description: str #: Description. title: str #: Title. - uri: str #: Uri. - thumb: t.Optional[str] = None #: Thumb. + uri: string_formats.Uri #: Uri. + thumb: t.Optional[string_formats.Uri] = None #: Thumb. py_type: t.Literal['app.bsky.embed.external#viewExternal'] = Field( default='app.bsky.embed.external#viewExternal', alias='$type', frozen=True diff --git a/packages/atproto_client/models/app/bsky/embed/images.py b/packages/atproto_client/models/app/bsky/embed/images.py index acc2b658..8b4f105a 100644 --- a/packages/atproto_client/models/app/bsky/embed/images.py +++ b/packages/atproto_client/models/app/bsky/embed/images.py @@ -9,6 +9,8 @@ from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models.blob_ref import BlobRef @@ -49,8 +51,8 @@ class ViewImage(base.ModelBase): """Definition model for :obj:`app.bsky.embed.images`.""" alt: str #: Alt text description of the image, for accessibility. - fullsize: str #: Fully-qualified URL where a large version of the image can be fetched. May or may not be the exact original blob. For example, CDN location provided by the App View. - thumb: str #: Fully-qualified URL where a thumbnail of the image can be fetched. For example, CDN location provided by the App View. + fullsize: string_formats.Uri #: Fully-qualified URL where a large version of the image can be fetched. May or may not be the exact original blob. For example, CDN location provided by the App View. + thumb: string_formats.Uri #: Fully-qualified URL where a thumbnail of the image can be fetched. For example, CDN location provided by the App View. aspect_ratio: t.Optional['models.AppBskyEmbedDefs.AspectRatio'] = None #: Aspect ratio. py_type: t.Literal['app.bsky.embed.images#viewImage'] = Field( diff --git a/packages/atproto_client/models/app/bsky/embed/record.py b/packages/atproto_client/models/app/bsky/embed/record.py index 4cb9ad24..52ab5250 100644 --- a/packages/atproto_client/models/app/bsky/embed/record.py +++ b/packages/atproto_client/models/app/bsky/embed/record.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models.unknown_type import UnknownType @@ -50,9 +52,9 @@ class ViewRecord(base.ModelBase): """Definition model for :obj:`app.bsky.embed.record`.""" author: 'models.AppBskyActorDefs.ProfileViewBasic' #: Author. - cid: str #: Cid. - indexed_at: str #: Indexed at. - uri: str #: Uri. + cid: string_formats.Cid #: Cid. + indexed_at: string_formats.DateTime #: Indexed at. + uri: string_formats.AtUri #: Uri. value: 'UnknownType' #: The record data itself. embeds: t.Optional[ t.List[ @@ -83,7 +85,7 @@ class ViewNotFound(base.ModelBase): """Definition model for :obj:`app.bsky.embed.record`.""" not_found: bool = Field(frozen=True) #: Not found. - uri: str #: Uri. + uri: string_formats.AtUri #: Uri. py_type: t.Literal['app.bsky.embed.record#viewNotFound'] = Field( default='app.bsky.embed.record#viewNotFound', alias='$type', frozen=True @@ -95,7 +97,7 @@ class ViewBlocked(base.ModelBase): author: 'models.AppBskyFeedDefs.BlockedAuthor' #: Author. blocked: bool = Field(frozen=True) #: Blocked. - uri: str #: Uri. + uri: string_formats.AtUri #: Uri. py_type: t.Literal['app.bsky.embed.record#viewBlocked'] = Field( default='app.bsky.embed.record#viewBlocked', alias='$type', frozen=True @@ -106,7 +108,7 @@ class ViewDetached(base.ModelBase): """Definition model for :obj:`app.bsky.embed.record`.""" detached: bool = Field(frozen=True) #: Detached. - uri: str #: Uri. + uri: string_formats.AtUri #: Uri. py_type: t.Literal['app.bsky.embed.record#viewDetached'] = Field( default='app.bsky.embed.record#viewDetached', alias='$type', frozen=True diff --git a/packages/atproto_client/models/app/bsky/embed/video.py b/packages/atproto_client/models/app/bsky/embed/video.py index 03c290ba..9e04629c 100644 --- a/packages/atproto_client/models/app/bsky/embed/video.py +++ b/packages/atproto_client/models/app/bsky/embed/video.py @@ -9,6 +9,8 @@ from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models.blob_ref import BlobRef @@ -32,7 +34,7 @@ class Caption(base.ModelBase): """Definition model for :obj:`app.bsky.embed.video`.""" file: 'BlobRef' #: File. - lang: str #: Lang. + lang: string_formats.Language #: Lang. py_type: t.Literal['app.bsky.embed.video#caption'] = Field( default='app.bsky.embed.video#caption', alias='$type', frozen=True @@ -42,11 +44,11 @@ class Caption(base.ModelBase): class View(base.ModelBase): """Definition model for :obj:`app.bsky.embed.video`.""" - cid: str #: Cid. - playlist: str #: Playlist. + cid: string_formats.Cid #: Cid. + playlist: string_formats.Uri #: Playlist. alt: t.Optional[str] = Field(default=None, max_length=10000) #: Alt. aspect_ratio: t.Optional['models.AppBskyEmbedDefs.AspectRatio'] = None #: Aspect ratio. - thumbnail: t.Optional[str] = None #: Thumbnail. + thumbnail: t.Optional[string_formats.Uri] = None #: Thumbnail. py_type: t.Literal['app.bsky.embed.video#view'] = Field( default='app.bsky.embed.video#view', alias='$type', frozen=True diff --git a/packages/atproto_client/models/app/bsky/feed/defs.py b/packages/atproto_client/models/app/bsky/feed/defs.py index 141323e5..402f392a 100644 --- a/packages/atproto_client/models/app/bsky/feed/defs.py +++ b/packages/atproto_client/models/app/bsky/feed/defs.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models.unknown_type import UnknownType @@ -20,10 +22,10 @@ class PostView(base.ModelBase): """Definition model for :obj:`app.bsky.feed.defs`.""" author: 'models.AppBskyActorDefs.ProfileViewBasic' #: Author. - cid: str #: Cid. - indexed_at: str #: Indexed at. + cid: string_formats.Cid #: Cid. + indexed_at: string_formats.DateTime #: Indexed at. record: 'UnknownType' #: Record. - uri: str #: Uri. + uri: string_formats.AtUri #: Uri. embed: t.Optional[ te.Annotated[ t.Union[ @@ -53,10 +55,10 @@ class ViewerState(base.ModelBase): """Definition model for :obj:`app.bsky.feed.defs`. Metadata about the requesting account's relationship with the subject content. Only has meaningful content for authed requests.""" embedding_disabled: t.Optional[bool] = None #: Embedding disabled. - like: t.Optional[str] = None #: Like. + like: t.Optional[string_formats.AtUri] = None #: Like. pinned: t.Optional[bool] = None #: Pinned. reply_disabled: t.Optional[bool] = None #: Reply disabled. - repost: t.Optional[str] = None #: Repost. + repost: t.Optional[string_formats.AtUri] = None #: Repost. thread_muted: t.Optional[bool] = None #: Thread muted. py_type: t.Literal['app.bsky.feed.defs#viewerState'] = Field( @@ -116,7 +118,7 @@ class ReasonRepost(base.ModelBase): """Definition model for :obj:`app.bsky.feed.defs`.""" by: 'models.AppBskyActorDefs.ProfileViewBasic' #: By. - indexed_at: str #: Indexed at. + indexed_at: string_formats.DateTime #: Indexed at. py_type: t.Literal['app.bsky.feed.defs#reasonRepost'] = Field( default='app.bsky.feed.defs#reasonRepost', alias='$type', frozen=True @@ -167,7 +169,7 @@ class NotFoundPost(base.ModelBase): """Definition model for :obj:`app.bsky.feed.defs`.""" not_found: bool = Field(frozen=True) #: Not found. - uri: str #: Uri. + uri: string_formats.AtUri #: Uri. py_type: t.Literal['app.bsky.feed.defs#notFoundPost'] = Field( default='app.bsky.feed.defs#notFoundPost', alias='$type', frozen=True @@ -179,7 +181,7 @@ class BlockedPost(base.ModelBase): author: 'models.AppBskyFeedDefs.BlockedAuthor' #: Author. blocked: bool = Field(frozen=True) #: Blocked. - uri: str #: Uri. + uri: string_formats.AtUri #: Uri. py_type: t.Literal['app.bsky.feed.defs#blockedPost'] = Field( default='app.bsky.feed.defs#blockedPost', alias='$type', frozen=True @@ -189,7 +191,7 @@ class BlockedPost(base.ModelBase): class BlockedAuthor(base.ModelBase): """Definition model for :obj:`app.bsky.feed.defs`.""" - did: str #: Did. + did: string_formats.Did #: Did. viewer: t.Optional['models.AppBskyActorDefs.ViewerState'] = None #: Viewer. py_type: t.Literal['app.bsky.feed.defs#blockedAuthor'] = Field( @@ -200,14 +202,14 @@ class BlockedAuthor(base.ModelBase): class GeneratorView(base.ModelBase): """Definition model for :obj:`app.bsky.feed.defs`.""" - cid: str #: Cid. + cid: string_formats.Cid #: Cid. creator: 'models.AppBskyActorDefs.ProfileView' #: Creator. - did: str #: Did. + did: string_formats.Did #: Did. display_name: str #: Display name. - indexed_at: str #: Indexed at. - uri: str #: Uri. + indexed_at: string_formats.DateTime #: Indexed at. + uri: string_formats.AtUri #: Uri. accepts_interactions: t.Optional[bool] = None #: Accepts interactions. - avatar: t.Optional[str] = None #: Avatar. + avatar: t.Optional[string_formats.Uri] = None #: Avatar. description: t.Optional[str] = Field(default=None, max_length=3000) #: Description. description_facets: t.Optional[t.List['models.AppBskyRichtextFacet.Main']] = None #: Description facets. labels: t.Optional[t.List['models.ComAtprotoLabelDefs.Label']] = None #: Labels. @@ -222,7 +224,7 @@ class GeneratorView(base.ModelBase): class GeneratorViewerState(base.ModelBase): """Definition model for :obj:`app.bsky.feed.defs`.""" - like: t.Optional[str] = None #: Like. + like: t.Optional[string_formats.AtUri] = None #: Like. py_type: t.Literal['app.bsky.feed.defs#generatorViewerState'] = Field( default='app.bsky.feed.defs#generatorViewerState', alias='$type', frozen=True @@ -232,7 +234,7 @@ class GeneratorViewerState(base.ModelBase): class SkeletonFeedPost(base.ModelBase): """Definition model for :obj:`app.bsky.feed.defs`.""" - post: str #: Post. + post: string_formats.AtUri #: Post. feed_context: t.Optional[str] = Field( default=None, max_length=2000 ) #: Context that will be passed through to client and may be passed to feed generator back alongside interactions. @@ -251,7 +253,7 @@ class SkeletonFeedPost(base.ModelBase): class SkeletonReasonRepost(base.ModelBase): """Definition model for :obj:`app.bsky.feed.defs`.""" - repost: str #: Repost. + repost: string_formats.AtUri #: Repost. py_type: t.Literal['app.bsky.feed.defs#skeletonReasonRepost'] = Field( default='app.bsky.feed.defs#skeletonReasonRepost', alias='$type', frozen=True @@ -269,10 +271,10 @@ class SkeletonReasonPin(base.ModelBase): class ThreadgateView(base.ModelBase): """Definition model for :obj:`app.bsky.feed.defs`.""" - cid: t.Optional[str] = None #: Cid. + cid: t.Optional[string_formats.Cid] = None #: Cid. lists: t.Optional[t.List['models.AppBskyGraphDefs.ListViewBasic']] = None #: Lists. record: t.Optional['UnknownType'] = None #: Record. - uri: t.Optional[str] = None #: Uri. + uri: t.Optional[string_formats.AtUri] = None #: Uri. py_type: t.Literal['app.bsky.feed.defs#threadgateView'] = Field( default='app.bsky.feed.defs#threadgateView', alias='$type', frozen=True @@ -302,7 +304,7 @@ class Interaction(base.ModelBase): feed_context: t.Optional[str] = Field( default=None, max_length=2000 ) #: Context on a feed item that was originally supplied by the feed generator on getFeedSkeleton. - item: t.Optional[str] = None #: Item. + item: t.Optional[string_formats.AtUri] = None #: Item. py_type: t.Literal['app.bsky.feed.defs#interaction'] = Field( default='app.bsky.feed.defs#interaction', alias='$type', frozen=True diff --git a/packages/atproto_client/models/app/bsky/feed/describe_feed_generator.py b/packages/atproto_client/models/app/bsky/feed/describe_feed_generator.py index 1b40b0e4..331c55d5 100644 --- a/packages/atproto_client/models/app/bsky/feed/describe_feed_generator.py +++ b/packages/atproto_client/models/app/bsky/feed/describe_feed_generator.py @@ -9,6 +9,8 @@ from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -17,7 +19,7 @@ class Response(base.ResponseModelBase): """Output data model for :obj:`app.bsky.feed.describeFeedGenerator`.""" - did: str #: Did. + did: string_formats.Did #: Did. feeds: t.List['models.AppBskyFeedDescribeFeedGenerator.Feed'] #: Feeds. links: t.Optional['models.AppBskyFeedDescribeFeedGenerator.Links'] = None #: Links. @@ -25,7 +27,7 @@ class Response(base.ResponseModelBase): class Feed(base.ModelBase): """Definition model for :obj:`app.bsky.feed.describeFeedGenerator`.""" - uri: str #: Uri. + uri: string_formats.AtUri #: Uri. py_type: t.Literal['app.bsky.feed.describeFeedGenerator#feed'] = Field( default='app.bsky.feed.describeFeedGenerator#feed', alias='$type', frozen=True diff --git a/packages/atproto_client/models/app/bsky/feed/generator.py b/packages/atproto_client/models/app/bsky/feed/generator.py index e5ff78af..8dd900f1 100644 --- a/packages/atproto_client/models/app/bsky/feed/generator.py +++ b/packages/atproto_client/models/app/bsky/feed/generator.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models.blob_ref import BlobRef @@ -19,8 +21,8 @@ class Record(base.RecordModelBase): """Record model for :obj:`app.bsky.feed.generator`.""" - created_at: str #: Created at. - did: str #: Did. + created_at: string_formats.DateTime #: Created at. + did: string_formats.Did #: Did. display_name: str = Field(max_length=240) #: Display name. accepts_interactions: t.Optional[bool] = ( None #: Declaration that a feed accepts feedback interactions from a client through app.bsky.feed.sendInteractions. diff --git a/packages/atproto_client/models/app/bsky/feed/get_actor_feeds.py b/packages/atproto_client/models/app/bsky/feed/get_actor_feeds.py index bd691213..4dcebb43 100644 --- a/packages/atproto_client/models/app/bsky/feed/get_actor_feeds.py +++ b/packages/atproto_client/models/app/bsky/feed/get_actor_feeds.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -18,13 +20,13 @@ class Params(base.ParamsModelBase): """Parameters model for :obj:`app.bsky.feed.getActorFeeds`.""" - actor: str #: Actor. + actor: string_formats.Handle #: Actor. cursor: t.Optional[str] = None #: Cursor. limit: t.Optional[int] = Field(default=50, ge=1, le=100) #: Limit. class ParamsDict(t.TypedDict): - actor: str #: Actor. + actor: string_formats.Handle #: Actor. cursor: te.NotRequired[t.Optional[str]] #: Cursor. limit: te.NotRequired[t.Optional[int]] #: Limit. diff --git a/packages/atproto_client/models/app/bsky/feed/get_actor_likes.py b/packages/atproto_client/models/app/bsky/feed/get_actor_likes.py index 81419031..77ac3a4d 100644 --- a/packages/atproto_client/models/app/bsky/feed/get_actor_likes.py +++ b/packages/atproto_client/models/app/bsky/feed/get_actor_likes.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -18,13 +20,13 @@ class Params(base.ParamsModelBase): """Parameters model for :obj:`app.bsky.feed.getActorLikes`.""" - actor: str #: Actor. + actor: string_formats.Handle #: Actor. cursor: t.Optional[str] = None #: Cursor. limit: t.Optional[int] = Field(default=50, ge=1, le=100) #: Limit. class ParamsDict(t.TypedDict): - actor: str #: Actor. + actor: string_formats.Handle #: Actor. cursor: te.NotRequired[t.Optional[str]] #: Cursor. limit: te.NotRequired[t.Optional[int]] #: Limit. diff --git a/packages/atproto_client/models/app/bsky/feed/get_author_feed.py b/packages/atproto_client/models/app/bsky/feed/get_author_feed.py index 2a7ea881..14033c04 100644 --- a/packages/atproto_client/models/app/bsky/feed/get_author_feed.py +++ b/packages/atproto_client/models/app/bsky/feed/get_author_feed.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -18,7 +20,7 @@ class Params(base.ParamsModelBase): """Parameters model for :obj:`app.bsky.feed.getAuthorFeed`.""" - actor: str #: Actor. + actor: string_formats.Handle #: Actor. cursor: t.Optional[str] = None #: Cursor. filter: t.Optional[ t.Union[ @@ -34,7 +36,7 @@ class Params(base.ParamsModelBase): class ParamsDict(t.TypedDict): - actor: str #: Actor. + actor: string_formats.Handle #: Actor. cursor: te.NotRequired[t.Optional[str]] #: Cursor. filter: te.NotRequired[ t.Optional[ diff --git a/packages/atproto_client/models/app/bsky/feed/get_feed.py b/packages/atproto_client/models/app/bsky/feed/get_feed.py index adb6b34b..35968bcf 100644 --- a/packages/atproto_client/models/app/bsky/feed/get_feed.py +++ b/packages/atproto_client/models/app/bsky/feed/get_feed.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -18,13 +20,13 @@ class Params(base.ParamsModelBase): """Parameters model for :obj:`app.bsky.feed.getFeed`.""" - feed: str #: Feed. + feed: string_formats.AtUri #: Feed. cursor: t.Optional[str] = None #: Cursor. limit: t.Optional[int] = Field(default=50, ge=1, le=100) #: Limit. class ParamsDict(t.TypedDict): - feed: str #: Feed. + feed: string_formats.AtUri #: Feed. cursor: te.NotRequired[t.Optional[str]] #: Cursor. limit: te.NotRequired[t.Optional[int]] #: Limit. diff --git a/packages/atproto_client/models/app/bsky/feed/get_feed_generator.py b/packages/atproto_client/models/app/bsky/feed/get_feed_generator.py index e72d01b8..499c8677 100644 --- a/packages/atproto_client/models/app/bsky/feed/get_feed_generator.py +++ b/packages/atproto_client/models/app/bsky/feed/get_feed_generator.py @@ -7,6 +7,8 @@ import typing as t +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -15,11 +17,11 @@ class Params(base.ParamsModelBase): """Parameters model for :obj:`app.bsky.feed.getFeedGenerator`.""" - feed: str #: AT-URI of the feed generator record. + feed: string_formats.AtUri #: AT-URI of the feed generator record. class ParamsDict(t.TypedDict): - feed: str #: AT-URI of the feed generator record. + feed: string_formats.AtUri #: AT-URI of the feed generator record. class Response(base.ResponseModelBase): diff --git a/packages/atproto_client/models/app/bsky/feed/get_feed_generators.py b/packages/atproto_client/models/app/bsky/feed/get_feed_generators.py index 376af424..ff549f58 100644 --- a/packages/atproto_client/models/app/bsky/feed/get_feed_generators.py +++ b/packages/atproto_client/models/app/bsky/feed/get_feed_generators.py @@ -7,6 +7,8 @@ import typing as t +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -15,11 +17,11 @@ class Params(base.ParamsModelBase): """Parameters model for :obj:`app.bsky.feed.getFeedGenerators`.""" - feeds: t.List[str] #: Feeds. + feeds: t.List[string_formats.AtUri] #: Feeds. class ParamsDict(t.TypedDict): - feeds: t.List[str] #: Feeds. + feeds: t.List[string_formats.AtUri] #: Feeds. class Response(base.ResponseModelBase): diff --git a/packages/atproto_client/models/app/bsky/feed/get_feed_skeleton.py b/packages/atproto_client/models/app/bsky/feed/get_feed_skeleton.py index 33533b3c..59770f5e 100644 --- a/packages/atproto_client/models/app/bsky/feed/get_feed_skeleton.py +++ b/packages/atproto_client/models/app/bsky/feed/get_feed_skeleton.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -18,13 +20,13 @@ class Params(base.ParamsModelBase): """Parameters model for :obj:`app.bsky.feed.getFeedSkeleton`.""" - feed: str #: Reference to feed generator record describing the specific feed being requested. + feed: string_formats.AtUri #: Reference to feed generator record describing the specific feed being requested. cursor: t.Optional[str] = None #: Cursor. limit: t.Optional[int] = Field(default=50, ge=1, le=100) #: Limit. class ParamsDict(t.TypedDict): - feed: str #: Reference to feed generator record describing the specific feed being requested. + feed: string_formats.AtUri #: Reference to feed generator record describing the specific feed being requested. cursor: te.NotRequired[t.Optional[str]] #: Cursor. limit: te.NotRequired[t.Optional[int]] #: Limit. diff --git a/packages/atproto_client/models/app/bsky/feed/get_likes.py b/packages/atproto_client/models/app/bsky/feed/get_likes.py index 9827f173..a815650f 100644 --- a/packages/atproto_client/models/app/bsky/feed/get_likes.py +++ b/packages/atproto_client/models/app/bsky/feed/get_likes.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -18,16 +20,18 @@ class Params(base.ParamsModelBase): """Parameters model for :obj:`app.bsky.feed.getLikes`.""" - uri: str #: AT-URI of the subject (eg, a post record). - cid: t.Optional[str] = None #: CID of the subject record (aka, specific version of record), to filter likes. + uri: string_formats.AtUri #: AT-URI of the subject (eg, a post record). + cid: t.Optional[string_formats.Cid] = ( + None #: CID of the subject record (aka, specific version of record), to filter likes. + ) cursor: t.Optional[str] = None #: Cursor. limit: t.Optional[int] = Field(default=50, ge=1, le=100) #: Limit. class ParamsDict(t.TypedDict): - uri: str #: AT-URI of the subject (eg, a post record). + uri: string_formats.AtUri #: AT-URI of the subject (eg, a post record). cid: te.NotRequired[ - t.Optional[str] + t.Optional[string_formats.Cid] ] #: CID of the subject record (aka, specific version of record), to filter likes. cursor: te.NotRequired[t.Optional[str]] #: Cursor. limit: te.NotRequired[t.Optional[int]] #: Limit. @@ -37,8 +41,8 @@ class Response(base.ResponseModelBase): """Output data model for :obj:`app.bsky.feed.getLikes`.""" likes: t.List['models.AppBskyFeedGetLikes.Like'] #: Likes. - uri: str #: Uri. - cid: t.Optional[str] = None #: Cid. + uri: string_formats.AtUri #: Uri. + cid: t.Optional[string_formats.Cid] = None #: Cid. cursor: t.Optional[str] = None #: Cursor. @@ -46,8 +50,8 @@ class Like(base.ModelBase): """Definition model for :obj:`app.bsky.feed.getLikes`.""" actor: 'models.AppBskyActorDefs.ProfileView' #: Actor. - created_at: str #: Created at. - indexed_at: str #: Indexed at. + created_at: string_formats.DateTime #: Created at. + indexed_at: string_formats.DateTime #: Indexed at. py_type: t.Literal['app.bsky.feed.getLikes#like'] = Field( default='app.bsky.feed.getLikes#like', alias='$type', frozen=True diff --git a/packages/atproto_client/models/app/bsky/feed/get_list_feed.py b/packages/atproto_client/models/app/bsky/feed/get_list_feed.py index a42b6999..1ae01ff4 100644 --- a/packages/atproto_client/models/app/bsky/feed/get_list_feed.py +++ b/packages/atproto_client/models/app/bsky/feed/get_list_feed.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -18,13 +20,13 @@ class Params(base.ParamsModelBase): """Parameters model for :obj:`app.bsky.feed.getListFeed`.""" - list: str #: Reference (AT-URI) to the list record. + list: string_formats.AtUri #: Reference (AT-URI) to the list record. cursor: t.Optional[str] = None #: Cursor. limit: t.Optional[int] = Field(default=50, ge=1, le=100) #: Limit. class ParamsDict(t.TypedDict): - list: str #: Reference (AT-URI) to the list record. + list: string_formats.AtUri #: Reference (AT-URI) to the list record. cursor: te.NotRequired[t.Optional[str]] #: Cursor. limit: te.NotRequired[t.Optional[int]] #: Limit. diff --git a/packages/atproto_client/models/app/bsky/feed/get_post_thread.py b/packages/atproto_client/models/app/bsky/feed/get_post_thread.py index c0ea4cf0..6663c527 100644 --- a/packages/atproto_client/models/app/bsky/feed/get_post_thread.py +++ b/packages/atproto_client/models/app/bsky/feed/get_post_thread.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -18,7 +20,7 @@ class Params(base.ParamsModelBase): """Parameters model for :obj:`app.bsky.feed.getPostThread`.""" - uri: str #: Reference (AT-URI) to post record. + uri: string_formats.AtUri #: Reference (AT-URI) to post record. depth: t.Optional[int] = Field( default=6, ge=0, le=1000 ) #: How many levels of reply depth should be included in response. @@ -28,7 +30,7 @@ class Params(base.ParamsModelBase): class ParamsDict(t.TypedDict): - uri: str #: Reference (AT-URI) to post record. + uri: string_formats.AtUri #: Reference (AT-URI) to post record. depth: te.NotRequired[t.Optional[int]] #: How many levels of reply depth should be included in response. parent_height: te.NotRequired[t.Optional[int]] #: How many levels of parent (and grandparent, etc) post to include. diff --git a/packages/atproto_client/models/app/bsky/feed/get_posts.py b/packages/atproto_client/models/app/bsky/feed/get_posts.py index 92992c1a..daee350d 100644 --- a/packages/atproto_client/models/app/bsky/feed/get_posts.py +++ b/packages/atproto_client/models/app/bsky/feed/get_posts.py @@ -9,6 +9,8 @@ from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -17,11 +19,11 @@ class Params(base.ParamsModelBase): """Parameters model for :obj:`app.bsky.feed.getPosts`.""" - uris: t.List[str] = Field(max_length=25) #: List of post AT-URIs to return hydrated views for. + uris: t.List[string_formats.AtUri] = Field(max_length=25) #: List of post AT-URIs to return hydrated views for. class ParamsDict(t.TypedDict): - uris: t.List[str] #: List of post AT-URIs to return hydrated views for. + uris: t.List[string_formats.AtUri] #: List of post AT-URIs to return hydrated views for. class Response(base.ResponseModelBase): diff --git a/packages/atproto_client/models/app/bsky/feed/get_quotes.py b/packages/atproto_client/models/app/bsky/feed/get_quotes.py index 01f64259..fad47d65 100644 --- a/packages/atproto_client/models/app/bsky/feed/get_quotes.py +++ b/packages/atproto_client/models/app/bsky/feed/get_quotes.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -18,16 +20,18 @@ class Params(base.ParamsModelBase): """Parameters model for :obj:`app.bsky.feed.getQuotes`.""" - uri: str #: Reference (AT-URI) of post record. - cid: t.Optional[str] = None #: If supplied, filters to quotes of specific version (by CID) of the post record. + uri: string_formats.AtUri #: Reference (AT-URI) of post record. + cid: t.Optional[string_formats.Cid] = ( + None #: If supplied, filters to quotes of specific version (by CID) of the post record. + ) cursor: t.Optional[str] = None #: Cursor. limit: t.Optional[int] = Field(default=50, ge=1, le=100) #: Limit. class ParamsDict(t.TypedDict): - uri: str #: Reference (AT-URI) of post record. + uri: string_formats.AtUri #: Reference (AT-URI) of post record. cid: te.NotRequired[ - t.Optional[str] + t.Optional[string_formats.Cid] ] #: If supplied, filters to quotes of specific version (by CID) of the post record. cursor: te.NotRequired[t.Optional[str]] #: Cursor. limit: te.NotRequired[t.Optional[int]] #: Limit. @@ -37,6 +41,6 @@ class Response(base.ResponseModelBase): """Output data model for :obj:`app.bsky.feed.getQuotes`.""" posts: t.List['models.AppBskyFeedDefs.PostView'] #: Posts. - uri: str #: Uri. - cid: t.Optional[str] = None #: Cid. + uri: string_formats.AtUri #: Uri. + cid: t.Optional[string_formats.Cid] = None #: Cid. cursor: t.Optional[str] = None #: Cursor. diff --git a/packages/atproto_client/models/app/bsky/feed/get_reposted_by.py b/packages/atproto_client/models/app/bsky/feed/get_reposted_by.py index 8169b383..5402c168 100644 --- a/packages/atproto_client/models/app/bsky/feed/get_reposted_by.py +++ b/packages/atproto_client/models/app/bsky/feed/get_reposted_by.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -18,16 +20,18 @@ class Params(base.ParamsModelBase): """Parameters model for :obj:`app.bsky.feed.getRepostedBy`.""" - uri: str #: Reference (AT-URI) of post record. - cid: t.Optional[str] = None #: If supplied, filters to reposts of specific version (by CID) of the post record. + uri: string_formats.AtUri #: Reference (AT-URI) of post record. + cid: t.Optional[string_formats.Cid] = ( + None #: If supplied, filters to reposts of specific version (by CID) of the post record. + ) cursor: t.Optional[str] = None #: Cursor. limit: t.Optional[int] = Field(default=50, ge=1, le=100) #: Limit. class ParamsDict(t.TypedDict): - uri: str #: Reference (AT-URI) of post record. + uri: string_formats.AtUri #: Reference (AT-URI) of post record. cid: te.NotRequired[ - t.Optional[str] + t.Optional[string_formats.Cid] ] #: If supplied, filters to reposts of specific version (by CID) of the post record. cursor: te.NotRequired[t.Optional[str]] #: Cursor. limit: te.NotRequired[t.Optional[int]] #: Limit. @@ -37,6 +41,6 @@ class Response(base.ResponseModelBase): """Output data model for :obj:`app.bsky.feed.getRepostedBy`.""" reposted_by: t.List['models.AppBskyActorDefs.ProfileView'] #: Reposted by. - uri: str #: Uri. - cid: t.Optional[str] = None #: Cid. + uri: string_formats.AtUri #: Uri. + cid: t.Optional[string_formats.Cid] = None #: Cid. cursor: t.Optional[str] = None #: Cursor. diff --git a/packages/atproto_client/models/app/bsky/feed/like.py b/packages/atproto_client/models/app/bsky/feed/like.py index a17e0616..63ad1b72 100644 --- a/packages/atproto_client/models/app/bsky/feed/like.py +++ b/packages/atproto_client/models/app/bsky/feed/like.py @@ -9,6 +9,8 @@ from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -17,7 +19,7 @@ class Record(base.RecordModelBase): """Record model for :obj:`app.bsky.feed.like`.""" - created_at: str #: Created at. + created_at: string_formats.DateTime #: Created at. subject: 'models.ComAtprotoRepoStrongRef.Main' #: Subject. py_type: t.Literal['app.bsky.feed.like'] = Field(default='app.bsky.feed.like', alias='$type', frozen=True) diff --git a/packages/atproto_client/models/app/bsky/feed/post.py b/packages/atproto_client/models/app/bsky/feed/post.py index 22192781..278b6ec1 100644 --- a/packages/atproto_client/models/app/bsky/feed/post.py +++ b/packages/atproto_client/models/app/bsky/feed/post.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -52,7 +54,7 @@ class TextSlice(base.ModelBase): class Record(base.RecordModelBase): """Record model for :obj:`app.bsky.feed.post`.""" - created_at: str #: Client-declared timestamp when this post was originally created. + created_at: string_formats.DateTime #: Client-declared timestamp when this post was originally created. text: str = Field(max_length=3000) #: The primary post content. May be an empty string, if there are embeds. embed: t.Optional[ te.Annotated[ @@ -75,7 +77,7 @@ class Record(base.RecordModelBase): labels: t.Optional[ te.Annotated[t.Union['models.ComAtprotoLabelDefs.SelfLabels'], Field(default=None, discriminator='py_type')] ] = None #: Self-label values for this post. Effectively content warnings. - langs: t.Optional[t.List[str]] = Field( + langs: t.Optional[t.List[string_formats.Language]] = Field( default=None, max_length=3 ) #: Indicates human language of post primary text content. reply: t.Optional['models.AppBskyFeedPost.ReplyRef'] = None #: Reply. diff --git a/packages/atproto_client/models/app/bsky/feed/postgate.py b/packages/atproto_client/models/app/bsky/feed/postgate.py index a2b2b392..f6367ff6 100644 --- a/packages/atproto_client/models/app/bsky/feed/postgate.py +++ b/packages/atproto_client/models/app/bsky/feed/postgate.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -26,9 +28,9 @@ class DisableRule(base.ModelBase): class Record(base.RecordModelBase): """Record model for :obj:`app.bsky.feed.postgate`.""" - created_at: str #: Created at. - post: str #: Reference (AT-URI) to the post record. - detached_embedding_uris: t.Optional[t.List[str]] = Field( + created_at: string_formats.DateTime #: Created at. + post: string_formats.AtUri #: Reference (AT-URI) to the post record. + detached_embedding_uris: t.Optional[t.List[string_formats.AtUri]] = Field( default=None, max_length=50 ) #: List of AT-URIs embedding this post that the author has detached from. embedding_rules: t.Optional[ diff --git a/packages/atproto_client/models/app/bsky/feed/repost.py b/packages/atproto_client/models/app/bsky/feed/repost.py index 71aec622..f20ce983 100644 --- a/packages/atproto_client/models/app/bsky/feed/repost.py +++ b/packages/atproto_client/models/app/bsky/feed/repost.py @@ -9,6 +9,8 @@ from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -17,7 +19,7 @@ class Record(base.RecordModelBase): """Record model for :obj:`app.bsky.feed.repost`.""" - created_at: str #: Created at. + created_at: string_formats.DateTime #: Created at. subject: 'models.ComAtprotoRepoStrongRef.Main' #: Subject. py_type: t.Literal['app.bsky.feed.repost'] = Field(default='app.bsky.feed.repost', alias='$type', frozen=True) diff --git a/packages/atproto_client/models/app/bsky/feed/search_posts.py b/packages/atproto_client/models/app/bsky/feed/search_posts.py index 501c45ca..8bce0f7e 100644 --- a/packages/atproto_client/models/app/bsky/feed/search_posts.py +++ b/packages/atproto_client/models/app/bsky/feed/search_posts.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -19,7 +21,7 @@ class Params(base.ParamsModelBase): """Parameters model for :obj:`app.bsky.feed.searchPosts`.""" q: str #: Search query string; syntax, phrase, boolean, and faceting is unspecified, but Lucene query syntax is recommended. - author: t.Optional[str] = ( + author: t.Optional[string_formats.Handle] = ( None #: Filter to posts by the given account. Handles are resolved to DID before query-time. ) cursor: t.Optional[str] = ( @@ -28,11 +30,11 @@ class Params(base.ParamsModelBase): domain: t.Optional[str] = ( None #: Filter to posts with URLs (facet links or embeds) linking to the given domain (hostname). Server may apply hostname normalization. ) - lang: t.Optional[str] = ( + lang: t.Optional[string_formats.Language] = ( None #: Filter to posts in the given language. Expected to be based on post language field, though server may override language detection. ) limit: t.Optional[int] = Field(default=25, ge=1, le=100) #: Limit. - mentions: t.Optional[str] = ( + mentions: t.Optional[string_formats.Handle] = ( None #: Filter to posts which mention the given account. Handles are resolved to DID before query-time. Only matches rich-text facet mentions. ) since: t.Optional[str] = ( @@ -47,7 +49,7 @@ class Params(base.ParamsModelBase): until: t.Optional[str] = ( None #: Filter results for posts before the indicated datetime (not inclusive). Expected to use 'sortAt' timestamp, which may not match 'createdAt'. Can be a datetime, or just an ISO date (YYY-MM-DD). ) - url: t.Optional[str] = ( + url: t.Optional[string_formats.Uri] = ( None #: Filter to posts with links (facet links or embeds) pointing to this URL. Server may apply URL normalization or fuzzy matching. ) @@ -55,7 +57,7 @@ class Params(base.ParamsModelBase): class ParamsDict(t.TypedDict): q: str #: Search query string; syntax, phrase, boolean, and faceting is unspecified, but Lucene query syntax is recommended. author: te.NotRequired[ - t.Optional[str] + t.Optional[string_formats.Handle] ] #: Filter to posts by the given account. Handles are resolved to DID before query-time. cursor: te.NotRequired[ t.Optional[str] @@ -64,11 +66,11 @@ class ParamsDict(t.TypedDict): t.Optional[str] ] #: Filter to posts with URLs (facet links or embeds) linking to the given domain (hostname). Server may apply hostname normalization. lang: te.NotRequired[ - t.Optional[str] + t.Optional[string_formats.Language] ] #: Filter to posts in the given language. Expected to be based on post language field, though server may override language detection. limit: te.NotRequired[t.Optional[int]] #: Limit. mentions: te.NotRequired[ - t.Optional[str] + t.Optional[string_formats.Handle] ] #: Filter to posts which mention the given account. Handles are resolved to DID before query-time. Only matches rich-text facet mentions. since: te.NotRequired[ t.Optional[str] @@ -83,7 +85,7 @@ class ParamsDict(t.TypedDict): t.Optional[str] ] #: Filter results for posts before the indicated datetime (not inclusive). Expected to use 'sortAt' timestamp, which may not match 'createdAt'. Can be a datetime, or just an ISO date (YYY-MM-DD). url: te.NotRequired[ - t.Optional[str] + t.Optional[string_formats.Uri] ] #: Filter to posts with links (facet links or embeds) pointing to this URL. Server may apply URL normalization or fuzzy matching. diff --git a/packages/atproto_client/models/app/bsky/feed/threadgate.py b/packages/atproto_client/models/app/bsky/feed/threadgate.py index f2cd40d7..9f9055a5 100644 --- a/packages/atproto_client/models/app/bsky/feed/threadgate.py +++ b/packages/atproto_client/models/app/bsky/feed/threadgate.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -34,7 +36,7 @@ class FollowingRule(base.ModelBase): class ListRule(base.ModelBase): """Definition model for :obj:`app.bsky.feed.threadgate`. Allow replies from actors on a list.""" - list: str #: List. + list: string_formats.AtUri #: List. py_type: t.Literal['app.bsky.feed.threadgate#listRule'] = Field( default='app.bsky.feed.threadgate#listRule', alias='$type', frozen=True @@ -44,8 +46,8 @@ class ListRule(base.ModelBase): class Record(base.RecordModelBase): """Record model for :obj:`app.bsky.feed.threadgate`.""" - created_at: str #: Created at. - post: str #: Reference (AT-URI) to the post record. + created_at: string_formats.DateTime #: Created at. + post: string_formats.AtUri #: Reference (AT-URI) to the post record. allow: t.Optional[ t.List[ te.Annotated[ @@ -58,7 +60,9 @@ class Record(base.RecordModelBase): ] ] ] = Field(default=None, max_length=5) #: Allow. - hidden_replies: t.Optional[t.List[str]] = Field(default=None, max_length=50) #: List of hidden reply URIs. + hidden_replies: t.Optional[t.List[string_formats.AtUri]] = Field( + default=None, max_length=50 + ) #: List of hidden reply URIs. py_type: t.Literal['app.bsky.feed.threadgate'] = Field( default='app.bsky.feed.threadgate', alias='$type', frozen=True diff --git a/packages/atproto_client/models/app/bsky/graph/block.py b/packages/atproto_client/models/app/bsky/graph/block.py index ba4a4c1d..cce95d96 100644 --- a/packages/atproto_client/models/app/bsky/graph/block.py +++ b/packages/atproto_client/models/app/bsky/graph/block.py @@ -9,6 +9,8 @@ from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -17,8 +19,8 @@ class Record(base.RecordModelBase): """Record model for :obj:`app.bsky.graph.block`.""" - created_at: str #: Created at. - subject: str #: DID of the account to be blocked. + created_at: string_formats.DateTime #: Created at. + subject: string_formats.Did #: DID of the account to be blocked. py_type: t.Literal['app.bsky.graph.block'] = Field(default='app.bsky.graph.block', alias='$type', frozen=True) diff --git a/packages/atproto_client/models/app/bsky/graph/defs.py b/packages/atproto_client/models/app/bsky/graph/defs.py index 2faf277f..4390cf71 100644 --- a/packages/atproto_client/models/app/bsky/graph/defs.py +++ b/packages/atproto_client/models/app/bsky/graph/defs.py @@ -9,6 +9,8 @@ from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models.unknown_type import UnknownType @@ -18,12 +20,12 @@ class ListViewBasic(base.ModelBase): """Definition model for :obj:`app.bsky.graph.defs`.""" - cid: str #: Cid. + cid: string_formats.Cid #: Cid. name: str = Field(min_length=1, max_length=64) #: Name. purpose: 'models.AppBskyGraphDefs.ListPurpose' #: Purpose. - uri: str #: Uri. - avatar: t.Optional[str] = None #: Avatar. - indexed_at: t.Optional[str] = None #: Indexed at. + uri: string_formats.AtUri #: Uri. + avatar: t.Optional[string_formats.Uri] = None #: Avatar. + indexed_at: t.Optional[string_formats.DateTime] = None #: Indexed at. labels: t.Optional[t.List['models.ComAtprotoLabelDefs.Label']] = None #: Labels. list_item_count: t.Optional[int] = Field(default=None, ge=0) #: List item count. viewer: t.Optional['models.AppBskyGraphDefs.ListViewerState'] = None #: Viewer. @@ -36,13 +38,13 @@ class ListViewBasic(base.ModelBase): class ListView(base.ModelBase): """Definition model for :obj:`app.bsky.graph.defs`.""" - cid: str #: Cid. + cid: string_formats.Cid #: Cid. creator: 'models.AppBskyActorDefs.ProfileView' #: Creator. - indexed_at: str #: Indexed at. + indexed_at: string_formats.DateTime #: Indexed at. name: str = Field(min_length=1, max_length=64) #: Name. purpose: 'models.AppBskyGraphDefs.ListPurpose' #: Purpose. - uri: str #: Uri. - avatar: t.Optional[str] = None #: Avatar. + uri: string_formats.AtUri #: Uri. + avatar: t.Optional[string_formats.Uri] = None #: Avatar. description: t.Optional[str] = Field(default=None, max_length=3000) #: Description. description_facets: t.Optional[t.List['models.AppBskyRichtextFacet.Main']] = None #: Description facets. labels: t.Optional[t.List['models.ComAtprotoLabelDefs.Label']] = None #: Labels. @@ -58,7 +60,7 @@ class ListItemView(base.ModelBase): """Definition model for :obj:`app.bsky.graph.defs`.""" subject: 'models.AppBskyActorDefs.ProfileView' #: Subject. - uri: str #: Uri. + uri: string_formats.AtUri #: Uri. py_type: t.Literal['app.bsky.graph.defs#listItemView'] = Field( default='app.bsky.graph.defs#listItemView', alias='$type', frozen=True @@ -68,11 +70,11 @@ class ListItemView(base.ModelBase): class StarterPackView(base.ModelBase): """Definition model for :obj:`app.bsky.graph.defs`.""" - cid: str #: Cid. + cid: string_formats.Cid #: Cid. creator: 'models.AppBskyActorDefs.ProfileViewBasic' #: Creator. - indexed_at: str #: Indexed at. + indexed_at: string_formats.DateTime #: Indexed at. record: 'UnknownType' #: Record. - uri: str #: Uri. + uri: string_formats.AtUri #: Uri. feeds: t.Optional[t.List['models.AppBskyFeedDefs.GeneratorView']] = Field(default=None, max_length=3) #: Feeds. joined_all_time_count: t.Optional[int] = Field(default=None, ge=0) #: Joined all time count. joined_week_count: t.Optional[int] = Field(default=None, ge=0) #: Joined week count. @@ -90,11 +92,11 @@ class StarterPackView(base.ModelBase): class StarterPackViewBasic(base.ModelBase): """Definition model for :obj:`app.bsky.graph.defs`.""" - cid: str #: Cid. + cid: string_formats.Cid #: Cid. creator: 'models.AppBskyActorDefs.ProfileViewBasic' #: Creator. - indexed_at: str #: Indexed at. + indexed_at: string_formats.DateTime #: Indexed at. record: 'UnknownType' #: Record. - uri: str #: Uri. + uri: string_formats.AtUri #: Uri. joined_all_time_count: t.Optional[int] = Field(default=None, ge=0) #: Joined all time count. joined_week_count: t.Optional[int] = Field(default=None, ge=0) #: Joined week count. labels: t.Optional[t.List['models.ComAtprotoLabelDefs.Label']] = None #: Labels. @@ -128,7 +130,7 @@ class StarterPackViewBasic(base.ModelBase): class ListViewerState(base.ModelBase): """Definition model for :obj:`app.bsky.graph.defs`.""" - blocked: t.Optional[str] = None #: Blocked. + blocked: t.Optional[string_formats.AtUri] = None #: Blocked. muted: t.Optional[bool] = None #: Muted. py_type: t.Literal['app.bsky.graph.defs#listViewerState'] = Field( @@ -139,7 +141,7 @@ class ListViewerState(base.ModelBase): class NotFoundActor(base.ModelBase): """Definition model for :obj:`app.bsky.graph.defs`. indicates that a handle or DID could not be resolved.""" - actor: str #: Actor. + actor: string_formats.Handle #: Actor. not_found: bool = Field(frozen=True) #: Not found. py_type: t.Literal['app.bsky.graph.defs#notFoundActor'] = Field( @@ -150,11 +152,13 @@ class NotFoundActor(base.ModelBase): class Relationship(base.ModelBase): """Definition model for :obj:`app.bsky.graph.defs`. lists the bi-directional graph relationships between one actor (not indicated in the object), and the target actors (the DID included in the object).""" - did: str #: Did. - followed_by: t.Optional[str] = ( + did: string_formats.Did #: Did. + followed_by: t.Optional[string_formats.AtUri] = ( None #: if the actor is followed by this DID, contains the AT-URI of the follow record. ) - following: t.Optional[str] = None #: if the actor follows this DID, this is the AT-URI of the follow record. + following: t.Optional[string_formats.AtUri] = ( + None #: if the actor follows this DID, this is the AT-URI of the follow record. + ) py_type: t.Literal['app.bsky.graph.defs#relationship'] = Field( default='app.bsky.graph.defs#relationship', alias='$type', frozen=True diff --git a/packages/atproto_client/models/app/bsky/graph/follow.py b/packages/atproto_client/models/app/bsky/graph/follow.py index c6039d53..c84c9dba 100644 --- a/packages/atproto_client/models/app/bsky/graph/follow.py +++ b/packages/atproto_client/models/app/bsky/graph/follow.py @@ -9,6 +9,8 @@ from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -17,8 +19,8 @@ class Record(base.RecordModelBase): """Record model for :obj:`app.bsky.graph.follow`.""" - created_at: str #: Created at. - subject: str #: Subject. + created_at: string_formats.DateTime #: Created at. + subject: string_formats.Did #: Subject. py_type: t.Literal['app.bsky.graph.follow'] = Field(default='app.bsky.graph.follow', alias='$type', frozen=True) diff --git a/packages/atproto_client/models/app/bsky/graph/get_actor_starter_packs.py b/packages/atproto_client/models/app/bsky/graph/get_actor_starter_packs.py index 9b33574b..567e54f4 100644 --- a/packages/atproto_client/models/app/bsky/graph/get_actor_starter_packs.py +++ b/packages/atproto_client/models/app/bsky/graph/get_actor_starter_packs.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -18,13 +20,13 @@ class Params(base.ParamsModelBase): """Parameters model for :obj:`app.bsky.graph.getActorStarterPacks`.""" - actor: str #: Actor. + actor: string_formats.Handle #: Actor. cursor: t.Optional[str] = None #: Cursor. limit: t.Optional[int] = Field(default=50, ge=1, le=100) #: Limit. class ParamsDict(t.TypedDict): - actor: str #: Actor. + actor: string_formats.Handle #: Actor. cursor: te.NotRequired[t.Optional[str]] #: Cursor. limit: te.NotRequired[t.Optional[int]] #: Limit. diff --git a/packages/atproto_client/models/app/bsky/graph/get_followers.py b/packages/atproto_client/models/app/bsky/graph/get_followers.py index 862177fb..550c4702 100644 --- a/packages/atproto_client/models/app/bsky/graph/get_followers.py +++ b/packages/atproto_client/models/app/bsky/graph/get_followers.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -18,13 +20,13 @@ class Params(base.ParamsModelBase): """Parameters model for :obj:`app.bsky.graph.getFollowers`.""" - actor: str #: Actor. + actor: string_formats.Handle #: Actor. cursor: t.Optional[str] = None #: Cursor. limit: t.Optional[int] = Field(default=50, ge=1, le=100) #: Limit. class ParamsDict(t.TypedDict): - actor: str #: Actor. + actor: string_formats.Handle #: Actor. cursor: te.NotRequired[t.Optional[str]] #: Cursor. limit: te.NotRequired[t.Optional[int]] #: Limit. diff --git a/packages/atproto_client/models/app/bsky/graph/get_follows.py b/packages/atproto_client/models/app/bsky/graph/get_follows.py index 45ba1e2b..794174c2 100644 --- a/packages/atproto_client/models/app/bsky/graph/get_follows.py +++ b/packages/atproto_client/models/app/bsky/graph/get_follows.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -18,13 +20,13 @@ class Params(base.ParamsModelBase): """Parameters model for :obj:`app.bsky.graph.getFollows`.""" - actor: str #: Actor. + actor: string_formats.Handle #: Actor. cursor: t.Optional[str] = None #: Cursor. limit: t.Optional[int] = Field(default=50, ge=1, le=100) #: Limit. class ParamsDict(t.TypedDict): - actor: str #: Actor. + actor: string_formats.Handle #: Actor. cursor: te.NotRequired[t.Optional[str]] #: Cursor. limit: te.NotRequired[t.Optional[int]] #: Limit. diff --git a/packages/atproto_client/models/app/bsky/graph/get_known_followers.py b/packages/atproto_client/models/app/bsky/graph/get_known_followers.py index c0e6bf9d..ddb75a55 100644 --- a/packages/atproto_client/models/app/bsky/graph/get_known_followers.py +++ b/packages/atproto_client/models/app/bsky/graph/get_known_followers.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -18,13 +20,13 @@ class Params(base.ParamsModelBase): """Parameters model for :obj:`app.bsky.graph.getKnownFollowers`.""" - actor: str #: Actor. + actor: string_formats.Handle #: Actor. cursor: t.Optional[str] = None #: Cursor. limit: t.Optional[int] = Field(default=50, ge=1, le=100) #: Limit. class ParamsDict(t.TypedDict): - actor: str #: Actor. + actor: string_formats.Handle #: Actor. cursor: te.NotRequired[t.Optional[str]] #: Cursor. limit: te.NotRequired[t.Optional[int]] #: Limit. diff --git a/packages/atproto_client/models/app/bsky/graph/get_list.py b/packages/atproto_client/models/app/bsky/graph/get_list.py index 125bdcac..4d43a0ff 100644 --- a/packages/atproto_client/models/app/bsky/graph/get_list.py +++ b/packages/atproto_client/models/app/bsky/graph/get_list.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -18,13 +20,13 @@ class Params(base.ParamsModelBase): """Parameters model for :obj:`app.bsky.graph.getList`.""" - list: str #: Reference (AT-URI) of the list record to hydrate. + list: string_formats.AtUri #: Reference (AT-URI) of the list record to hydrate. cursor: t.Optional[str] = None #: Cursor. limit: t.Optional[int] = Field(default=50, ge=1, le=100) #: Limit. class ParamsDict(t.TypedDict): - list: str #: Reference (AT-URI) of the list record to hydrate. + list: string_formats.AtUri #: Reference (AT-URI) of the list record to hydrate. cursor: te.NotRequired[t.Optional[str]] #: Cursor. limit: te.NotRequired[t.Optional[int]] #: Limit. diff --git a/packages/atproto_client/models/app/bsky/graph/get_lists.py b/packages/atproto_client/models/app/bsky/graph/get_lists.py index acd0d91e..ad09db12 100644 --- a/packages/atproto_client/models/app/bsky/graph/get_lists.py +++ b/packages/atproto_client/models/app/bsky/graph/get_lists.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -18,13 +20,13 @@ class Params(base.ParamsModelBase): """Parameters model for :obj:`app.bsky.graph.getLists`.""" - actor: str #: The account (actor) to enumerate lists from. + actor: string_formats.Handle #: The account (actor) to enumerate lists from. cursor: t.Optional[str] = None #: Cursor. limit: t.Optional[int] = Field(default=50, ge=1, le=100) #: Limit. class ParamsDict(t.TypedDict): - actor: str #: The account (actor) to enumerate lists from. + actor: string_formats.Handle #: The account (actor) to enumerate lists from. cursor: te.NotRequired[t.Optional[str]] #: Cursor. limit: te.NotRequired[t.Optional[int]] #: Limit. diff --git a/packages/atproto_client/models/app/bsky/graph/get_relationships.py b/packages/atproto_client/models/app/bsky/graph/get_relationships.py index c8b46ccf..48ce0a80 100644 --- a/packages/atproto_client/models/app/bsky/graph/get_relationships.py +++ b/packages/atproto_client/models/app/bsky/graph/get_relationships.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -18,15 +20,17 @@ class Params(base.ParamsModelBase): """Parameters model for :obj:`app.bsky.graph.getRelationships`.""" - actor: str #: Primary account requesting relationships for. - others: t.Optional[t.List[str]] = Field( + actor: string_formats.Handle #: Primary account requesting relationships for. + others: t.Optional[t.List[string_formats.Handle]] = Field( default=None, max_length=30 ) #: List of 'other' accounts to be related back to the primary. class ParamsDict(t.TypedDict): - actor: str #: Primary account requesting relationships for. - others: te.NotRequired[t.Optional[t.List[str]]] #: List of 'other' accounts to be related back to the primary. + actor: string_formats.Handle #: Primary account requesting relationships for. + others: te.NotRequired[ + t.Optional[t.List[string_formats.Handle]] + ] #: List of 'other' accounts to be related back to the primary. class Response(base.ResponseModelBase): @@ -38,4 +42,4 @@ class Response(base.ResponseModelBase): Field(discriminator='py_type'), ] ] #: Relationships. - actor: t.Optional[str] = None #: Actor. + actor: t.Optional[string_formats.Did] = None #: Actor. diff --git a/packages/atproto_client/models/app/bsky/graph/get_starter_pack.py b/packages/atproto_client/models/app/bsky/graph/get_starter_pack.py index 8feedff9..34f2c4b1 100644 --- a/packages/atproto_client/models/app/bsky/graph/get_starter_pack.py +++ b/packages/atproto_client/models/app/bsky/graph/get_starter_pack.py @@ -7,6 +7,8 @@ import typing as t +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -15,11 +17,11 @@ class Params(base.ParamsModelBase): """Parameters model for :obj:`app.bsky.graph.getStarterPack`.""" - starter_pack: str #: Reference (AT-URI) of the starter pack record. + starter_pack: string_formats.AtUri #: Reference (AT-URI) of the starter pack record. class ParamsDict(t.TypedDict): - starter_pack: str #: Reference (AT-URI) of the starter pack record. + starter_pack: string_formats.AtUri #: Reference (AT-URI) of the starter pack record. class Response(base.ResponseModelBase): diff --git a/packages/atproto_client/models/app/bsky/graph/get_starter_packs.py b/packages/atproto_client/models/app/bsky/graph/get_starter_packs.py index 4632d6ce..3d705d6c 100644 --- a/packages/atproto_client/models/app/bsky/graph/get_starter_packs.py +++ b/packages/atproto_client/models/app/bsky/graph/get_starter_packs.py @@ -9,6 +9,8 @@ from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -17,11 +19,11 @@ class Params(base.ParamsModelBase): """Parameters model for :obj:`app.bsky.graph.getStarterPacks`.""" - uris: t.List[str] = Field(max_length=25) #: Uris. + uris: t.List[string_formats.AtUri] = Field(max_length=25) #: Uris. class ParamsDict(t.TypedDict): - uris: t.List[str] #: Uris. + uris: t.List[string_formats.AtUri] #: Uris. class Response(base.ResponseModelBase): diff --git a/packages/atproto_client/models/app/bsky/graph/get_suggested_follows_by_actor.py b/packages/atproto_client/models/app/bsky/graph/get_suggested_follows_by_actor.py index 5ad3a751..ff4e53df 100644 --- a/packages/atproto_client/models/app/bsky/graph/get_suggested_follows_by_actor.py +++ b/packages/atproto_client/models/app/bsky/graph/get_suggested_follows_by_actor.py @@ -7,6 +7,8 @@ import typing as t +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -15,11 +17,11 @@ class Params(base.ParamsModelBase): """Parameters model for :obj:`app.bsky.graph.getSuggestedFollowsByActor`.""" - actor: str #: Actor. + actor: string_formats.Handle #: Actor. class ParamsDict(t.TypedDict): - actor: str #: Actor. + actor: string_formats.Handle #: Actor. class Response(base.ResponseModelBase): diff --git a/packages/atproto_client/models/app/bsky/graph/list.py b/packages/atproto_client/models/app/bsky/graph/list.py index 89c4acae..808b29a5 100644 --- a/packages/atproto_client/models/app/bsky/graph/list.py +++ b/packages/atproto_client/models/app/bsky/graph/list.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models.blob_ref import BlobRef @@ -19,7 +21,7 @@ class Record(base.RecordModelBase): """Record model for :obj:`app.bsky.graph.list`.""" - created_at: str #: Created at. + created_at: string_formats.DateTime #: Created at. name: str = Field(min_length=1, max_length=64) #: Display name for list; can not be empty. purpose: 'models.AppBskyGraphDefs.ListPurpose' #: Defines the purpose of the list (aka, moderation-oriented or curration-oriented). avatar: t.Optional['BlobRef'] = None #: Avatar. diff --git a/packages/atproto_client/models/app/bsky/graph/listblock.py b/packages/atproto_client/models/app/bsky/graph/listblock.py index 8fe4cde3..116d6e98 100644 --- a/packages/atproto_client/models/app/bsky/graph/listblock.py +++ b/packages/atproto_client/models/app/bsky/graph/listblock.py @@ -9,6 +9,8 @@ from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -17,8 +19,8 @@ class Record(base.RecordModelBase): """Record model for :obj:`app.bsky.graph.listblock`.""" - created_at: str #: Created at. - subject: str #: Reference (AT-URI) to the mod list record. + created_at: string_formats.DateTime #: Created at. + subject: string_formats.AtUri #: Reference (AT-URI) to the mod list record. py_type: t.Literal['app.bsky.graph.listblock'] = Field( default='app.bsky.graph.listblock', alias='$type', frozen=True diff --git a/packages/atproto_client/models/app/bsky/graph/listitem.py b/packages/atproto_client/models/app/bsky/graph/listitem.py index 718f1a56..8b446ba1 100644 --- a/packages/atproto_client/models/app/bsky/graph/listitem.py +++ b/packages/atproto_client/models/app/bsky/graph/listitem.py @@ -9,6 +9,8 @@ from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -17,9 +19,9 @@ class Record(base.RecordModelBase): """Record model for :obj:`app.bsky.graph.listitem`.""" - created_at: str #: Created at. - list: str #: Reference (AT-URI) to the list record (app.bsky.graph.list). - subject: str #: The account which is included on the list. + created_at: string_formats.DateTime #: Created at. + list: string_formats.AtUri #: Reference (AT-URI) to the list record (app.bsky.graph.list). + subject: string_formats.Did #: The account which is included on the list. py_type: t.Literal['app.bsky.graph.listitem'] = Field(default='app.bsky.graph.listitem', alias='$type', frozen=True) diff --git a/packages/atproto_client/models/app/bsky/graph/mute_actor.py b/packages/atproto_client/models/app/bsky/graph/mute_actor.py index 61ccf955..a602496e 100644 --- a/packages/atproto_client/models/app/bsky/graph/mute_actor.py +++ b/packages/atproto_client/models/app/bsky/graph/mute_actor.py @@ -7,14 +7,14 @@ import typing as t -from atproto_client.models import base +from atproto_client.models import base, string_formats class Data(base.DataModelBase): """Input data model for :obj:`app.bsky.graph.muteActor`.""" - actor: str #: Actor. + actor: string_formats.Handle #: Actor. class DataDict(t.TypedDict): - actor: str #: Actor. + actor: string_formats.Handle #: Actor. diff --git a/packages/atproto_client/models/app/bsky/graph/mute_actor_list.py b/packages/atproto_client/models/app/bsky/graph/mute_actor_list.py index e4e487ee..ab213a3f 100644 --- a/packages/atproto_client/models/app/bsky/graph/mute_actor_list.py +++ b/packages/atproto_client/models/app/bsky/graph/mute_actor_list.py @@ -7,14 +7,14 @@ import typing as t -from atproto_client.models import base +from atproto_client.models import base, string_formats class Data(base.DataModelBase): """Input data model for :obj:`app.bsky.graph.muteActorList`.""" - list: str #: List. + list: string_formats.AtUri #: List. class DataDict(t.TypedDict): - list: str #: List. + list: string_formats.AtUri #: List. diff --git a/packages/atproto_client/models/app/bsky/graph/mute_thread.py b/packages/atproto_client/models/app/bsky/graph/mute_thread.py index 04eb2a00..f432f9d1 100644 --- a/packages/atproto_client/models/app/bsky/graph/mute_thread.py +++ b/packages/atproto_client/models/app/bsky/graph/mute_thread.py @@ -7,14 +7,14 @@ import typing as t -from atproto_client.models import base +from atproto_client.models import base, string_formats class Data(base.DataModelBase): """Input data model for :obj:`app.bsky.graph.muteThread`.""" - root: str #: Root. + root: string_formats.AtUri #: Root. class DataDict(t.TypedDict): - root: str #: Root. + root: string_formats.AtUri #: Root. diff --git a/packages/atproto_client/models/app/bsky/graph/starterpack.py b/packages/atproto_client/models/app/bsky/graph/starterpack.py index ae5bfaba..338e1a3c 100644 --- a/packages/atproto_client/models/app/bsky/graph/starterpack.py +++ b/packages/atproto_client/models/app/bsky/graph/starterpack.py @@ -9,6 +9,8 @@ from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -17,7 +19,7 @@ class FeedItem(base.ModelBase): """Definition model for :obj:`app.bsky.graph.starterpack`.""" - uri: str #: Uri. + uri: string_formats.AtUri #: Uri. py_type: t.Literal['app.bsky.graph.starterpack#feedItem'] = Field( default='app.bsky.graph.starterpack#feedItem', alias='$type', frozen=True @@ -27,8 +29,8 @@ class FeedItem(base.ModelBase): class Record(base.RecordModelBase): """Record model for :obj:`app.bsky.graph.starterpack`.""" - created_at: str #: Created at. - list: str #: Reference (AT-URI) to the list record. + created_at: string_formats.DateTime #: Created at. + list: string_formats.AtUri #: Reference (AT-URI) to the list record. name: str = Field(min_length=1, max_length=500) #: Display name for starter pack; can not be empty. description: t.Optional[str] = Field(default=None, max_length=3000) #: Description. description_facets: t.Optional[t.List['models.AppBskyRichtextFacet.Main']] = None #: Description facets. diff --git a/packages/atproto_client/models/app/bsky/graph/unmute_actor.py b/packages/atproto_client/models/app/bsky/graph/unmute_actor.py index f519e512..c752ee9d 100644 --- a/packages/atproto_client/models/app/bsky/graph/unmute_actor.py +++ b/packages/atproto_client/models/app/bsky/graph/unmute_actor.py @@ -7,14 +7,14 @@ import typing as t -from atproto_client.models import base +from atproto_client.models import base, string_formats class Data(base.DataModelBase): """Input data model for :obj:`app.bsky.graph.unmuteActor`.""" - actor: str #: Actor. + actor: string_formats.Handle #: Actor. class DataDict(t.TypedDict): - actor: str #: Actor. + actor: string_formats.Handle #: Actor. diff --git a/packages/atproto_client/models/app/bsky/graph/unmute_actor_list.py b/packages/atproto_client/models/app/bsky/graph/unmute_actor_list.py index 26a5eadd..a8058e82 100644 --- a/packages/atproto_client/models/app/bsky/graph/unmute_actor_list.py +++ b/packages/atproto_client/models/app/bsky/graph/unmute_actor_list.py @@ -7,14 +7,14 @@ import typing as t -from atproto_client.models import base +from atproto_client.models import base, string_formats class Data(base.DataModelBase): """Input data model for :obj:`app.bsky.graph.unmuteActorList`.""" - list: str #: List. + list: string_formats.AtUri #: List. class DataDict(t.TypedDict): - list: str #: List. + list: string_formats.AtUri #: List. diff --git a/packages/atproto_client/models/app/bsky/graph/unmute_thread.py b/packages/atproto_client/models/app/bsky/graph/unmute_thread.py index bbaa4e63..4115b3ad 100644 --- a/packages/atproto_client/models/app/bsky/graph/unmute_thread.py +++ b/packages/atproto_client/models/app/bsky/graph/unmute_thread.py @@ -7,14 +7,14 @@ import typing as t -from atproto_client.models import base +from atproto_client.models import base, string_formats class Data(base.DataModelBase): """Input data model for :obj:`app.bsky.graph.unmuteThread`.""" - root: str #: Root. + root: string_formats.AtUri #: Root. class DataDict(t.TypedDict): - root: str #: Root. + root: string_formats.AtUri #: Root. diff --git a/packages/atproto_client/models/app/bsky/labeler/defs.py b/packages/atproto_client/models/app/bsky/labeler/defs.py index 1aac833e..ec15588e 100644 --- a/packages/atproto_client/models/app/bsky/labeler/defs.py +++ b/packages/atproto_client/models/app/bsky/labeler/defs.py @@ -9,6 +9,8 @@ from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -17,10 +19,10 @@ class LabelerView(base.ModelBase): """Definition model for :obj:`app.bsky.labeler.defs`.""" - cid: str #: Cid. + cid: string_formats.Cid #: Cid. creator: 'models.AppBskyActorDefs.ProfileView' #: Creator. - indexed_at: str #: Indexed at. - uri: str #: Uri. + indexed_at: string_formats.DateTime #: Indexed at. + uri: string_formats.AtUri #: Uri. labels: t.Optional[t.List['models.ComAtprotoLabelDefs.Label']] = None #: Labels. like_count: t.Optional[int] = Field(default=None, ge=0) #: Like count. viewer: t.Optional['models.AppBskyLabelerDefs.LabelerViewerState'] = None #: Viewer. @@ -33,11 +35,11 @@ class LabelerView(base.ModelBase): class LabelerViewDetailed(base.ModelBase): """Definition model for :obj:`app.bsky.labeler.defs`.""" - cid: str #: Cid. + cid: string_formats.Cid #: Cid. creator: 'models.AppBskyActorDefs.ProfileView' #: Creator. - indexed_at: str #: Indexed at. + indexed_at: string_formats.DateTime #: Indexed at. policies: 'models.AppBskyLabelerDefs.LabelerPolicies' #: Policies. - uri: str #: Uri. + uri: string_formats.AtUri #: Uri. labels: t.Optional[t.List['models.ComAtprotoLabelDefs.Label']] = None #: Labels. like_count: t.Optional[int] = Field(default=None, ge=0) #: Like count. viewer: t.Optional['models.AppBskyLabelerDefs.LabelerViewerState'] = None #: Viewer. @@ -50,7 +52,7 @@ class LabelerViewDetailed(base.ModelBase): class LabelerViewerState(base.ModelBase): """Definition model for :obj:`app.bsky.labeler.defs`.""" - like: t.Optional[str] = None #: Like. + like: t.Optional[string_formats.AtUri] = None #: Like. py_type: t.Literal['app.bsky.labeler.defs#labelerViewerState'] = Field( default='app.bsky.labeler.defs#labelerViewerState', alias='$type', frozen=True diff --git a/packages/atproto_client/models/app/bsky/labeler/get_services.py b/packages/atproto_client/models/app/bsky/labeler/get_services.py index 55ce8f10..279f4edc 100644 --- a/packages/atproto_client/models/app/bsky/labeler/get_services.py +++ b/packages/atproto_client/models/app/bsky/labeler/get_services.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -18,12 +20,12 @@ class Params(base.ParamsModelBase): """Parameters model for :obj:`app.bsky.labeler.getServices`.""" - dids: t.List[str] #: Dids. + dids: t.List[string_formats.Did] #: Dids. detailed: t.Optional[bool] = False #: Detailed. class ParamsDict(t.TypedDict): - dids: t.List[str] #: Dids. + dids: t.List[string_formats.Did] #: Dids. detailed: te.NotRequired[t.Optional[bool]] #: Detailed. diff --git a/packages/atproto_client/models/app/bsky/labeler/service.py b/packages/atproto_client/models/app/bsky/labeler/service.py index 592487e2..c5798e78 100644 --- a/packages/atproto_client/models/app/bsky/labeler/service.py +++ b/packages/atproto_client/models/app/bsky/labeler/service.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -18,7 +20,7 @@ class Record(base.RecordModelBase): """Record model for :obj:`app.bsky.labeler.service`.""" - created_at: str #: Created at. + created_at: string_formats.DateTime #: Created at. policies: 'models.AppBskyLabelerDefs.LabelerPolicies' #: Policies. labels: t.Optional[ te.Annotated[t.Union['models.ComAtprotoLabelDefs.SelfLabels'], Field(default=None, discriminator='py_type')] diff --git a/packages/atproto_client/models/app/bsky/notification/get_unread_count.py b/packages/atproto_client/models/app/bsky/notification/get_unread_count.py index 52ab1b41..b8f82098 100644 --- a/packages/atproto_client/models/app/bsky/notification/get_unread_count.py +++ b/packages/atproto_client/models/app/bsky/notification/get_unread_count.py @@ -9,19 +9,19 @@ import typing_extensions as te -from atproto_client.models import base +from atproto_client.models import base, string_formats class Params(base.ParamsModelBase): """Parameters model for :obj:`app.bsky.notification.getUnreadCount`.""" priority: t.Optional[bool] = None #: Priority. - seen_at: t.Optional[str] = None #: Seen at. + seen_at: t.Optional[string_formats.DateTime] = None #: Seen at. class ParamsDict(t.TypedDict): priority: te.NotRequired[t.Optional[bool]] #: Priority. - seen_at: te.NotRequired[t.Optional[str]] #: Seen at. + seen_at: te.NotRequired[t.Optional[string_formats.DateTime]] #: Seen at. class Response(base.ResponseModelBase): diff --git a/packages/atproto_client/models/app/bsky/notification/list_notifications.py b/packages/atproto_client/models/app/bsky/notification/list_notifications.py index c2edae9c..b0878efc 100644 --- a/packages/atproto_client/models/app/bsky/notification/list_notifications.py +++ b/packages/atproto_client/models/app/bsky/notification/list_notifications.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models.unknown_type import UnknownType @@ -22,14 +24,14 @@ class Params(base.ParamsModelBase): cursor: t.Optional[str] = None #: Cursor. limit: t.Optional[int] = Field(default=50, ge=1, le=100) #: Limit. priority: t.Optional[bool] = None #: Priority. - seen_at: t.Optional[str] = None #: Seen at. + seen_at: t.Optional[string_formats.DateTime] = None #: Seen at. class ParamsDict(t.TypedDict): cursor: te.NotRequired[t.Optional[str]] #: Cursor. limit: te.NotRequired[t.Optional[int]] #: Limit. priority: te.NotRequired[t.Optional[bool]] #: Priority. - seen_at: te.NotRequired[t.Optional[str]] #: Seen at. + seen_at: te.NotRequired[t.Optional[string_formats.DateTime]] #: Seen at. class Response(base.ResponseModelBase): @@ -38,15 +40,15 @@ class Response(base.ResponseModelBase): notifications: t.List['models.AppBskyNotificationListNotifications.Notification'] #: Notifications. cursor: t.Optional[str] = None #: Cursor. priority: t.Optional[bool] = None #: Priority. - seen_at: t.Optional[str] = None #: Seen at. + seen_at: t.Optional[string_formats.DateTime] = None #: Seen at. class Notification(base.ModelBase): """Definition model for :obj:`app.bsky.notification.listNotifications`.""" author: 'models.AppBskyActorDefs.ProfileView' #: Author. - cid: str #: Cid. - indexed_at: str #: Indexed at. + cid: string_formats.Cid #: Cid. + indexed_at: string_formats.DateTime #: Indexed at. is_read: bool #: Is read. reason: t.Union[ t.Literal['like'], @@ -59,9 +61,9 @@ class Notification(base.ModelBase): str, ] #: Expected values are 'like', 'repost', 'follow', 'mention', 'reply', 'quote', and 'starterpack-joined'. record: 'UnknownType' #: Record. - uri: str #: Uri. + uri: string_formats.AtUri #: Uri. labels: t.Optional[t.List['models.ComAtprotoLabelDefs.Label']] = None #: Labels. - reason_subject: t.Optional[str] = None #: Reason subject. + reason_subject: t.Optional[string_formats.AtUri] = None #: Reason subject. py_type: t.Literal['app.bsky.notification.listNotifications#notification'] = Field( default='app.bsky.notification.listNotifications#notification', alias='$type', frozen=True diff --git a/packages/atproto_client/models/app/bsky/notification/register_push.py b/packages/atproto_client/models/app/bsky/notification/register_push.py index 9df06dc3..856f64ac 100644 --- a/packages/atproto_client/models/app/bsky/notification/register_push.py +++ b/packages/atproto_client/models/app/bsky/notification/register_push.py @@ -7,7 +7,7 @@ import typing as t -from atproto_client.models import base +from atproto_client.models import base, string_formats class Data(base.DataModelBase): @@ -15,12 +15,12 @@ class Data(base.DataModelBase): app_id: str #: App id. platform: t.Union[t.Literal['ios'], t.Literal['android'], t.Literal['web'], str] #: Platform. - service_did: str #: Service did. + service_did: string_formats.Did #: Service did. token: str #: Token. class DataDict(t.TypedDict): app_id: str #: App id. platform: t.Union[t.Literal['ios'], t.Literal['android'], t.Literal['web'], str] #: Platform. - service_did: str #: Service did. + service_did: string_formats.Did #: Service did. token: str #: Token. diff --git a/packages/atproto_client/models/app/bsky/notification/update_seen.py b/packages/atproto_client/models/app/bsky/notification/update_seen.py index a39f348c..04f7c211 100644 --- a/packages/atproto_client/models/app/bsky/notification/update_seen.py +++ b/packages/atproto_client/models/app/bsky/notification/update_seen.py @@ -7,14 +7,14 @@ import typing as t -from atproto_client.models import base +from atproto_client.models import base, string_formats class Data(base.DataModelBase): """Input data model for :obj:`app.bsky.notification.updateSeen`.""" - seen_at: str #: Seen at. + seen_at: string_formats.DateTime #: Seen at. class DataDict(t.TypedDict): - seen_at: str #: Seen at. + seen_at: string_formats.DateTime #: Seen at. diff --git a/packages/atproto_client/models/app/bsky/richtext/facet.py b/packages/atproto_client/models/app/bsky/richtext/facet.py index e333ae18..10cf957d 100644 --- a/packages/atproto_client/models/app/bsky/richtext/facet.py +++ b/packages/atproto_client/models/app/bsky/richtext/facet.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -36,7 +38,7 @@ class Main(base.ModelBase): class Mention(base.ModelBase): """Definition model for :obj:`app.bsky.richtext.facet`. Facet feature for mention of another account. The text is usually a handle, including a '@' prefix, but the facet reference is a DID.""" - did: str #: Did. + did: string_formats.Did #: Did. py_type: t.Literal['app.bsky.richtext.facet#mention'] = Field( default='app.bsky.richtext.facet#mention', alias='$type', frozen=True @@ -46,7 +48,7 @@ class Mention(base.ModelBase): class Link(base.ModelBase): """Definition model for :obj:`app.bsky.richtext.facet`. Facet feature for a URL. The text URL may have been simplified or truncated, but the facet reference should be a complete URL.""" - uri: str #: Uri. + uri: string_formats.Uri #: Uri. py_type: t.Literal['app.bsky.richtext.facet#link'] = Field( default='app.bsky.richtext.facet#link', alias='$type', frozen=True diff --git a/packages/atproto_client/models/app/bsky/unspecced/defs.py b/packages/atproto_client/models/app/bsky/unspecced/defs.py index efcc3700..8f6e4efc 100644 --- a/packages/atproto_client/models/app/bsky/unspecced/defs.py +++ b/packages/atproto_client/models/app/bsky/unspecced/defs.py @@ -9,13 +9,13 @@ from pydantic import Field -from atproto_client.models import base +from atproto_client.models import base, string_formats class SkeletonSearchPost(base.ModelBase): """Definition model for :obj:`app.bsky.unspecced.defs`.""" - uri: str #: Uri. + uri: string_formats.AtUri #: Uri. py_type: t.Literal['app.bsky.unspecced.defs#skeletonSearchPost'] = Field( default='app.bsky.unspecced.defs#skeletonSearchPost', alias='$type', frozen=True @@ -25,7 +25,7 @@ class SkeletonSearchPost(base.ModelBase): class SkeletonSearchActor(base.ModelBase): """Definition model for :obj:`app.bsky.unspecced.defs`.""" - did: str #: Did. + did: string_formats.Did #: Did. py_type: t.Literal['app.bsky.unspecced.defs#skeletonSearchActor'] = Field( default='app.bsky.unspecced.defs#skeletonSearchActor', alias='$type', frozen=True @@ -35,7 +35,7 @@ class SkeletonSearchActor(base.ModelBase): class SkeletonSearchStarterPack(base.ModelBase): """Definition model for :obj:`app.bsky.unspecced.defs`.""" - uri: str #: Uri. + uri: string_formats.AtUri #: Uri. py_type: t.Literal['app.bsky.unspecced.defs#skeletonSearchStarterPack'] = Field( default='app.bsky.unspecced.defs#skeletonSearchStarterPack', alias='$type', frozen=True diff --git a/packages/atproto_client/models/app/bsky/unspecced/get_suggestions_skeleton.py b/packages/atproto_client/models/app/bsky/unspecced/get_suggestions_skeleton.py index 7df27df2..4d8979a4 100644 --- a/packages/atproto_client/models/app/bsky/unspecced/get_suggestions_skeleton.py +++ b/packages/atproto_client/models/app/bsky/unspecced/get_suggestions_skeleton.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -20,10 +22,10 @@ class Params(base.ParamsModelBase): cursor: t.Optional[str] = None #: Cursor. limit: t.Optional[int] = Field(default=50, ge=1, le=100) #: Limit. - relative_to_did: t.Optional[str] = ( + relative_to_did: t.Optional[string_formats.Did] = ( None #: DID of the account to get suggestions relative to. If not provided, suggestions will be based on the viewer. ) - viewer: t.Optional[str] = ( + viewer: t.Optional[string_formats.Did] = ( None #: DID of the account making the request (not included for public/unauthenticated queries). Used to boost followed accounts in ranking. ) @@ -32,10 +34,10 @@ class ParamsDict(t.TypedDict): cursor: te.NotRequired[t.Optional[str]] #: Cursor. limit: te.NotRequired[t.Optional[int]] #: Limit. relative_to_did: te.NotRequired[ - t.Optional[str] + t.Optional[string_formats.Did] ] #: DID of the account to get suggestions relative to. If not provided, suggestions will be based on the viewer. viewer: te.NotRequired[ - t.Optional[str] + t.Optional[string_formats.Did] ] #: DID of the account making the request (not included for public/unauthenticated queries). Used to boost followed accounts in ranking. @@ -44,6 +46,6 @@ class Response(base.ResponseModelBase): actors: t.List['models.AppBskyUnspeccedDefs.SkeletonSearchActor'] #: Actors. cursor: t.Optional[str] = None #: Cursor. - relative_to_did: t.Optional[str] = ( + relative_to_did: t.Optional[string_formats.Did] = ( None #: DID of the account these suggestions are relative to. If this is returned undefined, suggestions are based on the viewer. ) diff --git a/packages/atproto_client/models/app/bsky/unspecced/get_tagged_suggestions.py b/packages/atproto_client/models/app/bsky/unspecced/get_tagged_suggestions.py index 7930c357..31d8da14 100644 --- a/packages/atproto_client/models/app/bsky/unspecced/get_tagged_suggestions.py +++ b/packages/atproto_client/models/app/bsky/unspecced/get_tagged_suggestions.py @@ -9,6 +9,8 @@ from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -31,7 +33,7 @@ class Response(base.ResponseModelBase): class Suggestion(base.ModelBase): """Definition model for :obj:`app.bsky.unspecced.getTaggedSuggestions`.""" - subject: str #: Subject. + subject: string_formats.Uri #: Subject. subject_type: t.Union[t.Literal['actor'], t.Literal['feed'], str] #: Subject type. tag: str #: Tag. diff --git a/packages/atproto_client/models/app/bsky/unspecced/search_actors_skeleton.py b/packages/atproto_client/models/app/bsky/unspecced/search_actors_skeleton.py index 97944d6d..4df524b3 100644 --- a/packages/atproto_client/models/app/bsky/unspecced/search_actors_skeleton.py +++ b/packages/atproto_client/models/app/bsky/unspecced/search_actors_skeleton.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -24,7 +26,7 @@ class Params(base.ParamsModelBase): ) limit: t.Optional[int] = Field(default=25, ge=1, le=100) #: Limit. typeahead: t.Optional[bool] = None #: If true, acts as fast/simple 'typeahead' query. - viewer: t.Optional[str] = ( + viewer: t.Optional[string_formats.Did] = ( None #: DID of the account making the request (not included for public/unauthenticated queries). Used to boost followed accounts in ranking. ) @@ -37,7 +39,7 @@ class ParamsDict(t.TypedDict): limit: te.NotRequired[t.Optional[int]] #: Limit. typeahead: te.NotRequired[t.Optional[bool]] #: If true, acts as fast/simple 'typeahead' query. viewer: te.NotRequired[ - t.Optional[str] + t.Optional[string_formats.Did] ] #: DID of the account making the request (not included for public/unauthenticated queries). Used to boost followed accounts in ranking. diff --git a/packages/atproto_client/models/app/bsky/unspecced/search_posts_skeleton.py b/packages/atproto_client/models/app/bsky/unspecced/search_posts_skeleton.py index d71e2dd3..de233a09 100644 --- a/packages/atproto_client/models/app/bsky/unspecced/search_posts_skeleton.py +++ b/packages/atproto_client/models/app/bsky/unspecced/search_posts_skeleton.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -19,7 +21,7 @@ class Params(base.ParamsModelBase): """Parameters model for :obj:`app.bsky.unspecced.searchPostsSkeleton`.""" q: str #: Search query string; syntax, phrase, boolean, and faceting is unspecified, but Lucene query syntax is recommended. - author: t.Optional[str] = ( + author: t.Optional[string_formats.Handle] = ( None #: Filter to posts by the given account. Handles are resolved to DID before query-time. ) cursor: t.Optional[str] = ( @@ -28,11 +30,11 @@ class Params(base.ParamsModelBase): domain: t.Optional[str] = ( None #: Filter to posts with URLs (facet links or embeds) linking to the given domain (hostname). Server may apply hostname normalization. ) - lang: t.Optional[str] = ( + lang: t.Optional[string_formats.Language] = ( None #: Filter to posts in the given language. Expected to be based on post language field, though server may override language detection. ) limit: t.Optional[int] = Field(default=25, ge=1, le=100) #: Limit. - mentions: t.Optional[str] = ( + mentions: t.Optional[string_formats.Handle] = ( None #: Filter to posts which mention the given account. Handles are resolved to DID before query-time. Only matches rich-text facet mentions. ) since: t.Optional[str] = ( @@ -47,10 +49,10 @@ class Params(base.ParamsModelBase): until: t.Optional[str] = ( None #: Filter results for posts before the indicated datetime (not inclusive). Expected to use 'sortAt' timestamp, which may not match 'createdAt'. Can be a datetime, or just an ISO date (YYY-MM-DD). ) - url: t.Optional[str] = ( + url: t.Optional[string_formats.Uri] = ( None #: Filter to posts with links (facet links or embeds) pointing to this URL. Server may apply URL normalization or fuzzy matching. ) - viewer: t.Optional[str] = ( + viewer: t.Optional[string_formats.Did] = ( None #: DID of the account making the request (not included for public/unauthenticated queries). Used for 'from:me' queries. ) @@ -58,7 +60,7 @@ class Params(base.ParamsModelBase): class ParamsDict(t.TypedDict): q: str #: Search query string; syntax, phrase, boolean, and faceting is unspecified, but Lucene query syntax is recommended. author: te.NotRequired[ - t.Optional[str] + t.Optional[string_formats.Handle] ] #: Filter to posts by the given account. Handles are resolved to DID before query-time. cursor: te.NotRequired[ t.Optional[str] @@ -67,11 +69,11 @@ class ParamsDict(t.TypedDict): t.Optional[str] ] #: Filter to posts with URLs (facet links or embeds) linking to the given domain (hostname). Server may apply hostname normalization. lang: te.NotRequired[ - t.Optional[str] + t.Optional[string_formats.Language] ] #: Filter to posts in the given language. Expected to be based on post language field, though server may override language detection. limit: te.NotRequired[t.Optional[int]] #: Limit. mentions: te.NotRequired[ - t.Optional[str] + t.Optional[string_formats.Handle] ] #: Filter to posts which mention the given account. Handles are resolved to DID before query-time. Only matches rich-text facet mentions. since: te.NotRequired[ t.Optional[str] @@ -86,10 +88,10 @@ class ParamsDict(t.TypedDict): t.Optional[str] ] #: Filter results for posts before the indicated datetime (not inclusive). Expected to use 'sortAt' timestamp, which may not match 'createdAt'. Can be a datetime, or just an ISO date (YYY-MM-DD). url: te.NotRequired[ - t.Optional[str] + t.Optional[string_formats.Uri] ] #: Filter to posts with links (facet links or embeds) pointing to this URL. Server may apply URL normalization or fuzzy matching. viewer: te.NotRequired[ - t.Optional[str] + t.Optional[string_formats.Did] ] #: DID of the account making the request (not included for public/unauthenticated queries). Used for 'from:me' queries. diff --git a/packages/atproto_client/models/app/bsky/unspecced/search_starter_packs_skeleton.py b/packages/atproto_client/models/app/bsky/unspecced/search_starter_packs_skeleton.py index 40a006e4..edb20383 100644 --- a/packages/atproto_client/models/app/bsky/unspecced/search_starter_packs_skeleton.py +++ b/packages/atproto_client/models/app/bsky/unspecced/search_starter_packs_skeleton.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -23,7 +25,7 @@ class Params(base.ParamsModelBase): None #: Optional pagination mechanism; may not necessarily allow scrolling through entire result set. ) limit: t.Optional[int] = Field(default=25, ge=1, le=100) #: Limit. - viewer: t.Optional[str] = ( + viewer: t.Optional[string_formats.Did] = ( None #: DID of the account making the request (not included for public/unauthenticated queries). ) @@ -35,7 +37,7 @@ class ParamsDict(t.TypedDict): ] #: Optional pagination mechanism; may not necessarily allow scrolling through entire result set. limit: te.NotRequired[t.Optional[int]] #: Limit. viewer: te.NotRequired[ - t.Optional[str] + t.Optional[string_formats.Did] ] #: DID of the account making the request (not included for public/unauthenticated queries). diff --git a/packages/atproto_client/models/app/bsky/video/defs.py b/packages/atproto_client/models/app/bsky/video/defs.py index 12e02b4a..2194ef63 100644 --- a/packages/atproto_client/models/app/bsky/video/defs.py +++ b/packages/atproto_client/models/app/bsky/video/defs.py @@ -9,6 +9,8 @@ from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client.models.blob_ref import BlobRef from atproto_client.models import base @@ -17,7 +19,7 @@ class JobStatus(base.ModelBase): """Definition model for :obj:`app.bsky.video.defs`.""" - did: str #: Did. + did: string_formats.Did #: Did. job_id: str #: Job id. state: t.Union[ t.Literal['JOB_STATE_COMPLETED'], t.Literal['JOB_STATE_FAILED'], str diff --git a/packages/atproto_client/models/chat/bsky/actor/defs.py b/packages/atproto_client/models/chat/bsky/actor/defs.py index 0db6464e..24a0e37e 100644 --- a/packages/atproto_client/models/chat/bsky/actor/defs.py +++ b/packages/atproto_client/models/chat/bsky/actor/defs.py @@ -9,6 +9,8 @@ from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -17,10 +19,10 @@ class ProfileViewBasic(base.ModelBase): """Definition model for :obj:`chat.bsky.actor.defs`.""" - did: str #: Did. - handle: str #: Handle. + did: string_formats.Did #: Did. + handle: string_formats.Handle #: Handle. associated: t.Optional['models.AppBskyActorDefs.ProfileAssociated'] = None #: Associated. - avatar: t.Optional[str] = None #: Avatar. + avatar: t.Optional[string_formats.Uri] = None #: Avatar. chat_disabled: t.Optional[bool] = None #: Set to true when the actor cannot actively participate in converations. display_name: t.Optional[str] = Field(default=None, max_length=640) #: Display name. labels: t.Optional[t.List['models.ComAtprotoLabelDefs.Label']] = None #: Labels. diff --git a/packages/atproto_client/models/chat/bsky/convo/defs.py b/packages/atproto_client/models/chat/bsky/convo/defs.py index 7a9d22cb..74a16bc2 100644 --- a/packages/atproto_client/models/chat/bsky/convo/defs.py +++ b/packages/atproto_client/models/chat/bsky/convo/defs.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -19,7 +21,7 @@ class MessageRef(base.ModelBase): """Definition model for :obj:`chat.bsky.convo.defs`.""" convo_id: str #: Convo id. - did: str #: Did. + did: string_formats.Did #: Did. message_id: str #: Message id. py_type: t.Literal['chat.bsky.convo.defs#messageRef'] = Field( @@ -49,7 +51,7 @@ class MessageView(base.ModelBase): id: str #: Id. rev: str #: Rev. sender: 'models.ChatBskyConvoDefs.MessageViewSender' #: Sender. - sent_at: str #: Sent at. + sent_at: string_formats.DateTime #: Sent at. text: str = Field(max_length=10000) #: Text. embed: t.Optional[ te.Annotated[t.Union['models.AppBskyEmbedRecord.View'], Field(default=None, discriminator='py_type')] @@ -69,7 +71,7 @@ class DeletedMessageView(base.ModelBase): id: str #: Id. rev: str #: Rev. sender: 'models.ChatBskyConvoDefs.MessageViewSender' #: Sender. - sent_at: str #: Sent at. + sent_at: string_formats.DateTime #: Sent at. py_type: t.Literal['chat.bsky.convo.defs#deletedMessageView'] = Field( default='chat.bsky.convo.defs#deletedMessageView', alias='$type', frozen=True @@ -79,7 +81,7 @@ class DeletedMessageView(base.ModelBase): class MessageViewSender(base.ModelBase): """Definition model for :obj:`chat.bsky.convo.defs`.""" - did: str #: Did. + did: string_formats.Did #: Did. py_type: t.Literal['chat.bsky.convo.defs#messageViewSender'] = Field( default='chat.bsky.convo.defs#messageViewSender', alias='$type', frozen=True diff --git a/packages/atproto_client/models/chat/bsky/convo/get_convo_for_members.py b/packages/atproto_client/models/chat/bsky/convo/get_convo_for_members.py index 2b81a44d..8d1bb08f 100644 --- a/packages/atproto_client/models/chat/bsky/convo/get_convo_for_members.py +++ b/packages/atproto_client/models/chat/bsky/convo/get_convo_for_members.py @@ -9,6 +9,8 @@ from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -17,11 +19,11 @@ class Params(base.ParamsModelBase): """Parameters model for :obj:`chat.bsky.convo.getConvoForMembers`.""" - members: t.List[str] = Field(min_length=1, max_length=10) #: Members. + members: t.List[string_formats.Did] = Field(min_length=1, max_length=10) #: Members. class ParamsDict(t.TypedDict): - members: t.List[str] #: Members. + members: t.List[string_formats.Did] #: Members. class Response(base.ResponseModelBase): diff --git a/packages/atproto_client/models/chat/bsky/moderation/get_actor_metadata.py b/packages/atproto_client/models/chat/bsky/moderation/get_actor_metadata.py index c9dc3b8b..824295e8 100644 --- a/packages/atproto_client/models/chat/bsky/moderation/get_actor_metadata.py +++ b/packages/atproto_client/models/chat/bsky/moderation/get_actor_metadata.py @@ -9,6 +9,8 @@ from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -17,11 +19,11 @@ class Params(base.ParamsModelBase): """Parameters model for :obj:`chat.bsky.moderation.getActorMetadata`.""" - actor: str #: Actor. + actor: string_formats.Did #: Actor. class ParamsDict(t.TypedDict): - actor: str #: Actor. + actor: string_formats.Did #: Actor. class Response(base.ResponseModelBase): diff --git a/packages/atproto_client/models/chat/bsky/moderation/update_actor_access.py b/packages/atproto_client/models/chat/bsky/moderation/update_actor_access.py index 758bfb56..cb15acb0 100644 --- a/packages/atproto_client/models/chat/bsky/moderation/update_actor_access.py +++ b/packages/atproto_client/models/chat/bsky/moderation/update_actor_access.py @@ -9,18 +9,18 @@ import typing_extensions as te -from atproto_client.models import base +from atproto_client.models import base, string_formats class Data(base.DataModelBase): """Input data model for :obj:`chat.bsky.moderation.updateActorAccess`.""" - actor: str #: Actor. + actor: string_formats.Did #: Actor. allow_access: bool #: Allow access. ref: t.Optional[str] = None #: Ref. class DataDict(t.TypedDict): - actor: str #: Actor. + actor: string_formats.Did #: Actor. allow_access: bool #: Allow access. ref: te.NotRequired[t.Optional[str]] #: Ref. diff --git a/packages/atproto_client/models/com/atproto/admin/defs.py b/packages/atproto_client/models/com/atproto/admin/defs.py index 43919011..fa1c0918 100644 --- a/packages/atproto_client/models/com/atproto/admin/defs.py +++ b/packages/atproto_client/models/com/atproto/admin/defs.py @@ -9,6 +9,8 @@ from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models.unknown_type import UnknownType @@ -29,12 +31,12 @@ class StatusAttr(base.ModelBase): class AccountView(base.ModelBase): """Definition model for :obj:`com.atproto.admin.defs`.""" - did: str #: Did. - handle: str #: Handle. - indexed_at: str #: Indexed at. - deactivated_at: t.Optional[str] = None #: Deactivated at. + did: string_formats.Did #: Did. + handle: string_formats.Handle #: Handle. + indexed_at: string_formats.DateTime #: Indexed at. + deactivated_at: t.Optional[string_formats.DateTime] = None #: Deactivated at. email: t.Optional[str] = None #: Email. - email_confirmed_at: t.Optional[str] = None #: Email confirmed at. + email_confirmed_at: t.Optional[string_formats.DateTime] = None #: Email confirmed at. invite_note: t.Optional[str] = None #: Invite note. invited_by: t.Optional['models.ComAtprotoServerDefs.InviteCode'] = None #: Invited by. invites: t.Optional[t.List['models.ComAtprotoServerDefs.InviteCode']] = None #: Invites. @@ -50,7 +52,7 @@ class AccountView(base.ModelBase): class RepoRef(base.ModelBase): """Definition model for :obj:`com.atproto.admin.defs`.""" - did: str #: Did. + did: string_formats.Did #: Did. py_type: t.Literal['com.atproto.admin.defs#repoRef'] = Field( default='com.atproto.admin.defs#repoRef', alias='$type', frozen=True @@ -60,9 +62,9 @@ class RepoRef(base.ModelBase): class RepoBlobRef(base.ModelBase): """Definition model for :obj:`com.atproto.admin.defs`.""" - cid: str #: Cid. - did: str #: Did. - record_uri: t.Optional[str] = None #: Record uri. + cid: string_formats.Cid #: Cid. + did: string_formats.Did #: Did. + record_uri: t.Optional[string_formats.AtUri] = None #: Record uri. py_type: t.Literal['com.atproto.admin.defs#repoBlobRef'] = Field( default='com.atproto.admin.defs#repoBlobRef', alias='$type', frozen=True diff --git a/packages/atproto_client/models/com/atproto/admin/delete_account.py b/packages/atproto_client/models/com/atproto/admin/delete_account.py index a3c92282..373134a8 100644 --- a/packages/atproto_client/models/com/atproto/admin/delete_account.py +++ b/packages/atproto_client/models/com/atproto/admin/delete_account.py @@ -7,14 +7,14 @@ import typing as t -from atproto_client.models import base +from atproto_client.models import base, string_formats class Data(base.DataModelBase): """Input data model for :obj:`com.atproto.admin.deleteAccount`.""" - did: str #: Did. + did: string_formats.Did #: Did. class DataDict(t.TypedDict): - did: str #: Did. + did: string_formats.Did #: Did. diff --git a/packages/atproto_client/models/com/atproto/admin/disable_account_invites.py b/packages/atproto_client/models/com/atproto/admin/disable_account_invites.py index 19086cd0..cf99022b 100644 --- a/packages/atproto_client/models/com/atproto/admin/disable_account_invites.py +++ b/packages/atproto_client/models/com/atproto/admin/disable_account_invites.py @@ -9,16 +9,16 @@ import typing_extensions as te -from atproto_client.models import base +from atproto_client.models import base, string_formats class Data(base.DataModelBase): """Input data model for :obj:`com.atproto.admin.disableAccountInvites`.""" - account: str #: Account. + account: string_formats.Did #: Account. note: t.Optional[str] = None #: Optional reason for disabled invites. class DataDict(t.TypedDict): - account: str #: Account. + account: string_formats.Did #: Account. note: te.NotRequired[t.Optional[str]] #: Optional reason for disabled invites. diff --git a/packages/atproto_client/models/com/atproto/admin/enable_account_invites.py b/packages/atproto_client/models/com/atproto/admin/enable_account_invites.py index 31839299..ecb31828 100644 --- a/packages/atproto_client/models/com/atproto/admin/enable_account_invites.py +++ b/packages/atproto_client/models/com/atproto/admin/enable_account_invites.py @@ -9,16 +9,16 @@ import typing_extensions as te -from atproto_client.models import base +from atproto_client.models import base, string_formats class Data(base.DataModelBase): """Input data model for :obj:`com.atproto.admin.enableAccountInvites`.""" - account: str #: Account. + account: string_formats.Did #: Account. note: t.Optional[str] = None #: Optional reason for enabled invites. class DataDict(t.TypedDict): - account: str #: Account. + account: string_formats.Did #: Account. note: te.NotRequired[t.Optional[str]] #: Optional reason for enabled invites. diff --git a/packages/atproto_client/models/com/atproto/admin/get_account_info.py b/packages/atproto_client/models/com/atproto/admin/get_account_info.py index 094e4580..9ec48519 100644 --- a/packages/atproto_client/models/com/atproto/admin/get_account_info.py +++ b/packages/atproto_client/models/com/atproto/admin/get_account_info.py @@ -7,14 +7,14 @@ import typing as t -from atproto_client.models import base +from atproto_client.models import base, string_formats class Params(base.ParamsModelBase): """Parameters model for :obj:`com.atproto.admin.getAccountInfo`.""" - did: str #: Did. + did: string_formats.Did #: Did. class ParamsDict(t.TypedDict): - did: str #: Did. + did: string_formats.Did #: Did. diff --git a/packages/atproto_client/models/com/atproto/admin/get_account_infos.py b/packages/atproto_client/models/com/atproto/admin/get_account_infos.py index 725dcf19..941b7016 100644 --- a/packages/atproto_client/models/com/atproto/admin/get_account_infos.py +++ b/packages/atproto_client/models/com/atproto/admin/get_account_infos.py @@ -7,6 +7,8 @@ import typing as t +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -15,11 +17,11 @@ class Params(base.ParamsModelBase): """Parameters model for :obj:`com.atproto.admin.getAccountInfos`.""" - dids: t.List[str] #: Dids. + dids: t.List[string_formats.Did] #: Dids. class ParamsDict(t.TypedDict): - dids: t.List[str] #: Dids. + dids: t.List[string_formats.Did] #: Dids. class Response(base.ResponseModelBase): diff --git a/packages/atproto_client/models/com/atproto/admin/get_subject_status.py b/packages/atproto_client/models/com/atproto/admin/get_subject_status.py index f8ee7e75..2f40e043 100644 --- a/packages/atproto_client/models/com/atproto/admin/get_subject_status.py +++ b/packages/atproto_client/models/com/atproto/admin/get_subject_status.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -18,15 +20,15 @@ class Params(base.ParamsModelBase): """Parameters model for :obj:`com.atproto.admin.getSubjectStatus`.""" - blob: t.Optional[str] = None #: Blob. - did: t.Optional[str] = None #: Did. - uri: t.Optional[str] = None #: Uri. + blob: t.Optional[string_formats.Cid] = None #: Blob. + did: t.Optional[string_formats.Did] = None #: Did. + uri: t.Optional[string_formats.AtUri] = None #: Uri. class ParamsDict(t.TypedDict): - blob: te.NotRequired[t.Optional[str]] #: Blob. - did: te.NotRequired[t.Optional[str]] #: Did. - uri: te.NotRequired[t.Optional[str]] #: Uri. + blob: te.NotRequired[t.Optional[string_formats.Cid]] #: Blob. + did: te.NotRequired[t.Optional[string_formats.Did]] #: Did. + uri: te.NotRequired[t.Optional[string_formats.AtUri]] #: Uri. class Response(base.ResponseModelBase): diff --git a/packages/atproto_client/models/com/atproto/admin/send_email.py b/packages/atproto_client/models/com/atproto/admin/send_email.py index f776b43c..3ab724fa 100644 --- a/packages/atproto_client/models/com/atproto/admin/send_email.py +++ b/packages/atproto_client/models/com/atproto/admin/send_email.py @@ -9,15 +9,15 @@ import typing_extensions as te -from atproto_client.models import base +from atproto_client.models import base, string_formats class Data(base.DataModelBase): """Input data model for :obj:`com.atproto.admin.sendEmail`.""" content: str #: Content. - recipient_did: str #: Recipient did. - sender_did: str #: Sender did. + recipient_did: string_formats.Did #: Recipient did. + sender_did: string_formats.Did #: Sender did. comment: t.Optional[str] = ( None #: Additional comment by the sender that won't be used in the email itself but helpful to provide more context for moderators/reviewers. ) @@ -26,8 +26,8 @@ class Data(base.DataModelBase): class DataDict(t.TypedDict): content: str #: Content. - recipient_did: str #: Recipient did. - sender_did: str #: Sender did. + recipient_did: string_formats.Did #: Recipient did. + sender_did: string_formats.Did #: Sender did. comment: te.NotRequired[ t.Optional[str] ] #: Additional comment by the sender that won't be used in the email itself but helpful to provide more context for moderators/reviewers. diff --git a/packages/atproto_client/models/com/atproto/admin/update_account_email.py b/packages/atproto_client/models/com/atproto/admin/update_account_email.py index 5641ca17..5ef4fa86 100644 --- a/packages/atproto_client/models/com/atproto/admin/update_account_email.py +++ b/packages/atproto_client/models/com/atproto/admin/update_account_email.py @@ -7,16 +7,16 @@ import typing as t -from atproto_client.models import base +from atproto_client.models import base, string_formats class Data(base.DataModelBase): """Input data model for :obj:`com.atproto.admin.updateAccountEmail`.""" - account: str #: The handle or DID of the repo. + account: string_formats.Handle #: The handle or DID of the repo. email: str #: Email. class DataDict(t.TypedDict): - account: str #: The handle or DID of the repo. + account: string_formats.Handle #: The handle or DID of the repo. email: str #: Email. diff --git a/packages/atproto_client/models/com/atproto/admin/update_account_handle.py b/packages/atproto_client/models/com/atproto/admin/update_account_handle.py index b63ff7d3..37ab179d 100644 --- a/packages/atproto_client/models/com/atproto/admin/update_account_handle.py +++ b/packages/atproto_client/models/com/atproto/admin/update_account_handle.py @@ -7,16 +7,16 @@ import typing as t -from atproto_client.models import base +from atproto_client.models import base, string_formats class Data(base.DataModelBase): """Input data model for :obj:`com.atproto.admin.updateAccountHandle`.""" - did: str #: Did. - handle: str #: Handle. + did: string_formats.Did #: Did. + handle: string_formats.Handle #: Handle. class DataDict(t.TypedDict): - did: str #: Did. - handle: str #: Handle. + did: string_formats.Did #: Did. + handle: string_formats.Handle #: Handle. diff --git a/packages/atproto_client/models/com/atproto/admin/update_account_password.py b/packages/atproto_client/models/com/atproto/admin/update_account_password.py index a0daa3d1..aa09c008 100644 --- a/packages/atproto_client/models/com/atproto/admin/update_account_password.py +++ b/packages/atproto_client/models/com/atproto/admin/update_account_password.py @@ -7,16 +7,16 @@ import typing as t -from atproto_client.models import base +from atproto_client.models import base, string_formats class Data(base.DataModelBase): """Input data model for :obj:`com.atproto.admin.updateAccountPassword`.""" - did: str #: Did. + did: string_formats.Did #: Did. password: str #: Password. class DataDict(t.TypedDict): - did: str #: Did. + did: string_formats.Did #: Did. password: str #: Password. diff --git a/packages/atproto_client/models/com/atproto/identity/resolve_handle.py b/packages/atproto_client/models/com/atproto/identity/resolve_handle.py index cda26867..dc4f24e7 100644 --- a/packages/atproto_client/models/com/atproto/identity/resolve_handle.py +++ b/packages/atproto_client/models/com/atproto/identity/resolve_handle.py @@ -7,20 +7,20 @@ import typing as t -from atproto_client.models import base +from atproto_client.models import base, string_formats class Params(base.ParamsModelBase): """Parameters model for :obj:`com.atproto.identity.resolveHandle`.""" - handle: str #: The handle to resolve. + handle: string_formats.Handle #: The handle to resolve. class ParamsDict(t.TypedDict): - handle: str #: The handle to resolve. + handle: string_formats.Handle #: The handle to resolve. class Response(base.ResponseModelBase): """Output data model for :obj:`com.atproto.identity.resolveHandle`.""" - did: str #: Did. + did: string_formats.Did #: Did. diff --git a/packages/atproto_client/models/com/atproto/identity/update_handle.py b/packages/atproto_client/models/com/atproto/identity/update_handle.py index a85545cc..32725afc 100644 --- a/packages/atproto_client/models/com/atproto/identity/update_handle.py +++ b/packages/atproto_client/models/com/atproto/identity/update_handle.py @@ -7,14 +7,14 @@ import typing as t -from atproto_client.models import base +from atproto_client.models import base, string_formats class Data(base.DataModelBase): """Input data model for :obj:`com.atproto.identity.updateHandle`.""" - handle: str #: The new handle. + handle: string_formats.Handle #: The new handle. class DataDict(t.TypedDict): - handle: str #: The new handle. + handle: string_formats.Handle #: The new handle. diff --git a/packages/atproto_client/models/com/atproto/label/defs.py b/packages/atproto_client/models/com/atproto/label/defs.py index bab8677d..90a4f512 100644 --- a/packages/atproto_client/models/com/atproto/label/defs.py +++ b/packages/atproto_client/models/com/atproto/label/defs.py @@ -9,6 +9,8 @@ from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -17,14 +19,16 @@ class Label(base.ModelBase): """Definition model for :obj:`com.atproto.label.defs`. Metadata tag on an atproto resource (eg, repo or record).""" - cts: str #: Timestamp when this label was created. - src: str #: DID of the actor who created this label. - uri: str #: AT URI of the record, repository (account), or other resource that this label applies to. + cts: string_formats.DateTime #: Timestamp when this label was created. + src: string_formats.Did #: DID of the actor who created this label. + uri: ( + string_formats.Uri + ) #: AT URI of the record, repository (account), or other resource that this label applies to. val: str = Field(max_length=128) #: The short string name of the value or type of this label. - cid: t.Optional[str] = ( + cid: t.Optional[string_formats.Cid] = ( None #: Optionally, CID specifying the specific version of 'uri' resource this label applies to. ) - exp: t.Optional[str] = None #: Timestamp at which this label expires (no longer applies). + exp: t.Optional[string_formats.DateTime] = None #: Timestamp at which this label expires (no longer applies). neg: t.Optional[bool] = None #: If true, this is a negation label, overwriting a previous label. sig: t.Optional[t.Union[str, bytes]] = None #: Signature of dag-cbor encoded label. ver: t.Optional[int] = None #: The AT Protocol version of the label object. @@ -85,7 +89,7 @@ class LabelValueDefinitionStrings(base.ModelBase): description: str = Field( max_length=100000 ) #: A longer description of what the label means and why it might be applied. - lang: str #: The code of the language these strings are written in. + lang: string_formats.Language #: The code of the language these strings are written in. name: str = Field(max_length=640) #: A short human-readable name for the label. py_type: t.Literal['com.atproto.label.defs#labelValueDefinitionStrings'] = Field( diff --git a/packages/atproto_client/models/com/atproto/label/query_labels.py b/packages/atproto_client/models/com/atproto/label/query_labels.py index d89b9330..3a9c547b 100644 --- a/packages/atproto_client/models/com/atproto/label/query_labels.py +++ b/packages/atproto_client/models/com/atproto/label/query_labels.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -23,7 +25,7 @@ class Params(base.ParamsModelBase): ] #: List of AT URI patterns to match (boolean 'OR'). Each may be a prefix (ending with '*'; will match inclusive of the string leading to '*'), or a full URI. cursor: t.Optional[str] = None #: Cursor. limit: t.Optional[int] = Field(default=50, ge=1, le=250) #: Limit. - sources: t.Optional[t.List[str]] = None #: Optional list of label sources (DIDs) to filter on. + sources: t.Optional[t.List[string_formats.Did]] = None #: Optional list of label sources (DIDs) to filter on. class ParamsDict(t.TypedDict): @@ -32,7 +34,9 @@ class ParamsDict(t.TypedDict): ] #: List of AT URI patterns to match (boolean 'OR'). Each may be a prefix (ending with '*'; will match inclusive of the string leading to '*'), or a full URI. cursor: te.NotRequired[t.Optional[str]] #: Cursor. limit: te.NotRequired[t.Optional[int]] #: Limit. - sources: te.NotRequired[t.Optional[t.List[str]]] #: Optional list of label sources (DIDs) to filter on. + sources: te.NotRequired[ + t.Optional[t.List[string_formats.Did]] + ] #: Optional list of label sources (DIDs) to filter on. class Response(base.ResponseModelBase): diff --git a/packages/atproto_client/models/com/atproto/moderation/create_report.py b/packages/atproto_client/models/com/atproto/moderation/create_report.py index b3e4fb75..1cd4d56c 100644 --- a/packages/atproto_client/models/com/atproto/moderation/create_report.py +++ b/packages/atproto_client/models/com/atproto/moderation/create_report.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -44,10 +46,10 @@ class DataDict(t.TypedDict): class Response(base.ResponseModelBase): """Output data model for :obj:`com.atproto.moderation.createReport`.""" - created_at: str #: Created at. + created_at: string_formats.DateTime #: Created at. id: int #: Id. reason_type: 'models.ComAtprotoModerationDefs.ReasonType' #: Reason type. - reported_by: str #: Reported by. + reported_by: string_formats.Did #: Reported by. subject: te.Annotated[ t.Union['models.ComAtprotoAdminDefs.RepoRef', 'models.ComAtprotoRepoStrongRef.Main'], Field(discriminator='py_type'), diff --git a/packages/atproto_client/models/com/atproto/repo/apply_writes.py b/packages/atproto_client/models/com/atproto/repo/apply_writes.py index ef1dbf83..fa04c1af 100644 --- a/packages/atproto_client/models/com/atproto/repo/apply_writes.py +++ b/packages/atproto_client/models/com/atproto/repo/apply_writes.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models.unknown_type import UnknownType @@ -19,7 +21,7 @@ class Data(base.DataModelBase): """Input data model for :obj:`com.atproto.repo.applyWrites`.""" - repo: str #: The handle or DID of the repo (aka, current account). + repo: string_formats.Handle #: The handle or DID of the repo (aka, current account). writes: t.List[ te.Annotated[ t.Union[ @@ -30,7 +32,7 @@ class Data(base.DataModelBase): Field(discriminator='py_type'), ] ] #: Writes. - swap_commit: t.Optional[str] = ( + swap_commit: t.Optional[string_formats.Cid] = ( None #: If provided, the entire operation will fail if the current repo commit CID does not match this value. Used to prevent conflicting repo mutations. ) validate_: t.Optional[bool] = ( @@ -39,7 +41,7 @@ class Data(base.DataModelBase): class DataDict(t.TypedDict): - repo: str #: The handle or DID of the repo (aka, current account). + repo: string_formats.Handle #: The handle or DID of the repo (aka, current account). writes: t.List[ te.Annotated[ t.Union[ @@ -51,7 +53,7 @@ class DataDict(t.TypedDict): ] ] #: Writes. swap_commit: te.NotRequired[ - t.Optional[str] + t.Optional[string_formats.Cid] ] #: If provided, the entire operation will fail if the current repo commit CID does not match this value. Used to prevent conflicting repo mutations. validate: te.NotRequired[ t.Optional[bool] @@ -79,7 +81,7 @@ class Response(base.ResponseModelBase): class Create(base.ModelBase): """Definition model for :obj:`com.atproto.repo.applyWrites`. Operation which creates a new record.""" - collection: str #: Collection. + collection: string_formats.Nsid #: Collection. value: 'UnknownType' #: Value. rkey: t.Optional[str] = Field(default=None, max_length=512) #: Rkey. @@ -91,7 +93,7 @@ class Create(base.ModelBase): class Update(base.ModelBase): """Definition model for :obj:`com.atproto.repo.applyWrites`. Operation which updates an existing record.""" - collection: str #: Collection. + collection: string_formats.Nsid #: Collection. rkey: str #: Rkey. value: 'UnknownType' #: Value. @@ -103,7 +105,7 @@ class Update(base.ModelBase): class Delete(base.ModelBase): """Definition model for :obj:`com.atproto.repo.applyWrites`. Operation which deletes an existing record.""" - collection: str #: Collection. + collection: string_formats.Nsid #: Collection. rkey: str #: Rkey. py_type: t.Literal['com.atproto.repo.applyWrites#delete'] = Field( @@ -114,8 +116,8 @@ class Delete(base.ModelBase): class CreateResult(base.ModelBase): """Definition model for :obj:`com.atproto.repo.applyWrites`.""" - cid: str #: Cid. - uri: str #: Uri. + cid: string_formats.Cid #: Cid. + uri: string_formats.AtUri #: Uri. validation_status: t.Optional[t.Union[t.Literal['valid'], t.Literal['unknown'], str]] = None #: Validation status. py_type: t.Literal['com.atproto.repo.applyWrites#createResult'] = Field( @@ -126,8 +128,8 @@ class CreateResult(base.ModelBase): class UpdateResult(base.ModelBase): """Definition model for :obj:`com.atproto.repo.applyWrites`.""" - cid: str #: Cid. - uri: str #: Uri. + cid: string_formats.Cid #: Cid. + uri: string_formats.AtUri #: Uri. validation_status: t.Optional[t.Union[t.Literal['valid'], t.Literal['unknown'], str]] = None #: Validation status. py_type: t.Literal['com.atproto.repo.applyWrites#updateResult'] = Field( diff --git a/packages/atproto_client/models/com/atproto/repo/create_record.py b/packages/atproto_client/models/com/atproto/repo/create_record.py index 9dd8efaa..ff51b7f3 100644 --- a/packages/atproto_client/models/com/atproto/repo/create_record.py +++ b/packages/atproto_client/models/com/atproto/repo/create_record.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models.unknown_type import UnknownInputType @@ -19,22 +21,22 @@ class Data(base.DataModelBase): """Input data model for :obj:`com.atproto.repo.createRecord`.""" - collection: str #: The NSID of the record collection. + collection: string_formats.Nsid #: The NSID of the record collection. record: 'UnknownInputType' #: The record itself. Must contain a $type field. - repo: str #: The handle or DID of the repo (aka, current account). + repo: string_formats.Handle #: The handle or DID of the repo (aka, current account). rkey: t.Optional[str] = Field(default=None, max_length=512) #: The Record Key. - swap_commit: t.Optional[str] = None #: Compare and swap with the previous commit by CID. + swap_commit: t.Optional[string_formats.Cid] = None #: Compare and swap with the previous commit by CID. validate_: t.Optional[bool] = ( None #: Can be set to 'false' to skip Lexicon schema validation of record data, 'true' to require it, or leave unset to validate only for known Lexicons. ) class DataDict(t.TypedDict): - collection: str #: The NSID of the record collection. + collection: string_formats.Nsid #: The NSID of the record collection. record: 'UnknownInputType' #: The record itself. Must contain a $type field. - repo: str #: The handle or DID of the repo (aka, current account). + repo: string_formats.Handle #: The handle or DID of the repo (aka, current account). rkey: te.NotRequired[t.Optional[str]] #: The Record Key. - swap_commit: te.NotRequired[t.Optional[str]] #: Compare and swap with the previous commit by CID. + swap_commit: te.NotRequired[t.Optional[string_formats.Cid]] #: Compare and swap with the previous commit by CID. validate: te.NotRequired[ t.Optional[bool] ] #: Can be set to 'false' to skip Lexicon schema validation of record data, 'true' to require it, or leave unset to validate only for known Lexicons. @@ -43,7 +45,7 @@ class DataDict(t.TypedDict): class Response(base.ResponseModelBase): """Output data model for :obj:`com.atproto.repo.createRecord`.""" - cid: str #: Cid. - uri: str #: Uri. + cid: string_formats.Cid #: Cid. + uri: string_formats.AtUri #: Uri. commit: t.Optional['models.ComAtprotoRepoDefs.CommitMeta'] = None #: Commit. validation_status: t.Optional[t.Union[t.Literal['valid'], t.Literal['unknown'], str]] = None #: Validation status. diff --git a/packages/atproto_client/models/com/atproto/repo/defs.py b/packages/atproto_client/models/com/atproto/repo/defs.py index 036dd36d..0477aa76 100644 --- a/packages/atproto_client/models/com/atproto/repo/defs.py +++ b/packages/atproto_client/models/com/atproto/repo/defs.py @@ -9,13 +9,13 @@ from pydantic import Field -from atproto_client.models import base +from atproto_client.models import base, string_formats class CommitMeta(base.ModelBase): """Definition model for :obj:`com.atproto.repo.defs`.""" - cid: str #: Cid. + cid: string_formats.Cid #: Cid. rev: str #: Rev. py_type: t.Literal['com.atproto.repo.defs#commitMeta'] = Field( diff --git a/packages/atproto_client/models/com/atproto/repo/delete_record.py b/packages/atproto_client/models/com/atproto/repo/delete_record.py index 7528a272..26f6bcb4 100644 --- a/packages/atproto_client/models/com/atproto/repo/delete_record.py +++ b/packages/atproto_client/models/com/atproto/repo/delete_record.py @@ -9,6 +9,8 @@ import typing_extensions as te +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -17,19 +19,19 @@ class Data(base.DataModelBase): """Input data model for :obj:`com.atproto.repo.deleteRecord`.""" - collection: str #: The NSID of the record collection. - repo: str #: The handle or DID of the repo (aka, current account). + collection: string_formats.Nsid #: The NSID of the record collection. + repo: string_formats.Handle #: The handle or DID of the repo (aka, current account). rkey: str #: The Record Key. - swap_commit: t.Optional[str] = None #: Compare and swap with the previous commit by CID. - swap_record: t.Optional[str] = None #: Compare and swap with the previous record by CID. + swap_commit: t.Optional[string_formats.Cid] = None #: Compare and swap with the previous commit by CID. + swap_record: t.Optional[string_formats.Cid] = None #: Compare and swap with the previous record by CID. class DataDict(t.TypedDict): - collection: str #: The NSID of the record collection. - repo: str #: The handle or DID of the repo (aka, current account). + collection: string_formats.Nsid #: The NSID of the record collection. + repo: string_formats.Handle #: The handle or DID of the repo (aka, current account). rkey: str #: The Record Key. - swap_commit: te.NotRequired[t.Optional[str]] #: Compare and swap with the previous commit by CID. - swap_record: te.NotRequired[t.Optional[str]] #: Compare and swap with the previous record by CID. + swap_commit: te.NotRequired[t.Optional[string_formats.Cid]] #: Compare and swap with the previous commit by CID. + swap_record: te.NotRequired[t.Optional[string_formats.Cid]] #: Compare and swap with the previous record by CID. class Response(base.ResponseModelBase): diff --git a/packages/atproto_client/models/com/atproto/repo/describe_repo.py b/packages/atproto_client/models/com/atproto/repo/describe_repo.py index a0a8ec43..46512bb2 100644 --- a/packages/atproto_client/models/com/atproto/repo/describe_repo.py +++ b/packages/atproto_client/models/com/atproto/repo/describe_repo.py @@ -7,6 +7,8 @@ import typing as t +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client.models.unknown_type import UnknownType from atproto_client.models import base @@ -15,18 +17,20 @@ class Params(base.ParamsModelBase): """Parameters model for :obj:`com.atproto.repo.describeRepo`.""" - repo: str #: The handle or DID of the repo. + repo: string_formats.Handle #: The handle or DID of the repo. class ParamsDict(t.TypedDict): - repo: str #: The handle or DID of the repo. + repo: string_formats.Handle #: The handle or DID of the repo. class Response(base.ResponseModelBase): """Output data model for :obj:`com.atproto.repo.describeRepo`.""" - collections: t.List[str] #: List of all the collections (NSIDs) for which this repo contains at least one record. - did: str #: Did. + collections: t.List[ + string_formats.Nsid + ] #: List of all the collections (NSIDs) for which this repo contains at least one record. + did: string_formats.Did #: Did. did_doc: 'UnknownType' #: The complete DID document for this account. - handle: str #: Handle. + handle: string_formats.Handle #: Handle. handle_is_correct: bool #: Indicates if handle is currently valid (resolves bi-directionally). diff --git a/packages/atproto_client/models/com/atproto/repo/get_record.py b/packages/atproto_client/models/com/atproto/repo/get_record.py index de1d2825..f6b25f21 100644 --- a/packages/atproto_client/models/com/atproto/repo/get_record.py +++ b/packages/atproto_client/models/com/atproto/repo/get_record.py @@ -9,6 +9,8 @@ import typing_extensions as te +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client.models.unknown_type import UnknownType from atproto_client.models import base @@ -17,26 +19,26 @@ class Params(base.ParamsModelBase): """Parameters model for :obj:`com.atproto.repo.getRecord`.""" - collection: str #: The NSID of the record collection. - repo: str #: The handle or DID of the repo. + collection: string_formats.Nsid #: The NSID of the record collection. + repo: string_formats.Handle #: The handle or DID of the repo. rkey: str #: The Record Key. - cid: t.Optional[str] = ( + cid: t.Optional[string_formats.Cid] = ( None #: The CID of the version of the record. If not specified, then return the most recent version. ) class ParamsDict(t.TypedDict): - collection: str #: The NSID of the record collection. - repo: str #: The handle or DID of the repo. + collection: string_formats.Nsid #: The NSID of the record collection. + repo: string_formats.Handle #: The handle or DID of the repo. rkey: str #: The Record Key. cid: te.NotRequired[ - t.Optional[str] + t.Optional[string_formats.Cid] ] #: The CID of the version of the record. If not specified, then return the most recent version. class Response(base.ResponseModelBase): """Output data model for :obj:`com.atproto.repo.getRecord`.""" - uri: str #: Uri. + uri: string_formats.AtUri #: Uri. value: 'UnknownType' #: Value. - cid: t.Optional[str] = None #: Cid. + cid: t.Optional[string_formats.Cid] = None #: Cid. diff --git a/packages/atproto_client/models/com/atproto/repo/list_missing_blobs.py b/packages/atproto_client/models/com/atproto/repo/list_missing_blobs.py index aa0c750b..4ad7615c 100644 --- a/packages/atproto_client/models/com/atproto/repo/list_missing_blobs.py +++ b/packages/atproto_client/models/com/atproto/repo/list_missing_blobs.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -37,8 +39,8 @@ class Response(base.ResponseModelBase): class RecordBlob(base.ModelBase): """Definition model for :obj:`com.atproto.repo.listMissingBlobs`.""" - cid: str #: Cid. - record_uri: str #: Record uri. + cid: string_formats.Cid #: Cid. + record_uri: string_formats.AtUri #: Record uri. py_type: t.Literal['com.atproto.repo.listMissingBlobs#recordBlob'] = Field( default='com.atproto.repo.listMissingBlobs#recordBlob', alias='$type', frozen=True diff --git a/packages/atproto_client/models/com/atproto/repo/list_records.py b/packages/atproto_client/models/com/atproto/repo/list_records.py index a8bdc592..cb268dbe 100644 --- a/packages/atproto_client/models/com/atproto/repo/list_records.py +++ b/packages/atproto_client/models/com/atproto/repo/list_records.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models.unknown_type import UnknownType @@ -19,8 +21,8 @@ class Params(base.ParamsModelBase): """Parameters model for :obj:`com.atproto.repo.listRecords`.""" - collection: str #: The NSID of the record type. - repo: str #: The handle or DID of the repo. + collection: string_formats.Nsid #: The NSID of the record type. + repo: string_formats.Handle #: The handle or DID of the repo. cursor: t.Optional[str] = None #: Cursor. limit: t.Optional[int] = Field(default=50, ge=1, le=100) #: The number of records to return. reverse: t.Optional[bool] = None #: Flag to reverse the order of the returned records. @@ -29,8 +31,8 @@ class Params(base.ParamsModelBase): class ParamsDict(t.TypedDict): - collection: str #: The NSID of the record type. - repo: str #: The handle or DID of the repo. + collection: string_formats.Nsid #: The NSID of the record type. + repo: string_formats.Handle #: The handle or DID of the repo. cursor: te.NotRequired[t.Optional[str]] #: Cursor. limit: te.NotRequired[t.Optional[int]] #: The number of records to return. reverse: te.NotRequired[t.Optional[bool]] #: Flag to reverse the order of the returned records. @@ -48,8 +50,8 @@ class Response(base.ResponseModelBase): class Record(base.ModelBase): """Definition model for :obj:`com.atproto.repo.listRecords`.""" - cid: str #: Cid. - uri: str #: Uri. + cid: string_formats.Cid #: Cid. + uri: string_formats.AtUri #: Uri. value: 'UnknownType' #: Value. py_type: t.Literal['com.atproto.repo.listRecords#record'] = Field( diff --git a/packages/atproto_client/models/com/atproto/repo/put_record.py b/packages/atproto_client/models/com/atproto/repo/put_record.py index 96af2bb9..15b69ff6 100644 --- a/packages/atproto_client/models/com/atproto/repo/put_record.py +++ b/packages/atproto_client/models/com/atproto/repo/put_record.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models.unknown_type import UnknownInputType @@ -19,12 +21,12 @@ class Data(base.DataModelBase): """Input data model for :obj:`com.atproto.repo.putRecord`.""" - collection: str #: The NSID of the record collection. + collection: string_formats.Nsid #: The NSID of the record collection. record: 'UnknownInputType' #: The record to write. - repo: str #: The handle or DID of the repo (aka, current account). + repo: string_formats.Handle #: The handle or DID of the repo (aka, current account). rkey: str = Field(max_length=512) #: The Record Key. - swap_commit: t.Optional[str] = None #: Compare and swap with the previous commit by CID. - swap_record: t.Optional[str] = ( + swap_commit: t.Optional[string_formats.Cid] = None #: Compare and swap with the previous commit by CID. + swap_record: t.Optional[string_formats.Cid] = ( None #: Compare and swap with the previous record by CID. WARNING: nullable and optional field; may cause problems with golang implementation. ) validate_: t.Optional[bool] = ( @@ -33,13 +35,13 @@ class Data(base.DataModelBase): class DataDict(t.TypedDict): - collection: str #: The NSID of the record collection. + collection: string_formats.Nsid #: The NSID of the record collection. record: 'UnknownInputType' #: The record to write. - repo: str #: The handle or DID of the repo (aka, current account). + repo: string_formats.Handle #: The handle or DID of the repo (aka, current account). rkey: str #: The Record Key. - swap_commit: te.NotRequired[t.Optional[str]] #: Compare and swap with the previous commit by CID. + swap_commit: te.NotRequired[t.Optional[string_formats.Cid]] #: Compare and swap with the previous commit by CID. swap_record: te.NotRequired[ - t.Optional[str] + t.Optional[string_formats.Cid] ] #: Compare and swap with the previous record by CID. WARNING: nullable and optional field; may cause problems with golang implementation. validate: te.NotRequired[ t.Optional[bool] @@ -49,7 +51,7 @@ class DataDict(t.TypedDict): class Response(base.ResponseModelBase): """Output data model for :obj:`com.atproto.repo.putRecord`.""" - cid: str #: Cid. - uri: str #: Uri. + cid: string_formats.Cid #: Cid. + uri: string_formats.AtUri #: Uri. commit: t.Optional['models.ComAtprotoRepoDefs.CommitMeta'] = None #: Commit. validation_status: t.Optional[t.Union[t.Literal['valid'], t.Literal['unknown'], str]] = None #: Validation status. diff --git a/packages/atproto_client/models/com/atproto/repo/strong_ref.py b/packages/atproto_client/models/com/atproto/repo/strong_ref.py index 764ec471..8d8f0bd0 100644 --- a/packages/atproto_client/models/com/atproto/repo/strong_ref.py +++ b/packages/atproto_client/models/com/atproto/repo/strong_ref.py @@ -9,14 +9,14 @@ from pydantic import Field -from atproto_client.models import base +from atproto_client.models import base, string_formats class Main(base.ModelBase): """Definition model for :obj:`com.atproto.repo.strongRef`.""" - cid: str #: Cid. - uri: str #: Uri. + cid: string_formats.Cid #: Cid. + uri: string_formats.AtUri #: Uri. py_type: t.Literal['com.atproto.repo.strongRef'] = Field( default='com.atproto.repo.strongRef', alias='$type', frozen=True diff --git a/packages/atproto_client/models/com/atproto/server/check_account_status.py b/packages/atproto_client/models/com/atproto/server/check_account_status.py index 49fea873..bd251fd9 100644 --- a/packages/atproto_client/models/com/atproto/server/check_account_status.py +++ b/packages/atproto_client/models/com/atproto/server/check_account_status.py @@ -5,7 +5,7 @@ ################################################################## -from atproto_client.models import base +from atproto_client.models import base, string_formats class Response(base.ResponseModelBase): @@ -17,6 +17,6 @@ class Response(base.ResponseModelBase): indexed_records: int #: Indexed records. private_state_values: int #: Private state values. repo_blocks: int #: Repo blocks. - repo_commit: str #: Repo commit. + repo_commit: string_formats.Cid #: Repo commit. repo_rev: str #: Repo rev. valid_did: bool #: Valid did. diff --git a/packages/atproto_client/models/com/atproto/server/create_account.py b/packages/atproto_client/models/com/atproto/server/create_account.py index ca383610..ffdb72ff 100644 --- a/packages/atproto_client/models/com/atproto/server/create_account.py +++ b/packages/atproto_client/models/com/atproto/server/create_account.py @@ -9,6 +9,8 @@ import typing_extensions as te +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client.models.unknown_type import UnknownInputType, UnknownType from atproto_client.models import base @@ -17,8 +19,8 @@ class Data(base.DataModelBase): """Input data model for :obj:`com.atproto.server.createAccount`.""" - handle: str #: Requested handle for the account. - did: t.Optional[str] = None #: Pre-existing atproto DID, being imported to a new account. + handle: string_formats.Handle #: Requested handle for the account. + did: t.Optional[string_formats.Did] = None #: Pre-existing atproto DID, being imported to a new account. email: t.Optional[str] = None #: Email. invite_code: t.Optional[str] = None #: Invite code. password: t.Optional[str] = ( @@ -35,8 +37,8 @@ class Data(base.DataModelBase): class DataDict(t.TypedDict): - handle: str #: Requested handle for the account. - did: te.NotRequired[t.Optional[str]] #: Pre-existing atproto DID, being imported to a new account. + handle: string_formats.Handle #: Requested handle for the account. + did: te.NotRequired[t.Optional[string_formats.Did]] #: Pre-existing atproto DID, being imported to a new account. email: te.NotRequired[t.Optional[str]] #: Email. invite_code: te.NotRequired[t.Optional[str]] #: Invite code. password: te.NotRequired[ @@ -56,7 +58,7 @@ class Response(base.ResponseModelBase): """Output data model for :obj:`com.atproto.server.createAccount`. Account login session returned on successful account creation.""" access_jwt: str #: Access jwt. - did: str #: The DID of the new account. - handle: str #: Handle. + did: string_formats.Did #: The DID of the new account. + handle: string_formats.Handle #: Handle. refresh_jwt: str #: Refresh jwt. did_doc: t.Optional['UnknownType'] = None #: Complete DID document. diff --git a/packages/atproto_client/models/com/atproto/server/create_app_password.py b/packages/atproto_client/models/com/atproto/server/create_app_password.py index be2bfc51..954fc67d 100644 --- a/packages/atproto_client/models/com/atproto/server/create_app_password.py +++ b/packages/atproto_client/models/com/atproto/server/create_app_password.py @@ -10,7 +10,7 @@ import typing_extensions as te from pydantic import Field -from atproto_client.models import base +from atproto_client.models import base, string_formats class Data(base.DataModelBase): @@ -32,7 +32,7 @@ class DataDict(t.TypedDict): class AppPassword(base.ModelBase): """Definition model for :obj:`com.atproto.server.createAppPassword`.""" - created_at: str #: Created at. + created_at: string_formats.DateTime #: Created at. name: str #: Name. password: str #: Password. privileged: t.Optional[bool] = None #: Privileged. diff --git a/packages/atproto_client/models/com/atproto/server/create_invite_code.py b/packages/atproto_client/models/com/atproto/server/create_invite_code.py index 32d1e723..c766da78 100644 --- a/packages/atproto_client/models/com/atproto/server/create_invite_code.py +++ b/packages/atproto_client/models/com/atproto/server/create_invite_code.py @@ -9,19 +9,19 @@ import typing_extensions as te -from atproto_client.models import base +from atproto_client.models import base, string_formats class Data(base.DataModelBase): """Input data model for :obj:`com.atproto.server.createInviteCode`.""" use_count: int #: Use count. - for_account: t.Optional[str] = None #: For account. + for_account: t.Optional[string_formats.Did] = None #: For account. class DataDict(t.TypedDict): use_count: int #: Use count. - for_account: te.NotRequired[t.Optional[str]] #: For account. + for_account: te.NotRequired[t.Optional[string_formats.Did]] #: For account. class Response(base.ResponseModelBase): diff --git a/packages/atproto_client/models/com/atproto/server/create_invite_codes.py b/packages/atproto_client/models/com/atproto/server/create_invite_codes.py index 5b278824..9109e3c3 100644 --- a/packages/atproto_client/models/com/atproto/server/create_invite_codes.py +++ b/packages/atproto_client/models/com/atproto/server/create_invite_codes.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -20,13 +22,13 @@ class Data(base.DataModelBase): code_count: int = 1 #: Code count. use_count: int #: Use count. - for_accounts: t.Optional[t.List[str]] = None #: For accounts. + for_accounts: t.Optional[t.List[string_formats.Did]] = None #: For accounts. class DataDict(t.TypedDict): code_count: int #: Code count. use_count: int #: Use count. - for_accounts: te.NotRequired[t.Optional[t.List[str]]] #: For accounts. + for_accounts: te.NotRequired[t.Optional[t.List[string_formats.Did]]] #: For accounts. class Response(base.ResponseModelBase): diff --git a/packages/atproto_client/models/com/atproto/server/create_session.py b/packages/atproto_client/models/com/atproto/server/create_session.py index eb891056..cb72c190 100644 --- a/packages/atproto_client/models/com/atproto/server/create_session.py +++ b/packages/atproto_client/models/com/atproto/server/create_session.py @@ -9,6 +9,8 @@ import typing_extensions as te +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client.models.unknown_type import UnknownType from atproto_client.models import base @@ -32,8 +34,8 @@ class Response(base.ResponseModelBase): """Output data model for :obj:`com.atproto.server.createSession`.""" access_jwt: str #: Access jwt. - did: str #: Did. - handle: str #: Handle. + did: string_formats.Did #: Did. + handle: string_formats.Handle #: Handle. refresh_jwt: str #: Refresh jwt. active: t.Optional[bool] = None #: Active. did_doc: t.Optional['UnknownType'] = None #: Did doc. diff --git a/packages/atproto_client/models/com/atproto/server/deactivate_account.py b/packages/atproto_client/models/com/atproto/server/deactivate_account.py index 6796b801..e29ad387 100644 --- a/packages/atproto_client/models/com/atproto/server/deactivate_account.py +++ b/packages/atproto_client/models/com/atproto/server/deactivate_account.py @@ -9,18 +9,18 @@ import typing_extensions as te -from atproto_client.models import base +from atproto_client.models import base, string_formats class Data(base.DataModelBase): """Input data model for :obj:`com.atproto.server.deactivateAccount`.""" - delete_after: t.Optional[str] = ( + delete_after: t.Optional[string_formats.DateTime] = ( None #: A recommendation to server as to how long they should hold onto the deactivated account before deleting. ) class DataDict(t.TypedDict): delete_after: te.NotRequired[ - t.Optional[str] + t.Optional[string_formats.DateTime] ] #: A recommendation to server as to how long they should hold onto the deactivated account before deleting. diff --git a/packages/atproto_client/models/com/atproto/server/defs.py b/packages/atproto_client/models/com/atproto/server/defs.py index adad91bf..0701b48e 100644 --- a/packages/atproto_client/models/com/atproto/server/defs.py +++ b/packages/atproto_client/models/com/atproto/server/defs.py @@ -9,6 +9,8 @@ from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -19,7 +21,7 @@ class InviteCode(base.ModelBase): available: int #: Available. code: str #: Code. - created_at: str #: Created at. + created_at: string_formats.DateTime #: Created at. created_by: str #: Created by. disabled: bool #: Disabled. for_account: str #: For account. @@ -33,8 +35,8 @@ class InviteCode(base.ModelBase): class InviteCodeUse(base.ModelBase): """Definition model for :obj:`com.atproto.server.defs`.""" - used_at: str #: Used at. - used_by: str #: Used by. + used_at: string_formats.DateTime #: Used at. + used_by: string_formats.Did #: Used by. py_type: t.Literal['com.atproto.server.defs#inviteCodeUse'] = Field( default='com.atproto.server.defs#inviteCodeUse', alias='$type', frozen=True diff --git a/packages/atproto_client/models/com/atproto/server/delete_account.py b/packages/atproto_client/models/com/atproto/server/delete_account.py index bc2c4fec..cb416fd1 100644 --- a/packages/atproto_client/models/com/atproto/server/delete_account.py +++ b/packages/atproto_client/models/com/atproto/server/delete_account.py @@ -7,18 +7,18 @@ import typing as t -from atproto_client.models import base +from atproto_client.models import base, string_formats class Data(base.DataModelBase): """Input data model for :obj:`com.atproto.server.deleteAccount`.""" - did: str #: Did. + did: string_formats.Did #: Did. password: str #: Password. token: str #: Token. class DataDict(t.TypedDict): - did: str #: Did. + did: string_formats.Did #: Did. password: str #: Password. token: str #: Token. diff --git a/packages/atproto_client/models/com/atproto/server/describe_server.py b/packages/atproto_client/models/com/atproto/server/describe_server.py index 34796fd3..6627e41f 100644 --- a/packages/atproto_client/models/com/atproto/server/describe_server.py +++ b/packages/atproto_client/models/com/atproto/server/describe_server.py @@ -9,6 +9,8 @@ from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -18,7 +20,7 @@ class Response(base.ResponseModelBase): """Output data model for :obj:`com.atproto.server.describeServer`.""" available_user_domains: t.List[str] #: List of domain suffixes that can be used in account handles. - did: str #: Did. + did: string_formats.Did #: Did. contact: t.Optional['models.ComAtprotoServerDescribeServer.Contact'] = None #: Contact information. invite_code_required: t.Optional[bool] = ( None #: If true, an invite code must be supplied to create an account on this instance. @@ -32,8 +34,8 @@ class Response(base.ResponseModelBase): class Links(base.ModelBase): """Definition model for :obj:`com.atproto.server.describeServer`.""" - privacy_policy: t.Optional[str] = None #: Privacy policy. - terms_of_service: t.Optional[str] = None #: Terms of service. + privacy_policy: t.Optional[string_formats.Uri] = None #: Privacy policy. + terms_of_service: t.Optional[string_formats.Uri] = None #: Terms of service. py_type: t.Literal['com.atproto.server.describeServer#links'] = Field( default='com.atproto.server.describeServer#links', alias='$type', frozen=True diff --git a/packages/atproto_client/models/com/atproto/server/get_service_auth.py b/packages/atproto_client/models/com/atproto/server/get_service_auth.py index f4b0b970..e0105dd4 100644 --- a/packages/atproto_client/models/com/atproto/server/get_service_auth.py +++ b/packages/atproto_client/models/com/atproto/server/get_service_auth.py @@ -9,25 +9,25 @@ import typing_extensions as te -from atproto_client.models import base +from atproto_client.models import base, string_formats class Params(base.ParamsModelBase): """Parameters model for :obj:`com.atproto.server.getServiceAuth`.""" - aud: str #: The DID of the service that the token will be used to authenticate with. + aud: string_formats.Did #: The DID of the service that the token will be used to authenticate with. exp: t.Optional[int] = ( None #: The time in Unix Epoch seconds that the JWT expires. Defaults to 60 seconds in the future. The service may enforce certain time bounds on tokens depending on the requested scope. ) - lxm: t.Optional[str] = None #: Lexicon (XRPC) method to bind the requested token to. + lxm: t.Optional[string_formats.Nsid] = None #: Lexicon (XRPC) method to bind the requested token to. class ParamsDict(t.TypedDict): - aud: str #: The DID of the service that the token will be used to authenticate with. + aud: string_formats.Did #: The DID of the service that the token will be used to authenticate with. exp: te.NotRequired[ t.Optional[int] ] #: The time in Unix Epoch seconds that the JWT expires. Defaults to 60 seconds in the future. The service may enforce certain time bounds on tokens depending on the requested scope. - lxm: te.NotRequired[t.Optional[str]] #: Lexicon (XRPC) method to bind the requested token to. + lxm: te.NotRequired[t.Optional[string_formats.Nsid]] #: Lexicon (XRPC) method to bind the requested token to. class Response(base.ResponseModelBase): diff --git a/packages/atproto_client/models/com/atproto/server/get_session.py b/packages/atproto_client/models/com/atproto/server/get_session.py index 1b267536..1764cd0d 100644 --- a/packages/atproto_client/models/com/atproto/server/get_session.py +++ b/packages/atproto_client/models/com/atproto/server/get_session.py @@ -7,6 +7,8 @@ import typing as t +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client.models.unknown_type import UnknownType from atproto_client.models import base @@ -15,8 +17,8 @@ class Response(base.ResponseModelBase): """Output data model for :obj:`com.atproto.server.getSession`.""" - did: str #: Did. - handle: str #: Handle. + did: string_formats.Did #: Did. + handle: string_formats.Handle #: Handle. active: t.Optional[bool] = None #: Active. did_doc: t.Optional['UnknownType'] = None #: Did doc. email: t.Optional[str] = None #: Email. diff --git a/packages/atproto_client/models/com/atproto/server/list_app_passwords.py b/packages/atproto_client/models/com/atproto/server/list_app_passwords.py index 5f3f05a3..b8fd19ad 100644 --- a/packages/atproto_client/models/com/atproto/server/list_app_passwords.py +++ b/packages/atproto_client/models/com/atproto/server/list_app_passwords.py @@ -9,6 +9,8 @@ from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -23,7 +25,7 @@ class Response(base.ResponseModelBase): class AppPassword(base.ModelBase): """Definition model for :obj:`com.atproto.server.listAppPasswords`.""" - created_at: str #: Created at. + created_at: string_formats.DateTime #: Created at. name: str #: Name. privileged: t.Optional[bool] = None #: Privileged. diff --git a/packages/atproto_client/models/com/atproto/server/refresh_session.py b/packages/atproto_client/models/com/atproto/server/refresh_session.py index 22ad96a5..ae70bf1f 100644 --- a/packages/atproto_client/models/com/atproto/server/refresh_session.py +++ b/packages/atproto_client/models/com/atproto/server/refresh_session.py @@ -7,6 +7,8 @@ import typing as t +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client.models.unknown_type import UnknownType from atproto_client.models import base @@ -16,8 +18,8 @@ class Response(base.ResponseModelBase): """Output data model for :obj:`com.atproto.server.refreshSession`.""" access_jwt: str #: Access jwt. - did: str #: Did. - handle: str #: Handle. + did: string_formats.Did #: Did. + handle: string_formats.Handle #: Handle. refresh_jwt: str #: Refresh jwt. active: t.Optional[bool] = None #: Active. did_doc: t.Optional['UnknownType'] = None #: Did doc. diff --git a/packages/atproto_client/models/com/atproto/server/reserve_signing_key.py b/packages/atproto_client/models/com/atproto/server/reserve_signing_key.py index ebda1e39..6a325c51 100644 --- a/packages/atproto_client/models/com/atproto/server/reserve_signing_key.py +++ b/packages/atproto_client/models/com/atproto/server/reserve_signing_key.py @@ -9,17 +9,17 @@ import typing_extensions as te -from atproto_client.models import base +from atproto_client.models import base, string_formats class Data(base.DataModelBase): """Input data model for :obj:`com.atproto.server.reserveSigningKey`.""" - did: t.Optional[str] = None #: The DID to reserve a key for. + did: t.Optional[string_formats.Did] = None #: The DID to reserve a key for. class DataDict(t.TypedDict): - did: te.NotRequired[t.Optional[str]] #: The DID to reserve a key for. + did: te.NotRequired[t.Optional[string_formats.Did]] #: The DID to reserve a key for. class Response(base.ResponseModelBase): diff --git a/packages/atproto_client/models/com/atproto/sync/get_blob.py b/packages/atproto_client/models/com/atproto/sync/get_blob.py index f9b8a18f..3009a01b 100644 --- a/packages/atproto_client/models/com/atproto/sync/get_blob.py +++ b/packages/atproto_client/models/com/atproto/sync/get_blob.py @@ -9,19 +9,19 @@ import typing_extensions as te -from atproto_client.models import base +from atproto_client.models import base, string_formats class Params(base.ParamsModelBase): """Parameters model for :obj:`com.atproto.sync.getBlob`.""" - cid: str #: The CID of the blob to fetch. - did: str #: The DID of the account. + cid: string_formats.Cid #: The CID of the blob to fetch. + did: string_formats.Did #: The DID of the account. class ParamsDict(t.TypedDict): - cid: str #: The CID of the blob to fetch. - did: str #: The DID of the account. + cid: string_formats.Cid #: The CID of the blob to fetch. + did: string_formats.Did #: The DID of the account. #: Response raw data type. diff --git a/packages/atproto_client/models/com/atproto/sync/get_blocks.py b/packages/atproto_client/models/com/atproto/sync/get_blocks.py index 0a4bf6b1..c0abe958 100644 --- a/packages/atproto_client/models/com/atproto/sync/get_blocks.py +++ b/packages/atproto_client/models/com/atproto/sync/get_blocks.py @@ -9,19 +9,19 @@ import typing_extensions as te -from atproto_client.models import base +from atproto_client.models import base, string_formats class Params(base.ParamsModelBase): """Parameters model for :obj:`com.atproto.sync.getBlocks`.""" - cids: t.List[str] #: Cids. - did: str #: The DID of the repo. + cids: t.List[string_formats.Cid] #: Cids. + did: string_formats.Did #: The DID of the repo. class ParamsDict(t.TypedDict): - cids: t.List[str] #: Cids. - did: str #: The DID of the repo. + cids: t.List[string_formats.Cid] #: Cids. + did: string_formats.Did #: The DID of the repo. #: Response raw data type. diff --git a/packages/atproto_client/models/com/atproto/sync/get_checkout.py b/packages/atproto_client/models/com/atproto/sync/get_checkout.py index f3e68c9e..4c40c37b 100644 --- a/packages/atproto_client/models/com/atproto/sync/get_checkout.py +++ b/packages/atproto_client/models/com/atproto/sync/get_checkout.py @@ -9,17 +9,17 @@ import typing_extensions as te -from atproto_client.models import base +from atproto_client.models import base, string_formats class Params(base.ParamsModelBase): """Parameters model for :obj:`com.atproto.sync.getCheckout`.""" - did: str #: The DID of the repo. + did: string_formats.Did #: The DID of the repo. class ParamsDict(t.TypedDict): - did: str #: The DID of the repo. + did: string_formats.Did #: The DID of the repo. #: Response raw data type. diff --git a/packages/atproto_client/models/com/atproto/sync/get_head.py b/packages/atproto_client/models/com/atproto/sync/get_head.py index 0c325ff6..266f26d5 100644 --- a/packages/atproto_client/models/com/atproto/sync/get_head.py +++ b/packages/atproto_client/models/com/atproto/sync/get_head.py @@ -7,20 +7,20 @@ import typing as t -from atproto_client.models import base +from atproto_client.models import base, string_formats class Params(base.ParamsModelBase): """Parameters model for :obj:`com.atproto.sync.getHead`.""" - did: str #: The DID of the repo. + did: string_formats.Did #: The DID of the repo. class ParamsDict(t.TypedDict): - did: str #: The DID of the repo. + did: string_formats.Did #: The DID of the repo. class Response(base.ResponseModelBase): """Output data model for :obj:`com.atproto.sync.getHead`.""" - root: str #: Root. + root: string_formats.Cid #: Root. diff --git a/packages/atproto_client/models/com/atproto/sync/get_latest_commit.py b/packages/atproto_client/models/com/atproto/sync/get_latest_commit.py index 6582f48b..f25f623c 100644 --- a/packages/atproto_client/models/com/atproto/sync/get_latest_commit.py +++ b/packages/atproto_client/models/com/atproto/sync/get_latest_commit.py @@ -7,21 +7,21 @@ import typing as t -from atproto_client.models import base +from atproto_client.models import base, string_formats class Params(base.ParamsModelBase): """Parameters model for :obj:`com.atproto.sync.getLatestCommit`.""" - did: str #: The DID of the repo. + did: string_formats.Did #: The DID of the repo. class ParamsDict(t.TypedDict): - did: str #: The DID of the repo. + did: string_formats.Did #: The DID of the repo. class Response(base.ResponseModelBase): """Output data model for :obj:`com.atproto.sync.getLatestCommit`.""" - cid: str #: Cid. + cid: string_formats.Cid #: Cid. rev: str #: Rev. diff --git a/packages/atproto_client/models/com/atproto/sync/get_record.py b/packages/atproto_client/models/com/atproto/sync/get_record.py index f45ebb80..464c2ed8 100644 --- a/packages/atproto_client/models/com/atproto/sync/get_record.py +++ b/packages/atproto_client/models/com/atproto/sync/get_record.py @@ -9,26 +9,26 @@ import typing_extensions as te -from atproto_client.models import base +from atproto_client.models import base, string_formats class Params(base.ParamsModelBase): """Parameters model for :obj:`com.atproto.sync.getRecord`.""" - collection: str #: Collection. - did: str #: The DID of the repo. + collection: string_formats.Nsid #: Collection. + did: string_formats.Did #: The DID of the repo. rkey: str #: Record Key. - commit: t.Optional[str] = ( + commit: t.Optional[string_formats.Cid] = ( None #: DEPRECATED: referenced a repo commit by CID, and retrieved record as of that commit. ) class ParamsDict(t.TypedDict): - collection: str #: Collection. - did: str #: The DID of the repo. + collection: string_formats.Nsid #: Collection. + did: string_formats.Did #: The DID of the repo. rkey: str #: Record Key. commit: te.NotRequired[ - t.Optional[str] + t.Optional[string_formats.Cid] ] #: DEPRECATED: referenced a repo commit by CID, and retrieved record as of that commit. diff --git a/packages/atproto_client/models/com/atproto/sync/get_repo.py b/packages/atproto_client/models/com/atproto/sync/get_repo.py index a4570088..e29a3966 100644 --- a/packages/atproto_client/models/com/atproto/sync/get_repo.py +++ b/packages/atproto_client/models/com/atproto/sync/get_repo.py @@ -9,18 +9,18 @@ import typing_extensions as te -from atproto_client.models import base +from atproto_client.models import base, string_formats class Params(base.ParamsModelBase): """Parameters model for :obj:`com.atproto.sync.getRepo`.""" - did: str #: The DID of the repo. + did: string_formats.Did #: The DID of the repo. since: t.Optional[str] = None #: The revision ('rev') of the repo to create a diff from. class ParamsDict(t.TypedDict): - did: str #: The DID of the repo. + did: string_formats.Did #: The DID of the repo. since: te.NotRequired[t.Optional[str]] #: The revision ('rev') of the repo to create a diff from. diff --git a/packages/atproto_client/models/com/atproto/sync/get_repo_status.py b/packages/atproto_client/models/com/atproto/sync/get_repo_status.py index ea2f45ba..5e734b2a 100644 --- a/packages/atproto_client/models/com/atproto/sync/get_repo_status.py +++ b/packages/atproto_client/models/com/atproto/sync/get_repo_status.py @@ -7,24 +7,24 @@ import typing as t -from atproto_client.models import base +from atproto_client.models import base, string_formats class Params(base.ParamsModelBase): """Parameters model for :obj:`com.atproto.sync.getRepoStatus`.""" - did: str #: The DID of the repo. + did: string_formats.Did #: The DID of the repo. class ParamsDict(t.TypedDict): - did: str #: The DID of the repo. + did: string_formats.Did #: The DID of the repo. class Response(base.ResponseModelBase): """Output data model for :obj:`com.atproto.sync.getRepoStatus`.""" active: bool #: Active. - did: str #: Did. + did: string_formats.Did #: Did. rev: t.Optional[str] = None #: Optional field, the current rev of the repo, if active=true. status: t.Optional[t.Union[t.Literal['takendown'], t.Literal['suspended'], t.Literal['deactivated'], str]] = ( None #: If active=false, this optional field indicates a possible reason for why the account is not active. If active=false and no status is supplied, then the host makes no claim for why the repository is no longer being hosted. diff --git a/packages/atproto_client/models/com/atproto/sync/list_blobs.py b/packages/atproto_client/models/com/atproto/sync/list_blobs.py index 4002254c..036d77c8 100644 --- a/packages/atproto_client/models/com/atproto/sync/list_blobs.py +++ b/packages/atproto_client/models/com/atproto/sync/list_blobs.py @@ -10,20 +10,20 @@ import typing_extensions as te from pydantic import Field -from atproto_client.models import base +from atproto_client.models import base, string_formats class Params(base.ParamsModelBase): """Parameters model for :obj:`com.atproto.sync.listBlobs`.""" - did: str #: The DID of the repo. + did: string_formats.Did #: The DID of the repo. cursor: t.Optional[str] = None #: Cursor. limit: t.Optional[int] = Field(default=500, ge=1, le=1000) #: Limit. since: t.Optional[str] = None #: Optional revision of the repo to list blobs since. class ParamsDict(t.TypedDict): - did: str #: The DID of the repo. + did: string_formats.Did #: The DID of the repo. cursor: te.NotRequired[t.Optional[str]] #: Cursor. limit: te.NotRequired[t.Optional[int]] #: Limit. since: te.NotRequired[t.Optional[str]] #: Optional revision of the repo to list blobs since. @@ -32,5 +32,5 @@ class ParamsDict(t.TypedDict): class Response(base.ResponseModelBase): """Output data model for :obj:`com.atproto.sync.listBlobs`.""" - cids: t.List[str] #: Cids. + cids: t.List[string_formats.Cid] #: Cids. cursor: t.Optional[str] = None #: Cursor. diff --git a/packages/atproto_client/models/com/atproto/sync/list_repos.py b/packages/atproto_client/models/com/atproto/sync/list_repos.py index 13803bad..9cd5fb89 100644 --- a/packages/atproto_client/models/com/atproto/sync/list_repos.py +++ b/packages/atproto_client/models/com/atproto/sync/list_repos.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -37,8 +39,8 @@ class Response(base.ResponseModelBase): class Repo(base.ModelBase): """Definition model for :obj:`com.atproto.sync.listRepos`.""" - did: str #: Did. - head: str #: Current repo commit CID. + did: string_formats.Did #: Did. + head: string_formats.Cid #: Current repo commit CID. rev: str #: Rev. active: t.Optional[bool] = None #: Active. status: t.Optional[t.Union[t.Literal['takendown'], t.Literal['suspended'], t.Literal['deactivated'], str]] = ( diff --git a/packages/atproto_client/models/com/atproto/sync/subscribe_repos.py b/packages/atproto_client/models/com/atproto/sync/subscribe_repos.py index 4ebbb4f4..862fbb69 100644 --- a/packages/atproto_client/models/com/atproto/sync/subscribe_repos.py +++ b/packages/atproto_client/models/com/atproto/sync/subscribe_repos.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_core.cid import CIDType @@ -35,10 +37,10 @@ class Commit(base.ModelBase): commit: 'CIDType' #: Repo commit object CID. ops: t.List['models.ComAtprotoSyncSubscribeRepos.RepoOp'] = Field(max_length=200) #: Ops. rebase: bool #: DEPRECATED -- unused. - repo: str #: The repo this event comes from. + repo: string_formats.Did #: The repo this event comes from. rev: str #: The rev of the emitted commit. Note that this information is also in the commit object included in blocks, unless this is a tooBig event. seq: int #: The stream sequence number of this message. - time: str #: Timestamp of when this message was originally broadcast. + time: string_formats.DateTime #: Timestamp of when this message was originally broadcast. too_big: bool #: Indicates that this commit contained too many ops, or data size was too large. Consumers will need to make a separate request to get missing data. prev: t.Optional['CIDType'] = ( None #: DEPRECATED -- unused. WARNING -- nullable and optional; stick with optional to ensure golang interoperability. @@ -53,10 +55,10 @@ class Commit(base.ModelBase): class Identity(base.ModelBase): """Definition model for :obj:`com.atproto.sync.subscribeRepos`. Represents a change to an account's identity. Could be an updated handle, signing key, or pds hosting endpoint. Serves as a prod to all downstream services to refresh their identity cache.""" - did: str #: Did. + did: string_formats.Did #: Did. seq: int #: Seq. - time: str #: Time. - handle: t.Optional[str] = ( + time: string_formats.DateTime #: Time. + handle: t.Optional[string_formats.Handle] = ( None #: The current handle for the account, or 'handle.invalid' if validation fails. This field is optional, might have been validated or passed-through from an upstream source. Semantics and behaviors for PDS vs Relay may evolve in the future; see atproto specs for more details. ) @@ -71,9 +73,9 @@ class Account(base.ModelBase): active: ( bool #: Indicates that the account has a repository which can be fetched from the host that emitted this event. ) - did: str #: Did. + did: string_formats.Did #: Did. seq: int #: Seq. - time: str #: Time. + time: string_formats.DateTime #: Time. status: t.Optional[ t.Union[t.Literal['takendown'], t.Literal['suspended'], t.Literal['deleted'], t.Literal['deactivated'], str] ] = None #: If active=false, this optional field indicates a reason for why the account is not active. @@ -86,10 +88,10 @@ class Account(base.ModelBase): class Handle(base.ModelBase): """Definition model for :obj:`com.atproto.sync.subscribeRepos`. DEPRECATED -- Use #identity event instead.""" - did: str #: Did. - handle: str #: Handle. + did: string_formats.Did #: Did. + handle: string_formats.Handle #: Handle. seq: int #: Seq. - time: str #: Time. + time: string_formats.DateTime #: Time. py_type: t.Literal['com.atproto.sync.subscribeRepos#handle'] = Field( default='com.atproto.sync.subscribeRepos#handle', alias='$type', frozen=True @@ -99,9 +101,9 @@ class Handle(base.ModelBase): class Migrate(base.ModelBase): """Definition model for :obj:`com.atproto.sync.subscribeRepos`. DEPRECATED -- Use #account event instead.""" - did: str #: Did. + did: string_formats.Did #: Did. seq: int #: Seq. - time: str #: Time. + time: string_formats.DateTime #: Time. migrate_to: t.Optional[str] = None #: Migrate to. py_type: t.Literal['com.atproto.sync.subscribeRepos#migrate'] = Field( @@ -112,9 +114,9 @@ class Migrate(base.ModelBase): class Tombstone(base.ModelBase): """Definition model for :obj:`com.atproto.sync.subscribeRepos`. DEPRECATED -- Use #account event instead.""" - did: str #: Did. + did: string_formats.Did #: Did. seq: int #: Seq. - time: str #: Time. + time: string_formats.DateTime #: Time. py_type: t.Literal['com.atproto.sync.subscribeRepos#tombstone'] = Field( default='com.atproto.sync.subscribeRepos#tombstone', alias='$type', frozen=True diff --git a/packages/atproto_client/models/string_formats.py b/packages/atproto_client/models/string_formats.py new file mode 100644 index 00000000..b0598d5e --- /dev/null +++ b/packages/atproto_client/models/string_formats.py @@ -0,0 +1,219 @@ +import re +from datetime import datetime +from typing import Callable, Mapping, Set, Union, cast +from urllib.parse import urlparse + +from atproto_core.nsid import validate_nsid as atproto_core_validate_nsid +from pydantic import BeforeValidator, Field, ValidationInfo +from pydantic_core import core_schema +from typing_extensions import Annotated, Literal + +_OPT_IN_KEY: Literal['strict_string_format'] = 'strict_string_format' + +# constants +MAX_HANDLE_LENGTH: int = 253 +MAX_NSID_LENGTH: int = 317 +MAX_RECORD_KEY_LENGTH: int = 512 +MAX_URI_LENGTH: int = 8 * 1024 +MIN_CID_LENGTH: int = 8 +TID_LENGTH: int = 13 +INVALID_RECORD_KEYS: Set[str] = {'.', '..'} +MAX_DID_LENGTH: int = 2048 # Method-specific identifier max length +MAX_AT_URI_LENGTH: int = 8 * 1024 + +# patterns +DOMAIN_RE = re.compile(r'^([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z][a-zA-Z0-9-]*[a-zA-Z]$') +DID_RE = re.compile( + r'^did:' # Required prefix + r'[a-z]+:' # method-name (lowercase only) + r'[a-zA-Z0-9._%-]{1,2048}' # method-specific-id with length limit + r'(? Callable[..., str]: + """Skip pydantic validation if not opting into strict validation via context.""" + + def wrapper(v: str, info: ValidationInfo) -> str: + """Could likely be generalized to support arbitrary signatures.""" + if info and isinstance(info.context, Mapping) and info.context.get(_OPT_IN_KEY, False): + return cast(core_schema.NoInfoValidatorFunction, validate_fn)(v) + return v + + return wrapper + + +@only_validate_if_strict +def validate_handle(v: str) -> str: + # Check ASCII first + if not v.isascii(): + raise ValueError('Invalid handle: must contain only ASCII characters') + + # Use the spec's reference regex + if not DOMAIN_RE.match(v.lower()) or len(v) > MAX_HANDLE_LENGTH: + raise ValueError( + f'Invalid handle: must be a domain name (e.g. user.bsky.social) with max length {MAX_HANDLE_LENGTH}' + ) + + return v + + +@only_validate_if_strict +def validate_did(v: str) -> str: + # Check for invalid characters + if any(c in v for c in '/?#[]@'): + raise ValueError('Invalid DID: cannot contain /, ?, #, [, ], or @ characters') + + # Check for invalid percent encoding + if '%' in v: + percent_segments = v.split('%')[1:] + for segment in percent_segments: + if len(segment) < 2 or not segment[:2].isalnum(): + raise ValueError('Invalid DID: invalid percent-encoding') + + # Check against regex pattern (which now includes length restriction) + if not DID_RE.match(v): + raise ValueError('Invalid DID: must be in format did:method:identifier (e.g. did:plc:1234abcd)') + + return v + + +@only_validate_if_strict +def validate_nsid(v: str) -> str: + if ( + not atproto_core_validate_nsid(v, soft_fail=True) + or len(v) > MAX_NSID_LENGTH + or any(c in v for c in '@_*#!') # Explicitly disallow special chars + or any(len(seg) > 63 for seg in v.split('.')) # Max segment length + or any(seg[-1].isdigit() for seg in v.split('.')) # No segments ending in numbers + ): + raise ValueError( + f'Invalid NSID: must be dot-separated segments (e.g. app.bsky.feed.post) with max length {MAX_NSID_LENGTH}' + ) + return v + + +@only_validate_if_strict +def validate_language(v: str) -> str: + if not LANG_RE.match(v): + raise ValueError('Invalid language code: must be ISO language code (e.g. en or en-US)') + return v + + +@only_validate_if_strict +def validate_record_key(v: str) -> str: + if v in INVALID_RECORD_KEYS or not RKEY_RE.match(v): + raise ValueError( + 'Invalid record key: must contain only alphanumeric, dot, underscore, colon, tilde, or hyphen characters' + ) + return v + + +@only_validate_if_strict +def validate_cid(v: str) -> str: + if not CID_RE.match(v): + raise ValueError('Invalid CID: must be a valid Content Identifier with minimum length 8') + return v + + +@only_validate_if_strict +def validate_at_uri(v: str) -> str: + if len(v) >= MAX_AT_URI_LENGTH: + raise ValueError(f'Invalid AT-URI: must be under {MAX_AT_URI_LENGTH} chars') + + if not AT_URI_RE.match(v): + raise ValueError('Invalid AT-URI: invalid format') + + return v + + +@only_validate_if_strict +def validate_datetime(v: str) -> str: + # Must contain uppercase T and Z if used + if v != v.strip(): + raise ValueError('Invalid datetime: no whitespace allowed') + + # Must contain uppercase T + if 'T' not in v or ('z' in v and 'Z' not in v): + raise ValueError('Invalid datetime: must contain uppercase T separator') + + # Must have seconds (HH:MM:SS) + time_part = v.split('T')[1] + if len(time_part.split(':')) != 3: + raise ValueError('Invalid datetime: seconds are required') + + # If has decimal point, must have digits after it + if '.' in v and not re.search(r'\.\d+', v): + raise ValueError('Invalid datetime: invalid fractional seconds format') + + # Must match exactly timezone pattern with nothing after + if v.endswith('-00:00'): + raise ValueError('Invalid datetime: -00:00 timezone not allowed') + if not (re.match(r'.*Z$', v) or re.match(r'.*[+-]\d{2}:\d{2}$', v)): + raise ValueError('Invalid datetime: must include timezone') + + # Final validation + try: + datetime.fromisoformat(v.replace('Z', '+00:00')) + return v + except ValueError: + raise ValueError('Invalid datetime: invalid format') from None + + +@only_validate_if_strict +def validate_tid(v: str) -> str: + if not TID_RE.match(v) or (ord(v[0]) & 0x40): + raise ValueError(f'Invalid TID: must be exactly {TID_LENGTH} lowercase letters/numbers') + return v + + +@only_validate_if_strict +def validate_uri(v: str) -> str: + if len(v) >= MAX_URI_LENGTH or ' ' in v: + raise ValueError(f'Invalid URI: must be under {MAX_URI_LENGTH} chars and not contain spaces') + parsed = urlparse(v) + if not ( + parsed.scheme + and parsed.scheme[0].isalpha() + and (parsed.netloc or parsed.path or parsed.query or parsed.fragment) + ): + raise ValueError('Invalid URI: must be a valid URI with scheme and authority/path (e.g. https://example.com)') + return v + + +Handle = Annotated[str, BeforeValidator(validate_handle)] +Did = Annotated[str, BeforeValidator(validate_did)] +Nsid = Annotated[str, BeforeValidator(validate_nsid)] +Language = Annotated[str, BeforeValidator(validate_language)] +RecordKey = Annotated[str, BeforeValidator(validate_record_key)] +Cid = Annotated[str, BeforeValidator(validate_cid)] +AtUri = Annotated[str, BeforeValidator(validate_at_uri)] +DateTime = Annotated[str, BeforeValidator(validate_datetime)] # see pydantic-extra-types #239 +Tid = Annotated[str, BeforeValidator(validate_tid)] +Uri = Annotated[str, BeforeValidator(validate_uri)] + +# Any valid ATProto string format +AtProtoString = Annotated[ + Union[Handle, Did, Nsid, AtUri, Cid, DateTime, Tid, RecordKey, Uri, Language], + Field(description='ATProto string format'), +] diff --git a/packages/atproto_client/models/tools/ozone/communication/create_template.py b/packages/atproto_client/models/tools/ozone/communication/create_template.py index 90dec3fb..f5e6c9a7 100644 --- a/packages/atproto_client/models/tools/ozone/communication/create_template.py +++ b/packages/atproto_client/models/tools/ozone/communication/create_template.py @@ -9,7 +9,7 @@ import typing_extensions as te -from atproto_client.models import base +from atproto_client.models import base, string_formats class Data(base.DataModelBase): @@ -18,13 +18,13 @@ class Data(base.DataModelBase): content_markdown: str #: Content of the template, markdown supported, can contain variable placeholders. name: str #: Name of the template. subject: str #: Subject of the message, used in emails. - created_by: t.Optional[str] = None #: DID of the user who is creating the template. - lang: t.Optional[str] = None #: Message language. + created_by: t.Optional[string_formats.Did] = None #: DID of the user who is creating the template. + lang: t.Optional[string_formats.Language] = None #: Message language. class DataDict(t.TypedDict): content_markdown: str #: Content of the template, markdown supported, can contain variable placeholders. name: str #: Name of the template. subject: str #: Subject of the message, used in emails. - created_by: te.NotRequired[t.Optional[str]] #: DID of the user who is creating the template. - lang: te.NotRequired[t.Optional[str]] #: Message language. + created_by: te.NotRequired[t.Optional[string_formats.Did]] #: DID of the user who is creating the template. + lang: te.NotRequired[t.Optional[string_formats.Language]] #: Message language. diff --git a/packages/atproto_client/models/tools/ozone/communication/defs.py b/packages/atproto_client/models/tools/ozone/communication/defs.py index 6c2fe25e..d36e33e1 100644 --- a/packages/atproto_client/models/tools/ozone/communication/defs.py +++ b/packages/atproto_client/models/tools/ozone/communication/defs.py @@ -9,20 +9,20 @@ from pydantic import Field -from atproto_client.models import base +from atproto_client.models import base, string_formats class TemplateView(base.ModelBase): """Definition model for :obj:`tools.ozone.communication.defs`.""" content_markdown: str #: Subject of the message, used in emails. - created_at: str #: Created at. + created_at: string_formats.DateTime #: Created at. disabled: bool #: Disabled. id: str #: Id. - last_updated_by: str #: DID of the user who last updated the template. + last_updated_by: string_formats.Did #: DID of the user who last updated the template. name: str #: Name of the template. - updated_at: str #: Updated at. - lang: t.Optional[str] = None #: Message language. + updated_at: string_formats.DateTime #: Updated at. + lang: t.Optional[string_formats.Language] = None #: Message language. subject: t.Optional[str] = None #: Content of the template, can contain markdown and variable placeholders. py_type: t.Literal['tools.ozone.communication.defs#templateView'] = Field( diff --git a/packages/atproto_client/models/tools/ozone/communication/update_template.py b/packages/atproto_client/models/tools/ozone/communication/update_template.py index 14be48bc..43226db7 100644 --- a/packages/atproto_client/models/tools/ozone/communication/update_template.py +++ b/packages/atproto_client/models/tools/ozone/communication/update_template.py @@ -9,7 +9,7 @@ import typing_extensions as te -from atproto_client.models import base +from atproto_client.models import base, string_formats class Data(base.DataModelBase): @@ -20,10 +20,10 @@ class Data(base.DataModelBase): None #: Content of the template, markdown supported, can contain variable placeholders. ) disabled: t.Optional[bool] = None #: Disabled. - lang: t.Optional[str] = None #: Message language. + lang: t.Optional[string_formats.Language] = None #: Message language. name: t.Optional[str] = None #: Name of the template. subject: t.Optional[str] = None #: Subject of the message, used in emails. - updated_by: t.Optional[str] = None #: DID of the user who is updating the template. + updated_by: t.Optional[string_formats.Did] = None #: DID of the user who is updating the template. class DataDict(t.TypedDict): @@ -32,7 +32,7 @@ class DataDict(t.TypedDict): t.Optional[str] ] #: Content of the template, markdown supported, can contain variable placeholders. disabled: te.NotRequired[t.Optional[bool]] #: Disabled. - lang: te.NotRequired[t.Optional[str]] #: Message language. + lang: te.NotRequired[t.Optional[string_formats.Language]] #: Message language. name: te.NotRequired[t.Optional[str]] #: Name of the template. subject: te.NotRequired[t.Optional[str]] #: Subject of the message, used in emails. - updated_by: te.NotRequired[t.Optional[str]] #: DID of the user who is updating the template. + updated_by: te.NotRequired[t.Optional[string_formats.Did]] #: DID of the user who is updating the template. diff --git a/packages/atproto_client/models/tools/ozone/moderation/defs.py b/packages/atproto_client/models/tools/ozone/moderation/defs.py index 206b0f1b..b8f67d63 100644 --- a/packages/atproto_client/models/tools/ozone/moderation/defs.py +++ b/packages/atproto_client/models/tools/ozone/moderation/defs.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models.unknown_type import UnknownType @@ -19,8 +21,8 @@ class ModEventView(base.ModelBase): """Definition model for :obj:`tools.ozone.moderation.defs`.""" - created_at: str #: Created at. - created_by: str #: Created by. + created_at: string_formats.DateTime #: Created at. + created_by: string_formats.Did #: Created by. event: te.Annotated[ t.Union[ 'models.ToolsOzoneModerationDefs.ModEventTakedown', @@ -65,8 +67,8 @@ class ModEventView(base.ModelBase): class ModEventViewDetail(base.ModelBase): """Definition model for :obj:`tools.ozone.moderation.defs`.""" - created_at: str #: Created at. - created_by: str #: Created by. + created_at: string_formats.DateTime #: Created at. + created_by: string_formats.Did #: Created by. event: te.Annotated[ t.Union[ 'models.ToolsOzoneModerationDefs.ModEventTakedown', @@ -110,14 +112,18 @@ class ModEventViewDetail(base.ModelBase): class SubjectStatusView(base.ModelBase): """Definition model for :obj:`tools.ozone.moderation.defs`.""" - created_at: str #: Timestamp referencing the first moderation status impacting event was emitted on the subject. + created_at: ( + string_formats.DateTime + ) #: Timestamp referencing the first moderation status impacting event was emitted on the subject. id: int #: Id. review_state: 'models.ToolsOzoneModerationDefs.SubjectReviewState' #: Review state. subject: te.Annotated[ t.Union['models.ComAtprotoAdminDefs.RepoRef', 'models.ComAtprotoRepoStrongRef.Main'], Field(discriminator='py_type'), ] #: Subject. - updated_at: str #: Timestamp referencing when the last update was made to the moderation status of the subject. + updated_at: ( + string_formats.DateTime + ) #: Timestamp referencing when the last update was made to the moderation status of the subject. appealed: t.Optional[bool] = ( None #: True indicates that the a previously taken moderator action was appealed against, by the author of the content. False indicates last appeal was resolved by moderators. ) @@ -128,17 +134,17 @@ class SubjectStatusView(base.ModelBase): Field(default=None, discriminator='py_type'), ] ] = None #: Hosting. - last_appealed_at: t.Optional[str] = ( + last_appealed_at: t.Optional[string_formats.DateTime] = ( None #: Timestamp referencing when the author of the subject appealed a moderation action. ) - last_reported_at: t.Optional[str] = None #: Last reported at. - last_reviewed_at: t.Optional[str] = None #: Last reviewed at. - last_reviewed_by: t.Optional[str] = None #: Last reviewed by. - mute_reporting_until: t.Optional[str] = None #: Mute reporting until. - mute_until: t.Optional[str] = None #: Mute until. - subject_blob_cids: t.Optional[t.List[str]] = None #: Subject blob cids. + last_reported_at: t.Optional[string_formats.DateTime] = None #: Last reported at. + last_reviewed_at: t.Optional[string_formats.DateTime] = None #: Last reviewed at. + last_reviewed_by: t.Optional[string_formats.Did] = None #: Last reviewed by. + mute_reporting_until: t.Optional[string_formats.DateTime] = None #: Mute reporting until. + mute_until: t.Optional[string_formats.DateTime] = None #: Mute until. + subject_blob_cids: t.Optional[t.List[string_formats.Cid]] = None #: Subject blob cids. subject_repo_handle: t.Optional[str] = None #: Subject repo handle. - suspend_until: t.Optional[str] = None #: Suspend until. + suspend_until: t.Optional[string_formats.DateTime] = None #: Suspend until. tags: t.Optional[t.List[str]] = None #: Tags. takendown: t.Optional[bool] = None #: Takendown. @@ -349,7 +355,7 @@ class AccountEvent(base.ModelBase): active: ( bool #: Indicates that the account has a repository which can be fetched from the host that emitted this event. ) - timestamp: str #: Timestamp. + timestamp: string_formats.DateTime #: Timestamp. comment: t.Optional[str] = None #: Comment. status: t.Optional[ t.Union[ @@ -371,10 +377,10 @@ class AccountEvent(base.ModelBase): class IdentityEvent(base.ModelBase): """Definition model for :obj:`tools.ozone.moderation.defs`. Logs identity related events on a repo subject. Normally captured by automod from the firehose and emitted to ozone for historical tracking.""" - timestamp: str #: Timestamp. + timestamp: string_formats.DateTime #: Timestamp. comment: t.Optional[str] = None #: Comment. - handle: t.Optional[str] = None #: Handle. - pds_host: t.Optional[str] = None #: Pds host. + handle: t.Optional[string_formats.Handle] = None #: Handle. + pds_host: t.Optional[string_formats.Uri] = None #: Pds host. tombstone: t.Optional[bool] = None #: Tombstone. py_type: t.Literal['tools.ozone.moderation.defs#identityEvent'] = Field( @@ -386,8 +392,8 @@ class RecordEvent(base.ModelBase): """Definition model for :obj:`tools.ozone.moderation.defs`. Logs lifecycle event on a record subject. Normally captured by automod from the firehose and emitted to ozone for historical tracking.""" op: t.Union[t.Literal['create'], t.Literal['update'], t.Literal['delete'], str] #: Op. - timestamp: str #: Timestamp. - cid: t.Optional[str] = None #: Cid. + timestamp: string_formats.DateTime #: Timestamp. + cid: t.Optional[string_formats.Cid] = None #: Cid. comment: t.Optional[str] = None #: Comment. py_type: t.Literal['tools.ozone.moderation.defs#recordEvent'] = Field( @@ -398,12 +404,12 @@ class RecordEvent(base.ModelBase): class RepoView(base.ModelBase): """Definition model for :obj:`tools.ozone.moderation.defs`.""" - did: str #: Did. - handle: str #: Handle. - indexed_at: str #: Indexed at. + did: string_formats.Did #: Did. + handle: string_formats.Handle #: Handle. + indexed_at: string_formats.DateTime #: Indexed at. moderation: 'models.ToolsOzoneModerationDefs.Moderation' #: Moderation. related_records: t.List['UnknownType'] #: Related records. - deactivated_at: t.Optional[str] = None #: Deactivated at. + deactivated_at: t.Optional[string_formats.DateTime] = None #: Deactivated at. email: t.Optional[str] = None #: Email. invite_note: t.Optional[str] = None #: Invite note. invited_by: t.Optional['models.ComAtprotoServerDefs.InviteCode'] = None #: Invited by. @@ -418,14 +424,14 @@ class RepoView(base.ModelBase): class RepoViewDetail(base.ModelBase): """Definition model for :obj:`tools.ozone.moderation.defs`.""" - did: str #: Did. - handle: str #: Handle. - indexed_at: str #: Indexed at. + did: string_formats.Did #: Did. + handle: string_formats.Handle #: Handle. + indexed_at: string_formats.DateTime #: Indexed at. moderation: 'models.ToolsOzoneModerationDefs.ModerationDetail' #: Moderation. related_records: t.List['UnknownType'] #: Related records. - deactivated_at: t.Optional[str] = None #: Deactivated at. + deactivated_at: t.Optional[string_formats.DateTime] = None #: Deactivated at. email: t.Optional[str] = None #: Email. - email_confirmed_at: t.Optional[str] = None #: Email confirmed at. + email_confirmed_at: t.Optional[string_formats.DateTime] = None #: Email confirmed at. invite_note: t.Optional[str] = None #: Invite note. invited_by: t.Optional['models.ComAtprotoServerDefs.InviteCode'] = None #: Invited by. invites: t.Optional[t.List['models.ComAtprotoServerDefs.InviteCode']] = None #: Invites. @@ -441,7 +447,7 @@ class RepoViewDetail(base.ModelBase): class RepoViewNotFound(base.ModelBase): """Definition model for :obj:`tools.ozone.moderation.defs`.""" - did: str #: Did. + did: string_formats.Did #: Did. py_type: t.Literal['tools.ozone.moderation.defs#repoViewNotFound'] = Field( default='tools.ozone.moderation.defs#repoViewNotFound', alias='$type', frozen=True @@ -451,12 +457,12 @@ class RepoViewNotFound(base.ModelBase): class RecordView(base.ModelBase): """Definition model for :obj:`tools.ozone.moderation.defs`.""" - blob_cids: t.List[str] #: Blob cids. - cid: str #: Cid. - indexed_at: str #: Indexed at. + blob_cids: t.List[string_formats.Cid] #: Blob cids. + cid: string_formats.Cid #: Cid. + indexed_at: string_formats.DateTime #: Indexed at. moderation: 'models.ToolsOzoneModerationDefs.Moderation' #: Moderation. repo: 'models.ToolsOzoneModerationDefs.RepoView' #: Repo. - uri: str #: Uri. + uri: string_formats.AtUri #: Uri. value: 'UnknownType' #: Value. py_type: t.Literal['tools.ozone.moderation.defs#recordView'] = Field( @@ -468,11 +474,11 @@ class RecordViewDetail(base.ModelBase): """Definition model for :obj:`tools.ozone.moderation.defs`.""" blobs: t.List['models.ToolsOzoneModerationDefs.BlobView'] #: Blobs. - cid: str #: Cid. - indexed_at: str #: Indexed at. + cid: string_formats.Cid #: Cid. + indexed_at: string_formats.DateTime #: Indexed at. moderation: 'models.ToolsOzoneModerationDefs.ModerationDetail' #: Moderation. repo: 'models.ToolsOzoneModerationDefs.RepoView' #: Repo. - uri: str #: Uri. + uri: string_formats.AtUri #: Uri. value: 'UnknownType' #: Value. labels: t.Optional[t.List['models.ComAtprotoLabelDefs.Label']] = None #: Labels. @@ -484,7 +490,7 @@ class RecordViewDetail(base.ModelBase): class RecordViewNotFound(base.ModelBase): """Definition model for :obj:`tools.ozone.moderation.defs`.""" - uri: str #: Uri. + uri: string_formats.AtUri #: Uri. py_type: t.Literal['tools.ozone.moderation.defs#recordViewNotFound'] = Field( default='tools.ozone.moderation.defs#recordViewNotFound', alias='$type', frozen=True @@ -514,8 +520,8 @@ class ModerationDetail(base.ModelBase): class BlobView(base.ModelBase): """Definition model for :obj:`tools.ozone.moderation.defs`.""" - cid: str #: Cid. - created_at: str #: Created at. + cid: string_formats.Cid #: Cid. + created_at: string_formats.DateTime #: Created at. mime_type: str #: Mime type. size: int #: Size. details: t.Optional[ @@ -565,11 +571,11 @@ class AccountHosting(base.ModelBase): t.Literal['unknown'], str, ] #: Status. - created_at: t.Optional[str] = None #: Created at. - deactivated_at: t.Optional[str] = None #: Deactivated at. - deleted_at: t.Optional[str] = None #: Deleted at. - reactivated_at: t.Optional[str] = None #: Reactivated at. - updated_at: t.Optional[str] = None #: Updated at. + created_at: t.Optional[string_formats.DateTime] = None #: Created at. + deactivated_at: t.Optional[string_formats.DateTime] = None #: Deactivated at. + deleted_at: t.Optional[string_formats.DateTime] = None #: Deleted at. + reactivated_at: t.Optional[string_formats.DateTime] = None #: Reactivated at. + updated_at: t.Optional[string_formats.DateTime] = None #: Updated at. py_type: t.Literal['tools.ozone.moderation.defs#accountHosting'] = Field( default='tools.ozone.moderation.defs#accountHosting', alias='$type', frozen=True @@ -580,9 +586,9 @@ class RecordHosting(base.ModelBase): """Definition model for :obj:`tools.ozone.moderation.defs`.""" status: t.Union[t.Literal['deleted'], t.Literal['unknown'], str] #: Status. - created_at: t.Optional[str] = None #: Created at. - deleted_at: t.Optional[str] = None #: Deleted at. - updated_at: t.Optional[str] = None #: Updated at. + created_at: t.Optional[string_formats.DateTime] = None #: Created at. + deleted_at: t.Optional[string_formats.DateTime] = None #: Deleted at. + updated_at: t.Optional[string_formats.DateTime] = None #: Updated at. py_type: t.Literal['tools.ozone.moderation.defs#recordHosting'] = Field( default='tools.ozone.moderation.defs#recordHosting', alias='$type', frozen=True diff --git a/packages/atproto_client/models/tools/ozone/moderation/emit_event.py b/packages/atproto_client/models/tools/ozone/moderation/emit_event.py index 7ab4a4cd..4b9efc04 100644 --- a/packages/atproto_client/models/tools/ozone/moderation/emit_event.py +++ b/packages/atproto_client/models/tools/ozone/moderation/emit_event.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -18,7 +20,7 @@ class Data(base.DataModelBase): """Input data model for :obj:`tools.ozone.moderation.emitEvent`.""" - created_by: str #: Created by. + created_by: string_formats.Did #: Created by. event: te.Annotated[ t.Union[ 'models.ToolsOzoneModerationDefs.ModEventTakedown', @@ -45,11 +47,11 @@ class Data(base.DataModelBase): t.Union['models.ComAtprotoAdminDefs.RepoRef', 'models.ComAtprotoRepoStrongRef.Main'], Field(discriminator='py_type'), ] #: Subject. - subject_blob_cids: t.Optional[t.List[str]] = None #: Subject blob cids. + subject_blob_cids: t.Optional[t.List[string_formats.Cid]] = None #: Subject blob cids. class DataDict(t.TypedDict): - created_by: str #: Created by. + created_by: string_formats.Did #: Created by. event: te.Annotated[ t.Union[ 'models.ToolsOzoneModerationDefs.ModEventTakedown', @@ -76,4 +78,4 @@ class DataDict(t.TypedDict): t.Union['models.ComAtprotoAdminDefs.RepoRef', 'models.ComAtprotoRepoStrongRef.Main'], Field(discriminator='py_type'), ] #: Subject. - subject_blob_cids: te.NotRequired[t.Optional[t.List[str]]] #: Subject blob cids. + subject_blob_cids: te.NotRequired[t.Optional[t.List[string_formats.Cid]]] #: Subject blob cids. diff --git a/packages/atproto_client/models/tools/ozone/moderation/get_record.py b/packages/atproto_client/models/tools/ozone/moderation/get_record.py index 72995f4d..dfdb4734 100644 --- a/packages/atproto_client/models/tools/ozone/moderation/get_record.py +++ b/packages/atproto_client/models/tools/ozone/moderation/get_record.py @@ -9,16 +9,16 @@ import typing_extensions as te -from atproto_client.models import base +from atproto_client.models import base, string_formats class Params(base.ParamsModelBase): """Parameters model for :obj:`tools.ozone.moderation.getRecord`.""" - uri: str #: Uri. - cid: t.Optional[str] = None #: Cid. + uri: string_formats.AtUri #: Uri. + cid: t.Optional[string_formats.Cid] = None #: Cid. class ParamsDict(t.TypedDict): - uri: str #: Uri. - cid: te.NotRequired[t.Optional[str]] #: Cid. + uri: string_formats.AtUri #: Uri. + cid: te.NotRequired[t.Optional[string_formats.Cid]] #: Cid. diff --git a/packages/atproto_client/models/tools/ozone/moderation/get_records.py b/packages/atproto_client/models/tools/ozone/moderation/get_records.py index c4522c57..28e12d18 100644 --- a/packages/atproto_client/models/tools/ozone/moderation/get_records.py +++ b/packages/atproto_client/models/tools/ozone/moderation/get_records.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -18,11 +20,11 @@ class Params(base.ParamsModelBase): """Parameters model for :obj:`tools.ozone.moderation.getRecords`.""" - uris: t.List[str] = Field(max_length=100) #: Uris. + uris: t.List[string_formats.AtUri] = Field(max_length=100) #: Uris. class ParamsDict(t.TypedDict): - uris: t.List[str] #: Uris. + uris: t.List[string_formats.AtUri] #: Uris. class Response(base.ResponseModelBase): diff --git a/packages/atproto_client/models/tools/ozone/moderation/get_repo.py b/packages/atproto_client/models/tools/ozone/moderation/get_repo.py index 94b45a98..3c8014b5 100644 --- a/packages/atproto_client/models/tools/ozone/moderation/get_repo.py +++ b/packages/atproto_client/models/tools/ozone/moderation/get_repo.py @@ -7,14 +7,14 @@ import typing as t -from atproto_client.models import base +from atproto_client.models import base, string_formats class Params(base.ParamsModelBase): """Parameters model for :obj:`tools.ozone.moderation.getRepo`.""" - did: str #: Did. + did: string_formats.Did #: Did. class ParamsDict(t.TypedDict): - did: str #: Did. + did: string_formats.Did #: Did. diff --git a/packages/atproto_client/models/tools/ozone/moderation/get_repos.py b/packages/atproto_client/models/tools/ozone/moderation/get_repos.py index 6a1f436e..c27e888a 100644 --- a/packages/atproto_client/models/tools/ozone/moderation/get_repos.py +++ b/packages/atproto_client/models/tools/ozone/moderation/get_repos.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -18,11 +20,11 @@ class Params(base.ParamsModelBase): """Parameters model for :obj:`tools.ozone.moderation.getRepos`.""" - dids: t.List[str] = Field(max_length=100) #: Dids. + dids: t.List[string_formats.Did] = Field(max_length=100) #: Dids. class ParamsDict(t.TypedDict): - dids: t.List[str] #: Dids. + dids: t.List[string_formats.Did] #: Dids. class Response(base.ResponseModelBase): diff --git a/packages/atproto_client/models/tools/ozone/moderation/query_events.py b/packages/atproto_client/models/tools/ozone/moderation/query_events.py index 07b1d36c..c3c5e030 100644 --- a/packages/atproto_client/models/tools/ozone/moderation/query_events.py +++ b/packages/atproto_client/models/tools/ozone/moderation/query_events.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -24,15 +26,15 @@ class Params(base.ParamsModelBase): added_tags: t.Optional[t.List[str]] = ( None #: If specified, only events where all of these tags were added are returned. ) - collections: t.Optional[t.List[str]] = Field( + collections: t.Optional[t.List[string_formats.Nsid]] = Field( default=None, max_length=20 ) #: If specified, only events where the subject belongs to the given collections will be returned. When subjectType is set to 'account', this will be ignored. comment: t.Optional[str] = ( None #: If specified, only events with comments containing the keyword are returned. Apply || separator to use multiple keywords and match using OR condition. ) - created_after: t.Optional[str] = None #: Retrieve events created after a given timestamp. - created_before: t.Optional[str] = None #: Retrieve events created before a given timestamp. - created_by: t.Optional[str] = None #: Created by. + created_after: t.Optional[string_formats.DateTime] = None #: Retrieve events created after a given timestamp. + created_before: t.Optional[string_formats.DateTime] = None #: Retrieve events created before a given timestamp. + created_by: t.Optional[string_formats.Did] = None #: Created by. cursor: t.Optional[str] = None #: Cursor. has_comment: t.Optional[bool] = None #: If true, only events with comments are returned. include_all_user_records: t.Optional[bool] = ( @@ -49,7 +51,7 @@ class Params(base.ParamsModelBase): sort_direction: t.Optional[t.Union[t.Literal['asc'], t.Literal['desc']]] = ( 'desc' #: Sort direction for the events. Defaults to descending order of created at timestamp. ) - subject: t.Optional[str] = None #: Subject. + subject: t.Optional[string_formats.Uri] = None #: Subject. subject_type: t.Optional[t.Union[t.Literal['account'], t.Literal['record'], str]] = ( None #: If specified, only events where the subject is of the given type (account or record) will be returned. When this is set to 'account' the 'collections' parameter will be ignored. When includeAllUserRecords or subject is set, this will be ignored. ) @@ -66,14 +68,18 @@ class ParamsDict(t.TypedDict): t.Optional[t.List[str]] ] #: If specified, only events where all of these tags were added are returned. collections: te.NotRequired[ - t.Optional[t.List[str]] + t.Optional[t.List[string_formats.Nsid]] ] #: If specified, only events where the subject belongs to the given collections will be returned. When subjectType is set to 'account', this will be ignored. comment: te.NotRequired[ t.Optional[str] ] #: If specified, only events with comments containing the keyword are returned. Apply || separator to use multiple keywords and match using OR condition. - created_after: te.NotRequired[t.Optional[str]] #: Retrieve events created after a given timestamp. - created_before: te.NotRequired[t.Optional[str]] #: Retrieve events created before a given timestamp. - created_by: te.NotRequired[t.Optional[str]] #: Created by. + created_after: te.NotRequired[ + t.Optional[string_formats.DateTime] + ] #: Retrieve events created after a given timestamp. + created_before: te.NotRequired[ + t.Optional[string_formats.DateTime] + ] #: Retrieve events created before a given timestamp. + created_by: te.NotRequired[t.Optional[string_formats.Did]] #: Created by. cursor: te.NotRequired[t.Optional[str]] #: Cursor. has_comment: te.NotRequired[t.Optional[bool]] #: If true, only events with comments are returned. include_all_user_records: te.NotRequired[ @@ -90,7 +96,7 @@ class ParamsDict(t.TypedDict): sort_direction: te.NotRequired[ t.Optional[t.Union[t.Literal['asc'], t.Literal['desc']]] ] #: Sort direction for the events. Defaults to descending order of created at timestamp. - subject: te.NotRequired[t.Optional[str]] #: Subject. + subject: te.NotRequired[t.Optional[string_formats.Uri]] #: Subject. subject_type: te.NotRequired[ t.Optional[t.Union[t.Literal['account'], t.Literal['record'], str]] ] #: If specified, only events where the subject is of the given type (account or record) will be returned. When this is set to 'account' the 'collections' parameter will be ignored. When includeAllUserRecords or subject is set, this will be ignored. diff --git a/packages/atproto_client/models/tools/ozone/moderation/query_statuses.py b/packages/atproto_client/models/tools/ozone/moderation/query_statuses.py index 2604dc75..171bf16f 100644 --- a/packages/atproto_client/models/tools/ozone/moderation/query_statuses.py +++ b/packages/atproto_client/models/tools/ozone/moderation/query_statuses.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -19,45 +21,47 @@ class Params(base.ParamsModelBase): """Parameters model for :obj:`tools.ozone.moderation.queryStatuses`.""" appealed: t.Optional[bool] = None #: Get subjects in unresolved appealed status. - collections: t.Optional[t.List[str]] = Field( + collections: t.Optional[t.List[string_formats.Nsid]] = Field( default=None, max_length=20 ) #: If specified, subjects belonging to the given collections will be returned. When subjectType is set to 'account', this will be ignored. comment: t.Optional[str] = None #: Search subjects by keyword from comments. cursor: t.Optional[str] = None #: Cursor. exclude_tags: t.Optional[t.List[str]] = None #: Exclude tags. - hosting_deleted_after: t.Optional[str] = ( + hosting_deleted_after: t.Optional[string_formats.DateTime] = ( None #: Search subjects where the associated record/account was deleted after a given timestamp. ) - hosting_deleted_before: t.Optional[str] = ( + hosting_deleted_before: t.Optional[string_formats.DateTime] = ( None #: Search subjects where the associated record/account was deleted before a given timestamp. ) hosting_statuses: t.Optional[t.List[str]] = None #: Search subjects by the status of the associated record/account. - hosting_updated_after: t.Optional[str] = ( + hosting_updated_after: t.Optional[string_formats.DateTime] = ( None #: Search subjects where the associated record/account was updated after a given timestamp. ) - hosting_updated_before: t.Optional[str] = ( + hosting_updated_before: t.Optional[string_formats.DateTime] = ( None #: Search subjects where the associated record/account was updated before a given timestamp. ) - ignore_subjects: t.Optional[t.List[str]] = None #: Ignore subjects. + ignore_subjects: t.Optional[t.List[string_formats.Uri]] = None #: Ignore subjects. include_all_user_records: t.Optional[bool] = ( None #: All subjects, or subjects from given 'collections' param, belonging to the account specified in the 'subject' param will be returned. ) include_muted: t.Optional[bool] = ( None #: By default, we don't include muted subjects in the results. Set this to true to include them. ) - last_reviewed_by: t.Optional[str] = None #: Get all subject statuses that were reviewed by a specific moderator. + last_reviewed_by: t.Optional[string_formats.Did] = ( + None #: Get all subject statuses that were reviewed by a specific moderator. + ) limit: t.Optional[int] = Field(default=50, ge=1, le=100) #: Limit. only_muted: t.Optional[bool] = None #: When set to true, only muted subjects and reporters will be returned. - reported_after: t.Optional[str] = None #: Search subjects reported after a given timestamp. - reported_before: t.Optional[str] = None #: Search subjects reported before a given timestamp. + reported_after: t.Optional[string_formats.DateTime] = None #: Search subjects reported after a given timestamp. + reported_before: t.Optional[string_formats.DateTime] = None #: Search subjects reported before a given timestamp. review_state: t.Optional[str] = None #: Specify when fetching subjects in a certain state. - reviewed_after: t.Optional[str] = None #: Search subjects reviewed after a given timestamp. - reviewed_before: t.Optional[str] = None #: Search subjects reviewed before a given timestamp. + reviewed_after: t.Optional[string_formats.DateTime] = None #: Search subjects reviewed after a given timestamp. + reviewed_before: t.Optional[string_formats.DateTime] = None #: Search subjects reviewed before a given timestamp. sort_direction: t.Optional[t.Union[t.Literal['asc'], t.Literal['desc']]] = 'desc' #: Sort direction. sort_field: t.Optional[t.Union[t.Literal['lastReviewedAt'], t.Literal['lastReportedAt']]] = ( 'lastReportedAt' #: Sort field. ) - subject: t.Optional[str] = None #: The subject to get the status for. + subject: t.Optional[string_formats.Uri] = None #: The subject to get the status for. subject_type: t.Optional[t.Union[t.Literal['account'], t.Literal['record'], str]] = ( None #: If specified, subjects of the given type (account or record) will be returned. When this is set to 'account' the 'collections' parameter will be ignored. When includeAllUserRecords or subject is set, this will be ignored. ) @@ -68,27 +72,27 @@ class Params(base.ParamsModelBase): class ParamsDict(t.TypedDict): appealed: te.NotRequired[t.Optional[bool]] #: Get subjects in unresolved appealed status. collections: te.NotRequired[ - t.Optional[t.List[str]] + t.Optional[t.List[string_formats.Nsid]] ] #: If specified, subjects belonging to the given collections will be returned. When subjectType is set to 'account', this will be ignored. comment: te.NotRequired[t.Optional[str]] #: Search subjects by keyword from comments. cursor: te.NotRequired[t.Optional[str]] #: Cursor. exclude_tags: te.NotRequired[t.Optional[t.List[str]]] #: Exclude tags. hosting_deleted_after: te.NotRequired[ - t.Optional[str] + t.Optional[string_formats.DateTime] ] #: Search subjects where the associated record/account was deleted after a given timestamp. hosting_deleted_before: te.NotRequired[ - t.Optional[str] + t.Optional[string_formats.DateTime] ] #: Search subjects where the associated record/account was deleted before a given timestamp. hosting_statuses: te.NotRequired[ t.Optional[t.List[str]] ] #: Search subjects by the status of the associated record/account. hosting_updated_after: te.NotRequired[ - t.Optional[str] + t.Optional[string_formats.DateTime] ] #: Search subjects where the associated record/account was updated after a given timestamp. hosting_updated_before: te.NotRequired[ - t.Optional[str] + t.Optional[string_formats.DateTime] ] #: Search subjects where the associated record/account was updated before a given timestamp. - ignore_subjects: te.NotRequired[t.Optional[t.List[str]]] #: Ignore subjects. + ignore_subjects: te.NotRequired[t.Optional[t.List[string_formats.Uri]]] #: Ignore subjects. include_all_user_records: te.NotRequired[ t.Optional[bool] ] #: All subjects, or subjects from given 'collections' param, belonging to the account specified in the 'subject' param will be returned. @@ -96,22 +100,30 @@ class ParamsDict(t.TypedDict): t.Optional[bool] ] #: By default, we don't include muted subjects in the results. Set this to true to include them. last_reviewed_by: te.NotRequired[ - t.Optional[str] + t.Optional[string_formats.Did] ] #: Get all subject statuses that were reviewed by a specific moderator. limit: te.NotRequired[t.Optional[int]] #: Limit. only_muted: te.NotRequired[ t.Optional[bool] ] #: When set to true, only muted subjects and reporters will be returned. - reported_after: te.NotRequired[t.Optional[str]] #: Search subjects reported after a given timestamp. - reported_before: te.NotRequired[t.Optional[str]] #: Search subjects reported before a given timestamp. + reported_after: te.NotRequired[ + t.Optional[string_formats.DateTime] + ] #: Search subjects reported after a given timestamp. + reported_before: te.NotRequired[ + t.Optional[string_formats.DateTime] + ] #: Search subjects reported before a given timestamp. review_state: te.NotRequired[t.Optional[str]] #: Specify when fetching subjects in a certain state. - reviewed_after: te.NotRequired[t.Optional[str]] #: Search subjects reviewed after a given timestamp. - reviewed_before: te.NotRequired[t.Optional[str]] #: Search subjects reviewed before a given timestamp. + reviewed_after: te.NotRequired[ + t.Optional[string_formats.DateTime] + ] #: Search subjects reviewed after a given timestamp. + reviewed_before: te.NotRequired[ + t.Optional[string_formats.DateTime] + ] #: Search subjects reviewed before a given timestamp. sort_direction: te.NotRequired[t.Optional[t.Union[t.Literal['asc'], t.Literal['desc']]]] #: Sort direction. sort_field: te.NotRequired[ t.Optional[t.Union[t.Literal['lastReviewedAt'], t.Literal['lastReportedAt']]] ] #: Sort field. - subject: te.NotRequired[t.Optional[str]] #: The subject to get the status for. + subject: te.NotRequired[t.Optional[string_formats.Uri]] #: The subject to get the status for. subject_type: te.NotRequired[ t.Optional[t.Union[t.Literal['account'], t.Literal['record'], str]] ] #: If specified, subjects of the given type (account or record) will be returned. When this is set to 'account' the 'collections' parameter will be ignored. When includeAllUserRecords or subject is set, this will be ignored. diff --git a/packages/atproto_client/models/tools/ozone/server/get_config.py b/packages/atproto_client/models/tools/ozone/server/get_config.py index cc08859c..60b4dc5a 100644 --- a/packages/atproto_client/models/tools/ozone/server/get_config.py +++ b/packages/atproto_client/models/tools/ozone/server/get_config.py @@ -9,6 +9,8 @@ from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -27,7 +29,7 @@ class Response(base.ResponseModelBase): class ServiceConfig(base.ModelBase): """Definition model for :obj:`tools.ozone.server.getConfig`.""" - url: t.Optional[str] = None #: Url. + url: t.Optional[string_formats.Uri] = None #: Url. py_type: t.Literal['tools.ozone.server.getConfig#serviceConfig'] = Field( default='tools.ozone.server.getConfig#serviceConfig', alias='$type', frozen=True diff --git a/packages/atproto_client/models/tools/ozone/set/defs.py b/packages/atproto_client/models/tools/ozone/set/defs.py index f07a2f30..d76a6697 100644 --- a/packages/atproto_client/models/tools/ozone/set/defs.py +++ b/packages/atproto_client/models/tools/ozone/set/defs.py @@ -9,7 +9,7 @@ from pydantic import Field -from atproto_client.models import base +from atproto_client.models import base, string_formats class Set(base.ModelBase): @@ -26,10 +26,10 @@ class Set(base.ModelBase): class SetView(base.ModelBase): """Definition model for :obj:`tools.ozone.set.defs`.""" - created_at: str #: Created at. + created_at: string_formats.DateTime #: Created at. name: str = Field(min_length=3, max_length=128) #: Name. set_size: int #: Set size. - updated_at: str #: Updated at. + updated_at: string_formats.DateTime #: Updated at. description: t.Optional[str] = Field(default=None, max_length=10240) #: Description. py_type: t.Literal['tools.ozone.set.defs#setView'] = Field( diff --git a/packages/atproto_client/models/tools/ozone/setting/defs.py b/packages/atproto_client/models/tools/ozone/setting/defs.py index 1193902d..406f668d 100644 --- a/packages/atproto_client/models/tools/ozone/setting/defs.py +++ b/packages/atproto_client/models/tools/ozone/setting/defs.py @@ -9,6 +9,8 @@ from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models.unknown_type import UnknownType @@ -18,13 +20,13 @@ class Option(base.ModelBase): """Definition model for :obj:`tools.ozone.setting.defs`.""" - created_by: str #: Created by. - did: str #: Did. - key: str #: Key. - last_updated_by: str #: Last updated by. + created_by: string_formats.Did #: Created by. + did: string_formats.Did #: Did. + key: string_formats.Nsid #: Key. + last_updated_by: string_formats.Did #: Last updated by. scope: t.Union[t.Literal['instance'], t.Literal['personal'], str] #: Scope. value: 'UnknownType' #: Value. - created_at: t.Optional[str] = None #: Created at. + created_at: t.Optional[string_formats.DateTime] = None #: Created at. description: t.Optional[str] = Field(default=None, max_length=10240) #: Description. manager_role: t.Optional[ t.Union[ @@ -34,7 +36,7 @@ class Option(base.ModelBase): str, ] ] = None #: Manager role. - updated_at: t.Optional[str] = None #: Updated at. + updated_at: t.Optional[string_formats.DateTime] = None #: Updated at. py_type: t.Literal['tools.ozone.setting.defs#option'] = Field( default='tools.ozone.setting.defs#option', alias='$type', frozen=True diff --git a/packages/atproto_client/models/tools/ozone/setting/list_options.py b/packages/atproto_client/models/tools/ozone/setting/list_options.py index feac9d38..d94f37b4 100644 --- a/packages/atproto_client/models/tools/ozone/setting/list_options.py +++ b/packages/atproto_client/models/tools/ozone/setting/list_options.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -19,7 +21,7 @@ class Params(base.ParamsModelBase): """Parameters model for :obj:`tools.ozone.setting.listOptions`.""" cursor: t.Optional[str] = None #: Cursor. - keys: t.Optional[t.List[str]] = Field( + keys: t.Optional[t.List[string_formats.Nsid]] = Field( default=None, max_length=100 ) #: Filter for only the specified keys. Ignored if prefix is provided. limit: t.Optional[int] = Field(default=50, ge=1, le=100) #: Limit. @@ -29,7 +31,9 @@ class Params(base.ParamsModelBase): class ParamsDict(t.TypedDict): cursor: te.NotRequired[t.Optional[str]] #: Cursor. - keys: te.NotRequired[t.Optional[t.List[str]]] #: Filter for only the specified keys. Ignored if prefix is provided. + keys: te.NotRequired[ + t.Optional[t.List[string_formats.Nsid]] + ] #: Filter for only the specified keys. Ignored if prefix is provided. limit: te.NotRequired[t.Optional[int]] #: Limit. prefix: te.NotRequired[t.Optional[str]] #: Filter keys by prefix. scope: te.NotRequired[t.Optional[t.Union[t.Literal['instance'], t.Literal['personal'], str]]] #: Scope. diff --git a/packages/atproto_client/models/tools/ozone/setting/remove_options.py b/packages/atproto_client/models/tools/ozone/setting/remove_options.py index f82c2c34..5959a3c1 100644 --- a/packages/atproto_client/models/tools/ozone/setting/remove_options.py +++ b/packages/atproto_client/models/tools/ozone/setting/remove_options.py @@ -9,18 +9,18 @@ from pydantic import Field -from atproto_client.models import base +from atproto_client.models import base, string_formats class Data(base.DataModelBase): """Input data model for :obj:`tools.ozone.setting.removeOptions`.""" - keys: t.List[str] = Field(min_length=1, max_length=200) #: Keys. + keys: t.List[string_formats.Nsid] = Field(min_length=1, max_length=200) #: Keys. scope: t.Union[t.Literal['instance'], t.Literal['personal'], str] #: Scope. class DataDict(t.TypedDict): - keys: t.List[str] #: Keys. + keys: t.List[string_formats.Nsid] #: Keys. scope: t.Union[t.Literal['instance'], t.Literal['personal'], str] #: Scope. diff --git a/packages/atproto_client/models/tools/ozone/setting/upsert_option.py b/packages/atproto_client/models/tools/ozone/setting/upsert_option.py index ff6d2f41..52362d3f 100644 --- a/packages/atproto_client/models/tools/ozone/setting/upsert_option.py +++ b/packages/atproto_client/models/tools/ozone/setting/upsert_option.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models.unknown_type import UnknownInputType @@ -19,7 +21,7 @@ class Data(base.DataModelBase): """Input data model for :obj:`tools.ozone.setting.upsertOption`.""" - key: str #: Key. + key: string_formats.Nsid #: Key. scope: t.Union[t.Literal['instance'], t.Literal['personal'], str] #: Scope. value: 'UnknownInputType' #: Value. description: t.Optional[str] = Field(default=None, max_length=2000) #: Description. @@ -34,7 +36,7 @@ class Data(base.DataModelBase): class DataDict(t.TypedDict): - key: str #: Key. + key: string_formats.Nsid #: Key. scope: t.Union[t.Literal['instance'], t.Literal['personal'], str] #: Scope. value: 'UnknownInputType' #: Value. description: te.NotRequired[t.Optional[str]] #: Description. diff --git a/packages/atproto_client/models/tools/ozone/signature/find_correlation.py b/packages/atproto_client/models/tools/ozone/signature/find_correlation.py index d8d477de..efcf8ae9 100644 --- a/packages/atproto_client/models/tools/ozone/signature/find_correlation.py +++ b/packages/atproto_client/models/tools/ozone/signature/find_correlation.py @@ -7,6 +7,8 @@ import typing as t +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -15,11 +17,11 @@ class Params(base.ParamsModelBase): """Parameters model for :obj:`tools.ozone.signature.findCorrelation`.""" - dids: t.List[str] #: Dids. + dids: t.List[string_formats.Did] #: Dids. class ParamsDict(t.TypedDict): - dids: t.List[str] #: Dids. + dids: t.List[string_formats.Did] #: Dids. class Response(base.ResponseModelBase): diff --git a/packages/atproto_client/models/tools/ozone/signature/find_related_accounts.py b/packages/atproto_client/models/tools/ozone/signature/find_related_accounts.py index 11019b02..1a18ce7e 100644 --- a/packages/atproto_client/models/tools/ozone/signature/find_related_accounts.py +++ b/packages/atproto_client/models/tools/ozone/signature/find_related_accounts.py @@ -10,6 +10,8 @@ import typing_extensions as te from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -18,13 +20,13 @@ class Params(base.ParamsModelBase): """Parameters model for :obj:`tools.ozone.signature.findRelatedAccounts`.""" - did: str #: Did. + did: string_formats.Did #: Did. cursor: t.Optional[str] = None #: Cursor. limit: t.Optional[int] = Field(default=50, ge=1, le=100) #: Limit. class ParamsDict(t.TypedDict): - did: str #: Did. + did: string_formats.Did #: Did. cursor: te.NotRequired[t.Optional[str]] #: Cursor. limit: te.NotRequired[t.Optional[int]] #: Limit. diff --git a/packages/atproto_client/models/tools/ozone/team/add_member.py b/packages/atproto_client/models/tools/ozone/team/add_member.py index aa801496..6a506c0b 100644 --- a/packages/atproto_client/models/tools/ozone/team/add_member.py +++ b/packages/atproto_client/models/tools/ozone/team/add_member.py @@ -7,6 +7,8 @@ import typing as t +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -15,7 +17,7 @@ class Data(base.DataModelBase): """Input data model for :obj:`tools.ozone.team.addMember`.""" - did: str #: Did. + did: string_formats.Did #: Did. role: t.Union[ 'models.ToolsOzoneTeamDefs.RoleAdmin', 'models.ToolsOzoneTeamDefs.RoleModerator', @@ -25,7 +27,7 @@ class Data(base.DataModelBase): class DataDict(t.TypedDict): - did: str #: Did. + did: string_formats.Did #: Did. role: t.Union[ 'models.ToolsOzoneTeamDefs.RoleAdmin', 'models.ToolsOzoneTeamDefs.RoleModerator', diff --git a/packages/atproto_client/models/tools/ozone/team/defs.py b/packages/atproto_client/models/tools/ozone/team/defs.py index 6d5f9e96..935cecce 100644 --- a/packages/atproto_client/models/tools/ozone/team/defs.py +++ b/packages/atproto_client/models/tools/ozone/team/defs.py @@ -9,6 +9,8 @@ from pydantic import Field +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -17,18 +19,18 @@ class Member(base.ModelBase): """Definition model for :obj:`tools.ozone.team.defs`.""" - did: str #: Did. + did: string_formats.Did #: Did. role: t.Union[ 'models.ToolsOzoneTeamDefs.RoleAdmin', 'models.ToolsOzoneTeamDefs.RoleModerator', 'models.ToolsOzoneTeamDefs.RoleTriage', str, ] #: Role. - created_at: t.Optional[str] = None #: Created at. + created_at: t.Optional[string_formats.DateTime] = None #: Created at. disabled: t.Optional[bool] = None #: Disabled. last_updated_by: t.Optional[str] = None #: Last updated by. profile: t.Optional['models.AppBskyActorDefs.ProfileViewDetailed'] = None #: Profile. - updated_at: t.Optional[str] = None #: Updated at. + updated_at: t.Optional[string_formats.DateTime] = None #: Updated at. py_type: t.Literal['tools.ozone.team.defs#member'] = Field( default='tools.ozone.team.defs#member', alias='$type', frozen=True diff --git a/packages/atproto_client/models/tools/ozone/team/delete_member.py b/packages/atproto_client/models/tools/ozone/team/delete_member.py index e9a07c14..41dd28c4 100644 --- a/packages/atproto_client/models/tools/ozone/team/delete_member.py +++ b/packages/atproto_client/models/tools/ozone/team/delete_member.py @@ -7,14 +7,14 @@ import typing as t -from atproto_client.models import base +from atproto_client.models import base, string_formats class Data(base.DataModelBase): """Input data model for :obj:`tools.ozone.team.deleteMember`.""" - did: str #: Did. + did: string_formats.Did #: Did. class DataDict(t.TypedDict): - did: str #: Did. + did: string_formats.Did #: Did. diff --git a/packages/atproto_client/models/tools/ozone/team/update_member.py b/packages/atproto_client/models/tools/ozone/team/update_member.py index f829a3cf..976e8b1c 100644 --- a/packages/atproto_client/models/tools/ozone/team/update_member.py +++ b/packages/atproto_client/models/tools/ozone/team/update_member.py @@ -9,6 +9,8 @@ import typing_extensions as te +from atproto_client.models import string_formats + if t.TYPE_CHECKING: from atproto_client import models from atproto_client.models import base @@ -17,7 +19,7 @@ class Data(base.DataModelBase): """Input data model for :obj:`tools.ozone.team.updateMember`.""" - did: str #: Did. + did: string_formats.Did #: Did. disabled: t.Optional[bool] = None #: Disabled. role: t.Optional[ t.Union[ @@ -30,7 +32,7 @@ class Data(base.DataModelBase): class DataDict(t.TypedDict): - did: str #: Did. + did: string_formats.Did #: Did. disabled: te.NotRequired[t.Optional[bool]] #: Disabled. role: te.NotRequired[ t.Optional[ diff --git a/packages/atproto_client/models/utils.py b/packages/atproto_client/models/utils.py index 23bad3d4..94ae0d43 100644 --- a/packages/atproto_client/models/utils.py +++ b/packages/atproto_client/models/utils.py @@ -2,7 +2,7 @@ import typing as t import typing_extensions as te -from pydantic import ValidationError +from pydantic import BaseModel, ValidationError from pydantic_core import from_json, to_json from atproto_client import models @@ -28,7 +28,11 @@ def get_or_create( - model_data: ModelData[M], model: t.Optional[t.Type[M]] = None, *, strict: bool = True + model_data: ModelData[M], + model: t.Optional[t.Type[M]] = None, + *, + strict: bool = True, + strict_string_format: bool = False, ) -> t.Optional[t.Union[M, UnknownRecordType, DotDict]]: """Get model instance from raw data. @@ -53,13 +57,14 @@ def get_or_create( model: Class of the model or any another type. If None, it will be resolved automatically. strict: Disable fallback to dictionary (:obj:`atproto.xrpc_client.models.base.DotDict`) if it can't be properly deserialized in provided `model`. Will raise the exception instead. + strict_string_format: Enable strict string format validation. Returns: Instance of :obj:`model` or :obj:`None` or :obj:`atproto.xrpc_client.models.dot_dict.DotDict` if `strict` is disabled. """ try: - model_instance = _get_or_create(model_data, model, strict=strict) + model_instance = _get_or_create(model_data, model, strict=strict, strict_string_format=strict_string_format) if strict and model_instance is not None and (not model or not isinstance(model_instance, model)): raise ModelError(f"Can't properly parse model of type {model}") @@ -72,7 +77,7 @@ def get_or_create( def _get_or_create( - model_data: ModelData[M], model: t.Optional[t.Type[M]], *, strict: bool + model_data: ModelData[M], model: t.Optional[t.Type[M]], *, strict: bool, strict_string_format: bool ) -> t.Optional[t.Union[M, UnknownRecordType, DotDict]]: if model_data is None: return None @@ -92,12 +97,21 @@ def _get_or_create( # now we are sure that this is str because it's in RECORD_TYPE_TO_MODEL_CLASS record_type = t.cast(str, record_type) - return get_or_create(model_data, RECORD_TYPE_TO_MODEL_CLASS[record_type], strict=strict) + return get_or_create( + model_data, + RECORD_TYPE_TO_MODEL_CLASS[record_type], + strict=strict, + strict_string_format=strict_string_format, + ) if isinstance(model_data, model): return model_data try: + if issubclass(model, BaseModel): + return model.model_validate(model_data, context={'strict_string_format': strict_string_format}) + if not isinstance(model_data, t.Mapping): + raise ModelError(f'Cannot parse model of type {model}') return model(**model_data) except ValidationError as e: raise ModelError(str(e)) from e diff --git a/packages/atproto_codegen/models/generator.py b/packages/atproto_codegen/models/generator.py index 02940337..507d9e38 100644 --- a/packages/atproto_codegen/models/generator.py +++ b/packages/atproto_codegen/models/generator.py @@ -70,6 +70,8 @@ def _get_model_imports() -> str: 'import typing_extensions as te', 'from pydantic import Field', '', + 'from atproto_client.models import string_formats', + '', 'if t.TYPE_CHECKING:', f'{_(1)}from atproto_client import models', f'{_(1)}from atproto_client.models.unknown_type import UnknownType', @@ -139,7 +141,7 @@ def _get_optional_typehint(type_hint: str, *, optional: bool) -> str: def _get_str_enum_typehint(nsid: NSID, field_type_def: models.LexString, *, optional: bool) -> str: - values = field_type_def.known_values or field_type_def.enum + values = field_type_def.known_values or field_type_def.enum or [] union_type_parts = [] for value in values: @@ -161,6 +163,25 @@ def _get_str_enum_typehint(nsid: NSID, field_type_def: models.LexString, *, opti def _get_str_typehint(nsid: NSID, field_type_def: models.LexString, *, optional: bool) -> str: str_typehint = 'str' + # Map lexicon string formats to our validator types + if field_type_def.format: + # Map format types to our string_formats types + format_map = { + 'at-identifier': 'string_formats.Handle', + 'at-uri': 'string_formats.AtUri', + 'cid': 'string_formats.Cid', + 'datetime': 'string_formats.DateTime', + 'did': 'string_formats.Did', + 'handle': 'string_formats.Handle', + 'nsid': 'string_formats.Nsid', + 'tid': 'string_formats.Tid', + 'record-key': 'string_formats.RecordKey', + 'uri': 'string_formats.Uri', + 'language': 'string_formats.Language', + } + str_typehint = format_map.get(field_type_def.format, 'str') + + # Handle existing enum/known_values logic if field_type_def.known_values or field_type_def.enum: str_typehint = _get_str_enum_typehint(nsid, field_type_def, optional=optional) diff --git a/tests/test_atproto_client/interop-test-files/syntax/atidentifier_syntax_invalid.txt b/tests/test_atproto_client/interop-test-files/syntax/atidentifier_syntax_invalid.txt new file mode 100644 index 00000000..f0f84309 --- /dev/null +++ b/tests/test_atproto_client/interop-test-files/syntax/atidentifier_syntax_invalid.txt @@ -0,0 +1,28 @@ + +# invalid handles +did:thing.test +did:thing +john-.test +john.0 +john.- +xn--bcher-.tld +john..test +jo_hn.test + +# invalid DIDs +did +didmethodval +method:did:val +did:method: +didmethod:val +did:methodval) +:did:method:val +did:method:val: +did:method:val% +DID:method:val + +# other invalid stuff +email@example.com +@handle@example.com +@handle +blah diff --git a/tests/test_atproto_client/interop-test-files/syntax/atidentifier_syntax_valid.txt b/tests/test_atproto_client/interop-test-files/syntax/atidentifier_syntax_valid.txt new file mode 100644 index 00000000..cc4a42b0 --- /dev/null +++ b/tests/test_atproto_client/interop-test-files/syntax/atidentifier_syntax_valid.txt @@ -0,0 +1,15 @@ + +# allows valid handles +XX.LCS.MIT.EDU +john.test +jan.test +a234567890123456789.test +john2.test +john-john.test + +# allows valid DIDs +did:method:val +did:method:VAL +did:method:val123 +did:method:123 +did:method:val-two diff --git a/tests/test_atproto_client/interop-test-files/syntax/aturi_syntax_invalid.txt b/tests/test_atproto_client/interop-test-files/syntax/aturi_syntax_invalid.txt new file mode 100644 index 00000000..2ac2eada --- /dev/null +++ b/tests/test_atproto_client/interop-test-files/syntax/aturi_syntax_invalid.txt @@ -0,0 +1,89 @@ + +# enforces spec basics +a://did:plc:asdf123 +at//did:plc:asdf123 +at:/a/did:plc:asdf123 +at:/did:plc:asdf123 +AT://did:plc:asdf123 +http://did:plc:asdf123 +://did:plc:asdf123 +at:did:plc:asdf123 +at:/did:plc:asdf123 +at:///did:plc:asdf123 +at://:/did:plc:asdf123 +at:/ /did:plc:asdf123 +at://did:plc:asdf123 +at://did:plc:asdf123/ + at://did:plc:asdf123 +at://did:plc:asdf123/com.atproto.feed.post +at://did:plc:asdf123/com.atproto.feed.post# +at://did:plc:asdf123/com.atproto.feed.post#/ +at://did:plc:asdf123/com.atproto.feed.post#/frag +at://did:plc:asdf123/com.atproto.feed.post#fr ag +//did:plc:asdf123 +at://name +at://name.0 +at://diD:plc:asdf123 +at://did:plc:asdf123/com.atproto.feed.p@st +at://did:plc:asdf123/com.atproto.feed.p$st +at://did:plc:asdf123/com.atproto.feed.p%st +at://did:plc:asdf123/com.atproto.feed.p&st +at://did:plc:asdf123/com.atproto.feed.p()t +at://did:plc:asdf123/com.atproto.feed_post +at://did:plc:asdf123/-com.atproto.feed.post +at://did:plc:asdf@123/com.atproto.feed.post +at://DID:plc:asdf123 +at://user.bsky.123 +at://bsky +at://did:plc: +at://did:plc: +at://frag + +# too long: 'at://did:plc:asdf123/com.atproto.feed.post/' + 'o'.repeat(8200) +at://did:plc:asdf123/com.atproto.feed.post/oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo + +# has specified behavior on edge cases +at://user.bsky.social// +at://user.bsky.social//com.atproto.feed.post +at://user.bsky.social/com.atproto.feed.post// +at://did:plc:asdf123/com.atproto.feed.post/asdf123/more/more', +at://did:plc:asdf123/short/stuff +at://did:plc:asdf123/12345 + +# enforces no trailing slashes +at://did:plc:asdf123/ +at://user.bsky.social/ +at://did:plc:asdf123/com.atproto.feed.post/ +at://did:plc:asdf123/com.atproto.feed.post/record/ +at://did:plc:asdf123/com.atproto.feed.post/record/#/frag + +# enforces strict paths +at://did:plc:asdf123/com.atproto.feed.post/asdf123/asdf + +# is very permissive about fragments +at://did:plc:asdf123# +at://did:plc:asdf123## +#at://did:plc:asdf123 +at://did:plc:asdf123#/asdf#/asdf + +# new less permissive about record keys for Lexicon use (with recordkey more specified) +at://did:plc:asdf123/com.atproto.feed.post/%23 +at://did:plc:asdf123/com.atproto.feed.post/$@!*)(:,;~.sdf123 +at://did:plc:asdf123/com.atproto.feed.post/~'sdf123") +at://did:plc:asdf123/com.atproto.feed.post/$ +at://did:plc:asdf123/com.atproto.feed.post/@ +at://did:plc:asdf123/com.atproto.feed.post/! +at://did:plc:asdf123/com.atproto.feed.post/* +at://did:plc:asdf123/com.atproto.feed.post/( +at://did:plc:asdf123/com.atproto.feed.post/, +at://did:plc:asdf123/com.atproto.feed.post/; +at://did:plc:asdf123/com.atproto.feed.post/abc%30123 +at://did:plc:asdf123/com.atproto.feed.post/%30 +at://did:plc:asdf123/com.atproto.feed.post/%3 +at://did:plc:asdf123/com.atproto.feed.post/% +at://did:plc:asdf123/com.atproto.feed.post/%zz +at://did:plc:asdf123/com.atproto.feed.post/%%% + +# disallow dot / double-dot +at://did:plc:asdf123/com.atproto.feed.post/. +at://did:plc:asdf123/com.atproto.feed.post/.. diff --git a/tests/test_atproto_client/interop-test-files/syntax/aturi_syntax_valid.txt b/tests/test_atproto_client/interop-test-files/syntax/aturi_syntax_valid.txt new file mode 100644 index 00000000..fd4523d0 --- /dev/null +++ b/tests/test_atproto_client/interop-test-files/syntax/aturi_syntax_valid.txt @@ -0,0 +1,34 @@ + +# enforces spec basics +at://did:plc:asdf123 +at://user.bsky.social +at://did:plc:asdf123/com.atproto.feed.post +at://did:plc:asdf123/com.atproto.feed.post/record + +# very long: 'at://did:plc:asdf123/com.atproto.feed.post/' + 'o'.repeat(512) +at://did:plc:asdf123/com.atproto.feed.post/oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo + +# enforces no trailing slashes +at://did:plc:asdf123 +at://user.bsky.social +at://did:plc:asdf123/com.atproto.feed.post +at://did:plc:asdf123/com.atproto.feed.post/record + +# enforces strict paths +at://did:plc:asdf123/com.atproto.feed.post/asdf123 + +# is very permissive about record keys +at://did:plc:asdf123/com.atproto.feed.post/asdf123 +at://did:plc:asdf123/com.atproto.feed.post/a + +at://did:plc:asdf123/com.atproto.feed.post/asdf-123 +at://did:abc:123 +at://did:abc:123/io.nsid.someFunc/record-key + +at://did:abc:123/io.nsid.someFunc/self. +at://did:abc:123/io.nsid.someFunc/lang: +at://did:abc:123/io.nsid.someFunc/: +at://did:abc:123/io.nsid.someFunc/- +at://did:abc:123/io.nsid.someFunc/_ +at://did:abc:123/io.nsid.someFunc/~ +at://did:abc:123/io.nsid.someFunc/... diff --git a/tests/test_atproto_client/interop-test-files/syntax/datetime_parse_invalid.txt b/tests/test_atproto_client/interop-test-files/syntax/datetime_parse_invalid.txt new file mode 100644 index 00000000..3672453a --- /dev/null +++ b/tests/test_atproto_client/interop-test-files/syntax/datetime_parse_invalid.txt @@ -0,0 +1,7 @@ +# superficial syntax parses ok, but are not valid datetimes for semantic reasons (eg, "month zero") +1985-00-12T23:20:50.123Z +1985-04-00T23:20:50.123Z +1985-13-12T23:20:50.123Z +1985-04-12T25:20:50.123Z +1985-04-12T23:99:50.123Z +1985-04-12T23:20:61.123Z diff --git a/tests/test_atproto_client/interop-test-files/syntax/datetime_syntax_invalid.txt b/tests/test_atproto_client/interop-test-files/syntax/datetime_syntax_invalid.txt new file mode 100644 index 00000000..6702e43e --- /dev/null +++ b/tests/test_atproto_client/interop-test-files/syntax/datetime_syntax_invalid.txt @@ -0,0 +1,68 @@ + +# subtle changes to: 1985-04-12T23:20:50.123Z +1985-04-12T23:20:50.123z +01985-04-12T23:20:50.123Z +985-04-12T23:20:50.123Z +1985-04-12T23:20:50.Z +1985-04-32T23;20:50.123Z +1985-04-32T23;20:50.123Z + +# en-dash and em-dash +1985—04-32T23;20:50.123Z +1985–04-32T23;20:50.123Z + +# whitespace + 1985-04-12T23:20:50.123Z +1985-04-12T23:20:50.123Z +1985-04-12T 23:20:50.123Z + +# not enough zero padding +1985-4-12T23:20:50.123Z +1985-04-2T23:20:50.123Z +1985-04-12T3:20:50.123Z +1985-04-12T23:0:50.123Z +1985-04-12T23:20:5.123Z + +# too much zero padding +01985-04-12T23:20:50.123Z +1985-004-12T23:20:50.123Z +1985-04-012T23:20:50.123Z +1985-04-12T023:20:50.123Z +1985-04-12T23:020:50.123Z +1985-04-12T23:20:050.123Z + +# strict capitalization (ISO-8601) +1985-04-12t23:20:50.123Z +1985-04-12T23:20:50.123z + +# RFC-3339, but not ISO-8601 +1985-04-12T23:20:50.123-00:00 +1985-04-12_23:20:50.123Z +1985-04-12 23:20:50.123Z + +# ISO-8601, but weird +1985-04-274T23:20:50.123Z + +# timezone is required +1985-04-12T23:20:50.123 +1985-04-12T23:20:50 + +1985-04-12 +1985-04-12T23:20Z +1985-04-12T23:20:5Z +1985-04-12T23:20:50.123 ++001985-04-12T23:20:50.123Z +23:20:50.123Z + +1985-04-12T23:20:50.123+00 +1985-04-12T23:20:50.123+00:0 +1985-04-12T23:20:50.123+0:00 +1985-04-12T23:20:50.123 +1985-04-12T23:20:50.123+0000 +1985-04-12T23:20:50.123+00 +1985-04-12T23:20:50.123+ +1985-04-12T23:20:50.123- + +# ISO-8601, but normalizes to a negative time +0000-01-01T00:00:00+01:00 +-000001-12-31T23:00:00.000Z diff --git a/tests/test_atproto_client/interop-test-files/syntax/datetime_syntax_valid.txt b/tests/test_atproto_client/interop-test-files/syntax/datetime_syntax_valid.txt new file mode 100644 index 00000000..f47d539c --- /dev/null +++ b/tests/test_atproto_client/interop-test-files/syntax/datetime_syntax_valid.txt @@ -0,0 +1,40 @@ +# "preferred" +1985-04-12T23:20:50.123Z +1985-04-12T23:20:50.000Z +2000-01-01T00:00:00.000Z +1985-04-12T23:20:50.123456Z +1985-04-12T23:20:50.120Z +1985-04-12T23:20:50.120000Z + +# "supported" +1985-04-12T23:20:50.1235678912345Z +1985-04-12T23:20:50.100Z +1985-04-12T23:20:50Z +1985-04-12T23:20:50.0Z +1985-04-12T23:20:50.123+00:00 +1985-04-12T23:20:50.123-07:00 +1985-04-12T23:20:50.123+07:00 +1985-04-12T23:20:50.123+01:45 +0985-04-12T23:20:50.123-07:00 +1985-04-12T23:20:50.123-07:00 +0123-01-01T00:00:00.000Z + +# various precisions, up through at least 12 digits +1985-04-12T23:20:50.1Z +1985-04-12T23:20:50.12Z +1985-04-12T23:20:50.123Z +1985-04-12T23:20:50.1234Z +1985-04-12T23:20:50.12345Z +1985-04-12T23:20:50.123456Z +1985-04-12T23:20:50.1234567Z +1985-04-12T23:20:50.12345678Z +1985-04-12T23:20:50.123456789Z +1985-04-12T23:20:50.1234567890Z +1985-04-12T23:20:50.12345678901Z +1985-04-12T23:20:50.123456789012Z + +# extreme but currently allowed +0010-12-31T23:00:00.000Z +1000-12-31T23:00:00.000Z +1900-12-31T23:00:00.000Z +3001-12-31T23:00:00.000Z diff --git a/tests/test_atproto_client/interop-test-files/syntax/did_syntax_invalid.txt b/tests/test_atproto_client/interop-test-files/syntax/did_syntax_invalid.txt new file mode 100644 index 00000000..9e724b3d --- /dev/null +++ b/tests/test_atproto_client/interop-test-files/syntax/did_syntax_invalid.txt @@ -0,0 +1,19 @@ +did +didmethodval +method:did:val +did:method: +didmethod:val +did:methodval) +:did:method:val +did.method.val +did:method:val: +did:method:val% +DID:method:val +did:METHOD:val +did:m123:val +did:method:val/two +did:method:val?two +did:method:val#two +did:method:val% +did:method:vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + diff --git a/tests/test_atproto_client/interop-test-files/syntax/did_syntax_valid.txt b/tests/test_atproto_client/interop-test-files/syntax/did_syntax_valid.txt new file mode 100644 index 00000000..5aa6c9e7 --- /dev/null +++ b/tests/test_atproto_client/interop-test-files/syntax/did_syntax_valid.txt @@ -0,0 +1,26 @@ +did:method:val +did:method:VAL +did:method:val123 +did:method:123 +did:method:val-two +did:method:val_two +did:method:val.two +did:method:val:two +did:method:val%BB +did:method:vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +did:m:v +did:method::::val +did:method:- +did:method:-:_:.:%ab +did:method:. +did:method:_ +did:method::. + +# allows some real DID values +did:onion:2gzyxa5ihm7nsggfxnu52rck2vv4rvmdlkiu3zzui5du4xyclen53wid +did:example:123456789abcdefghi +did:plc:7iza6de2dwap2sbkpav7c6c6 +did:web:example.com +did:web:localhost%3A1234 +did:key:zQ3shZc2QzApp2oymGvQbzP8eKheVshBHbU4ZYjeXqwSKEn6N +did:ethr:0xb9c5714089478a327f09197987f16f9e5d936e8a diff --git a/tests/test_atproto_client/interop-test-files/syntax/handle_syntax_invalid.txt b/tests/test_atproto_client/interop-test-files/syntax/handle_syntax_invalid.txt new file mode 100644 index 00000000..49275a39 --- /dev/null +++ b/tests/test_atproto_client/interop-test-files/syntax/handle_syntax_invalid.txt @@ -0,0 +1,61 @@ +# throws on invalid handles +did:thing.test +did:thing +john-.test +john.0 +john.- +xn--bcher-.tld +john..test +jo_hn.test +-john.test +.john.test +jo!hn.test +jo%hn.test +jo&hn.test +jo@hn.test +jo*hn.test +jo|hn.test +jo:hn.test +jo/hn.test +john💩.test +bücher.test +john .test +john.test. +john +john. +.john +john.test. +.john.test + john.test +john.test +joh-.test +john.-est +john.tes- + +# max over all handle: 'shoooort' + '.loooooooooooooooooooooooooong'.repeat(9) + '.test' +shoooort.loooooooooooooooooooooooooong.loooooooooooooooooooooooooong.loooooooooooooooooooooooooong.loooooooooooooooooooooooooong.loooooooooooooooooooooooooong.loooooooooooooooooooooooooong.loooooooooooooooooooooooooong.loooooooooooooooooooooooooong.loooooooooooooooooooooooooong.test + +# max segment: 'short.' + 'o'.repeat(64) + '.test' +short.oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo.test + +# throws on "dotless" TLD handles +org +ai +gg +io + +# correctly validates corner cases (modern vs. old RFCs) +cn.8 +thing.0aa +thing.0aa + +# does not allow IP addresses as handles +127.0.0.1 +192.168.0.142 +fe80::7325:8a97:c100:94b +2600:3c03::f03c:9100:feb0:af1f + +# examples from stackoverflow +-notvalid.at-all +-thing.com +www.masełkowski.pl.com diff --git a/tests/test_atproto_client/interop-test-files/syntax/handle_syntax_valid.txt b/tests/test_atproto_client/interop-test-files/syntax/handle_syntax_valid.txt new file mode 100644 index 00000000..a23a9213 --- /dev/null +++ b/tests/test_atproto_client/interop-test-files/syntax/handle_syntax_valid.txt @@ -0,0 +1,90 @@ +# allows valid handles +A.ISI.EDU +XX.LCS.MIT.EDU +SRI-NIC.ARPA +john.test +jan.test +a234567890123456789.test +john2.test +john-john.test +john.bsky.app +jo.hn +a.co +a.org +joh.n +j0.h0 +jaymome-johnber123456.test +jay.mome-johnber123456.test +john.test.bsky.app + +# max over all handle: 'shoooort' + '.loooooooooooooooooooooooooong'.repeat(8) + '.test' +shoooort.loooooooooooooooooooooooooong.loooooooooooooooooooooooooong.loooooooooooooooooooooooooong.loooooooooooooooooooooooooong.loooooooooooooooooooooooooong.loooooooooooooooooooooooooong.loooooooooooooooooooooooooong.loooooooooooooooooooooooooong.test + +# max segment: 'short.' + 'o'.repeat(63) + '.test' +short.ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo.test + +# NOTE: this probably isn't ever going to be a real domain, but my read of the RFC is that it would be possible +john.t + +# allows .local and .arpa handles (proto-level) +laptop.local +laptop.arpa + +# allows punycode handles +# 💩.test +xn--ls8h.test +# bücher.tld +xn--bcher-kva.tld +xn--3jk.com +xn--w3d.com +xn--vqb.com +xn--ppd.com +xn--cs9a.com +xn--8r9a.com +xn--cfd.com +xn--5jk.com +xn--2lb.com + +# allows onion (Tor) handles +expyuzz4wqqyqhjn.onion +friend.expyuzz4wqqyqhjn.onion +g2zyxa5ihm7nsggfxnu52rck2vv4rvmdlkiu3zzui5du4xyclen53wid.onion +friend.g2zyxa5ihm7nsggfxnu52rck2vv4rvmdlkiu3zzui5du4xyclen53wid.onion +friend.g2zyxa5ihm7nsggfxnu52rck2vv4rvmdlkiu3zzui5du4xyclen53wid.onion +2gzyxa5ihm7nsggfxnu52rck2vv4rvmdlkiu3zzui5du4xyclen53wid.onion +friend.2gzyxa5ihm7nsggfxnu52rck2vv4rvmdlkiu3zzui5du4xyclen53wid.onion + +# correctly validates corner cases (modern vs. old RFCs) +12345.test +8.cn +4chan.org +4chan.o-g +blah.4chan.org +thing.a01 +120.0.0.1.com +0john.test +9sta--ck.com +99stack.com +0ohn.test +john.t--t +thing.0aa.thing + +# examples from stackoverflow +stack.com +sta-ck.com +sta---ck.com +sta--ck9.com +stack99.com +sta99ck.com +google.com.uk +google.co.in +google.com +maselkowski.pl +m.maselkowski.pl +xn--masekowski-d0b.pl +xn--fiqa61au8b7zsevnm8ak20mc4a87e.xn--fiqs8s +xn--stackoverflow.com +stackoverflow.xn--com +stackoverflow.co.uk +xn--masekowski-d0b.pl +xn--fiqa61au8b7zsevnm8ak20mc4a87e.xn--fiqs8s diff --git a/tests/test_atproto_client/interop-test-files/syntax/nsid_syntax_invalid.txt b/tests/test_atproto_client/interop-test-files/syntax/nsid_syntax_invalid.txt new file mode 100644 index 00000000..bc0bd2fd --- /dev/null +++ b/tests/test_atproto_client/interop-test-files/syntax/nsid_syntax_invalid.txt @@ -0,0 +1,32 @@ +# length checks +com.oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo.foo +com.example.oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo +com.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.foo + +# invliad examples +com.example.foo.* +com.example.foo.blah* +com.example.foo.*blah +com.example.f00 +com.exa💩ple.thing +a-0.b-1.c-3 +a-0.b-1.c-o +a0.b1.c3 +1.0.0.127.record +0two.example.foo +example.com +com.example +a. +.one.two.three +one.two.three +one.two..three +one .two.three + one.two.three +com.exa💩ple.thing +com.atproto.feed.p@st +com.atproto.feed.p_st +com.atproto.feed.p*st +com.atproto.feed.po#t +com.atproto.feed.p!ot +com.example-.foo + diff --git a/tests/test_atproto_client/interop-test-files/syntax/nsid_syntax_valid.txt b/tests/test_atproto_client/interop-test-files/syntax/nsid_syntax_valid.txt new file mode 100644 index 00000000..54ef351f --- /dev/null +++ b/tests/test_atproto_client/interop-test-files/syntax/nsid_syntax_valid.txt @@ -0,0 +1,29 @@ +# length checks +com.ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo.foo +com.example.ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo +com.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.foo + +# valid examples +com.example.fooBar +net.users.bob.ping +a.b.c +m.xn--masekowski-d0b.pl +one.two.three +one.two.three.four-and.FiVe +one.2.three +a-0.b-1.c +a0.b1.cc +cn.8.lex.stuff +test.12345.record +a01.thing.record +a.0.c +xn--fiqs8s.xn--fiqa61au8b7zsevnm8ak20mc4a87e.record.two + +# allows onion (Tor) NSIDs +onion.expyuzz4wqqyqhjn.spec.getThing +onion.g2zyxa5ihm7nsggfxnu52rck2vv4rvmdlkiu3zzui5du4xyclen53wid.lex.deleteThing + +# allows starting-with-numeric segments (same as domains) +org.4chan.lex.getThing +cn.8.lex.stuff +onion.2gzyxa5ihm7nsggfxnu52rck2vv4rvmdlkiu3zzui5du4xyclen53wid.lex.deleteThing diff --git a/tests/test_atproto_client/interop-test-files/syntax/recordkey_syntax_invalid.txt b/tests/test_atproto_client/interop-test-files/syntax/recordkey_syntax_invalid.txt new file mode 100644 index 00000000..52106d87 --- /dev/null +++ b/tests/test_atproto_client/interop-test-files/syntax/recordkey_syntax_invalid.txt @@ -0,0 +1,15 @@ +# specs +alpha/beta +. +.. +#extra +@handle +any space +any+space +number[3] +number(3) +"quote" +dHJ1ZQ== + +# too long: 'o'.repeat(513) +ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo diff --git a/tests/test_atproto_client/interop-test-files/syntax/recordkey_syntax_valid.txt b/tests/test_atproto_client/interop-test-files/syntax/recordkey_syntax_valid.txt new file mode 100644 index 00000000..92e8b7e3 --- /dev/null +++ b/tests/test_atproto_client/interop-test-files/syntax/recordkey_syntax_valid.txt @@ -0,0 +1,21 @@ +# specs +self +example.com +~1.2-3_ +dHJ1ZQ +_ +literal:self +pre:fix + +# more corner-cases +: +- +_ +~ +... +self. +lang: +:lang + +# very long: 'o'.repeat(512) +oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo diff --git a/tests/test_atproto_client/interop-test-files/syntax/tid_syntax_invalid.txt b/tests/test_atproto_client/interop-test-files/syntax/tid_syntax_invalid.txt new file mode 100644 index 00000000..eca90b2d --- /dev/null +++ b/tests/test_atproto_client/interop-test-files/syntax/tid_syntax_invalid.txt @@ -0,0 +1,15 @@ + +# not base32 +3jzfcijpj2z21 +0000000000000 + +# too long/short +3jzfcijpj2z2aa +3jzfcijpj2z2 + +# old dashes syntax not actually supported (TTTT-TTT-TTTT-CC) +3jzf-cij-pj2z-2a + +# high bit can't be high +zzzzzzzzzzzzz +kjzfcijpj2z2a diff --git a/tests/test_atproto_client/interop-test-files/syntax/tid_syntax_valid.txt b/tests/test_atproto_client/interop-test-files/syntax/tid_syntax_valid.txt new file mode 100644 index 00000000..b161a3fe --- /dev/null +++ b/tests/test_atproto_client/interop-test-files/syntax/tid_syntax_valid.txt @@ -0,0 +1,6 @@ +# 13 digits +# 234567abcdefghijklmnopqrstuvwxyz + +3jzfcijpj2z2a +7777777777777 +3zzzzzzzzzzzz diff --git a/tests/test_atproto_client/models/tests/test_string_formats.py b/tests/test_atproto_client/models/tests/test_string_formats.py new file mode 100644 index 00000000..87203ebe --- /dev/null +++ b/tests/test_atproto_client/models/tests/test_string_formats.py @@ -0,0 +1,184 @@ +from functools import lru_cache +from pathlib import Path +from typing import List + +import pytest +from atproto_client.exceptions import ModelError +from atproto_client.models import string_formats +from atproto_client.models.string_formats import _OPT_IN_KEY +from atproto_client.models.utils import get_or_create +from pydantic import BaseModel, TypeAdapter, ValidationError + +# Test data sourced directly from bluesky-social/atproto repo: +# https://github.com/bluesky-social/atproto/tree/main/interop-test-files/syntax +INTEROP_TEST_FILES_DIR: Path = Path('tests/test_atproto_client/interop-test-files/syntax') + + +def get_test_cases(filename: str) -> List[str]: + """Get non-comment, non-empty lines from an interop test file. + + Important: Preserves whitespace in test cases. This is critical for + format validators where leading/trailing/internal whitespace makes a + value invalid. For example, ' 1985-04-12T23:20:50.123Z' (with leading space) + should be invalid for datetime validation. + + Args: + filename: Name of the test file to read from interop test files directory + + Returns: + List of test cases with original whitespace preserved + """ + return [ + line + for line in INTEROP_TEST_FILES_DIR.joinpath(filename).read_text().splitlines() + if line and not line.startswith('#') + ] + + +@lru_cache +def read_test_data() -> dict: + """Load all test data once at session start""" + return { + 'valid': { + 'handle': get_test_cases('handle_syntax_valid.txt'), + 'did': get_test_cases('did_syntax_valid.txt'), + 'nsid': get_test_cases('nsid_syntax_valid.txt'), + 'at_uri': get_test_cases('aturi_syntax_valid.txt'), + 'datetime': get_test_cases('datetime_syntax_valid.txt'), + 'tid': get_test_cases('tid_syntax_valid.txt'), + 'record_key': get_test_cases('recordkey_syntax_valid.txt'), + }, + 'invalid': { + 'handle': get_test_cases('handle_syntax_invalid.txt'), + 'did': get_test_cases('did_syntax_invalid.txt'), + 'nsid': get_test_cases('nsid_syntax_invalid.txt'), + 'at_uri': get_test_cases('aturi_syntax_invalid.txt'), + 'datetime': get_test_cases('datetime_syntax_invalid.txt'), + 'tid': get_test_cases('tid_syntax_invalid.txt'), + 'record_key': get_test_cases('recordkey_syntax_invalid.txt'), + }, + } + + +@pytest.fixture +def valid_data() -> dict: + """Get first valid example of each type plus constants""" + test_data = read_test_data() + return { + 'handle': test_data['valid']['handle'][0], + 'did': test_data['valid']['did'][0], + 'nsid': test_data['valid']['nsid'][0], + 'at_uri': test_data['valid']['at_uri'][0], + 'cid': 'bafyreidfayvfuwqa2beehqn7axeeeaej5aqvaowxgwcdt2rw', # No interop test file for CID + 'datetime': test_data['valid']['datetime'][0], + 'tid': test_data['valid']['tid'][0], + 'record_key': test_data['valid']['record_key'][0], + 'uri': 'https://example.com', # No interop test file for URI + 'language': 'en-US', # No interop test file for language + } + + +@pytest.fixture +def invalid_data() -> dict: + """Get first invalid example of each type plus constants""" + test_data = read_test_data() + return { + 'handle': test_data['invalid']['handle'][0], + 'did': test_data['invalid']['did'][0], + 'nsid': test_data['invalid']['nsid'][0], + 'at_uri': test_data['invalid']['at_uri'][0], + 'cid': 'short', # No interop test file for CID + 'datetime': test_data['invalid']['datetime'][0], + 'tid': test_data['invalid']['tid'][0], + 'record_key': test_data['invalid']['record_key'][0], + 'uri': 'invalid-uri-no-scheme', # No interop test file for URI + 'language': 'invalid!', # No interop test file for language + } + + +@pytest.mark.parametrize( + 'validator_type,field_name,invalid_value', + [ + (validator_type, field_name, invalid_value) + for validator_type, field_name in [ + (string_formats.AtUri, 'at_uri'), + (string_formats.DateTime, 'datetime'), + (string_formats.Handle, 'handle'), + (string_formats.Did, 'did'), + (string_formats.Nsid, 'nsid'), + (string_formats.Tid, 'tid'), + (string_formats.RecordKey, 'record_key'), + ] + for invalid_value in read_test_data()['invalid'][field_name] + ], +) +def test_string_format_validation(validator_type: type, field_name: str, invalid_value: str, valid_data: dict) -> None: + """Test validation for each string format type.""" + SomeTypeAdapter = TypeAdapter(validator_type) + + # Test that validation is skipped by default + assert SomeTypeAdapter.validate_python(invalid_value) == invalid_value + + # Test that valid data passes strict validation + validated_value = SomeTypeAdapter.validate_python(valid_data[field_name], context={_OPT_IN_KEY: True}) + assert validated_value == valid_data[field_name] + + # Test that invalid data fails strict validation + with pytest.raises(ValidationError): + SomeTypeAdapter.validate_python(invalid_value, context={_OPT_IN_KEY: True}) + + +@pytest.mark.parametrize( + 'valid_value', + [ + 'test.bsky.social', + 'did:plc:1234abcd', + 'app.bsky.feed.post', + 'at://user.bsky.social/posts/123', + 'bafyreidfayvfuwqa2beehqn7axeeeaej5aqvaowxgwcdt2rw', + '2023-01-01T12:00:00Z', + '3jqvenncqkgbm', + 'valid-key', + 'https://example.com', + 'en-US', + ], +) +def test_generic_string_format_validation(valid_value: str) -> None: + """Test that ATProtoString accepts each valid string format.""" + + validated = TypeAdapter(string_formats.AtProtoString).validate_python(valid_value, context={_OPT_IN_KEY: True}) + assert validated == valid_value + + +def test_get_or_create_with_strict_validation(valid_data: dict, invalid_data: dict) -> None: + """Test that get_or_create uses strict validation.""" + + class FooModel(BaseModel): + handle: string_formats.Handle + did: string_formats.Did + + # Test valid data passes + instance = get_or_create( + {'handle': valid_data['handle'], 'did': valid_data['did']}, FooModel, strict_string_format=True + ) + assert isinstance(instance, FooModel) + assert instance.handle == valid_data['handle'] + assert instance.did == valid_data['did'] + + # Test invalid handle fails + with pytest.raises(ModelError) as exc_info: + get_or_create({'handle': invalid_data['handle'], 'did': valid_data['did']}, FooModel, strict_string_format=True) + assert 'must be a domain name' in str(exc_info.value) + + # Test invalid did fails + with pytest.raises(ModelError) as exc_info: + get_or_create({'handle': valid_data['handle'], 'did': invalid_data['did']}, FooModel, strict_string_format=True) + assert 'must be in format did:method:identifier' in str(exc_info.value) + + # Test that validation is skipped when strict_string_format=False + instance = get_or_create( + {'handle': invalid_data['handle'], 'did': invalid_data['did']}, FooModel, strict_string_format=False + ) + assert isinstance(instance, FooModel) + assert instance.handle == invalid_data['handle'] + assert instance.did == invalid_data['did'] diff --git a/tests/test_atproto_client/models/tests/test_utils.py b/tests/test_atproto_client/models/tests/test_utils.py index f08427bc..f58a5339 100644 --- a/tests/test_atproto_client/models/tests/test_utils.py +++ b/tests/test_atproto_client/models/tests/test_utils.py @@ -1,5 +1,8 @@ +from dataclasses import dataclass + import pytest -from atproto_client.models.utils import is_json, load_json +from atproto_client.exceptions import ModelError +from atproto_client.models.utils import get_or_create, is_json, load_json def test_load_json() -> None: @@ -17,7 +20,7 @@ def test_load_json() -> None: assert load_json('{"key": "value"}'.encode('UTF-16'), strict=False) is None with pytest.raises(TypeError): - load_json(None) + load_json(None) # type: ignore[reportArgumentType] def test_is_json() -> None: @@ -33,4 +36,18 @@ def test_is_json() -> None: assert is_json(b'{}') is True with pytest.raises(TypeError): - load_json(None) + load_json(None) # type: ignore[reportArgumentType] + + +def test_get_or_create_works_with_dataclasses() -> None: + """Test that get_or_create works with dataclasses.""" + + @dataclass + class Foo: + bar: str + + with pytest.raises(ModelError, match='Cannot parse model of type'): + get_or_create(('bar', 'not a mapping'), Foo) + + result = get_or_create({'bar': 'baz'}, Foo) + assert result == Foo(bar='baz')