What's Changed
🚀 Features
- feat(confluent): add Topic schema to configure topic creation by @vyhuholl in #3026
- feat: add pyright over the public API surface and fix what it found by @Lancetnik in #3029
- feat: the 3.0
addressfield carries the address (#2357) by @Lancetnik in #3038 - Render filter_subjects in the NATS AsyncAPI channel by @00yhj22-debug in #3041
- feat: support literal braces in addresses across all brokers by @SammySN-car in #3042
- feat(redis): add StreamSub claim_min_idle_time (XREADGROUP CLAIM) by @kon28289 in #3049
- feat: annotations for the native Confluent consumer and MQTT client by @Lancetnik in #3054
- feat(redis): expose stream delivery count by @lxingy3 in #3066
- feat(testing):
assert_called_once_withfor subscribers and publishers by @Lancetnik in #3110 - feat(testing):
assert_called_withandassert_any_callbesideassert_called_once_withby @Lancetnik in #3111
🐛 Bug Fixes
- fix(cli): surface YAML and AsyncAPI errors from
docs serveby @SarthakB11 in #2874 - fix: #2625 Fix TelemetryMiddleware by @IvanKirpichnikov in #3016
- Deregister fake subscribers when the TestBroker closes by @00yhj22-debug in #3046
- fix(docs): repair the release-notes generator and the duplicated 0.7.* notes by @Lancetnik in #3055
- fix(docs): repair the 404 link to the documentation contribution guide by @vyhuholl in #3059
- fix (#3056): publish an empty message when a batch publisher has nothing to send by @Lancetnik in #3060
- fix(redis): allow MANUAL ack_policy with max_workers for stream subscribers by @kon28289 in #3069
- fix: a subscriber over several addresses is several channels (#2357) by @Lancetnik in #3070
- fix: a declaration's brace escaping never reaches anything that reads it by @Lancetnik in #3072
- fix: a router prefix is part of the address it decorates (#2357) by @Lancetnik in #3074
- fix(redis): keep group read cursor in get_one and iterator by @Pizzagami in #3080
- fix: a handler keeps its declared call apart from its composed one by @Lancetnik in #3103
- fix(testing): stop fake subscribers before hiding them from the real broker by @Lancetnik in #3108
- fix(redis): stop the subscriber on terminal stream errors instead of restarting by @kon28289 in #3115
- fix(cli): stop the supervisor deadlocking on shutdown by @Lancetnik in #3118
- fix(mqtt):
subscriber()is typed bymax_workers, so a decorated handler stays typed by @Lancetnik in #3123 - fix(redis): stop warning that
no_ackhas no effect with a consumer group by @Griger10 in #3129 - fix(nats): type the pull consumer callback as a coroutine function by @Lancetnik in #3152
- fix: warn when a batch subscriber drops max_workers by @Lancetnik in #3164
- fix: accept a plain str as the License and Contact url by @Lancetnik in #3166
- fix(kafka): accept KafkaPublishMessage in batch publish signatures by @Lancetnik in #3173
- fix(redis): type the ssl_* options of RedisClusterBroker by @Lancetnik in #3174
- fix: resolve batch subscribers and publishers to one type, not a Union by @Lancetnik in #3175
- fix(mqtt): tell the user to install the extra when zmqtt is missing by @Lancetnik in #3179
- fix(confluent): type a plain publish() as the message, not a Future by @Lancetnik in #3182
- fix: close four typing gaps found by running mypy over docs_src by @Lancetnik in #3188
- fix: open a concurrent subscriber's queue on start and close it on stop by @Lancetnik in #3190
⚡ Performance
- perf: one context scope object per consumed message by @Lancetnik in #3130
♻️ Refactoring
- refactor: give the two Kafka packages a shared home in _internal/kafka by @Lancetnik in #3063
- refactor: Kafka
TopicPartitionis FastStream's own type by @Lancetnik in #3087 - refactor: one base for the Subscriber and Publisher Specifications by @Lancetnik in #3102
- refactor:
Address.literalandAddress.describeby @Lancetnik in #3104 - refactor(asgi): let each TestBroker register itself for try-it-out by @Lancetnik in #3163
🧪 Tests
- test(redis): sound cluster pub/sub tests — arrival order and channel isolation by @Lancetnik in #3078
- test: add syrupy JSON snapshots for Rabbit AsyncAPI arguments by @StepanKatin in #3099
- test: expand syrupy JSON snapshots in Rabbit AsyncAPI tests (v2_6_0, v3_0_0) by @StepanKatin in #3132
- test: make tests/utils and tests/cli pass strict mypy by @Lancetnik in #3159
- test: add the type annotations mypy reports as missing in tests/ by @Lancetnik in #3160
- test: make the small test directories pass strict mypy by @Lancetnik in #3161
- test: put tests/asyncapi under strict mypy by @Lancetnik in #3165
- test: check handler observations from outside the handler by @Lancetnik in #3168
- test: put tests/prometheus and tests/opentelemetry under strict mypy by @Lancetnik in #3170
- test: put tests/brokers under strict mypy by @Lancetnik in #3176
- test(cli): drain stderr before a finished CLI process is inspected by @Lancetnik in #3185
- test: make xfail strict and close what a warnings-as-errors run found open by @Lancetnik in #3186
- test: read Kafka test topics from the earliest offset by @Lancetnik in #3187
📝 Documentation
- Document the concurrency model for subscribers by @00yhj22-debug in #2885
- docs: add RabbitMQ batch subscriber How-To by @StepanKatin in #3011
- docs: lead with native broker features instead of a unified API by @Lancetnik in #3053
- docs: correct logging config CLI flag from --log-file to --log-config by @awsomesud347 in #3061
- docs: list HBB (AI·SW Maestro 17th) on the users page by @Lancetnik in #3077
- Update Telegram badge in README by @chirizxc in #3092
- docs(skills): minimal test coverage rule in testing-patterns by @Lancetnik in #3094
- docs(skills): one dirty-equals equality per behaviour in testing-patterns by @Lancetnik in #3101
- Update who-uses.md by @C3EQUALZz in #3116
- docs: the Context7 widget replaces the Gurubase one by @Lancetnik in #3119
- docs: keep Context7 chat keystrokes away from Material's shortcuts by @Lancetnik in #3121
- Document graceful shutdown and default graceful_timeout to 15s everywhere by @Lancetnik in #3122
- docs: SEO basics — robots.txt, root sitemap, real titles by @Lancetnik in #3133
- docs: keep the Search Console token in the repository by @Lancetnik in #3134
- docs: give the site root a canonical link and a real title by @Lancetnik in #3136
- docs: per-page meta descriptions and structured data by @Lancetnik in #3137
- docs: add ADOPTERS.md, a directory maintained by adopters themselves by @Lancetnik in #3142
- docs: point adopters without a pull request to the pinned issue by @Lancetnik in #3144
- docs: shield the literal-braces sections from the macros plugin by @Lancetnik in #3145
- docs: ADOPTERS.md — organizations named in their own job postings by @Lancetnik in #3146
- feat: issue-3143 add tochka to adopters by @ApostolFet in #3147
- docs: drop i18n, API reference out of the sitemap, broker-qualified titles by @Lancetnik in #3150
- docs: restore the release notes #3042 reverted by @Lancetnik in #3151
- docs: fix the PageSpeed findings on the landing page by @Lancetnik in #3156
- Update ADOPTERS.md by @Peopl3s in #3157
- docs(redis): replace Annotated descriptions with field docstrings by @Lancetnik in #3183
⚙️ CI & Build
- ci: stop publishing the source tree to the docs site by @Lancetnik in #3135
- ci: skip relator notifications for Lancetnik's PRs by @Lancetnik in #3153
- ci: build the guides strictly and check the built site on every PR by @Lancetnik in #3154
- ci: keep a single deploy commit on gh-pages by @Lancetnik in #3155
- ci: fail on unused fixtures by @Lancetnik in #3167
- ci: type check all of tests/ with mypy by @Lancetnik in #3177
- ci: type check docs/docs_src with mypy by @Lancetnik in #3189
- ci: run the linters workflow in the merge queue; bump to 0.7.6 by @Lancetnik in #3192
🧹 Chores
- chore: own Redis, label AsyncAPI, drop a stale README aside by @Lancetnik in #3081
- chore: three small clean-ups in one PR by @Lancetnik in #3100
- chore: Context7 replaces Gurubase by @Lancetnik in #3117
- chore(lint): enable import placement, no-self-use, private-import, json and bug-catching ruff rules by @Lancetnik in #3158
- chore(mypy): enable five more error codes and fix their findings by @Lancetnik in #3184
New Contributors
- @vyhuholl made their first contribution in #3059
- @awsomesud347 made their first contribution in #3061
- @StepanKatin made their first contribution in #3011
- @kon28289 made their first contribution in #3069
- @SammySN-car made their first contribution in #3042
- @Pizzagami made their first contribution in #3080
- @lxingy3 made their first contribution in #3066
- @Griger10 made their first contribution in #3129
- @SarthakB11 made their first contribution in #2874
- @Peopl3s made their first contribution in #3157
Full Changelog: 0.7.5...0.7.6