Use WSS doesn't work

I've searched in all the issue but I cannot make it work.
On ios i got:
"Invalid HTTP upgrade. code=403, type=upgradeError"
On android:
"unknown protocol: wss"
I have read that sockeio is not websocket but I read some of you works so I don't know what to do

This is a limitation of the underlying native libraries. On iOS you can set secure: true in the options to enable handling for secure sockets.
const socket = io.connect('wss://example.com/', { secure: true });

The Android native client simply doesn't support wss: protocol so try to specify the url using https: instead.

I have the same problem! I tried all the tips I found on the internet. Nothing solves!

Nothing has documentation that helps, the developers of modules don't know how to solve community problems.
Have you ever thought about killing this technology that shouldn't even be called technology?


Empty dict is incompatible with Mapping

The following code:
from typing import List, Mapping

from pytypes import TypeChecker

def f() -> List[Mapping[int, str]]:
    return [{}]

with TypeChecker():
    f()
    print("OK")

fails as follows:
$ python3 Test.py
Traceback (most recent call last):
  File "Test.py", line 9, in <module>
    f()
  File "Test.py", line 6, in f
    return [{}]
pytypes.exceptions.ReturnTypeError:
  __main__.f
  returned incompatible type:
Expected: List[Mapping[int, str]]
Received: List[Empty[Dict]]

Does this also occur when not wrapped in a List?
Otherwise I suspect the answer from https://github.com/Stewori/pytypes/issues/67#issuecomment-524914412 applies here as well.

No, it doesn't occur when not wrapped in a List.

Closing this in favor of #76.


Workaround for negative timestamp misinterpretation

This pull request is related to disccusions on the red5-client repository, issue #44.
Unsigned timestamps between 231 and 232 -1, which Red5 misinterprets as negative signed integers between -231 and -1, are now rolled over to positive integers between 0 and 231 - 1. Instead of being discarded, RTMP messages with large timestamps are now sent downstream.
I have added some unit tests to cover this behaviour and have successfully tested the patch on our pre-production environment with a few different RTMP output destinations.

Thank you, @PyvesB

@mondain do you have any timeline on when the next Red 5 milestone will be published? It would be nice to have this easily available as part of a Maven release. Thanks in advance!

@mondain I noticed your recent 1.0.10-M10 release, however, it does not seem to contain the changes from this pull request. Is this to be expected?

It wasn't intentionally skipped.

It doesn't appear to be skipped, its in the codebase https://github.com/Red5/red5-server-common/blob/0f183769cf5fd4a99542be8638acafbc068d2d72/src/main/java/org/red5/server/stream/consumer/ConnectionConsumer.java#L147

It is in the codebase, but I didn't see it there when I decompiled the 1.0.10-M10 source. Might this be related to merge commit 3faa0ae988b92a649e7c52b6e5bde1eb23ca047c, which was pushed after the tagging done in ec518220557b37688c8e3557286261a3c638eabf? I'm wondering whether the release of red5-server-common was not performed from an outdated local copy, which then led to that merge commit.

If its not in the decompile than you are probably correct; I'll get it in the release if I don't see any issues posted before January 1st.


Add interrupt support

The chip has support for generating interrupts based on differential pressure low or high events. Add support for setting and reading these.

WIP
High-threshold interrupts functionality verified with internal testing, however low-threshold don't seem to assert an interrupt?


"Unknown" in .subp is refer to the character

As I understand so far from .subp, each character had a number that defined him inside the file.
It will be easy to understand that from tape.subp where there is a number before that starting of each line.
[C=15] is miller talking
[C=16] ocelot talking
[C=13] snake talking
[C=37] skull face talking
[C=117] code talker talking
[C=20] Zero talking
etc

but for the rest of subps files, mostly there's no defining of the character in each line text the same way, it is located at the entry header
This line spoken by Ocelot character code 16
<Entry Id="28377578" Priority="28" Flags="770" Unknown="16" AdditionalLength="0">

This line spoken by miller character code 15
<Entry Id="22634616" Priority="14" Flags="771" Unknown="15" AdditionalLength="0">

etc

Nice find. Did you figure out what the flags-number is for?

Still no clue on that, once I figured that out I will be happy to share.

As for Flags, I'm pretty sure that, Flags="1024", in referring to cut-scene content on all subp. When there's Flags="1024" surely there's a cut-scene text line no doubt about that. For the other Flags="xxx" I still didn't understand the pattern. But Flags is Content with no doubts.


[CELEBORN-1470] CelebornInputStream should retry to get next chunk starting from returned chunk for no replication

What changes were proposed in this pull request?
CelebornInputStream retries to get next chunk starting from returned chunk for no replication.
Why are the changes needed?
CelebornInputStream retries to get next chunk starting from the beginning for retry for no replication at present. CelebornInputStream could retry to get next chunk starting from returned chunk instead of starting from the beginning to improve performance of fetching chunk without replication.
Does this PR introduce any user-facing change?
No.
How was this patch tested?
No.

Ping @FMX, @waitinfuture, @AngersZhuuuu.

Using a bitset to record return chunks can solve this data loss scenario. For most partition split, it won't be larger than 8 GB, I think the default value could be 1024 or 2048. This won't consume too much memory.
val bitSet = new java.util.BitSet(1024)


Using file-loader to load fonts doesn't work in production build.

With reference to #430 , we currently load font files on the site as embedded data URI's using the url-loader. This may not be ideal as users have to download both woff and woff2 versions of the font, which is blocking in nature.
We can use file-loader to solve this issue, but antwar / configuration doesn't support it currently. @bebraw would have a better idea perhaps.

Don't know for sure, but this could be related to the hack I had to do here. It seems that the .svg only works when you import it twice in different files. Very weird.

This should be fixed now by #450. It's vanilla webpack setup now (antwar does less work).


Diagnostics assistance tool: detection of unbalanced schematisation elements

unbalanced setup of schematisation elements may cause stability issues or computation time issues.
it would be great if potential risky elements could be detected beforehand in some kind of diagnostisc tool

Perhaps we can add logging on which node is limiting for the timestepping, possibly some courant number.


Validate 2 traps

Fixed the flux problem with #16

Validated with "Macrosopic rate equation modeling of trapping/detrapping of hydrogen isotopes in tungsten materials"


Replace shortcut

Hi, is it possible to replace to shortcut that runs the plugin? I'm using a plugin that already uses control + cmd + R as a shortcut so I can't use RenameIt with shortcuts..

I use a plugin called Monster to manage all the plugin shortcuts. I think it will help you re-asign shortcuts. https://github.com/PeachScript/sketch-plugin-monster


General WebExt improvements

Set minimum version to current FF pre-v57 Nightly (see discussion comment)
Fixed bug where background tab option in context menu was never selected
Compare with triple equals (yes, it is only ever set to a number, but a good practice)
Add shortname to manifest (needed for Chrome/Opera extensions if you plan to do that too)
Added homepage URL to manifest
I would recommend adding the developer and author keys to the manifest as well.

I've cherry picked the bits of this I like.


[REQUEST] Forcing ANSI

Have you checked the issues for a similar suggestions? YES
I need an Environment variable which forces ANSI output whatever the system may be.
This is particularly useful in GitHub Actions, where it doesn't show any colored output, currently, but setting that a environment variable should print colors.
Is it currently possible to do now?

You can construct the Console like this to generate ANSI regardless of environment:
console = Console(force_terminal=True, color_system="truecolor")

I think there is an env var that indicates if running on GH Actions, or maybe you can define one.

You can construct the Console like this to generate ANSI regardless of environment:
console = Console(force_terminal=True, color_system="truecolor")

I think there is an env var that indicates if running on GH Actions, or maybe you can define one.

You can construct the Console like this to generate ANSI regardless of environment:

Looks like it doesn't work? I just tried it. The code was pretty much simple though
logger = logging.getLogger(__name__)
custom_theme = Theme(
    {
        "log.level": "magenta",
        "repr.number": "bold green blink",
        "log.message": "white on red",
        "logging.level.info": "green on white",
        "logging.level.notset":"red on white"
    },
)

console=Console(theme=custom_theme, force_terminal=True, color_system="truecolor")

logger.addHandler(
    RichHandler(
        show_time=False,
        show_path=False,
        console=console,
        rich_tracebacks=True
    )
)

I could see no coloured output in GHA or ANSI locally on Git Bash(#330), where if ANSI is printed it should be turned into colours.

You can construct the Console like this to generate ANSI regardless of environment:

Looks like it doesn't work? I just tried it. The code was pretty much simple though
logger = logging.getLogger(__name__)
custom_theme = Theme(
    {
        "log.level": "magenta",
        "repr.number": "bold green blink",
        "log.message": "white on red",
        "logging.level.info": "green on white",
        "logging.level.notset":"red on white"
    },
)

console=Console(theme=custom_theme, force_terminal=True, color_system="truecolor")

logger.addHandler(
    RichHandler(
        show_time=False,
        show_path=False,
        console=console,
        rich_tracebacks=True
    )
)

I could see no coloured output in GHA or ANSI locally on Git Bash(#330), where if ANSI is printed it should be turned into colours.

That does work. Try printing os.environ or running python -m rich.diagnose

That does work. Try printing os.environ or running python -m rich.diagnose

Try printing os.environ or running python -m rich.diagnose

I haven't actually, made it based on an environment variable. That is a script is meant to be run in CI so I just forced it.
Just that poetry's ANSI forcing works. I have run python -m rich.diagnose here..
This is the place where the logger is present. I would be happy if you could help me :)

Try printing os.environ or running python -m rich.diagnose

I haven't actually, made it based on an environment variable. That is a script is meant to be run in CI so I just forced it.
Just that poetry's ANSI forcing works. I have run python -m rich.diagnose here..
This is the place where the logger is present. I would be happy if you could help me :)

Ah, you're on Windows. Try also setting legacy_windows=False. You might also want to set width to say 120 or so.

Ah, you're on Windows. Try also setting legacy_windows=False. You might also want to set width to say 120 or so.

Ah, you're on Windows.

I am sorry I didn't say this beforehand.

Try also setting legacy_windows=False. You might also want to set width to say 120 or so.

I did it https://github.com/naveen521kk/msys2-updator/commit/bd834deccffcfb2f8d784e8772380eb90ff84e6d but there isn't any colour there https://github.com/naveen521kk/msys2-updator/runs/1669125766?check_suite_focus=true#step:6:11

Ah, you're on Windows.

I am sorry I didn't say this beforehand.

Try also setting legacy_windows=False. You might also want to set width to say 120 or so.

I did it https://github.com/naveen521kk/msys2-updator/commit/bd834deccffcfb2f8d784e8772380eb90ff84e6d but there isn't any colour there https://github.com/naveen521kk/msys2-updator/runs/1669125766?check_suite_focus=true#step:6:11

Try logging console.options

Try logging console.options

See this

See this

I suspect that colorama may be stripping out ansi codes, even when legacy_windows is False. I'll look in to it.

I suspect that colorama may be stripping out ansi codes, even when legacy_windows is False. I'll look in to it.

Any updates?

Any updates?

Can’t do much about this without reinventing colorama. I may revisit this issue in future.

Maybe I will make an issue on Colorama about this? Asking them to check for an environment variable?

looks like there is a PR upstream https://github.com/tartley/colorama/pull/230

Update: I just did a regular dependency update and this seems to be fixed https://github.com/naveen521kk/msys2-updator/commit/4a34e98decd7bc8c1865517554bbd11eed43de85.
https://github.com/naveen521kk/msys2-updator/runs/2739486117?check_suite_focus=true#step:10:284 (I was happy without those colours though)

I have this issue as well and it seems that at least for me this isn't fixed.
What I try is to use tee to display it on stdout and to a file. How it doesn't seem to work.
console = Console(
        force_terminal=True,
        no_color=False,
        color_system="truecolor",
        width=120,
        legacy_windows=False,
        stderr=True,
    )

are my options for now...
This is what python3 -m rich.diagnose | tee shows me:
╭───────────────────────── <class 'rich.console.Console'> ─────────────────────────╮
│ A high level console interface.                                                  │
│                                                                                │
│ ╭──────────────────────────────────────────────────────────────────────────────╮ │
│ │ <console width=188 None>                                                     │ │
│ ╰──────────────────────────────────────────────────────────────────────────────╯ │
│                                                                                │
│     color_system = None                                                          │
│         encoding = 'utf-8'                                                       │
│             file = <_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'> │
│           height = 49                                                            │
│    is_alt_screen = False                                                         │
│ is_dumb_terminal = False                                                         │
│   is_interactive = False                                                         │
│       is_jupyter = False                                                         │
│      is_terminal = False                                                         │
│   legacy_windows = False                                                         │
│         no_color = False                                                         │
│          options = ConsoleOptions(                                               │
│                        size=ConsoleDimensions(width=188, height=49),             │
│                        legacy_windows=False,                                     │
│                        min_width=1,                                              │
│                        max_width=188,                                            │
│                        is_terminal=False,                                        │
│                        encoding='utf-8',                                         │
│                        max_height=49,                                            │
│                        justify=None,                                             │
│                        overflow=None,                                            │
│                        no_wrap=False,                                            │
│                        highlight=None,                                           │
│                        markup=None,                                              │
│                        height=None                                               │
│                    )                                                             │
│            quiet = False                                                         │
│           record = False                                                         │
│         safe_box = True                                                          │
│             size = ConsoleDimensions(width=188, height=49)                       │
│        soft_wrap = False                                                         │
│           stderr = False                                                         │
│            style = None                                                          │
│         tab_size = 8                                                             │
│            width = 188                                                           │
╰──────────────────────────────────────────────────────────────────────────────────╯

what I want is an option like force_colors=True in the Console constructor

Interesting enough: python3 -m rich | tee works flawlessly. I cann see all colors, so there must be a way :)

Sorry for the noise!  :) Instead of console.print(my_tree) I just did print(my_tree).... It works! I'm really sorry :)


Add SetEvent

CreateEvent, OpenEvent, ResetEvent exists but SetEvent is missing.

That seems like an oversight -- thank you so much for the contribution!


build: add a script to detect component ID collisions

As of v16, the framework uses the metadata of a component to generate an ID. If two components have identical metadata, they may end up with the same ID which will log a warning. These changes add a script to detect such cases automatically.
Relates to https://github.com/angular/components/issues/27163.

Why does Angular throw an error here? Isn't our use case valid - we are making a new version of a component.

tl;dr is that Angular has always had a unique ID for each component. Pre-v16 the ID was based on a counter so components were guaranteed to have a unique ID. When hydration was introduced, the counter approach didn't work anymore since different components might be executed on the server and the client so the ID algorithm was switched to use the metadata instead.

Could the ID generation take into account it's filepath or something unique beyond just metadata? It'd be helpful to know they intend to prevent this case otherwise

It can't since:

JIT compilation doesn't know about the file system.
This happens in the runtime, not at compilation.

Oof...well that's a bummer.
When should we run this script? Seems like it's a proactive thing that we ought to run when we change metadata?

Two quick thoughts:

Should some of this check be performed in the compiler CLI itself? seems like something other libraries would need too.
Could we just have a runtime test that imports all components and asserts that nothing breaks?

Things don't necessarily break at the moment, they just log a warning and I wanted to automate catching the warnings instead of having users report it to us.
As for having it in the compiler: I think it's trickier to do it there, because compilations might be spread across different build units running in parallel and things would only conflict once they're on the same page.

I thought we could potentially intercept logging and see if there is a matching error/or something, without having to replicate some of the serialization logic. At the same time though- adding all components is likely not super nice either

Yeah I feel like having it run as a part of the CI against the source code is the simplest without having to maintain even more code.


Prepare for v2 release

Small edits needed for the v2 release to PyPI.

I rebased this to fix some conflicts. I had separately bumped the version to match pypi before this PR was created.


fix section headers

What I Did
fix section headers in generated documentation to reflect ship-www layout
How I Did it
update templates and markdown builders in hack/docs/
How to verify it
cd hack/docs && make pipeline copy-help-center-gopath

make sure the links in reference docs headers work
Description for the Changelog
fix section headers in generated documentation to reflect ship-www layout
:boat:

Couple things

This breaks help center docs, so at the very least you should update the pr description to use a ship-www make command
Possibly add an 'update ship-www' command?

@laverya I'm pretty sure copy-to-help-center-gopath is ship-www
https://github.com/replicatedhq/ship/blob/master/hack/docs/Makefile#L58

That it is. Weird
Still should change the make command then lol


Option to inject keychain only to list of preallowed websites.

According to the docs, the extension injects itself into every website. It would be a good to add an option/make it default to inject the extension only to websites allowed by a user. This way, websites that do not have the access will not be able to track who has the extension installed. Moreover, the extension will not unnecessarily slow down user's browser. From the user perspective, the user will simple once add a website to a list if he chooses to use this option once and enjoy increased benefits of privacy.

Making it the default would make the extension much less user friendly for most of users.
The code injected is extremely light so I believe the proportion in which it would slow down a browser is insignificant, almost all of the heavy lifting happens on the background, which is independent of the number of open tabs.
I'll leave it open in case someone wants to work on this once the refactor is done, but I'm not ready to commit resources for this now, we have a lot going on.

Okay, thank you for your reply. Also users, for now, have the option to use a separate browser profile with the extension to achieve similar purpose.


[cudaaligner] Add aligner.reset_bandwidth(int32_t) to banded Myers aligner

Make batched_device_matrices default-constructible.
Add aligner.reset_bandwidth(int32_t) to banded Myers aligner.

Proper tests of reset_bandwidth() will follow in a separate PR.

🚀

I added a commit to restrict the scope of the in-source warning disablers and added a new one to fix my PR. Please (re-)review.

rerun tests

Can we propagate this function up to claraparabricks::genomeworks::cudaaligner::Aligner?


Improve error message on azd up in empty dir

Running azd up on an empty directory (pre-init) yields this error:

We should improve this. The first part of the error message seems good but the second bit about service name is confusing.
Note that this is on 0.8.0 (azd version 0.8.0-beta.1-pr.2687840 (commit a4f6a60a52ac5f8efa6243d2c0527f0dfc9c4a3c))

@savannahostrowski I think you may have created an azure.yaml somewhere in /c/Users/sostrowski
Here's what I get with azd up:
PS D:\tmp\empty> azd up
Error: no project exists; to create a new project, run `azd init`
PS D:\tmp\empty> azd version
azd version 0.8.0-beta.1 (commit 08209da7c22d28c6a123ef4e88d433132066b800)

Here's what I get after running azd init inside d:\tmp:
PS D:\tmp\lol> azd up

Packaging services (azd package)

ERROR: current working directory is not a project or service directory. Please specify a service name to package a service, or specify --all to package all services

Lol, yes...we really need to address #1638 so I stop doing this.
I'll close this :)


Make beacon node runnable

How was it fixed?

[x] Add back ReceiveServer
[x] Deactivae BCCRequestServer
[x] Various fixed to make beacon node runnable again

To-Do

[ ] Clean up commit history

[ ] Add entry to the release notes

Cute Animal Picture

It looks like the fastecdsa dependency of libp2p breaks the RTD build (hooray, that we catch these now!).
Maybe we can exclude libp2p here:
https://github.com/ethereum/trinity/blob/248efac0cc6daf43e49e5739a80f11737dd06161/setup.py#L141

Ah damn it, I think the git dependency broke my bullet proof regex
https://github.com/ethereum/trinity/blob/248efac0cc6daf43e49e5739a80f11737dd06161/setup.py#L131
Reading this will put a smile on @carver 's face in the morning :see_no_evil:

Something like [!=<>@ ](.|)+ might serve us better :)

Ah damn it, I think the git dependency broke my bullet proof regex
https://github.com/ethereum/trinity/blob/248efac0cc6daf43e49e5739a80f11737dd06161/setup.py#L131
Reading this will put a smile on @carver 's face in the morning

Lol, that didn't take long.

If this ever breaks again, let's nuke it from orbit and find another solution.

Merging this one. Feel free to leave comments/reviews here and I will fix them in subsequent PR.


Attach screenshots with the SDK

Now that we have mobile screenshots, let's do it for desktop! https://blog.sentry.io/2022/07/07/introducing-mobile-screenshots-and-suspect-commits/
https://develop.sentry.dev/sdk/features/#screenshots
This will have to be opt-in. We can configure this through an attachScreenshot option, and add a BIG warning about PII

There are a few things to consider with this feature and Electron.

We cannot capture screenshots of windows that have native crashed.
An app can have multiple windows. Which should we capture?
For some crashes, screenshots probably don't make any sense (I'm thinking of things GPU crashes here)

An app can have multiple windows. Which should we capture?

Can we send screenshots for every window? The spec: Subsequent screenshots in the same event should be named screenshot-n, where n is the screenshot number starting with 2. Maybe this can be user configurable 🤔.
Whatever we decide here will propogate to other desktop platforms, so we have the freedom to make the call.

For some crashes, screenshots probably don't make any sense (I'm thinking of things like GPU crashes here)

On mobile we only send screenshots for errors, not messages. I think we can just send it for all errors/crashes to start, and then refine it down as we get feedback.

Rather than adding a attachScreenshot option, would it not be better to use a non-default included integration?
That way we can keep the potential PII code completely excluded unless it's specifically included.

I think we can include the integration by default as long as we are sure that it's all locked behind the attachScreenshot option.


Add Korean (ko_KR) localization

Added a Korean translation file for Wearable Backpacks.

Thanks for your contribution. Sorry for taking so long to accept your PR! ❤


Fixe missing platform argument

react-native cli (0.1.7) need the platform argument in order to build.

Thanks! Will ship 0.3.7 with this fix :) :ship:


Step 1 - typo

$subscriptionID=='<your subscription ID>'   # the ID  of subscription name you will use
There is an extra equals sign that is not required on this line

Document Details
⚠ Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

ID: 15e8e46c-01f3-a76a-761f-5206e6d878e9
Version Independent ID: 3945290e-ef38-b04c-9ee6-d3889b4b94e4
Content: Tutorial: Use Azure Blob storage service with SQL Server 2016 - SQL Server
Content Source: docs/relational-databases/tutorial-use-azure-blob-storage-service-with-sql-server-2016.md
Product: sql
GitHub Login: @MashaMSFT
Microsoft Alias: mathoma

Hi @banzaisi , you're right, that's not supposed to be there :) Did you want to remove it yourself and be added as a contributor to the doc?
To do so, please do the following:

Navigate to the page of interest
Select the "Edit" button at the top right of the page
Select the "Pencil" icon on the right
Modify the text within the text box in markdown format - more info: https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet
Name your file change and provide a description, if necessary
Select "Propose file change"
Select "Create pull request" on the 'Comparing changes' page
Select "Create pull request" on the 'Open a pull request' page

Please let me know if you wanted to give that a try, or if you wanted me to move forward with processing the change?
Thanks!
Masha from the SQL Docs team


Footer with links to report bugs, etc

contain links for:
“About”, “Developers”, “Report a bug”, “Sponsors”, “Why MusicBox”, “Integrations”, “Blog”, “Help Center”, “How to use”, “Watch the Demo”, “News”.

bootstrap example footer: https://getbootstrap.com/docs/4.1/examples/pricing/

we should probably plan out what each link would point to, and if that page doesn't exist yet figure out what it would contain/look like

We could add one 'about' page which has different sections for things like 'developers', 'sponsors', “Why MusicBox”, “Integrations”, etc.
the links in the footer can just link to the sections of that page

sounds good - maybe we can just add these sections to the home page, below the 'get started' button?

That sounds good to me

“About”
"Contact us"
“How to use”
“Report a bug - email link”
“Sponsors”
“Developers”
"Partners - UIUC, NCAR, ..."
For later:
“Help Center FAQ's”
“Watch the Demo - URL-links to videos”
"Help Wanted (projects that someone could contribute to)"
“News”
“Components- MICM, CAMP, PHOTO, models, partners”,
“Why MusicBox”, -- after aerosols


listDocuments making too many requests

Environment details

OS: MacOS
Node.js version: 10
npm version: 6.14.8
@google-cloud/firestore version: 4.1.1

Steps to reproduce
We changed part of our code to use listDocuments instead of doing a get on the collection, as we are only interested in the ids. However we are seeing a considerable increase in the latency to get the results.
The weird part is that the listDocuments request seems to be retried/paginated? thousand of times, as shown by the OpenTelemetry data, where there are 1239 grpc calls to grpc.google.firestore.v1.Firestore/ListDocuments.

Waterfall showing the nested requests

Latency increased considerably

The code we are using is:
async generateCode() {
    const codes = await getInviteCodes();
    let code = generateRandomCode();
    while (codes.has(code)) {
      code = generateRandomCode();
    }
}

async function getCodes() {
    const codeRefs = await db.collection('codes').listDocuments();
    return new Set(codeRefs.map((ref) => ref.id));
}

Note that all requests return with grpc.status_code: 0.
We are using listDocuments in other parts of our codebase (for example to recursively delete users) and we checked the behavior and we did not find a high number of calls to this grpc endpoint.
Any idea what could be triggering that many retries or how to disable them? Or is it that the endpoint is paginating the results? However the listDocuments call sets the page size to 2**32-1, maybe that value is too high and the backend is using the default instead.

We reverted the collection.listDocuments() call to a collection.select().get() and the function now takes 5 seconds.

I tested the REST api (for the sake of convenience) with different pageSizes:

The default is 20, which is in line with what we are seeing. We are reading ~23k documents / 20 = 1150 calls.
A pageSize of 2**32-1 as used by listDocuments is rejected with an error
Setting it to 200000 or 1000 only returns 300 documents.

My theory is that by setting the pageSize in the rpc call to such a large value, does not have any effect and the backend ends up using the default value of 20.
https://github.com/googleapis/nodejs-firestore/blob/6139b5f83feed3957ea769ccf2f639d5b9d73d36/dev/src/reference.ts#L2434)
This limit is quite problematic, as if you want to list the documents in a large collection, it will take n/300 sequential calls.

Note that in the same file there is a comment explaining how MAX_INT32 cannot be used, and they use instead 2**16 - 1.
https://github.com/googleapis/nodejs-firestore/blob/6139b5f83feed3957ea769ccf2f639d5b9d73d36/dev/src/reference.ts#L300-L303

Still I think that the maximum pageSize of 300 is too low for this API call and makes it much slower compared to just using just collection.get(). Of course this is only possible in case you know there are no phantom documents.
Another difference could be the pricing. A query will cost 1 read per returned document, whereas according to https://cloud.google.com/firestore/pricing#other-queries

For queries other than document reads, such as a request for a list of collection IDs, you are billed for one document read.

However I'm not sure that the listDocuments api call actually cost one read per call, because the underlying API method not only returns the references, but also the document contents.


feat(events): Update and Add Cognito User Pool Events

Issue number: #3987
Summary
Changes

Please provide a summary of what's being changed

This change updates the UserMigrationTriggerEvent data class, adds the V2 of Pre Token Generation Lambda Triggers and adds two new data classes for Custom Sender Lambda triggers
User experience

Please share what the user experience looks like before and after this change

Events did not exist before. A workaround was to self-implement the data classes by inheriting base classes like so:
Before
from typing import Optional

from aws_lambda_powertools.utilities.data_classes import cognito_user_pool_event
from aws_lambda_powertools.utilities.data_classes import common

class CustomSMSSenderTriggerEventRequest(common.DictWrapper):
    @property
    def code(self) -> str:
        """A string for you to use as the placeholder for the verification code in the custom message."""
        return self["request"]["code"]

    @property
    def user_attributes(self) -> dict[str, str]:
        """One or more name-value pairs representing user attributes. The attribute names are the keys."""
        return self["request"]["userAttributes"]

    @property
    def client_metadata(self) -> Optional[dict[str, str]]:
        """One or more key-value pairs that you can provide as custom input to the Lambda function
        that you specify for the pre sign-up trigger."""
        return self["request"].get("clientMetadata")

class CustomSMSSenderEvent(cognito_user_pool_event.BaseTriggerEvent):

    @property
    def request(self) -> CustomSMSSenderTriggerEventRequest:
        return CustomSMSSenderTriggerEventRequest(self._data)

from . import CustomSMSSenderEvent

@data_classes.event_source(data_class=CustomSMSSenderEvent)
def handler(event: CustomSMSSenderEvent, context):
    return handle_event(event=event)

After

from aws_lambda_powertools.utilities.data_classes.cognito_user_pool_event import CustomSMSSenderTriggerEvent

@data_classes.event_source(data_class=CustomSMSSenderTriggerEvent)
def handler(event: CustomSMSSenderTriggerEvent, context):
    return handle_event(event=event)

Checklist
If your change doesn't seem to apply, please leave them unchecked.

[x] Meet tenets criteria
[ ] I have performed a self-review of this change
[x] Changes have been tested
[x] Changes are documented
[x] PR title follows conventional commit semantics

Is this a breaking change?
RFC issue number:
Checklist:

[ ] Migration process documented
[ ] Implement warnings (if it can live side by side)

Acknowledgment
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.
Disclaimer: We value your time and bandwidth. As such, any pull requests created on non-triaged issues might not be successful.

Hi @knightmre this is a super detailed PR with an impressive level of awesome docs/documentation. I'm working on other PRs and will schedule the first review of this PR for early next week.
Thanks

Hi @knightmre this is a super detailed PR with an impressive level of awesome docs/documentation. I'm working on other PRs and will schedule the first review of this PR for early next week.
Thanks

Hi, thanks for your time, I just found out I missed out on some tests so I'll be reworking this a little before your review.

Reviewing this now.

Hey @knightmre! Well done! This was one of the most detailed PRs I've looked at. Creating all those events in Cognito must have taken a lot of hard work and I'm sure you spent some days. I tried making some myself, and it took me over a day.
I just made a few small comments to your great work. 🚀

Hi @leandrodamascena Thanks for the review. I've included your comments and updated the PR.


fix the spelling error

Coverage remained the same at 79.951% when pulling 1b9768bd83d0fe2ba02d4ac3d069eaf837fae96b on rpdg:rpdg-patch-1 into 9c6b385b6a39ac65c0db4fe1b134afea57645d39 on aui:master.


Question on card with low VRAM

Hey, my graphics card only has 2GB of VRAM is there anyway I can change the batch size for the training to work. I always get an error saying tensorflow ran out of memory. I've changed some settings in the configs but can't seem to get it to work. Or can someone maybe please upload a pretrained model I just wanted to test a few things.
Thanks

Even with trained model, there is no way you can run this architecture on a GPU with < 4GB memory.

Ok thanks for the info.


Incorrect Header Readout from *.nrrd Images using scikit-image 0.15

I was using the same code on two different machines, one having installed scikit-image 0.14.2 and the other 0.15.
It seams that since version 0.15 scikit-image is able to read *.nrrd images, however it does not correctly read the meta information, which leads to wrong image dimensions. On the other machine using scikit-image 0.14.2 the loader faild to load the *.nrrd image and the next loader 'SimpleITK' was used, which could correctly load the image.

Hi @elitap I think you could add loader = simpleitk to your config's input data sections.
Also, we might change the order of the loader's attempts -- prefer simpleitk if it's installed. I'll double-check that.


async fn tracking issue

This issue is a placeholder issue which I'd like to use to keep track of what we need to do to support async fn for #[pyfunction] (and #[pymethods]).
While this would be a great feature to have, I think anything which we merge into PyO3 core should be simple to use, performant, and (ideally) async-runtime agnostic.
Users have started researching the design space of how possible cross-language implementations could be written. The most advanced candidate is pyo3-asyncio. See the guide as a great example of how to use it: https://pyo3.rs/latest/ecosystem/async-await.html
At the moment I suggest we allow some time for that and other crates to mature, and once we understand performance trade-offs / difficulties etc. we can consider upstreaming something here.
As this is supported by third-party crates I think we can afford patience for now.

pyo3-asyncio still needs some time and development to mature. There are currently a few things that I think need to be addressed:

Documentation and testing for pyo3-asyncio within native modules - seems like many users need this to get started
Cleaner initialization - better asyncio configuration, potentially some AlreadyInitialized errors, etc.
Stream <-> async generator conversions - my first draft had some performance concerns
Cleaner error handling - no complaints yet, but I have a few nitpicks here and there

I've been taking a bit of a passive approach to this library lately to see what users need it for, and it seems like these are the main concerns right now.

For the time being, using async conditionally can be enabled with qualifier_attr.

I've just released pyo3-async (see reddit).
Its approach is completely different from pyo3-asyncio as it is runtime-agnostic on Rust side. I've also added the support for trio, as it's quite popular (and supporting it was simple enough, contrary to curio for example). Last but not least, it supports async generators (simply reusing its coroutine implementation for __anext__), and cancellation.
Adding a macro for async fn is on my TODO list, but I think I have to discuss about it here first, whether or not the implementation could be good enough to be quoted in the documentation.

I've run some quick benchmarks to compare both pyo3-async and pyo3-asyncio. Results are as expected:

for wrapping of already ready future, performances are not comparable (more than 10x faster, but can be even worse if event loops are busy). This is because pyo3-async doesn't spawn task both on Python and Rust side, so successful polling is done synchronously on Python await operation, which become synchronous too. On the other side, pyo3-async will always be asynchronous.
you can also wrap spawned tokio task in pyo3-async coroutine, so you can emulate pyo3-asyncio behavior, and thus you get comparable performances.

Here is a simple example illustrating the first point:
#[pymodule]
fn example(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
    m.add_class::<Sender>()?;
    Ok(())
}

#[derive(Clone)]
#[pyclass]
struct Sender(tokio::sync::mpsc::Sender<()>);

impl Sender {
    async fn future(self) -> PyResult<()> {
        self.0.send(()).await.ok();
        Ok(())
    }
}

#[pymethods]
impl Sender {
    #[new]
    fn __new__(capacity: usize) -> Self {
        let (tx, mut rx) = tokio::sync::mpsc::channel(capacity);
        pyo3_asyncio::tokio::get_runtime().spawn(async move { while rx.recv().await.is_some() {} });
        Self(tx)
    }

    fn send_async(&self) -> asyncio::Coroutine {
        asyncio::Coroutine::from_future(self.clone().future())
    }

    fn send_asyncio<'py>(&self, py: Python<'py>) -> PyResult<&'py PyAny> {
        pyo3_asyncio::tokio::future_into_py(py, self.clone().future())
    }
}

import asyncio
import example  # built with maturin
import time

CAPA = 100
N = 10000

async def send_async():
    sender = example.Sender(CAPA)
    start = time.perf_counter()
    for _ in range(N):
        await sender.send_async()
    print("pyo3-async", time.perf_counter() - start)

async def send_asyncio():
    sender = example.Sender(CAPA)
    start = time.perf_counter()
    for _ in range(N):
        await sender.send_asyncio()
    print("pyo3-asyncio", time.perf_counter() - start)

for _ in range(3):
    asyncio.run(send_async())
    asyncio.run(send_asyncio())
    print("===============")

P.S. I'm currently implementing a pyasync macro, and I've some interesting issues about GIL-bound parameters, but I think I've found an elegant solution (with a bit of unsafe behind).

I've publish a new release of pyo3-async with #[pyfunction]/#[pymethods]!
@davidhewitt Would you mind taking a look at this crate? Could it be worth to mention it in PyO3 documentation?

@wyfo sorry for the slow reply, this looks like a very interesting development! I'm reading through the code today and will let you know what I think ASAP!

Overall I think it looks like a great crate, though I would suggest you add some CI to test with multiple Python / OS versions. Hopefully our testing in CI here means that you don't have any platform-specific quirks, but I wouldn't guarantee that.
This would definitely be welcome of a mention in the PyO3 documentation. I also suspect there are common parts which can be shared with pyo3-asyncio (and both projects may benefit from sharing what they can for interoperability's sake).
At the moment I think the key API reason which would prevent pyo3-async from being brought into the main PyO3's package would be that you have a couple of #[pyclass] types to represent various coroutines and generators on the Python side. The downside of this is that these end up as unique types in each Python extension module compiled using pyo3-async. Apart from PanicException, which exists out of necessity (and we have discussed a lot, we have avoided adding #[pyclass] types into PyO3 itself.
This prompted me to ask the CPython core devs in the Python discourse how they might want us to deal with these #[pyclass] types. Let's see what they say.
A couple of more specific thoughts:

It's very nice to see a runtime-agnostic solution to how to bind Rust and Python futures.
The fact you need to re-wrap the PyO3 macros is unfortunate though also understandable. I wonder if there's something which can be done to avoid the need for you to do this? At least from a cursory scan of the implementation you're not overly coupled to the PyO3 macro implementations.

CI is indeed on the TODO list, my first goal was write the code to illustrate the potential of this approach.
I don't think however that there are common parts with pyo3-asyncio, because both crates don't operate on the same level, as pyo3 fully relies on runtimes. But both return Python object or trait implementation, so nothing should prevent to work with both crates at the same time.
Actually, I did not know about this #[pyclass] issue, and that's indeed unfortunate. Funny enough, pyo3-asyncio has the same issue, but on Python-to-Rust side, while my crate is concerned on Rust-to-Python side.
Well, the answers to your post on Python forum are interesting, particularly the Cython hack. It may indeed be a thing for PyO3 coroutine implementation (but I'm still hoping that CPython will fix the coroutine ABI in the future).
For the macro part, I've hesitated to do a unique #[pyasync] macro to decorate both PyO3 #[pyfunction] and #[pymethods], but I've finally preferred re-wrapping them. But I'm not really coupled with their implementation, the only thing I need is to know if there is a #[pyo3(name = "...")] attribute, because PyO3 doesn't support having two of them.
In fact, another design decision was to generate an additional function returning the coroutine (to be decorated with #[pyfunction], or inside #[pymethods] impl) and keeping the original async one, or to modify the function in place. Because I don't like to modify code in macro, I've choosen the first solution, but the generated function needs then to have a #[pyo3(name = "...")] to match the original (if it doesn't already have one).
Also, the goal was to showcase a possible integration in PyO3, so re-wrapping was more suited. But a  #[pyasync] thing would be ok for me too.

Yes, it sounds like if Cython has set a precedent with its Coroutine types it seems reasonable to me for us to do something similar. @adamreichold and I have talked a lot about this kind of problem in the past, see #3073. At the time we were leaning towards a pyo3_runtime package, but maybe there's strengths of both approaches for different parts of the problem.
Maybe if we can sketch out a summary of all the pieces that we'd need to add to PyO3 to support async fn, and also what the limitations of our support would be, we could make a decision on whether we now have enough design knowledge to be confident in adding this feature.
Main concerns I'd have would be on:

interactions between the GIL and async code
any performance limitations which we know about in this design
how to ensure PyO3 core remains async runtime agnostic
how applications already using pyo3-asyncio can build upon PyO3's async fn

If it all fits together well, maybe with this latest development we get to a point where async fn sugar is supported in PyO3 and pyo3-asyncio can build upon that to add advanced helpers and async runtime integrations? (And we also perhaps bring pyo3-asyncio under the pyo3 org, if @awestlake87 wants that.)
@wyfo would you be interested in collecting that together, as this is freshest in your mind? (And if we think it makes sense, implementing? 👀)

After a second reflexion about this #[pyclass] issue, I've changed my mind quite a bit. Actually, several libraries defines their own exceptions, so why not consider PanicException as a per-library defined exception, that should be exported with the rest of the Python objects? I will open an new issue to discuss this particular topic.
Regarding coroutines, what would be the issue of having one coroutine type per extension? (You have this https://github.com/python/cpython/blob/84b7e9e3fa67fb9b92088d17839d8235f1cec62e/Lib/asyncio/coroutines.py#L38, but it's not really an issue).  Coroutines are only meant to be awaited, not used with == or isinstance, and you can still use isinstance(..., collections.abc.Coroutine) or asyncio.iscoroutine (which use isinstance), or even inspect.isawaitable. So I quite agree with PetrViktorin.
About async fn support:

Python async ecosystem is not normalized, contrary to Rust's one with the Future trait. There are multiple async backends, with incompatible implementation; asyncio is of course the main one, because standard, but there is also trio, which is quite popular now, especially with the anyio project, allowing him to be supported in trendy projects like Starlette/FastAPI. Should PyO3 only support asyncio, or multiple backends (with asyncio as default, of course)?
In pyo3-async, I've chosen to support both asyncio and trio, but also a lazy specialized implementation using sniffio, following the anyio trend. (I did not found a way to support curio, and didn't look to other backends)
Python coroutines are similar to Rust futures, both are suspendable computations. With asyncio, a Rust Future can "simply" be wrapped into a Python awaitable, which will yield asyncio.Future instantiated on demand, and using the asyncio.Future.set_result as wake method for a custom std::task::Waker. (That's what is implemented in *pyo3-async).
However, because Python async backends are single-threaded, wake operation must use thread-safe method, e.g. call_soon_threadsafe. (I've added a quick optimization in pyo3-async, I store the thread id at the future creation and check the current thread id in wake method to determine if call_soon_threadsafe must be called)
The direct binding between Python and Rust async executions is necessary, at least to have decent performance, because it allows synchronous execution of futures already ready (see https://github.com/PyO3/pyo3/issues/1632#issuecomment-1752582018)
There is still an important difference between Rust and Python async world: cancellation. In Python, cancellation is an exception that can be caught and even ignored, there can be asynchronous cleanup, while in Rust, you can only drop your future an cleanup with synchronous Drop. That's why Python async cancellation is not equivalent to just dropping a Rust future. A good design should give a way to properly handle Python cancellation.
In pyo3-async, coroutine wrapper has an optional throw callback, allowing to react to cancellation exception (for example using a mpsc::UnboundedSender). This is the best design I've found, because simple and not tied to a particular library.
Python awaitable doesn't require to be a coroutine, it just need to implement __await__ (i.e. to be awaitable). However, in pyo3-async, I've chosen to implement directly the coroutine protocol (which imply the awaitable one) because async backends like asyncio or trio don't support raw awaitables (asyncio automatically wraps them in a dummy coroutine), so it seemed to me that it should be more performant, but I've not tested this. It's also possible to implement the generator protocol without implementing __await__, by using types.coroutine wrapper, but I suspect this call could have performance impact; I still have to test it.
With direct binding between Rust and Python asynchronous execution (see second point), Rust Future is always polled with GIL acquired. However, to be embedded in a Python object, the future must be Send + 'static, so it's not possible for it to capture pyo3::marker::Python or any &pyo3::types::PyAny (#[pyfunction] parameters are thus also concerned), and to hold them across an await boundary. However, because the GIL is held, Python::with_gil is only one thread-local check, so it seems to be an acceptable safety cost, with unsafe Python::assume_gil_acquired for the zero-cost alternative.
By the way, having the GIL held for Future polling allows to use it to convert the  Future result to a Python type, so it doesn't have to be in the future code, allowing them to return a Result<T, E> where T: IntoPy<PyObject>, PyErr: From<E>.
In pyo3-async, this is materialized by the PyFuture type and its blanket implementation.

I don't know any performance limitation about this design for now. It is also completely agnostic of any Rust async runtime, and I don't see a reason to change that. In fact, it may be more efficient to spawn a big future into a tokio task, to have it polled exclusively on Rust side, and to wrap the task handle into a Python coroutine, but this optimization is just few lines of code and doesn't require first-class support IMO. But PyO3 needs to expose the Coroutine wrapper to allow this kind of use case (and cancellation support).
Regarding pyo3-asyncio, async fn support/Coroutine wrapper should completely replace future_into_py, while still allowing them to wrap their futures in a tokio/async-std task as mentioned above.
pyo3-asyncio also provides into_future for the opposite transformation Python to Rust. It does the job, but doesn't support task groups (so cannot be used with trio/anyio), and requires acquiring the GIL every time it's called.
I've recently thought about another way of handling Python awaitables which could be more optimized depending on the workflow:

spawn a Python task with a Rust coroutine awaiting a mpsc::UnboundedReceiver<(PyObject, oneshot::Sender<PyResult<PyObject>>)>, where the PyObject is the awaitable, and the onshot will be used to send its result
spawn each awaitable received in a task, and register a done-callback sending the result in the oneshot (at least for asyncio, because trio hasn't callbacks, so it's not so easy)

That's pretty much what into_future is doing, but the call to call_soon_threadsafe is replaced by mpsc::UnboundedSender::send, which will acquire them GIL and call call_soon_threadsafe (see coroutine implementation proposal), but only if there is a waker registered – the "only if" is the important thing here. This way, all Python context stay in the spawned spawner task, and there is only a mpsc::UnboundedSender to pass between threads (and potentially less GIL acquiring). I've to find a way to benchmark this, but I think I may recommand this pattern over pyo3-asyncio into_future.
Here is what I can say for now. Regarding the implementation, I would pretty much copy-paste the content of pyo3-async :innocent:

Thank you, there's a lot of detail here and it's taken me a little while to chew on it.
I think you're right that the Coroutine type can be an internal part of PyO3 and that will be what we would want async fn to return from #[pyfunction] and #[pymethods] to return. It's probably ok to have this compiled into each extension as per the Python discourse thread, and if we want to optimize it to reuse for the same PyO3 version from multiple extensions that can always come later.
I'm a little nervous around the complexity of all the different Python async backends. I sort of feel like it's worth us supporting asyncio only in PyO3 itself and then leaving other backends for separate crates, but it depends really on how easy it is to define abstractions which let us do that.
As a first step, let's try merging the Coroutine type along with a simple example? I'll learn a lot from reviewing that, I think.

I've written a new POC this weekend based on the current state if #3540, but also https://github.com/PyO3/pyo3/pull/3540#discussion_r1375530565.
Here are the improvements compared to the previous implementation:

coroutine __name__/__qualname__
warning when non-awaited coroutine are dropped (same as Python async def coroutine)
generic waker with multiple async backend support (asyncio, trio and anyio (with sniffio))
support for &self/&mut self in #[pymethods]
#[pyo3(allow_threads)] for async fn (and regular fn for coherence) with a generic parameter in Coroutine::new
cancellation support with CancelHandle and #[pyo3(cancel_handle = "param")] (and a generic throw_callback parameter in Coroutine::new if needed)
Rust-awaitable PyFuture as a wrapper around the result of __await__, can only be awaited in the context of a future polled by a coroutine and don't support select! (panic otherwise) no nightly required
like Python coroutines, PyO3 coroutines delegate send/throw/close call to the currently awaited PyFuture if there is one

I've tested this implementation in a real project, awaiting thousands Python awaitables per second inside PyO3 coroutines running on asyncio, and it works well. By the way the performance difference between awaiting PyFuture and spawning a task like pyo3_asyncio::into_future is quite huge.
My only issue about the default waker implementation for #[pyfunction]. I haven't found a way to make it configurable by the user now, so only asyncio is used for now.
I've also added a lot of tests https://github.com/wyfo/pyo3/blob/async_support/tests/test_coroutine.rs, https://github.com/wyfo/pyo3/blob/async_support/tests/test_awaitable.rs and https://github.com/wyfo/pyo3/blob/async_support/src/gil.rs#L930.

@davidhewitt should we keep this issue open until all the planned features are merged?

Would it make sense to make this functionality option/behind a cargo feature?
The dependency on futures-util adds quite a few dependencies to the tree, which probably impacts compile time, and I think many users probably don't have a need for it.

There was discussion in https://github.com/PyO3/pyo3/pull/3540#discussion_r1375251395 where we decided not to feature gate for the moment, but then we did switch from futures-task to futures-util.
I wouldn't be opposed to having the feature if it was strongly wanted.

In fact, future_util is not really useful.
Here are the uses in the implementation (I'm mixing the current state and my last POC):

AtomicWaker and poll_fn for cancellation, poll_fn is trivial to reimplement, and AtomicWaker could simply be replaced by a mutex, as there should be no contention issue.
FutureExt::catch_unwind and CatchUnwind, again trivial to reimplement
ArcWake and waker, just a mistake of me, I didn't remember about std::task::Wake, so they can be simply replaced by the std counterpart
I can remove this dependency in the next PR.

If itd make sense to implement, rather than depend, that would also work
for my concerns!
On Wed, Nov 29, 2023, 2:37 AM Joseph Perez @.***> wrote:

In fact, future_util is not really useful.
Here are the uses in the implementation (I'm mixing the current state and
my last POC):

AtomicWaker and poll_fn for cancellation, poll_fn is trivial to
reimplement, and AtomicWaker could simply be replaced by a mutex, as
there should be no contention issue.
FutureExt::catch_unwind and CatchUnwind, again trivial to reimplement
ArcWake and waker, just a mistake of me, I didn't remember about
std::task::Wake, so they can be simply replaced by the std counterpart
I can remove this dependency in the next PR.

—
Reply to this email directly, view it on GitHub
https://github.com/PyO3/pyo3/issues/1632#issuecomment-1831365338, or
unsubscribe
https://github.com/notifications/unsubscribe-auth/AAAAGBFZX4ICWG6K7Q7SJ4LYG3Q4BAVCNFSM45QJT3ZKU5DIOJSWCZC7NNSXTN2JONZXKZKDN5WW2ZLOOQ5TCOBTGEZTMNJTGM4A
.
You are receiving this because you commented.Message ID:
@.***>

@wyfo, @davidhewitt Apologies for taking so long to catch up on this thread. I've been taking a look at @wyfo's work in pyo3-async, and it's all positive. I think it's a good approach and clearly has performance benefits over pyo3-asyncio, and I think there's a place for both libraries or a combined approach going forward.
pyo3-async is a great candidate for an async library that can be merged into pyo3, and I think it should be the implementation chosen for an async fn for #[pyfunction]. Aside from performance, pyo3-asyncio's implementation is too deeply coupled to the Rust runtimes because of it's use of task locals. These serve an important purpose, but are not necessary for all async functions that can be used with Python.
Just a heads up, this'll be a long response! It's taken awhile for me to gather my thoughts because this is a complicated subject. I felt like I needed to dig into the code to really understand the differences and the synergies for these libraries, and to refresh my memory on our past design decisions
Past Discussions
pyo3-async's design reminds me a lot of @ThibaultLemaire's proof-of-concept for Asyncio-driven futures that we discussed at the start of pyo3-asyncio's development. Reading back through that thread, there were other priorities for pyo3-asyncio at the time, and in hindsight I may have been a bit too dismissive. It seems like now we might have some concrete answers to the concerns that I brought up back then:

Are there any real-world examples where people do not need a specific runtime for their future?

Yes! If you're writing Rust code that relies purely on Python's awaitables, then there may not be a need to spawn your future onto a runtime like Tokio. pyo3-async can bridge the gaps between the two languages without the need for a Rust-specific runtime.
In addition, if you need a runtime like tokio or async-std for some Rust functionality, you just await the JoinHandle from the pyo3-async function. This is probably good enough in many cases, but not all cases (I'll explain why).

Are there any performance wins with this approach? Would they be on the hot-path or cold-path for most use-cases?

Clearly 😅, sounds like pyo3-async has been blowing pyo3-asyncio out of the water performance-wise. The advantages here were not so clear to us at the time, and we were completely focused on compatibility.
As for the hot-path/cold-path, I'm optimistic, but less certain about that. It really depends on the bindings that users need to create. I think we need more users to start using pyo3-async to see how often we can take advantage of these performance wins.

Does this provide better interop between Rust Futures and Python Libraries?

Yes, I think so. Converting these awaitables to Futures that can be polled directly inside Rust has some performance advantages. The main drawback (as I understand it) is that the Rust Future that's polling them has to be running on the same thread as the Python event loop in order for some Python functionality like get_running_loop to work.

Sharing the asyncio executor could have some advantages that I haven't considered yet.

There was some thought at the time that if Rust futures were polled from asyncio, we could potentially support !Send futures. I'm still not so sure this is practical, but it was completely out of the question with pyo3-asyncio's approach.
So can pyo3-async replace pyo3-asyncio completely?
There are still some use-cases that users of pyo3-async might struggle with, and in those cases I think the solution will end up looking very similar to what pyo3-asyncio does. The good news is that you don't need to choose one or the other. pyo3-asyncio and pyo3-async can be used to address completely different problems.
After doing some investigation here, I think the main advantage to pyo3-asyncio's approach is in using async Python from tokio/async-std threads.
As a practical example, imagine we are trying to wrap the Tide library for Python. Tide servers listen for connections, then execute some user-defined async operation when it receives a request. Using this library from Python would probably look something like this:
import asyncio
import rust_http

async def handler():
    await asyncio.sleep(1)
    return "hello"

async def main():
    server = rust_http.Server()

    # Setup two routes for this handler to highlight the differences between
    # the libraries
    server.get_with_pyo3_async('/pyo3_async', handler)
    server.get_with_pyo3_asyncio('/pyo3_asyncio', handler)

    await server.run()

asyncio.run(main())

There's some nuance involved when dealing with event loop references that I've highlighted in pyo3-asyncio's docs. Because we're working with Python's threads and async-std's threads, and Python's coroutines often rely on thread-local storage when using asyncio's library, we need to capture the current event loop and context vars in order for our Python handler to behave correctly.
use pyo3::prelude::*;

/// A Python module implemented in Rust.
#[pymodule]
fn rust_http(_py: Python, m: &PyModule) -> PyResult<()> {
    m.add_class::<Server>()?;
    Ok(())
}

#[pyclass]
struct Server {
    app: tide::Server<()>,
}

#[pyo3_async::pymethods]
impl Server {
    #[new]
    fn new() -> Self {
        Self { app: tide::new() }
    }

    async fn run(this: Py<Self>) -> PyResult<()> {
        let app = Python::with_gil(|py| this.as_ref(py).borrow().app.clone());
        app.listen("<IP_ADDRESS>:8080").await.unwrap();
        Ok(())
    }

    fn get_with_pyo3_asyncio(&mut self, path: &str, handler: PyObject) -> PyResult<()> {
        // Capture the locals when this function is called.
        let locals =
            Python::with_gil(|py| pyo3_asyncio::async_std::get_current_locals(py)).unwrap();

        self.app.at(path).get(move |_| {
            let handler = handler.clone();
            let locals = locals.clone();
            async move {
                // Pass the locals we captured earlier into a pyo3-asyncio conversion
                //
                // Internally, the coroutine returned by handler is passed to the event loop
                // using call_soon_threadsafe and wrapped in an asyncio Future.
                //
                // That way if it calls something like asyncio.get_running_loop(), it'll be
                // running on a Python thread.
                //
                // It works!
                let rsp = Python::with_gil(|py| {
                    pyo3_asyncio::into_future_with_locals(
                        &locals,
                        handler.as_ref(py).call0().unwrap(),
                    )
                })
                .unwrap()
                .await
                .unwrap();

                let text: String = Python::with_gil(|py| rsp.extract(py)).unwrap();

                Ok(tide::Response::from(text))
            }
        });

        Ok(())
    }

    fn get_with_pyo3_async(&mut self, path: &str, handler: PyObject) -> PyResult<()> {
        self.app.at(path).get(move |_| {
            let handler = handler.clone();
            async move {
                // Wrap our handler's coroutine in an AwaitableWrapper to drive it from Rust
                //
                // The AwaitableWrapper will drive the coroutine directly using __await__ and
                // __next__. This is a bit problematic in this case the polling is happening on one
                // of async-std's threads.
                //
                // When it runs, we'll get the following error:
                //
                // thread 'async-std/runtime' panicked at src\lib.rs:32:18:
                // called `Result::unwrap()` on an `Err` value: RuntimeError('no running event loop')
                let rsp = Python::with_gil(|py| {
                    pyo3_async::asyncio::AwaitableWrapper::new(handler.as_ref(py).call0().unwrap())
                })
                .unwrap()
                .await
                .unwrap();

                let text: String = Python::with_gil(|py| rsp.extract(py)).unwrap();

                Ok(tide::Response::from(text))
            }
        });

        Ok(())
    }
}

I think in this case, moving the coroutine to asyncio's event loop is inevitable. It needs to run on a Python thread, and we need some way of tracking references to the Event Loop and Contextvars. This is done behind the scenes with pyo3_asyncio.
Likewise, things like tokio::spawn don't 'just work' in futures driven from Python's threads. You need some way of finding a reference to Tokio's runtime (often through global storage like pyo3-asyncio). pyo3-asyncio does make this more seamless for users, but at the cost of some performance.
So what now?
The main questions I have now are:

How often do cases like this come up? Are they edge cases or common?
Is pyo3-asyncio trying too hard to hide details like this?

Allowing users to encounter these problems quickly may be the best way to teach them how to address them properly

How can we help the community solve problems like this when they inevitably come up?

Obviously some new docs / guides will be needed
Can we provide some suggestions in the error messages?
Can our two libraries be tweaked or merged for better interop?

Looking forward to hearing your thoughts on this!

Having an official async fn for the proc_macros in pyo3 itself would be a good start I think

Note that this is underway even if a bit stalled in #3610, #3611, #3612 and #3613.

@awestlake87 You're right, pyo3-async and the currently implemented async support in PyO3 are not made to run coroutine outside of the Python thread, and this could indeed be the main job of pyo3-asyncio. Actually, I wonder if future_into_py and other pyo3_asyncio::async_std::main are still a thing with PyO3 async support, especially when pyo3::coroutine::Coroutine will be exposed; in fact, I think Coroutine will completely replace future_into_py.
By the way, AwaitableWrapper will not be added in PyO3, for the reason you spotted. Instead, you can take a look to the PyFuture type which is already planned in #3611.

As usual, I like writing some POC on the weekend, and #4057 is my latest one. It comes from my previous comment, about the current async support plan not allowing to await Python awaitables in arbitrary threads. This draft PR provides a PyFuture(PyAny) wrapper around a Python future-like object, either asyncio or concurrent.futures one. It allows converting the PyFuture to a Rust std::future::Future (roughly same way pyo3-asyncio or pyo3-async does). To handle any awaitable, it requires to call asyncio.ensure_future but I think it's better to have it explicit, to avoid pyo3-asyncio issue. With this, I think the async support in PyO3 will be complete.
I know the name PyFuture echoes with #3611, but as written in a comment, this name was not well suited. I think I have to rename it, but I don't have any idea. I've written a post in Python forum to ask for help with the naming.

Maybe the best solution is simply to not expose the type in #3611, but only an async function named await_in_coroutine or something like this. Named type are less and less useful now we have async trait.
Actually, I start liking this await_in_coroutine function more than a type, because it's more explicit about the fact the returned future can only be awaited in a coroutine, and because it can be defined in coroutine module. I will update the PR in consequence. We can still going back to a type if it is preferred.

Welcome back, sorry to hear you were suffering and glad you are better. I see you opened a few PRs already, with apologies I'm a bit busy this week, so I may be slow to review them.  I intend to be back at the keyboard as regular soon!

Something I didn't thought about is to accept IntoFuture instead of Future in coroutine constructor. into_future would be called in __await__.
Of course it will wait MSRV bump to 1.64, but this is definitely a thing we can/need to implement.

Hello. I'm not a very experienced Rust developer, I've worked with pyo3 a bit and never with pyo3-asyncio.
I have a compilation error:
error[E0432]: unresolved import `pyo3::coroutine`
 --> src\main.rs:8:11
  |
8 | use pyo3::coroutine::Coroutine;
  |           ^^^^^^^^^ could not find `coroutine` in `pyo3`

These are my dependencies:
[dependencies]
pyo3 = "0.21.2"
tokio = "1.37.0"

Command "cargo add pyo3-asyncio --features tokio" ends up with this:
error: failed to select a version for `pyo3-ffi`.
    ... required by package `pyo3 v0.20.0`
    ... which satisfies dependency `pyo3 = "^0.20"` of package `pyo3-asyncio v0.20.0`
    ... which satisfies dependency `pyo3-asyncio = "^0.20.0"` of package `devita v0.1.0 (F:\work\rust-tests\devita\1\devita)`
versions that meet the requirements `=0.20.0` are: 0.20.0

the package `pyo3-ffi` links to the native library `python`, but it conflicts with a previous package which links to `python` as well:
package `pyo3-ffi v0.21.2`
    ... which satisfies dependency `pyo3-ffi = "=0.21.2"` of package `pyo3 v0.21.2`
    ... which satisfies dependency `pyo3 = "^0.21.2"` of package `devita v0.1.0 (F:\work\rust-tests\devita\1\devita)`
Only one package in the dependency graph may specify the same links value. This helps ensure that only one copy of a native library is linked in the final binary. Try to adjust your dependencies so that only one package uses the `links = "python"` value. For more information, see https://doc.rust-lang.org/cargo/reference/resolver.html#links.

failed to select a version for `pyo3-ffi` which could resolve this conflict

What am I doing wrong?

What am I doing wrong?

You need to add experimental-async feature to pyo3 in your Cargo.toml.
Replace pyo3 = "0.21.2" with pyo3 = { version = "0.21.2", features = ["experimental-async"] }

Thank you very much! That's really what I missed.
But now I have another question. If I embed a Python interpreter in my application, how do I expose Rust async functions (or Futures) into it? Say, as an argument for py.run.

But now I have another question. If I embed a Python interpreter in my application, how do I expose Rust async functions (or Futures) into it? Say, as an argument for py.run_bound.

Async pyfunctions are just normal pyfunctions (only their return type is converted to coroutine). So you can expose async pyfunction the same way you expose sync pyfunction, using wrap_function! for example.

how do i configure tokio with this experimental async feature?

See this example from the original POC. You have to manually declare a runtime, like this:
fn tokio() -> &'static tokio::runtime::Runtime {
    use std::sync::OnceLock;
    static RT: OnceLock<tokio::runtime::Runtime> = OnceLock::new();
    RT.get_or_init(|| tokio::runtime::Runtime::new().unwrap())
}

and you can use it with for example tokio()spawn(...)

the thing is that i am using a crate which is internally calling tokio::task::spawn(future);

Async pyfunctions are just normal pyfunctions (only their return type is converted to coroutine). So you can expose async pyfunction the same way you expose sync pyfunction, using wrap_function! for example.

Is there any way to create PyCFunction from async closure? PyCFunction::new_closure_bound doesn't seem to be able to do this.

Is there any way to create PyCFunction from async block? PyCFunction::new_closure_bound doesn't seem to be able to do this.

See #3613. When coroutine constructor will be exposed, you will be able to return a coroutine from any function/closure, hence using PyCFunction::new_closure_bound.
But there is #3610, #3611 #3612 to be merged before, as well as  #4057 to complete the async support.

FWIW I experienced deadlocks when combining pyo3 async support with tonic. I was running blocks that required tokio (calls into tonic) using the OnceLock of a tokio Runtime suggested elsewhere in the thread. Unfortunately it's difficult for me to provide the code that ends up in this deadlock, but the deadlocks went away when I switched my pyo3 functions back to non-async and just used block_on for any awaits. I also never experienced deadlocks using pyo3-asyncio's tokio::run function which I was using previously.
Anyway, I know that isn't anything to go on, and it may be that my code is incorrect somehow, but just want to record this here in case someone else hits the same issue.

Actually, I've already experienced deadlock in one of my experiment, see https://github.com/PyO3/pyo3/pull/3540#issuecomment-1789623562.
As written in my next comment, the solution was simply to release the GIL in the async function – the feature is already implemented, but is not yet merged, see #3610.
Could you try to build your code with that branch, add #[pyo3(allow_threads)] attribute where needed, and see if the deadlock still occurs?
I think the difference with pyo3-asyncio causing the deadlocks is the fact that Waker implementation needs to acquire the GIL, but it may be called from arbitrary thread with arbitrary locks already acquired.
We may need to better document this risk

Anyway, I've discovered today the existence of https://github.com/mozilla/uniffi-rs, and was quite surprised to see it already supports converting a Rust future into a Python awaitable.
I've looked a bit into the code, their way of doing it is a little bit different of the one we chose in PyO3, so it could be interesting to do some comparisons.

Quite interestingly, at the beginning, uniffi was not mapping a rust future to a python coroutine but directly to a python future; their waker implementation was scheduling rust future poll on the Python event loop, and setting the python future result when the rust future was ready. Then changed their approach to better handle cancellation and now, this is quite similar to what we do, as they return a coroutine yielding a python future for each rust future poll. The main difference is that they use a generated Python coroutine, while we use a pyclass (without taking account PyO3 additional features like #[pyo3(allow_threads)], await_in_coroutines, manual coroutine instantiation, etc.)
Anyway, I find their first approach quite interesting, and think it should have better performance over creating a new future for each poll. I will maybe try to implement it and run some benchmarks to see – I still don't think it will be worth adding this much complexity in the code, but I like making POC.

Interesting indeed. I think uniffi also uses PyO3 so if we are close to their design they might be pleased to be able to reuse code.
@wyfo I'm keen to review the async PRs again ASAP, I hope to be more available from tomorrow. Which one should I be starting with? I got a bit lost given the time gap; it would indeed be nice to move this further along for 0.22
Also have you seen #4064? I might take a look at that, I guess our protocol methods may need some handling...

There is no mention of PyO3 in uniffi code, so I don't think design convergence matters. By the way, as I said, our design is now quite similar. I'm still interested in their first (incomplete) design, but that's pure curiosity.
The first PR to review is #3610, then #3611, #3612 and #3613. There is also #4057 draft that can be interesting to complete  the support. There are conflicts with recent PRs, so I need to resolve them tonight.
I didn't seen #4064. I admit I don't know at all this part of the code (for example, I wasn't able to solve #4113 myself, fortunately @Icxolu was here to help), so I don't know if I will be able to solve the issue myself. I don't really understand why the code is so different between pyfunction/pymethods and magic methods like __anext__, but I assume we should port all the stuff we implemented for async pyfunction (cancellation, allow_threads, receiver special case) there.
I think we should turn #4064 into an issue, and ask for some experienced maintainer to take it.

How to call python async function?

Hello everyone!
Could you please tell me how to use the __anext__ method with the experimental-async feature?
In my case __anext__ previously returned exact result Result<Py<PyAny>, Error> with pyo3_asyncio::tokio::future_into_py. Now this variant isn't working because pyo3_asyncio depends on a lower version of pyo3.
In general, I want to create a Future in class method __anext__ and return it as a Coroutine object to Python.
I read this thread and didn't find any examples or information about it. Maybe it's impossible now?

@chandr-andr you may be able to use pyo3-asyncio-0-21, a temporary fork with support for PyO3 0.21 (it's available at crates.io). I'm not sure if this will solve your problem, but it might! Sometime soon a more permanent fork is going to get unrolled from here: https://github.com/PyO3/pyo3-async-runtimes.

@douglasdavis Thank you, good man!
I tried it and it works! I didn't know about that fork.

I've updated the OP to link there too. 👍


When encoding to mp3, the bitrate is always 128kbps

Could you post the encoder settings you're using?

Could you post the encoder settings you're using?

OK, like this
[.mp3TargetIsBitrate: NSNumber(value: 1),
.mp3Quality: NSNumber(value: 5),
.mp3Bitrate: NSNumber(value: 192),
.mp3EnableCBR: NSNumber(value: 0),
.mp3StereoMode: MP3StereoMode.jointStereo,
.mp3CalculateReplayGain: NSNumber(value: 1)]

I tested it again, still the same 128kbps, and the duration read through SFBAudioFile is wrong

I believe all of these problems are truly fixed now.
Using
encoder.settings = [
	.mp3UseVariableBitrate: true,
	.mp3VBRMinimumBitrate: 192,
	.mp3VBRQuality: 5,
	.mp3CalculateReplayGain: true
]

gives the expected result:
Encoder Version     : LAME3.100
LAME Tag Revision   : 0
VBR Method          : Variable Bitrate method2 (mtrh)
Lowpass Filter      : 17000
Radio Replay Gain   : 8.3 dB (Set automatically)
Encoding Flags      : --nspsytune --nssafejoint
ATH Type            : 5
Bitrate (Minimum)   : 192
Encoder Delay       : 576 samples
Encoder Padding     : 1017 samples
Noise Shaping       : 1
Stereo Mode         : Joint
Unwise Settings     : False
Sample Frequency    : 44.1 kHz
MP3 Gain            : 0 (+0.0 dB)
Preset              : V5
Surround Info       : None
Music Length        : 49.31 KB
Music CRC-16        : 82B5
LAME Tag CRC-16     : FA81