lexrpc 2.0__tar.gz → 2.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (427) hide show
  1. {lexrpc-2.0 → lexrpc-2.2}/PKG-INFO +55 -16
  2. lexrpc-2.0/lexrpc.egg-info/PKG-INFO → lexrpc-2.2/README.md +42 -38
  3. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/base.py +57 -47
  4. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/client.py +25 -12
  5. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/flask_server.py +11 -4
  6. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/actor/defs.json +92 -6
  7. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/actor/getSuggestions.json +4 -0
  8. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/actor/profile.json +7 -0
  9. lexrpc-2.2/lexrpc/lexicons/app/bsky/ageassurance/begin.json +48 -0
  10. lexrpc-2.2/lexrpc/lexicons/app/bsky/ageassurance/defs.json +255 -0
  11. lexrpc-2.2/lexrpc/lexicons/app/bsky/ageassurance/getConfig.json +17 -0
  12. lexrpc-2.2/lexrpc/lexicons/app/bsky/ageassurance/getState.json +35 -0
  13. lexrpc-2.2/lexrpc/lexicons/app/bsky/authCreatePosts.json +35 -0
  14. lexrpc-2.2/lexrpc/lexicons/app/bsky/authDeleteContent.json +27 -0
  15. lexrpc-2.2/lexrpc/lexicons/app/bsky/authFullApp.json +136 -0
  16. lexrpc-2.2/lexrpc/lexicons/app/bsky/authManageFeedDeclarations.json +21 -0
  17. lexrpc-2.2/lexrpc/lexicons/app/bsky/authManageLabelerService.json +21 -0
  18. lexrpc-2.2/lexrpc/lexicons/app/bsky/authManageModeration.json +36 -0
  19. lexrpc-2.2/lexrpc/lexicons/app/bsky/authManageNotifications.json +32 -0
  20. lexrpc-2.2/lexrpc/lexicons/app/bsky/authManageProfile.json +25 -0
  21. lexrpc-2.2/lexrpc/lexicons/app/bsky/authViewAll.json +89 -0
  22. lexrpc-2.2/lexrpc/lexicons/app/bsky/contact/defs.json +57 -0
  23. lexrpc-2.2/lexrpc/lexicons/app/bsky/contact/dismissMatch.json +39 -0
  24. lexrpc-2.2/lexrpc/lexicons/app/bsky/contact/getMatches.json +53 -0
  25. lexrpc-2.2/lexrpc/lexicons/app/bsky/contact/getSyncStatus.json +35 -0
  26. lexrpc-2.2/lexrpc/lexicons/app/bsky/contact/importContacts.json +66 -0
  27. lexrpc-2.2/lexrpc/lexicons/app/bsky/contact/removeData.json +32 -0
  28. lexrpc-2.2/lexrpc/lexicons/app/bsky/contact/sendNotification.json +36 -0
  29. lexrpc-2.2/lexrpc/lexicons/app/bsky/contact/startPhoneVerification.json +44 -0
  30. lexrpc-2.2/lexrpc/lexicons/app/bsky/contact/verifyPhone.json +57 -0
  31. lexrpc-2.2/lexrpc/lexicons/app/bsky/draft/createDraft.json +42 -0
  32. lexrpc-2.2/lexrpc/lexicons/app/bsky/draft/defs.json +241 -0
  33. lexrpc-2.2/lexrpc/lexicons/app/bsky/draft/deleteDraft.json +23 -0
  34. lexrpc-2.2/lexrpc/lexicons/app/bsky/draft/getDrafts.json +39 -0
  35. lexrpc-2.2/lexrpc/lexicons/app/bsky/draft/updateDraft.json +23 -0
  36. lexrpc-2.2/lexrpc/lexicons/app/bsky/embed/external.json +149 -0
  37. lexrpc-2.2/lexrpc/lexicons/app/bsky/embed/gallery.json +79 -0
  38. lexrpc-2.2/lexrpc/lexicons/app/bsky/embed/getEmbedExternalView.json +55 -0
  39. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/embed/images.json +2 -1
  40. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/embed/record.json +1 -0
  41. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/embed/recordWithMedia.json +2 -0
  42. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/embed/video.json +10 -0
  43. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/feed/defs.json +6 -1
  44. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/feed/post.json +1 -0
  45. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/feed/sendInteractions.json +1 -0
  46. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/feed/threadgate.json +1 -1
  47. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/graph/defs.json +20 -0
  48. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/graph/follow.json +2 -1
  49. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/graph/getSuggestedFollowsByActor.json +6 -2
  50. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/notification/listNotifications.json +2 -1
  51. lexrpc-2.2/lexrpc/lexicons/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.json +37 -0
  52. lexrpc-2.2/lexrpc/lexicons/app/bsky/unspecced/getOnboardingSuggestedStarterPacksSkeleton.json +42 -0
  53. lexrpc-2.2/lexrpc/lexicons/app/bsky/unspecced/getOnboardingSuggestedUsersSkeleton.json +54 -0
  54. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/unspecced/getPostThreadOtherV2.json +0 -5
  55. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/unspecced/getPostThreadV2.json +0 -5
  56. lexrpc-2.2/lexrpc/lexicons/app/bsky/unspecced/getSuggestedOnboardingUsers.json +49 -0
  57. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/unspecced/getSuggestedUsers.json +8 -0
  58. lexrpc-2.2/lexrpc/lexicons/app/bsky/unspecced/getSuggestedUsersForDiscover.json +41 -0
  59. lexrpc-2.2/lexrpc/lexicons/app/bsky/unspecced/getSuggestedUsersForDiscoverSkeleton.json +46 -0
  60. lexrpc-2.2/lexrpc/lexicons/app/bsky/unspecced/getSuggestedUsersForExplore.json +45 -0
  61. lexrpc-2.2/lexrpc/lexicons/app/bsky/unspecced/getSuggestedUsersForExploreSkeleton.json +50 -0
  62. lexrpc-2.2/lexrpc/lexicons/app/bsky/unspecced/getSuggestedUsersForSeeMore.json +45 -0
  63. lexrpc-2.2/lexrpc/lexicons/app/bsky/unspecced/getSuggestedUsersForSeeMoreSkeleton.json +50 -0
  64. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/unspecced/getSuggestedUsersSkeleton.json +8 -0
  65. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/unspecced/getSuggestionsSkeleton.json +4 -0
  66. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/chat/bsky/actor/declaration.json +5 -0
  67. lexrpc-2.2/lexrpc/lexicons/chat/bsky/actor/defs.json +79 -0
  68. lexrpc-2.2/lexrpc/lexicons/chat/bsky/actor/getStatus.json +31 -0
  69. lexrpc-2.2/lexrpc/lexicons/chat/bsky/authFullChatClient.json +69 -0
  70. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/chat/bsky/convo/acceptConvo.json +2 -0
  71. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/chat/bsky/convo/addReaction.json +5 -0
  72. lexrpc-2.2/lexrpc/lexicons/chat/bsky/convo/defs.json +848 -0
  73. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/chat/bsky/convo/deleteMessageForSelf.json +8 -0
  74. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/chat/bsky/convo/getConvo.json +2 -0
  75. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/chat/bsky/convo/getConvoAvailability.json +1 -1
  76. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/chat/bsky/convo/getConvoForMembers.json +9 -0
  77. lexrpc-2.0/lexrpc/lexicons/chat/bsky/convo/getMessages.json → lexrpc-2.2/lexrpc/lexicons/chat/bsky/convo/getConvoMembers.json +7 -8
  78. lexrpc-2.2/lexrpc/lexicons/chat/bsky/convo/getLog.json +69 -0
  79. lexrpc-2.2/lexrpc/lexicons/chat/bsky/convo/getMessages.json +54 -0
  80. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/chat/bsky/convo/leaveConvo.json +8 -0
  81. lexrpc-2.2/lexrpc/lexicons/chat/bsky/convo/listConvoRequests.json +42 -0
  82. lexrpc-2.2/lexrpc/lexicons/chat/bsky/convo/listConvos.json +58 -0
  83. lexrpc-2.2/lexrpc/lexicons/chat/bsky/convo/lockConvo.json +38 -0
  84. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/chat/bsky/convo/muteConvo.json +2 -0
  85. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/chat/bsky/convo/removeReaction.json +5 -0
  86. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/chat/bsky/convo/sendMessage.json +2 -0
  87. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/chat/bsky/convo/sendMessageBatch.json +2 -0
  88. lexrpc-2.2/lexrpc/lexicons/chat/bsky/convo/unlockConvo.json +34 -0
  89. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/chat/bsky/convo/unmuteConvo.json +2 -0
  90. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/chat/bsky/convo/updateAllRead.json +1 -0
  91. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/chat/bsky/convo/updateRead.json +2 -0
  92. lexrpc-2.2/lexrpc/lexicons/chat/bsky/embed/joinLink.json +27 -0
  93. lexrpc-2.2/lexrpc/lexicons/chat/bsky/group/addMembers.json +57 -0
  94. lexrpc-2.2/lexrpc/lexicons/chat/bsky/group/approveJoinRequest.json +39 -0
  95. lexrpc-2.2/lexrpc/lexicons/chat/bsky/group/createGroup.json +55 -0
  96. lexrpc-2.2/lexrpc/lexicons/chat/bsky/group/createJoinLink.json +46 -0
  97. lexrpc-2.2/lexrpc/lexicons/chat/bsky/group/defs.json +111 -0
  98. lexrpc-2.2/lexrpc/lexicons/chat/bsky/group/disableJoinLink.json +38 -0
  99. lexrpc-2.2/lexrpc/lexicons/chat/bsky/group/editGroup.json +44 -0
  100. lexrpc-2.2/lexrpc/lexicons/chat/bsky/group/editJoinLink.json +43 -0
  101. lexrpc-2.2/lexrpc/lexicons/chat/bsky/group/enableJoinLink.json +39 -0
  102. lexrpc-2.2/lexrpc/lexicons/chat/bsky/group/getJoinLinkPreviews.json +38 -0
  103. lexrpc-2.2/lexrpc/lexicons/chat/bsky/group/listJoinRequests.json +42 -0
  104. lexrpc-2.0/lexrpc/lexicons/chat/bsky/convo/listConvos.json → lexrpc-2.2/lexrpc/lexicons/chat/bsky/group/listMutualGroups.json +8 -10
  105. lexrpc-2.2/lexrpc/lexicons/chat/bsky/group/rejectJoinRequest.json +30 -0
  106. lexrpc-2.2/lexrpc/lexicons/chat/bsky/group/removeMembers.json +39 -0
  107. lexrpc-2.2/lexrpc/lexicons/chat/bsky/group/requestJoin.json +46 -0
  108. lexrpc-2.2/lexrpc/lexicons/chat/bsky/group/updateJoinRequestsRead.json +29 -0
  109. lexrpc-2.2/lexrpc/lexicons/chat/bsky/group/withdrawJoinRequest.json +29 -0
  110. lexrpc-2.2/lexrpc/lexicons/chat/bsky/moderation/defs.json +70 -0
  111. lexrpc-2.2/lexrpc/lexicons/chat/bsky/moderation/getConvo.json +31 -0
  112. lexrpc-2.2/lexrpc/lexicons/chat/bsky/moderation/getConvoMembers.json +42 -0
  113. lexrpc-2.2/lexrpc/lexicons/chat/bsky/moderation/getConvos.json +38 -0
  114. lexrpc-2.2/lexrpc/lexicons/chat/bsky/moderation/getMessageContext.json +56 -0
  115. lexrpc-2.2/lexrpc/lexicons/chat/bsky/moderation/subscribeModEvents.json +559 -0
  116. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/label/defs.json +2 -5
  117. lexrpc-2.2/lexrpc/lexicons/com/atproto/lexicon/resolveLexicon.json +51 -0
  118. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/moderation/defs.json +10 -15
  119. lexrpc-2.2/lexrpc/lexicons/com/atproto/server/deleteSession.json +11 -0
  120. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/server/getServiceAuth.json +2 -2
  121. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/server/refreshSession.json +8 -1
  122. lexrpc-2.2/lexrpc/lexicons/com/germnetwork/declaration.json +64 -0
  123. lexrpc-2.2/lexrpc/lexicons/community/lexicon/bookmarks/authManageBookmarks.json +41 -0
  124. lexrpc-2.2/lexrpc/lexicons/community/lexicon/bookmarks/authViewBookmarks.json +34 -0
  125. lexrpc-2.2/lexrpc/lexicons/community/lexicon/bookmarks/bookmark.json +35 -0
  126. lexrpc-2.2/lexrpc/lexicons/community/lexicon/bookmarks/getActorBookmarks.json +51 -0
  127. lexrpc-2.2/lexrpc/lexicons/community/lexicon/calendar/event.json +150 -0
  128. lexrpc-2.2/lexrpc/lexicons/community/lexicon/calendar/rsvp.json +45 -0
  129. lexrpc-2.2/lexrpc/lexicons/community/lexicon/interaction/like.json +28 -0
  130. lexrpc-2.2/lexrpc/lexicons/community/lexicon/location/address.json +41 -0
  131. lexrpc-2.2/lexrpc/lexicons/community/lexicon/location/fsq.json +29 -0
  132. lexrpc-2.2/lexrpc/lexicons/community/lexicon/location/geo.json +29 -0
  133. lexrpc-2.2/lexrpc/lexicons/community/lexicon/location/hthree.json +23 -0
  134. lexrpc-2.2/lexrpc/lexicons/community/lexicon/payments/webMonetization.json +27 -0
  135. lexrpc-2.2/lexrpc/lexicons/community/lexicon/preference/ai.json +99 -0
  136. lexrpc-2.2/lexrpc/lexicons/site/standard/authFull.json +23 -0
  137. lexrpc-2.2/lexrpc/lexicons/site/standard/authSocial.json +21 -0
  138. lexrpc-2.2/lexrpc/lexicons/site/standard/document.json +125 -0
  139. lexrpc-2.2/lexrpc/lexicons/site/standard/graph/recommend.json +29 -0
  140. lexrpc-2.2/lexrpc/lexicons/site/standard/graph/subscription.json +28 -0
  141. lexrpc-2.2/lexrpc/lexicons/site/standard/publication.json +72 -0
  142. lexrpc-2.2/lexrpc/lexicons/site/standard/theme/basic.json +50 -0
  143. lexrpc-2.2/lexrpc/lexicons/site/standard/theme/color.json +62 -0
  144. lexrpc-2.2/lexrpc/lexicons/tools/ozone/moderation/cancelScheduledActions.json +64 -0
  145. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/moderation/defs.json +241 -12
  146. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/moderation/emitEvent.json +37 -1
  147. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/moderation/getAccountTimeline.json +3 -1
  148. lexrpc-2.2/lexrpc/lexicons/tools/ozone/moderation/listScheduledActions.json +78 -0
  149. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/moderation/queryEvents.json +6 -2
  150. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/moderation/queryStatuses.json +14 -3
  151. lexrpc-2.2/lexrpc/lexicons/tools/ozone/moderation/scheduleAction.json +155 -0
  152. lexrpc-2.2/lexrpc/lexicons/tools/ozone/queue/assignModerator.json +40 -0
  153. lexrpc-2.2/lexrpc/lexicons/tools/ozone/queue/createQueue.json +69 -0
  154. lexrpc-2.2/lexrpc/lexicons/tools/ozone/queue/defs.json +148 -0
  155. lexrpc-2.2/lexrpc/lexicons/tools/ozone/queue/deleteQueue.json +43 -0
  156. lexrpc-2.2/lexrpc/lexicons/tools/ozone/queue/getAssignments.json +63 -0
  157. lexrpc-2.2/lexrpc/lexicons/tools/ozone/queue/listQueues.json +61 -0
  158. lexrpc-2.2/lexrpc/lexicons/tools/ozone/queue/routeReports.json +50 -0
  159. lexrpc-2.2/lexrpc/lexicons/tools/ozone/queue/unassignModerator.json +34 -0
  160. lexrpc-2.2/lexrpc/lexicons/tools/ozone/queue/updateQueue.json +48 -0
  161. lexrpc-2.2/lexrpc/lexicons/tools/ozone/report/assignModerator.json +53 -0
  162. lexrpc-2.2/lexrpc/lexicons/tools/ozone/report/createActivity.json +75 -0
  163. lexrpc-2.2/lexrpc/lexicons/tools/ozone/report/defs.json +587 -0
  164. lexrpc-2.2/lexrpc/lexicons/tools/ozone/report/getAssignments.json +65 -0
  165. lexrpc-2.2/lexrpc/lexicons/tools/ozone/report/getHistoricalStats.json +71 -0
  166. lexrpc-2.2/lexrpc/lexicons/tools/ozone/report/getLatestReport.json +33 -0
  167. lexrpc-2.2/lexrpc/lexicons/tools/ozone/report/getLiveStats.json +45 -0
  168. lexrpc-2.2/lexrpc/lexicons/tools/ozone/report/getReport.json +33 -0
  169. lexrpc-2.2/lexrpc/lexicons/tools/ozone/report/listActivities.json +48 -0
  170. lexrpc-2.2/lexrpc/lexicons/tools/ozone/report/queryReports.json +120 -0
  171. lexrpc-2.2/lexrpc/lexicons/tools/ozone/report/reassignQueue.json +66 -0
  172. lexrpc-2.2/lexrpc/lexicons/tools/ozone/report/refreshStats.json +41 -0
  173. lexrpc-2.2/lexrpc/lexicons/tools/ozone/report/unassignModerator.json +36 -0
  174. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/team/defs.json +4 -4
  175. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/server.py +10 -2
  176. lexrpc-2.0/README.md → lexrpc-2.2/lexrpc.egg-info/PKG-INFO +77 -8
  177. {lexrpc-2.0 → lexrpc-2.2}/lexrpc.egg-info/SOURCES.txt +115 -0
  178. lexrpc-2.2/lexrpc.egg-info/requires.txt +18 -0
  179. lexrpc-2.2/lexrpc.egg-info/top_level.txt +1 -0
  180. {lexrpc-2.0 → lexrpc-2.2}/pyproject.toml +47 -17
  181. lexrpc-2.0/lexrpc/lexicons/app/bsky/embed/external.json +0 -51
  182. lexrpc-2.0/lexrpc/lexicons/chat/bsky/actor/defs.json +0 -37
  183. lexrpc-2.0/lexrpc/lexicons/chat/bsky/convo/defs.json +0 -236
  184. lexrpc-2.0/lexrpc/lexicons/chat/bsky/convo/getLog.json +0 -44
  185. lexrpc-2.0/lexrpc/lexicons/chat/bsky/moderation/getMessageContext.json +0 -41
  186. lexrpc-2.0/lexrpc/lexicons/com/atproto/server/deleteSession.json +0 -10
  187. lexrpc-2.0/lexrpc/lexicons/tools/ozone/report/defs.json +0 -249
  188. lexrpc-2.0/lexrpc.egg-info/requires.txt +0 -12
  189. lexrpc-2.0/lexrpc.egg-info/top_level.txt +0 -8
  190. {lexrpc-2.0 → lexrpc-2.2}/LICENSE +0 -0
  191. {lexrpc-2.0 → lexrpc-2.2}/MANIFEST.in +0 -0
  192. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/__init__.py +0 -0
  193. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/actor/getPreferences.json +0 -0
  194. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/actor/getProfile.json +0 -0
  195. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/actor/getProfiles.json +0 -0
  196. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/actor/putPreferences.json +0 -0
  197. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/actor/searchActors.json +0 -0
  198. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/actor/searchActorsTypeahead.json +0 -0
  199. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/actor/status.json +0 -0
  200. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/bookmark/createBookmark.json +0 -0
  201. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/bookmark/defs.json +0 -0
  202. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/bookmark/deleteBookmark.json +0 -0
  203. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/bookmark/getBookmarks.json +0 -0
  204. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/embed/defs.json +0 -0
  205. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/feed/describeFeedGenerator.json +0 -0
  206. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/feed/generator.json +0 -0
  207. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/feed/getActorFeeds.json +0 -0
  208. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/feed/getActorLikes.json +0 -0
  209. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/feed/getAuthorFeed.json +0 -0
  210. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/feed/getFeed.json +0 -0
  211. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/feed/getFeedGenerator.json +0 -0
  212. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/feed/getFeedGenerators.json +0 -0
  213. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/feed/getFeedSkeleton.json +0 -0
  214. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/feed/getLikes.json +0 -0
  215. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/feed/getListFeed.json +0 -0
  216. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/feed/getPostThread.json +0 -0
  217. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/feed/getPosts.json +0 -0
  218. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/feed/getQuotes.json +0 -0
  219. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/feed/getRepostedBy.json +0 -0
  220. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/feed/getSuggestedFeeds.json +0 -0
  221. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/feed/getTimeline.json +0 -0
  222. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/feed/like.json +0 -0
  223. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/feed/postgate.json +0 -0
  224. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/feed/repost.json +0 -0
  225. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/feed/searchPosts.json +0 -0
  226. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/graph/block.json +0 -0
  227. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/graph/getActorStarterPacks.json +0 -0
  228. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/graph/getBlocks.json +0 -0
  229. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/graph/getFollowers.json +0 -0
  230. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/graph/getFollows.json +0 -0
  231. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/graph/getKnownFollowers.json +0 -0
  232. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/graph/getList.json +0 -0
  233. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/graph/getListBlocks.json +0 -0
  234. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/graph/getListMutes.json +0 -0
  235. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/graph/getLists.json +0 -0
  236. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/graph/getListsWithMembership.json +0 -0
  237. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/graph/getMutes.json +0 -0
  238. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/graph/getRelationships.json +0 -0
  239. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/graph/getStarterPack.json +0 -0
  240. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/graph/getStarterPacks.json +0 -0
  241. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/graph/getStarterPacksWithMembership.json +0 -0
  242. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/graph/list.json +0 -0
  243. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/graph/listblock.json +0 -0
  244. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/graph/listitem.json +0 -0
  245. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/graph/muteActor.json +0 -0
  246. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/graph/muteActorList.json +0 -0
  247. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/graph/muteThread.json +0 -0
  248. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/graph/searchStarterPacks.json +0 -0
  249. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/graph/starterpack.json +0 -0
  250. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/graph/unmuteActor.json +0 -0
  251. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/graph/unmuteActorList.json +0 -0
  252. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/graph/unmuteThread.json +0 -0
  253. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/graph/verification.json +0 -0
  254. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/labeler/defs.json +0 -0
  255. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/labeler/getServices.json +0 -0
  256. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/labeler/service.json +0 -0
  257. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/notification/declaration.json +0 -0
  258. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/notification/defs.json +0 -0
  259. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/notification/getPreferences.json +0 -0
  260. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/notification/getUnreadCount.json +0 -0
  261. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/notification/listActivitySubscriptions.json +0 -0
  262. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/notification/putActivitySubscription.json +0 -0
  263. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/notification/putPreferences.json +0 -0
  264. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/notification/putPreferencesV2.json +0 -0
  265. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/notification/registerPush.json +0 -0
  266. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/notification/unregisterPush.json +0 -0
  267. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/notification/updateSeen.json +0 -0
  268. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/richtext/facet.json +0 -0
  269. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/unspecced/defs.json +0 -0
  270. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/unspecced/getAgeAssuranceState.json +0 -0
  271. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/unspecced/getConfig.json +0 -0
  272. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/unspecced/getPopularFeedGenerators.json +0 -0
  273. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/unspecced/getSuggestedFeeds.json +0 -0
  274. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/unspecced/getSuggestedFeedsSkeleton.json +0 -0
  275. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/unspecced/getSuggestedStarterPacks.json +0 -0
  276. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/unspecced/getSuggestedStarterPacksSkeleton.json +0 -0
  277. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/unspecced/getTaggedSuggestions.json +0 -0
  278. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/unspecced/getTrendingTopics.json +0 -0
  279. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/unspecced/getTrends.json +0 -0
  280. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/unspecced/getTrendsSkeleton.json +0 -0
  281. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/unspecced/initAgeAssurance.json +0 -0
  282. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/unspecced/searchActorsSkeleton.json +0 -0
  283. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/unspecced/searchPostsSkeleton.json +0 -0
  284. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/unspecced/searchStarterPacksSkeleton.json +0 -0
  285. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/video/defs.json +0 -0
  286. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/video/getJobStatus.json +0 -0
  287. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/video/getUploadLimits.json +0 -0
  288. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/app/bsky/video/uploadVideo.json +0 -0
  289. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/chat/bsky/actor/deleteAccount.json +0 -0
  290. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/chat/bsky/actor/exportAccountData.json +0 -0
  291. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/chat/bsky/moderation/getActorMetadata.json +0 -0
  292. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/chat/bsky/moderation/updateActorAccess.json +0 -0
  293. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/admin/defs.json +0 -0
  294. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/admin/deleteAccount.json +0 -0
  295. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/admin/disableAccountInvites.json +0 -0
  296. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/admin/disableInviteCodes.json +0 -0
  297. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/admin/enableAccountInvites.json +0 -0
  298. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/admin/getAccountInfo.json +0 -0
  299. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/admin/getAccountInfos.json +0 -0
  300. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/admin/getInviteCodes.json +0 -0
  301. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/admin/getSubjectStatus.json +0 -0
  302. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/admin/searchAccounts.json +0 -0
  303. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/admin/sendEmail.json +0 -0
  304. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/admin/updateAccountEmail.json +0 -0
  305. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/admin/updateAccountHandle.json +0 -0
  306. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/admin/updateAccountPassword.json +0 -0
  307. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/admin/updateAccountSigningKey.json +0 -0
  308. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/admin/updateSubjectStatus.json +0 -0
  309. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/identity/defs.json +0 -0
  310. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/identity/getRecommendedDidCredentials.json +0 -0
  311. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/identity/refreshIdentity.json +0 -0
  312. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/identity/requestPlcOperationSignature.json +0 -0
  313. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/identity/resolveDid.json +0 -0
  314. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/identity/resolveHandle.json +0 -0
  315. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/identity/resolveIdentity.json +0 -0
  316. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/identity/signPlcOperation.json +0 -0
  317. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/identity/submitPlcOperation.json +0 -0
  318. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/identity/updateHandle.json +0 -0
  319. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/label/queryLabels.json +0 -0
  320. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/label/subscribeLabels.json +0 -0
  321. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/lexicon/schema.json +0 -0
  322. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/moderation/createReport.json +0 -0
  323. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/repo/applyWrites.json +0 -0
  324. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/repo/createRecord.json +0 -0
  325. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/repo/defs.json +0 -0
  326. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/repo/deleteRecord.json +0 -0
  327. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/repo/describeRepo.json +0 -0
  328. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/repo/getRecord.json +0 -0
  329. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/repo/importRepo.json +0 -0
  330. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/repo/listMissingBlobs.json +0 -0
  331. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/repo/listRecords.json +0 -0
  332. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/repo/putRecord.json +0 -0
  333. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/repo/strongRef.json +0 -0
  334. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/repo/uploadBlob.json +0 -0
  335. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/server/activateAccount.json +0 -0
  336. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/server/checkAccountStatus.json +0 -0
  337. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/server/confirmEmail.json +0 -0
  338. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/server/createAccount.json +0 -0
  339. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/server/createAppPassword.json +0 -0
  340. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/server/createInviteCode.json +0 -0
  341. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/server/createInviteCodes.json +0 -0
  342. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/server/createSession.json +0 -0
  343. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/server/deactivateAccount.json +0 -0
  344. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/server/defs.json +0 -0
  345. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/server/deleteAccount.json +0 -0
  346. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/server/describeServer.json +0 -0
  347. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/server/getAccountInviteCodes.json +0 -0
  348. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/server/getSession.json +1 -1
  349. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/server/listAppPasswords.json +0 -0
  350. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/server/requestAccountDelete.json +0 -0
  351. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/server/requestEmailConfirmation.json +0 -0
  352. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/server/requestEmailUpdate.json +0 -0
  353. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/server/requestPasswordReset.json +0 -0
  354. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/server/reserveSigningKey.json +0 -0
  355. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/server/resetPassword.json +0 -0
  356. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/server/revokeAppPassword.json +0 -0
  357. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/server/updateEmail.json +0 -0
  358. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/sync/defs.json +0 -0
  359. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/sync/getBlob.json +0 -0
  360. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/sync/getBlocks.json +0 -0
  361. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/sync/getCheckout.json +0 -0
  362. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/sync/getHead.json +0 -0
  363. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/sync/getHostStatus.json +0 -0
  364. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/sync/getLatestCommit.json +0 -0
  365. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/sync/getRecord.json +0 -0
  366. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/sync/getRepo.json +0 -0
  367. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/sync/getRepoStatus.json +0 -0
  368. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/sync/listBlobs.json +0 -0
  369. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/sync/listHosts.json +0 -0
  370. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/sync/listRepos.json +0 -0
  371. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/sync/listReposByCollection.json +0 -0
  372. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/sync/notifyOfUpdate.json +0 -0
  373. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/sync/requestCrawl.json +0 -0
  374. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/sync/subscribeRepos.json +0 -0
  375. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/temp/addReservedHandle.json +0 -0
  376. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/temp/checkHandleAvailability.json +0 -0
  377. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/temp/checkSignupQueue.json +0 -0
  378. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/temp/dereferenceScope.json +0 -0
  379. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/temp/fetchLabels.json +0 -0
  380. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/temp/requestPhoneVerification.json +0 -0
  381. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/com/atproto/temp/revokeAccountCredentials.json +0 -0
  382. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/communication/createTemplate.json +0 -0
  383. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/communication/defs.json +0 -0
  384. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/communication/deleteTemplate.json +0 -0
  385. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/communication/listTemplates.json +0 -0
  386. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/communication/updateTemplate.json +0 -0
  387. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/hosting/getAccountHistory.json +0 -0
  388. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/moderation/getEvent.json +0 -0
  389. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/moderation/getRecord.json +0 -0
  390. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/moderation/getRecords.json +0 -0
  391. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/moderation/getRepo.json +0 -0
  392. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/moderation/getReporterStats.json +0 -0
  393. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/moderation/getRepos.json +0 -0
  394. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/moderation/getSubjects.json +0 -0
  395. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/moderation/searchRepos.json +0 -0
  396. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/safelink/addRule.json +0 -0
  397. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/safelink/defs.json +0 -0
  398. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/safelink/queryEvents.json +0 -0
  399. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/safelink/queryRules.json +0 -0
  400. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/safelink/removeRule.json +0 -0
  401. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/safelink/updateRule.json +0 -0
  402. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/server/getConfig.json +0 -0
  403. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/set/addValues.json +0 -0
  404. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/set/defs.json +0 -0
  405. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/set/deleteSet.json +0 -0
  406. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/set/deleteValues.json +0 -0
  407. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/set/getValues.json +0 -0
  408. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/set/querySets.json +0 -0
  409. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/set/upsertSet.json +0 -0
  410. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/setting/defs.json +0 -0
  411. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/setting/listOptions.json +0 -0
  412. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/setting/removeOptions.json +0 -0
  413. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/setting/upsertOption.json +0 -0
  414. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/signature/defs.json +0 -0
  415. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/signature/findCorrelation.json +0 -0
  416. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/signature/findRelatedAccounts.json +0 -0
  417. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/signature/searchAccounts.json +0 -0
  418. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/team/addMember.json +0 -0
  419. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/team/deleteMember.json +0 -0
  420. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/team/listMembers.json +0 -0
  421. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/team/updateMember.json +0 -0
  422. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/verification/defs.json +0 -0
  423. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/verification/grantVerifications.json +0 -0
  424. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/verification/listVerifications.json +0 -0
  425. {lexrpc-2.0 → lexrpc-2.2}/lexrpc/lexicons/tools/ozone/verification/revokeVerifications.json +0 -0
  426. {lexrpc-2.0 → lexrpc-2.2}/lexrpc.egg-info/dependency_links.txt +0 -0
  427. {lexrpc-2.0 → lexrpc-2.2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lexrpc
3
- Version: 2.0
3
+ Version: 2.2
4
4
  Summary: Python implementation of AT Protocol's XRPC + Lexicon
5
5
  Author-email: Ryan Barrett <lexrpc@ryanb.org>
6
6
  Project-URL: Homepage, https://github.com/snarfed/lexrpc
@@ -12,20 +12,25 @@ Classifier: Operating System :: OS Independent
12
12
  Classifier: Intended Audience :: Developers
13
13
  Classifier: Development Status :: 3 - Alpha
14
14
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
15
- Requires-Python: >=3.7
15
+ Requires-Python: >=3.9
16
16
  Description-Content-Type: text/markdown
17
17
  License-File: LICENSE
18
- Requires-Dist: dag-cbor
18
+ Requires-Dist: dag-cbor>=0.3
19
19
  Requires-Dist: dag-json>=0.3
20
- Requires-Dist: grapheme
21
- Requires-Dist: iterators
22
- Requires-Dist: libipld<4.0.0
20
+ Requires-Dist: grapheme>=0.6.0
21
+ Requires-Dist: iterators>=0.2.0
22
+ Requires-Dist: libipld<4.0.0,>=3.0.0
23
23
  Requires-Dist: multiformats>=0.3.1.post4
24
24
  Requires-Dist: requests>=2.0
25
- Requires-Dist: simple-websocket
25
+ Requires-Dist: simple-websocket>=0.10.0
26
26
  Provides-Extra: flask
27
27
  Requires-Dist: Flask>=2.0; extra == "flask"
28
- Requires-Dist: flask-sock; extra == "flask"
28
+ Requires-Dist: flask-sock>=0.6.0; extra == "flask"
29
+ Requires-Dist: werkzeug>=2.0; extra == "flask"
30
+ Requires-Dist: wsproto>=1.0; extra == "flask"
31
+ Provides-Extra: docs
32
+ Requires-Dist: sphinx>=7.0.0; extra == "docs"
33
+ Requires-Dist: sphinx-rtd-theme>=3.0.0; extra == "docs"
29
34
  Dynamic: license-file
30
35
 
31
36
  lexrpc [![Circle CI](https://circleci.com/gh/snarfed/lexrpc.svg?style=svg)](https://circleci.com/gh/snarfed/lexrpc) [![Coverage Status](https://coveralls.io/repos/github/snarfed/lexrpc/badge.svg?branch=main)](https://coveralls.io/github/snarfed/lexrpc?branch=master)
@@ -176,25 +181,26 @@ Here's how to package, test, and ship a new release.
176
181
  ```
177
182
  1. Run the unit tests.
178
183
  ```sh
179
- source local/bin/activate.csh
184
+ source .venv/bin/activate.csh
180
185
  python -m unittest discover
181
186
  ```
182
187
  1. Bump the version number in `pyproject.toml` and `docs/conf.py`. `git grep` the old version number to make sure it only appears in the changelog. Change the current changelog entry in `README.md` for this new version from _unreleased_ to the current date.
183
188
  1. Build the docs. If you added any new modules, add them to the appropriate file(s) in `docs/source/`. Then run `./docs/build.sh`. Check that the generated HTML looks fine by opening `docs/_build/html/index.html` and looking around.
184
- 1. `git commit -am 'release vX.Y'`
189
+ 1. ```sh
190
+ setenv ver X.Y
191
+ git commit -am "release v$ver"
192
+ ```
185
193
  1. Upload to [test.pypi.org](https://test.pypi.org/) for testing.
186
194
  ```sh
187
- python -m build
188
- setenv ver X.Y
189
- twine upload -r pypitest dist/lexrpc-$ver*
195
+ uv build
196
+ twine upload -r pypitest dist/lexrpc-$ver.tar.gz dist/lexrpc-$ver-py3-none-any.whl
190
197
  ```
191
198
  1. Install from test.pypi.org.
192
199
  ```sh
193
200
  cd /tmp
194
- python -m venv local
195
- source local/bin/activate.csh
201
+ python -m venv .venv
202
+ source .venv/bin/activate.csh
196
203
  pip uninstall lexrpc # make sure we force pip to use the uploaded version
197
- pip install --upgrade pip
198
204
  pip install -i https://test.pypi.org/simple --extra-index-url https://pypi.org/simple lexrpc==$ver
199
205
  ```
200
206
  1. Smoke test that the code trivially loads and runs.
@@ -248,6 +254,39 @@ Here's how to package, test, and ship a new release.
248
254
 
249
255
  ## Changelog
250
256
 
257
+ ### 2.2 - 2026-06-29
258
+
259
+ * Schema validation:
260
+ * Fix crash (`KeyError`) when validating a `blob` value inside an open union; now raises `ValidationError` for invalid blob refs.
261
+ * `client`:
262
+ * For websocket event streams, close the websocket connection when a non-`ConnectionClosed` exception is raised.
263
+ * Use the lexicon method's `input.encoding` as the `Content-Type` request header.
264
+ * `Client.__init__`: new `requests_session` kwarg, an optional :class:`requests.Session` to use for HTTP requests.
265
+ * `server`:
266
+ * `Server.call`: unknown parameters not in the lexicon are now silently ignored instead of raising `ValidationError`. [Background.](https://github.com/bluesky-social/atproto/discussions/5094)
267
+ * `flask_server`:
268
+ * Close websocket connections with reason 1011 for unknown/not implemented endpoint NSIDs.
269
+ * Update bundled lexicons:
270
+ * Bluesky PBC's (`app.bsky.*` etc) at [cf4843c](https://github.com/bluesky-social/atproto/commit/cf4843c339396e98fc0191b5c7ccf8db2e48da5b)
271
+ * [`site.standard.*`](https://standard.site/) at [549453e](https://tangled.org/standard.site/lexicons/commit/549453e37a4e15e8318f5b7655b230d0925b9e02)
272
+ * [`lexicon.community.*`](https://lexicon.community/) at [91c50cb](https://github.com/lexicon-community/lexicon/commit/91c50cbd84a9da8014332a6e37812c276889c8ac)
273
+
274
+
275
+ ### 2.1 - 2026-02-06
276
+
277
+ * Bundle new lexicons:
278
+ * [`lexicon.community.*`](https://lexicon.community/), as of [2bf2cbb](https://github.com/lexicon-community/lexicon/commit/2bf2cbbfd3058d710f8c468307ef7e003bc22383).
279
+ * [`site.standard.*`](https://standard.site/), [from lexicon.garden](https://lexicon.garden/identity/did:plc:re3ebnp5v7ffagz6rb6xfei4), as of 2026-02-03.
280
+ * Update bundled Bluesky PBC lexicons (`app.bsky`, `com.atproto`, etc.) as of [19ecf5f](https://github.com/bluesky-social/atproto/commit/19ecf5f76ae0d88c1963211a76920e00eecdd965).
281
+ * `base.load_lexicons`: ignore non-lexicon files.
282
+ * Schema validation:
283
+ * For the `uri` string format, handle URLs with brackets (eg `]`) in the hostname, eg `https://example.com]`.
284
+ * Don't require `$type` in event stream subscription payloads.
285
+ * Bug fixes for unions and arrays.
286
+ * Ignore `maxGraphemes` on non-string fields.
287
+ * Allow `type: permission-set`.
288
+
289
+
251
290
  ### 2.0 - 2025-09-13
252
291
 
253
292
  _Breaking changes:_
@@ -1,33 +1,3 @@
1
- Metadata-Version: 2.4
2
- Name: lexrpc
3
- Version: 2.0
4
- Summary: Python implementation of AT Protocol's XRPC + Lexicon
5
- Author-email: Ryan Barrett <lexrpc@ryanb.org>
6
- Project-URL: Homepage, https://github.com/snarfed/lexrpc
7
- Project-URL: Documentation, https://lexrpc.readthedocs.io/
8
- Keywords: XRPC,Lexicon,AT Protocol,ATP
9
- Classifier: Programming Language :: Python :: 3
10
- Classifier: License :: Public Domain
11
- Classifier: Operating System :: OS Independent
12
- Classifier: Intended Audience :: Developers
13
- Classifier: Development Status :: 3 - Alpha
14
- Classifier: Topic :: Software Development :: Libraries :: Python Modules
15
- Requires-Python: >=3.7
16
- Description-Content-Type: text/markdown
17
- License-File: LICENSE
18
- Requires-Dist: dag-cbor
19
- Requires-Dist: dag-json>=0.3
20
- Requires-Dist: grapheme
21
- Requires-Dist: iterators
22
- Requires-Dist: libipld<4.0.0
23
- Requires-Dist: multiformats>=0.3.1.post4
24
- Requires-Dist: requests>=2.0
25
- Requires-Dist: simple-websocket
26
- Provides-Extra: flask
27
- Requires-Dist: Flask>=2.0; extra == "flask"
28
- Requires-Dist: flask-sock; extra == "flask"
29
- Dynamic: license-file
30
-
31
1
  lexrpc [![Circle CI](https://circleci.com/gh/snarfed/lexrpc.svg?style=svg)](https://circleci.com/gh/snarfed/lexrpc) [![Coverage Status](https://coveralls.io/repos/github/snarfed/lexrpc/badge.svg?branch=main)](https://coveralls.io/github/snarfed/lexrpc?branch=master)
32
2
  ===
33
3
 
@@ -176,25 +146,26 @@ Here's how to package, test, and ship a new release.
176
146
  ```
177
147
  1. Run the unit tests.
178
148
  ```sh
179
- source local/bin/activate.csh
149
+ source .venv/bin/activate.csh
180
150
  python -m unittest discover
181
151
  ```
182
152
  1. Bump the version number in `pyproject.toml` and `docs/conf.py`. `git grep` the old version number to make sure it only appears in the changelog. Change the current changelog entry in `README.md` for this new version from _unreleased_ to the current date.
183
153
  1. Build the docs. If you added any new modules, add them to the appropriate file(s) in `docs/source/`. Then run `./docs/build.sh`. Check that the generated HTML looks fine by opening `docs/_build/html/index.html` and looking around.
184
- 1. `git commit -am 'release vX.Y'`
154
+ 1. ```sh
155
+ setenv ver X.Y
156
+ git commit -am "release v$ver"
157
+ ```
185
158
  1. Upload to [test.pypi.org](https://test.pypi.org/) for testing.
186
159
  ```sh
187
- python -m build
188
- setenv ver X.Y
189
- twine upload -r pypitest dist/lexrpc-$ver*
160
+ uv build
161
+ twine upload -r pypitest dist/lexrpc-$ver.tar.gz dist/lexrpc-$ver-py3-none-any.whl
190
162
  ```
191
163
  1. Install from test.pypi.org.
192
164
  ```sh
193
165
  cd /tmp
194
- python -m venv local
195
- source local/bin/activate.csh
166
+ python -m venv .venv
167
+ source .venv/bin/activate.csh
196
168
  pip uninstall lexrpc # make sure we force pip to use the uploaded version
197
- pip install --upgrade pip
198
169
  pip install -i https://test.pypi.org/simple --extra-index-url https://pypi.org/simple lexrpc==$ver
199
170
  ```
200
171
  1. Smoke test that the code trivially loads and runs.
@@ -248,6 +219,39 @@ Here's how to package, test, and ship a new release.
248
219
 
249
220
  ## Changelog
250
221
 
222
+ ### 2.2 - 2026-06-29
223
+
224
+ * Schema validation:
225
+ * Fix crash (`KeyError`) when validating a `blob` value inside an open union; now raises `ValidationError` for invalid blob refs.
226
+ * `client`:
227
+ * For websocket event streams, close the websocket connection when a non-`ConnectionClosed` exception is raised.
228
+ * Use the lexicon method's `input.encoding` as the `Content-Type` request header.
229
+ * `Client.__init__`: new `requests_session` kwarg, an optional :class:`requests.Session` to use for HTTP requests.
230
+ * `server`:
231
+ * `Server.call`: unknown parameters not in the lexicon are now silently ignored instead of raising `ValidationError`. [Background.](https://github.com/bluesky-social/atproto/discussions/5094)
232
+ * `flask_server`:
233
+ * Close websocket connections with reason 1011 for unknown/not implemented endpoint NSIDs.
234
+ * Update bundled lexicons:
235
+ * Bluesky PBC's (`app.bsky.*` etc) at [cf4843c](https://github.com/bluesky-social/atproto/commit/cf4843c339396e98fc0191b5c7ccf8db2e48da5b)
236
+ * [`site.standard.*`](https://standard.site/) at [549453e](https://tangled.org/standard.site/lexicons/commit/549453e37a4e15e8318f5b7655b230d0925b9e02)
237
+ * [`lexicon.community.*`](https://lexicon.community/) at [91c50cb](https://github.com/lexicon-community/lexicon/commit/91c50cbd84a9da8014332a6e37812c276889c8ac)
238
+
239
+
240
+ ### 2.1 - 2026-02-06
241
+
242
+ * Bundle new lexicons:
243
+ * [`lexicon.community.*`](https://lexicon.community/), as of [2bf2cbb](https://github.com/lexicon-community/lexicon/commit/2bf2cbbfd3058d710f8c468307ef7e003bc22383).
244
+ * [`site.standard.*`](https://standard.site/), [from lexicon.garden](https://lexicon.garden/identity/did:plc:re3ebnp5v7ffagz6rb6xfei4), as of 2026-02-03.
245
+ * Update bundled Bluesky PBC lexicons (`app.bsky`, `com.atproto`, etc.) as of [19ecf5f](https://github.com/bluesky-social/atproto/commit/19ecf5f76ae0d88c1963211a76920e00eecdd965).
246
+ * `base.load_lexicons`: ignore non-lexicon files.
247
+ * Schema validation:
248
+ * For the `uri` string format, handle URLs with brackets (eg `]`) in the hostname, eg `https://example.com]`.
249
+ * Don't require `$type` in event stream subscription payloads.
250
+ * Bug fixes for unions and arrays.
251
+ * Ignore `maxGraphemes` on non-string fields.
252
+ * Allow `type: permission-set`.
253
+
254
+
251
255
  ### 2.0 - 2025-09-13
252
256
 
253
257
  _Breaking changes:_
@@ -6,7 +6,7 @@ import json
6
6
  import logging
7
7
  import re
8
8
  import string
9
- from urllib.parse import urlencode, urljoin, urlparse
9
+ from urllib.parse import urlencode, urlparse
10
10
 
11
11
  import grapheme
12
12
  from multiformats import CID
@@ -20,6 +20,7 @@ METHOD_TYPES = frozenset((
20
20
  ))
21
21
  LEXICON_TYPES = METHOD_TYPES | frozenset((
22
22
  'object',
23
+ 'permission-set',
23
24
  'record',
24
25
  'ref',
25
26
  'token',
@@ -54,7 +55,7 @@ BLOB_DEF = {
54
55
  'required': ['ref', 'mimeType', 'size'],
55
56
  'properties': {
56
57
  'ref': {
57
- 'type': 'ref',
58
+ 'type': 'cid-link',
58
59
  },
59
60
  'mimeType': {
60
61
  'type': 'string',
@@ -68,43 +69,41 @@ BLOB_DEF = {
68
69
  },
69
70
  }
70
71
 
71
- # duplicated in bridgy-fed/common.py
72
- DOMAIN_PATTERN = r'([a-z0-9][a-z0-9-]{0,62}(?<!-)\.){1,}[a-z][a-z0-9-]*(?<!-)'
73
- DOMAIN_RE = re.compile(f'^{DOMAIN_PATTERN}$')
72
+ # duplicated in bridgy-fed/domains.py
73
+ DOMAIN_RE = re.compile(r'([a-z0-9][a-z0-9-]{0,62}(?<!-)\.){1,}[a-z][a-z0-9-]*(?<!-)')
74
74
 
75
75
  # https://atproto.com/specs/nsid
76
- NSID_SEGMENT = '[a-zA-Z0-9-]+'
77
- NSID_SEGMENT_RE = re.compile(f'^{NSID_SEGMENT}$')
78
- NSID_PATTERN = r'(?![0-9])((?!-)[a-z0-9-]{1,63}(?<!-)\.){2,}[a-zA-Z][a-zA-Z0-9]{0,62}'
79
- NSID_RE = re.compile(f'^{NSID_PATTERN}$')
76
+ NSID_SEGMENT_RE = re.compile('[a-zA-Z0-9-]+')
77
+ NSID_RE = re.compile(r'(?![0-9])((?!-)[a-z0-9-]{1,63}(?<!-)\.){2,}[a-zA-Z][a-zA-Z0-9]{0,62}')
80
78
 
81
79
  # https://atproto.com/specs/lexicon#string-formats
82
80
  # https://datatracker.ietf.org/doc/html/rfc5646#section-2.1
83
- LANG_RE = re.compile(r'^(i|[a-z]{2,3})(-[A-Za-z0-9-]+)?$')
81
+ LANG_RE = re.compile(r'(i|[a-z]{2,3})(-[A-Za-z0-9-]+)?')
84
82
 
85
83
  # https://atproto.com/specs/record-key
86
- RKEY_RE = re.compile(r'^[A-Za-z0-9._:~-]{1,512}$')
84
+ RKEY_RE = re.compile(r'[A-Za-z0-9._:~-]{1,512}')
87
85
 
88
86
  # https://atproto.com/specs/record-key#record-key-type-tid
89
87
  BASE32_CHARS = string.ascii_lowercase + "234567"
90
- TID_RE = re.compile(rf'^[{BASE32_CHARS}]{{13}}$')
88
+ TID_RE = re.compile(rf'[{BASE32_CHARS}]{{13}}')
91
89
 
92
- CID_RE = re.compile(r'^[A-Za-z0-9+]{8,}$')
90
+ CID_RE = re.compile(r'[A-Za-z0-9+]{8,}')
93
91
 
94
92
  # https://www.w3.org/TR/did-core/#did-syntax
95
- DID_PATTERN = r'did:[a-z]+:[A-Za-z0-9._%:-]{1,2048}(?<!:)'
96
- DID_RE = re.compile(f'^{DID_PATTERN}$')
93
+ DID_RE = re.compile(r'did:[a-z]+:[A-Za-z0-9._%:-]{1,2048}(?<!:)')
97
94
 
98
95
  # https://atproto.com/specs/at-uri-scheme
99
96
  # NOTE: duplicated in granary.bluesky!
100
97
  # also see arroba.util.parse_at_uri
98
+ # TODO: add query and fragment? they're currently unused in the protocol
99
+ # https://atproto.com/specs/at-uri-scheme#structure
101
100
  _CHARS = 'a-zA-Z0-9-.'
102
101
  AT_URI_RE = re.compile(rf"""
103
- ^at://
104
- (?P<repo>{DID_PATTERN}|{DOMAIN_PATTERN})
105
- (?:/(?P<collection>{NSID_PATTERN})
102
+ at://
103
+ (?P<repo>{DID_RE.pattern}|{DOMAIN_RE.pattern})
104
+ (?:/(?P<collection>{NSID_RE.pattern})
106
105
  (?:/(?P<rkey>[{_CHARS}:~_]+))?)?
107
- $""", re.VERBOSE)
106
+ """, re.VERBOSE)
108
107
 
109
108
  # wrapper for datetime.now, lets us mock it out in tests
110
109
  now = lambda tz=timezone.utc, **kwargs: datetime.now(tz=tz, **kwargs)
@@ -123,13 +122,12 @@ class XrpcError(ValueError):
123
122
 
124
123
 
125
124
  def load_lexicons(traversable):
126
- if traversable.is_file():
127
- lexicons = [json.loads(traversable.read_text())]
125
+ if traversable.is_file() and traversable.suffix == '.json':
126
+ return [json.loads(traversable.read_text())]
128
127
  elif traversable.is_dir():
129
- lexicons = sum((load_lexicons(item) for item in traversable.iterdir()),
130
- start=[])
128
+ return sum((load_lexicons(item) for item in traversable.iterdir()), start=[])
131
129
 
132
- return lexicons
130
+ return []
133
131
 
134
132
  _bundled_lexicons = load_lexicons(files('lexrpc').joinpath('lexicons'))
135
133
  logger.info(f'{len(_bundled_lexicons)} lexicons loaded')
@@ -267,12 +265,12 @@ class Base():
267
265
  # we'd fail if a query with no params gets requested with any query
268
266
  # params at all, eg utm_* tracking params
269
267
 
270
- self._validate_schema(name=type, val=obj, type_=nsid, lexicon=nsid,
268
+ self._validate_schema(name=type, val=obj, type_name=nsid, lexicon=nsid,
271
269
  schema=schema)
272
270
 
273
271
  return obj
274
272
 
275
- def _validate_schema(self, *, name, val, type_, lexicon, schema):
273
+ def _validate_schema(self, *, name, val, type_name, lexicon, schema):
276
274
  """Validates an ATProto value against a lexicon schema.
277
275
 
278
276
  Returns ``None`` if the value validates, otherwise raises an exception.
@@ -282,7 +280,7 @@ class Base():
282
280
  Args:
283
281
  name (str): field name
284
282
  val: value
285
- type_ (str): name of type, eg ``integer`` or ``app.bsky.feed.post#replyRef``
283
+ type_name (str): name of type, eg ``integer`` or ``app.bsky.feed.post#replyRef``
286
284
  lexicon (str): fully qualified lexicon name that contains this schema,
287
285
  eg ``app.bsky.feed.post`` or ``app.bsky.feed.post#replyRef``
288
286
  schema (dict): schema to validate against if this is a compound
@@ -291,11 +289,14 @@ class Base():
291
289
  Raises:
292
290
  ValidationError: if the value is invalid
293
291
  """
294
- # logger.debug(f'@ {name} {type_} {lexicon} {str(val)[:100]} {str(schema)[:100]}')
292
+ # logger.debug(f'@ {name} {type_name} {lexicon} {str(val)[:100]} {str(schema)[:100]}')
295
293
 
296
294
  def get_schema(lex_name):
297
295
  """Returns (fully qualified lexicon name, lexicon) tuple."""
298
- schema_name = urljoin(lexicon, lex_name)
296
+ if lex_name.startswith('#'):
297
+ schema_name = lexicon.split('#')[0] + lex_name
298
+ else:
299
+ schema_name = lex_name
299
300
  schema = self._get_def(schema_name)
300
301
  if schema.get('type') == 'record':
301
302
  schema = schema.get('record')
@@ -308,9 +309,11 @@ class Base():
308
309
  val_str = repr(val)
309
310
  if len(val_str) > 50:
310
311
  val_str = val_str[:50] + '…'
311
- prefix = f'in {lexicon}, ' if lexicon != type_ else ''
312
+ prefix = f'in {lexicon}, ' if lexicon != type_name else ''
312
313
  raise ValidationError(
313
- f'{prefix}{type_} {name} with value `{val_str}`: {msg}')
314
+ f'{prefix}{type_name} {name} with value `{val_str}`: {msg}')
315
+
316
+ type_ = schema.get('type') or type_name
314
317
 
315
318
  if const := schema.get('const'):
316
319
  if val != const:
@@ -379,8 +382,11 @@ class Base():
379
382
 
380
383
  if type_ == 'union':
381
384
  if isinstance(val, dict):
382
- inner_type = val.get('$type')
383
- if not inner_type:
385
+ if not (inner_type := val.get('$type')):
386
+ if name == 'message':
387
+ # event stream subscription messages (payloads) don't
388
+ # require $type, it's in the header
389
+ return
384
390
  fail('missing $type')
385
391
  elif isinstance(val, str):
386
392
  inner_type = val
@@ -388,7 +394,7 @@ class Base():
388
394
  fail("is invalid")
389
395
 
390
396
  if schema.get('closed'):
391
- refs = [urljoin(lexicon, ref) for ref in schema['refs']]
397
+ refs = [get_schema(ref)[0] for ref in schema['refs']]
392
398
  if inner_type not in refs:
393
399
  fail(f"{inner_type} isn't one of {refs}")
394
400
 
@@ -415,7 +421,7 @@ class Base():
415
421
  if type_ == 'array':
416
422
  for item in val:
417
423
  self._validate_schema(
418
- name=name, val=item, type_=schema['items']['type'],
424
+ name=name, val=item, type_name=schema['items']['type'],
419
425
  lexicon=lexicon, schema=schema['items'])
420
426
 
421
427
  props = schema.get('properties', {})
@@ -438,7 +444,8 @@ class Base():
438
444
  fail(f'property {prop_name} is not nullable')
439
445
  continue
440
446
 
441
- elif self._truncate and (max_graphemes := prop_schema.get('maxGraphemes')):
447
+ elif (self._truncate and prop_type == 'string'
448
+ and (max_graphemes := prop_schema.get('maxGraphemes'))):
442
449
  if grapheme.length(prop_val) > max_graphemes:
443
450
  prop_val = val[prop_name] = grapheme.slice(
444
451
  prop_val, end=max_graphemes - 1) + '…'
@@ -447,7 +454,7 @@ class Base():
447
454
  prop_lexicon, prop_schema = get_schema(prop_schema['ref'])
448
455
  prop_type = prop_schema['type']
449
456
 
450
- self._validate_schema(name=prop_name, val=prop_val, type_=prop_type,
457
+ self._validate_schema(name=prop_name, val=prop_val, type_name=prop_type,
451
458
  lexicon=prop_lexicon, schema=prop_schema)
452
459
 
453
460
  # unknown parameters aren't allowed
@@ -475,11 +482,11 @@ class Base():
475
482
 
476
483
  # TODO: switch to match once we require Python 3.10+
477
484
  if format == 'at-identifier':
478
- check(DID_RE.match(val) or DOMAIN_RE.match(val.lower()))
485
+ check(DID_RE.fullmatch(val) or DOMAIN_RE.fullmatch(val.lower()))
479
486
 
480
487
  elif format == 'at-uri':
481
488
  check(len(val) < 8 * 1024)
482
- check(AT_URI_RE.match(val))
489
+ check(AT_URI_RE.fullmatch(val))
483
490
  check('/./' not in val
484
491
  and '/../' not in val
485
492
  and not val.endswith('/.')
@@ -488,7 +495,7 @@ class Base():
488
495
  elif format == 'cid':
489
496
  # ideally I'd use CID.decode here, but it doesn't support CIDv5,
490
497
  # it's too strict about padding, etc.
491
- check(CID_RE.match(val))
498
+ check(CID_RE.fullmatch(val))
492
499
 
493
500
  elif format == 'datetime':
494
501
  check('T' in val)
@@ -507,35 +514,38 @@ class Base():
507
514
  check(False)
508
515
 
509
516
  elif format == 'did':
510
- check(DID_RE.match(val))
517
+ check(DID_RE.fullmatch(val))
511
518
 
512
519
  elif format == 'nsid':
513
520
  check(len(val) <= 317)
514
- check(NSID_RE.match(val) and '.' in val)
521
+ check(NSID_RE.fullmatch(val) and '.' in val)
515
522
 
516
523
  elif format in 'handle':
517
524
  check(len(val) <= 253)
518
- check(DOMAIN_RE.match(val.lower()))
525
+ check(DOMAIN_RE.fullmatch(val.lower()))
519
526
 
520
527
  elif format == 'tid':
521
- check(TID_RE.match(val))
528
+ check(TID_RE.fullmatch(val))
522
529
  # high bit, big-endian, can't be 1
523
530
  check(not ord(val[0]) & 0x40)
524
531
 
525
532
  elif format == 'record-key':
526
- check(val not in ('.', '..') and RKEY_RE.match(val))
533
+ check(val not in ('.', '..') and RKEY_RE.fullmatch(val))
527
534
 
528
535
  elif format == 'uri':
529
536
  check(len(val) < 8 * 1024)
530
537
  check(' ' not in val)
531
- parsed = urlparse(val)
538
+ try:
539
+ parsed = urlparse(val)
540
+ except ValueError as e:
541
+ raise ValidationError(f"Couldn't parse URI {val}")
532
542
  check(parsed.scheme
533
543
  and parsed.scheme[0].lower() in string.ascii_lowercase
534
544
  and (parsed.netloc or parsed.path or parsed.query
535
545
  or parsed.fragment))
536
546
 
537
547
  elif format == 'language':
538
- check(LANG_RE.match(val))
548
+ check(LANG_RE.fullmatch(val))
539
549
 
540
550
  else:
541
551
  raise ValidationError(f'unknown format {format}')
@@ -48,7 +48,7 @@ class _NsidClient():
48
48
 
49
49
  def __getattr__(self, attr):
50
50
  segment = attr.replace('_', '-')
51
- if NSID_SEGMENT_RE.match(segment):
51
+ if NSID_SEGMENT_RE.fullmatch(segment):
52
52
  return _NsidClient(self.client, f'{self.nsid}.{segment}')
53
53
 
54
54
  return getattr(super(), attr)
@@ -70,12 +70,14 @@ class Client(Base):
70
70
  address (str): base URL of XRPC server, eg ``https://bsky.social/``
71
71
  session (dict): ``createSession`` response with ``accessJwt``,
72
72
  `refreshJwt``, ``handle``, and ``did``
73
- requests_kwargs (dict): passed to :func:`requests.get`/:func:`requests.post`
73
+ requests_kwargs (dict): passed to :func:`requests.Session.get` /
74
+ :func:`requests.Session.post`
75
+ requests_session (requests.Session): HTTP session to use for requests
74
76
  """
75
77
 
76
78
  def __init__(self, address=None, access_token=None, refresh_token=None,
77
79
  session_callback=None, lexicons=None, validate=True, truncate=False,
78
- **requests_kwargs):
80
+ requests_session=None, **requests_kwargs):
79
81
  """Constructor.
80
82
 
81
83
  Args:
@@ -96,9 +98,12 @@ class Client(Base):
96
98
  and output bodies
97
99
  truncate (bool): whether to truncate string values that are longer
98
100
  than their ``maxGraphemes`` or ``maxLength`` in their lexicon
99
- requests_kwargs: passed to :func:`requests.get`/:func:`requests.post`, eg
100
- ``auth`` (:class:`requests.auth.AuthBase`), ``headers`` (dict),
101
- ``timeout`` (int, seconds), etc.
101
+ requests_session (requests.Session): optional HTTP session to use for
102
+ requests. Defaults to a new :class:`requests.Session`.
103
+ requests_kwargs: passed to :func:`requests.Session.get` /
104
+ :func:`requests.Session.post`, eg ``auth``
105
+ (:class:`requests.auth.AuthBase`), ``headers`` (dict), ``timeout``
106
+ (int seconds), etc.
102
107
 
103
108
  Raises:
104
109
  ValidationError: if any lexicon schema is invalid
@@ -115,6 +120,7 @@ class Client(Base):
115
120
  self.address = DEFAULT_PDS
116
121
  # logger.debug(f'Using server at {address}')
117
122
 
123
+ self.requests_session = requests_session or requests.Session()
118
124
  self.requests_kwargs = copy.copy(requests_kwargs)
119
125
  headers = self.requests_kwargs.setdefault('headers', {})
120
126
  for name, val in DEFAULT_HEADERS.items():
@@ -129,7 +135,7 @@ class Client(Base):
129
135
  self.session_callback = session_callback
130
136
 
131
137
  def __getattr__(self, attr):
132
- if NSID_SEGMENT_RE.match(attr):
138
+ if NSID_SEGMENT_RE.fullmatch(attr):
133
139
  return _NsidClient(self, attr)
134
140
 
135
141
  return getattr(super(), attr)
@@ -158,6 +164,7 @@ class Client(Base):
158
164
  loaded lexicons
159
165
  ValidationError: if the parameters, input, or returned output don't
160
166
  validate against the method's schemas
167
+ requests.HTTPError: if the remote server returned an error
161
168
  requests.RequestException: if the connection or HTTP request to the
162
169
  remote server failed
163
170
  """
@@ -168,13 +175,15 @@ class Client(Base):
168
175
  params = self.validate(nsid, 'parameters', params)
169
176
  params_str = self.encode_params(params)
170
177
 
171
- type = self._get_def(nsid)['type']
178
+ lexicon = self._get_def(nsid)
179
+ type = lexicon['type']
172
180
  if type == 'subscription':
173
181
  input = self.validate(nsid, 'input', input)
174
182
 
175
183
  requests_kwargs = copy.copy(self.requests_kwargs)
184
+ content_type = lexicon.get('input', {}).get('encoding', 'application/json')
176
185
  headers = {
177
- 'Content-Type': 'application/json',
186
+ 'Content-Type': content_type,
178
187
  **requests_kwargs.pop('headers'),
179
188
  **headers,
180
189
  }
@@ -195,7 +204,8 @@ class Client(Base):
195
204
  return self._subscribe(url, nsid, decode=decode)
196
205
 
197
206
  # query or procedure
198
- fn = requests.get if type == 'query' else requests.post
207
+ fn = (self.requests_session.get if type == 'query'
208
+ else self.requests_session.post)
199
209
 
200
210
  # buffer binary inputs in memory. ideally we'd stream instead, but if we
201
211
  # have to refresh our token below, we need to seek the stream back to the
@@ -203,7 +213,7 @@ class Client(Base):
203
213
  if isinstance(input, IOBase) or hasattr(input, 'read'):
204
214
  input = input.read()
205
215
 
206
- logger.debug(f'requests.{getattr(fn, "__name__", fn)} {url} {params_str} {self.loggable(input)} {headers} {requests_kwargs}')
216
+ logger.debug(f'requests.{"get" if type == "query" else "post"} {url} {params_str} {self.loggable(input)} {headers} {requests_kwargs}')
207
217
 
208
218
  if auth := requests_kwargs.get('auth'):
209
219
  orig_token = getattr(auth, 'token', None)
@@ -275,7 +285,7 @@ class Client(Base):
275
285
  ValidationError: if ``decode`` is True and an output payload doesn't
276
286
  validate gainst the subscription method's lexicon
277
287
  """
278
- ws = simple_websocket.Client(url, headers={
288
+ ws = simple_websocket.Client.connect(url, headers={
279
289
  **DEFAULT_HEADERS,
280
290
  **self.requests_kwargs.get('headers', {}),
281
291
  })
@@ -291,3 +301,6 @@ class Client(Base):
291
301
  yield msg
292
302
  except simple_websocket.ConnectionClosed as cc:
293
303
  logger.debug(cc)
304
+ finally:
305
+ if ws.connected:
306
+ ws.close()
@@ -4,13 +4,11 @@ from datetime import datetime, timedelta
4
4
  import logging
5
5
 
6
6
  import dag_cbor
7
- import dag_json
8
7
  from flask import after_this_request, make_response, request
9
8
  from flask.json import jsonify
10
9
  from flask.views import View
11
10
  from flask_sock import Sock
12
11
  from iterators import TimeoutIterator
13
- import libipld
14
12
  from multiformats import CID
15
13
  from simple_websocket import ConnectionClosed
16
14
  from werkzeug.exceptions import TooManyRequests
@@ -69,7 +67,7 @@ class XrpcEndpoint(View):
69
67
  self.server = server
70
68
 
71
69
  def dispatch_request(self, nsid):
72
- if not NSID_RE.match(nsid):
70
+ if not NSID_RE.fullmatch(nsid):
73
71
  return {
74
72
  'error': 'InvalidRequest',
75
73
  'message': f'{nsid} is not a valid NSID',
@@ -155,6 +153,10 @@ def subscription(xrpc_server, nsid, limit_ips=False):
155
153
  # while we block waiting for results from the XRPC server method, and
156
154
  # we'll eventually exhaust the WSGI worker thread pool. background:
157
155
  # https://github.com/miguelgrinberg/flask-sock/issues/78
156
+ #
157
+ # TODO: put the client IP and maybe user agent into the thread name. (can
158
+ # assign to Thread.name directly.) would need to modify TimeoutIterator to
159
+ # support that.
158
160
  iter = TimeoutIterator(xrpc_server.call(nsid, **params),
159
161
  timeout=SUBSCRIPTION_ITERATOR_TIMEOUT.total_seconds())
160
162
  for result in iter:
@@ -166,7 +168,7 @@ def subscription(xrpc_server, nsid, limit_ips=False):
166
168
  continue
167
169
 
168
170
  header, payload = result
169
- # TODO: validate header, payload?
171
+ # payload was validated in Server.call; header has no schema
170
172
 
171
173
  # log
172
174
  seq = payload.get('seq')
@@ -216,6 +218,11 @@ def subscription(xrpc_server, nsid, limit_ips=False):
216
218
 
217
219
  try:
218
220
  handle(ws)
221
+ except NotImplementedError as e:
222
+ msg = str(e)
223
+ logger.info(msg)
224
+ # WebSocket closure code 1011 is for "unexpected conditions"
225
+ ws.close(reason=1011, message=msg)
219
226
  finally:
220
227
  # ideally I'd use Flask's after_this_request instead, but it doesn't
221
228
  # guarantee that it'll run if the request raises an uncaught