Skip to content

Commit

Permalink
Add Python 3.13 support (#416)
Browse files Browse the repository at this point in the history
  • Loading branch information
MarshalX authored Oct 24, 2024
1 parent e5b1364 commit 78fca92
Show file tree
Hide file tree
Showing 71 changed files with 645 additions and 965 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/codegen.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
- name: Setup Poetry.
uses: snok/install-poetry@v1
with:
version: 1.5.1
version: 1.8.3

- name: Install dependencies.
run: poetry install --no-interaction
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish_release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:
- name: Setup Poetry.
uses: snok/install-poetry@v1
with:
version: 1.5.1
version: 1.8.3

- name: Install Poetry Plugin.
run: poetry self add "poetry-dynamic-versioning[plugin]"
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/ruff.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ jobs:
python-version: 3.8

- name: Run linter check.
uses: chartboost/ruff-action@v1
uses: astral-sh/ruff-action@v1
with:
version: 0.1.2
version: 0.7.0

- name: Run code style check.
uses: chartboost/ruff-action@v1
uses: astral-sh/ruff-action@v1
with:
version: 0.1.2
args: format --check
version: 0.7.0
args: "format --check"
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
strategy:
matrix:
os: [ macos-latest, ubuntu-latest, windows-latest ]
python-version: [ "3.8", "3.9", "3.10", "3.11", "3.12" ]
python-version: [ "3.8", "3.9", "3.10", "3.11", "3.12", "3.13" ]

runs-on: ${{matrix.os}}

Expand Down Expand Up @@ -43,7 +43,7 @@ jobs:
- name: Setup Poetry.
uses: snok/install-poetry@v1
with:
version: 1.5.1
version: 1.8.3

- name: Install dependencies.
run: poetry install --without docs
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/update_lexicons.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
- name: Setup Poetry.
uses: snok/install-poetry@v1
with:
version: 1.5.1
version: 1.8.3

- name: Install dependencies.
run: poetry install --no-interaction
Expand Down
2 changes: 1 addition & 1 deletion examples/advanced_usage/notifications_callback.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ async def on_notification_callback(notification: Notification) -> None:
# example: "Got new notification! Type: like; from: did:plc:hlorqa2iqfooopmyzvb4byaz"

async def listen_for_notifications(
on_notification: t.Callable[[Notification], t.Coroutine[t.Any, t.Any, None]]
on_notification: t.Callable[[Notification], t.Coroutine[t.Any, t.Any, None]],
) -> None:
print('Start listening for notifications...')
while True:
Expand Down
3 changes: 2 additions & 1 deletion examples/firehose/stop_client_async.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@ async def _stop_after_n_sec() -> None:
await client.stop()

# save ref to task to eliminate problems with GC
_ = asyncio.create_task(_stop_after_n_sec())
_stop_after_n_sec_task = asyncio.create_task(_stop_after_n_sec())

await client.start(on_message_handler)
await _stop_after_n_sec_task

print(f'Successfully stopped after {_STOP_AFTER_SECONDS} seconds!')

Expand Down
2 changes: 1 addition & 1 deletion packages/atproto_client/client/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def _handle_kwagrs(kwargs: dict) -> None:
if content_type == _CONTENT_TYPE_JSON and 'data' in kwargs and kwargs['data']:
kwargs['data'] = get_model_as_json(kwargs['data'])

if 'params' in kwargs and kwargs['params']:
if kwargs.get('params'):
kwargs['params'] = get_model_as_dict(kwargs['params'])

# pop non-request kwargs
Expand Down
21 changes: 7 additions & 14 deletions packages/atproto_client/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,37 +9,30 @@
_DEFAULT_LOGING_REQUIRED_ERROR_MESSAGE = 'To perform this action, you must be logged in. Use the `login` method first.'


class ModelError(AtProtocolError):
...
class ModelError(AtProtocolError): ...


class ModelFieldNotFoundError(ModelError):
...
class ModelFieldNotFoundError(ModelError): ...


class RequestErrorBase(AtProtocolError):
def __init__(self, response: t.Optional['Response'] = None) -> None:
self.response: t.Optional['Response'] = response


class NetworkError(RequestErrorBase):
...
class NetworkError(RequestErrorBase): ...


class InvokeTimeoutError(NetworkError):
...
class InvokeTimeoutError(NetworkError): ...


class UnauthorizedError(RequestErrorBase):
...
class UnauthorizedError(RequestErrorBase): ...


class RequestException(RequestErrorBase):
...
class RequestException(RequestErrorBase): ...


class BadRequestError(RequestErrorBase):
...
class BadRequestError(RequestErrorBase): ...


class LoginRequiredError(AtProtocolError):
Expand Down
30 changes: 15 additions & 15 deletions packages/atproto_client/models/app/bsky/actor/defs.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,9 @@ class ProfileViewDetailed(base.ModelBase):
followers_count: t.Optional[int] = None #: Followers count.
follows_count: t.Optional[int] = None #: Follows count.
indexed_at: t.Optional[str] = None #: Indexed at.
joined_via_starter_pack: t.Optional[
'models.AppBskyGraphDefs.StarterPackViewBasic'
] = None #: Joined via starter pack.
joined_via_starter_pack: t.Optional['models.AppBskyGraphDefs.StarterPackViewBasic'] = (
None #: Joined via starter pack.
)
labels: t.Optional[t.List['models.ComAtprotoLabelDefs.Label']] = None #: Labels.
pinned_post: t.Optional['models.ComAtprotoRepoStrongRef.Main'] = None #: Pinned post.
posts_count: t.Optional[int] = None #: Posts count.
Expand Down Expand Up @@ -226,9 +226,9 @@ class FeedViewPref(base.ModelBase):
feed: str #: The URI of the feed, or an identifier which describes the feed.
hide_quote_posts: t.Optional[bool] = None #: Hide quote posts in the feed.
hide_replies: t.Optional[bool] = None #: Hide replies in the feed.
hide_replies_by_like_count: t.Optional[
int
] = None #: Hide replies in the feed if they do not have this number of likes.
hide_replies_by_like_count: t.Optional[int] = (
None #: Hide replies in the feed if they do not have this number of likes.
)
hide_replies_by_unfollowed: t.Optional[bool] = True #: Hide replies in the feed if they are not by followed users.
hide_reposts: t.Optional[bool] = None #: Hide reposts in the feed.

Expand Down Expand Up @@ -270,12 +270,12 @@ class MutedWord(base.ModelBase):

targets: t.List['models.AppBskyActorDefs.MutedWordTarget'] #: The intended targets of the muted word.
value: str = Field(max_length=10000) #: The muted word itself.
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
] = None #: The date and time at which the muted word will expire and no longer be applied.
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] = (
None #: The date and time at which the muted word will expire and no longer be applied.
)
id: t.Optional[str] = None #: Id.

py_type: t.Literal['app.bsky.actor.defs#mutedWord'] = Field(
Expand Down Expand Up @@ -357,8 +357,8 @@ 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
] = None #: The date and time at which the NUX will expire and should be considered completed.
expires_at: t.Optional[str] = (
None #: The date and time at which the NUX will expire and should be considered completed.
)

py_type: t.Literal['app.bsky.actor.defs#nux'] = Field(default='app.bsky.actor.defs#nux', alias='$type', frozen=True)
6 changes: 3 additions & 3 deletions packages/atproto_client/models/app/bsky/actor/profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@
class Record(base.RecordModelBase):
"""Record model for :obj:`app.bsky.actor.profile`."""

avatar: t.Optional[
'BlobRef'
] = None #: Small image to be displayed next to posts from account. AKA, 'profile picture'.
avatar: t.Optional['BlobRef'] = (
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.
description: t.Optional[str] = Field(default=None, max_length=2560) #: Free-form profile description text.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ class Params(base.ParamsModelBase):

cursor: t.Optional[str] = None #: Cursor.
limit: t.Optional[int] = Field(default=25, ge=1, le=100) #: Limit.
q: t.Optional[
str
] = None #: Search query string. Syntax, phrase, boolean, and faceting is unspecified, but Lucene query syntax is recommended.
q: t.Optional[str] = (
None #: Search query string. Syntax, phrase, boolean, and faceting is unspecified, but Lucene query syntax is recommended.
)
term: t.Optional[str] = None #: DEPRECATED: use 'q' instead.


Expand Down
6 changes: 3 additions & 3 deletions packages/atproto_client/models/app/bsky/feed/defs.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,9 @@ class ReplyRef(base.ModelBase):
],
Field(discriminator='py_type'),
] #: Root.
grandparent_author: t.Optional[
'models.AppBskyActorDefs.ProfileViewBasic'
] = None #: When parent is a reply to another post, this is the author of that post.
grandparent_author: t.Optional['models.AppBskyActorDefs.ProfileViewBasic'] = (
None #: When parent is a reply to another post, this is the author of that post.
)

py_type: t.Literal['app.bsky.feed.defs#replyRef'] = Field(
default='app.bsky.feed.defs#replyRef', alias='$type', frozen=True
Expand Down
8 changes: 3 additions & 5 deletions packages/atproto_client/models/app/bsky/feed/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,9 @@ class Record(base.RecordModelBase):
created_at: str #: Created at.
did: str #: 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.
accepts_interactions: t.Optional[bool] = (
None #: Declaration that a feed accepts feedback interactions from a client through app.bsky.feed.sendInteractions.
)
avatar: t.Optional['BlobRef'] = 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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class Response(base.ResponseModelBase):
"""Output data model for :obj:`app.bsky.feed.getFeedGenerator`."""

is_online: (
bool
) #: Indicates whether the feed generator service has been online recently, or else seems to be inactive.
bool #: Indicates whether the feed generator service has been online recently, or else seems to be inactive.
)
is_valid: bool #: Indicates whether the feed generator service is compatible with the record declaration.
view: 'models.AppBskyFeedDefs.GeneratorView' #: View.
6 changes: 3 additions & 3 deletions packages/atproto_client/models/app/bsky/feed/get_timeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@
class Params(base.ParamsModelBase):
"""Parameters model for :obj:`app.bsky.feed.getTimeline`."""

algorithm: t.Optional[
str
] = None #: Variant 'algorithm' for timeline. Implementation-specific. NOTE: most feed flexibility has been moved to feed generator mechanism.
algorithm: t.Optional[str] = (
None #: Variant 'algorithm' for timeline. Implementation-specific. NOTE: most feed flexibility has been moved to feed generator mechanism.
)
cursor: t.Optional[str] = None #: Cursor.
limit: t.Optional[int] = Field(default=50, ge=1, le=100) #: Limit.

Expand Down
12 changes: 6 additions & 6 deletions packages/atproto_client/models/app/bsky/feed/post.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,12 @@ class Record(base.RecordModelBase):
Field(default=None, discriminator='py_type'),
]
] = None #: Embed.
entities: t.Optional[
t.List['models.AppBskyFeedPost.Entity']
] = None #: DEPRECATED: replaced by app.bsky.richtext.facet.
facets: t.Optional[
t.List['models.AppBskyRichtextFacet.Main']
] = None #: Annotations of text (mentions, URLs, hashtags, etc).
entities: t.Optional[t.List['models.AppBskyFeedPost.Entity']] = (
None #: DEPRECATED: replaced by app.bsky.richtext.facet.
)
facets: t.Optional[t.List['models.AppBskyRichtextFacet.Main']] = (
None #: Annotations of text (mentions, URLs, hashtags, etc).
)
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.
Expand Down
66 changes: 33 additions & 33 deletions packages/atproto_client/models/app/bsky/feed/search_posts.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,37 +19,37 @@ 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
] = None #: Filter to posts by the given account. Handles are resolved to DID before query-time.
cursor: t.Optional[
str
] = None #: Optional pagination mechanism; may not necessarily allow scrolling through entire result set.
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
] = None #: Filter to posts in the given language. Expected to be based on post language field, though server may override language detection.
author: t.Optional[str] = (
None #: Filter to posts by the given account. Handles are resolved to DID before query-time.
)
cursor: t.Optional[str] = (
None #: Optional pagination mechanism; may not necessarily allow scrolling through entire result set.
)
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] = (
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
] = 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
] = None #: Filter results for posts after the indicated datetime (inclusive). Expected to use 'sortAt' timestamp, which may not match 'createdAt'. Can be a datetime, or just an ISO date (YYYY-MM-DD).
sort: t.Optional[
t.Union[t.Literal['top'], t.Literal['latest'], str]
] = 'latest' #: Specifies the ranking order of results.
tag: t.Optional[
t.List[str]
] = None #: Filter to posts with the given tag (hashtag), based on rich-text facet or tag field. Do not include the hash (#) prefix. Multiple tags can be specified, with 'AND' matching.
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
] = None #: Filter to posts with links (facet links or embeds) pointing to this URL. Server may apply URL normalization or fuzzy matching.
mentions: t.Optional[str] = (
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] = (
None #: Filter results for posts after the indicated datetime (inclusive). Expected to use 'sortAt' timestamp, which may not match 'createdAt'. Can be a datetime, or just an ISO date (YYYY-MM-DD).
)
sort: t.Optional[t.Union[t.Literal['top'], t.Literal['latest'], str]] = (
'latest' #: Specifies the ranking order of results.
)
tag: t.Optional[t.List[str]] = (
None #: Filter to posts with the given tag (hashtag), based on rich-text facet or tag field. Do not include the hash (#) prefix. Multiple tags can be specified, with 'AND' matching.
)
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] = (
None #: Filter to posts with links (facet links or embeds) pointing to this URL. Server may apply URL normalization or fuzzy matching.
)


class ParamsDict(t.TypedDict):
Expand Down Expand Up @@ -92,6 +92,6 @@ class Response(base.ResponseModelBase):

posts: t.List['models.AppBskyFeedDefs.PostView'] #: Posts.
cursor: t.Optional[str] = None #: Cursor.
hits_total: t.Optional[
int
] = None #: Count of search hits. Optional, may be rounded/truncated, and may not be possible to paginate through all hits.
hits_total: t.Optional[int] = (
None #: Count of search hits. Optional, may be rounded/truncated, and may not be possible to paginate through all hits.
)
6 changes: 3 additions & 3 deletions packages/atproto_client/models/app/bsky/graph/defs.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,9 @@ 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
] = None #: if the actor is followed by this DID, contains the AT-URI of the follow record.
followed_by: t.Optional[str] = (
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.

py_type: t.Literal['app.bsky.graph.defs#relationship'] = Field(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ class Response(base.ResponseModelBase):
"""Output data model for :obj:`app.bsky.graph.getSuggestedFollowsByActor`."""

suggestions: t.List['models.AppBskyActorDefs.ProfileView'] #: Suggestions.
is_fallback: t.Optional[
bool
] = False #: If true, response has fallen-back to generic results, and is not scoped using relativeToDid.
is_fallback: t.Optional[bool] = (
False #: If true, response has fallen-back to generic results, and is not scoped using relativeToDid.
)
Loading

0 comments on commit 78fca92

Please sign in to comment.