Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Python stubs #130

Closed
Kludex opened this issue Dec 11, 2021 · 18 comments · Fixed by #192
Closed

Add Python stubs #130

Kludex opened this issue Dec 11, 2021 · 18 comments · Fixed by #192

Comments

@Kludex
Copy link
Contributor

Kludex commented Dec 11, 2021

I'm very noob in the Rust->Python binding stuff, but I guess we need .pyi files?

@sansyrox
Copy link
Member

I export the functions that need to be publicly available and python-language servers provide autocompletion for them.

Did you face an issue where the lsp was not recognizing anything?

@Kludex
Copy link
Contributor Author

Kludex commented Dec 11, 2021

I guess my thoughts were more about the types, but I see that the only one that matters on this issue would be the "request" dictionary. 🤔

I didn't know it was a dict, but https://docs.python.org/3/library/typing.html#typing.TypedDict can be used to define the keys it holds, and the LSP will be able to autocomplete the keys as well, jfyk.

@sansyrox
Copy link
Member

sansyrox commented Dec 11, 2021

I guess my thoughts were more about the types, but I see that the only one that matters on this issue would be the "request" dictionary.

Ah, I see. I am not a big fan of typed languages. So, I never really bothered to learn more about types in python. But I can definitely have a look if you folks use them. :D

@ShadowJonathan
Copy link

Supplying types would help immensely with verifying type-correctness with checkers like mypy, so I would really recommend bundling and maintaining pyi files with robyn.

Type annotations in python has been getting a boost and wider recognition lately, so I don’t think it’s wrong to focus on this as well.

If you pass user functions any object that’s only defined in native code, or expose functions defined the same, then it is common practice to either at least document it, and often to then provide type stubs as described here.

@sansyrox
Copy link
Member

@ShadowJonathan @Kludex , I started reading about pyi files today. So, do people maintain python stubs as well as python functions?

Could you folks point me to a codebase that uses them, so that I could take some inspiration from it?

@Kludex
Copy link
Contributor Author

Kludex commented Dec 25, 2021

I'm on my phone, but look for "blacksheep python"

@sansyrox
Copy link
Member

Hi @Kludex @ShadowJonathan , I have been thinking about adding some types to the public methods atleast.

Do you folks have any strong opinions about mypy or pyright ?

@Kludex
Copy link
Contributor Author

Kludex commented Apr 11, 2022

mypy is the most used, pyright is used by VSCode. I only use mypy.

@sansyrox
Copy link
Member

Ah okay. And do you think that mypy has gradual adoption or is it very enforcing?

@Kludex
Copy link
Contributor Author

Kludex commented Apr 12, 2022

@sansyrox
Copy link
Member

Thank you @Kludex. I will have a look the PRs :D

@Kludex
Copy link
Contributor Author

Kludex commented Apr 13, 2022

Feel free to ping me as reviewer.

@RobertCraigie
Copy link

RobertCraigie commented Apr 30, 2022

@sansyrox Pyright is more feature rich and much faster than mypy. Feature requests / bug fixes also get implemented considerably faster.

The only feature that mypy has over pyright in my opinion is plugin support which is currently missing in pyright.

With that said, mypy is currently more popular than pyright for people's choice of type checker although pyright is still fairly popular and can also be used as a language server with support for VSCode, Sublime Text, vim etc.

From a library maintainer's perspective it is best for the public API to support both although I highly recommend pyright for any internal usage if you need to use a type checker.

do you think that mypy has gradual adoption or is it very enforcing?

Pyright also supports incremental adoption, you can explicitly list the files to check or exclude files from being type checked through the config file, see https://github.com/microsoft/pyright/blob/main/docs/configuration.md#main-pyright-config-options.

Also you only need to add stub files for the Rust -> Python interface, all other standard python files you can add inline type annotations.

Feel free to ping me for review or if you need help as well :)

For reference, I maintain https://github.com/RobertCraigie/prisma-client-py which makes heavy use of type annotations.

@sansyrox
Copy link
Member

sansyrox commented May 1, 2022

Hi @RobertCraigie ,

Firstly, thank you so much for the detailed explanation. :D

I checked out prisma-client-py , it looks amazing 🔥

From a library maintainer's perspective it is best for the public API to support both although I highly recommend pyright for any internal usage if you need to use a type checker.

So, then just adding and including Python stubs in the repo should be enough. Right?

Also you only need to add stub files for the Rust -> Python interface, all other standard python files you can add inline type annotations.

Actually, I was thinking of adding stub files for everything. As I am not a big fan of inline types.(I know. I am sorry :p)

Would that bring any issue(s) ?

Feel free to ping me for review or if you need help as well :)

Thank you so much. This feature is the next thing that I plan to implement. So, hopefully soon 🤞

@RobertCraigie
Copy link

Thank you :D

So, then just adding and including Python stubs in the repo should be enough. Right?

Yes, by supporting both I mean only using features that both type checkers support. For example, pyright has support for Unpacking TypedDicts and recursive types whereas mypy does not. There are a few other features that only pyright supports but they are only for complicated use cases which I doubt this library would need.

Actually, I was thinking of adding stub files for everything. As I am not a big fan of inline types.(I know. I am sorry :p)

No worries everyone has their own personal preferences, I'm just glad you're willing to add type stubs for the people that do want to use types. I know of other libraries that are completely against adding types. So thank you :)

Would that bring any issue(s) ?

I'm not familiar with packaging type stubs as all of the projects I've worked on have used inline types. The only issues I can see arising from using type stubs is that different type checkers use different semantics to resolve stub files and I'm not aware of the nuances between them.

Adding the .pyi files alongside the .py files should work with both pyright and mypy but I'm not 100% sure. Just remember to include the stub files in the packaged distribution :)

@sansyrox
Copy link
Member

sansyrox commented May 1, 2022

@RobertCraigie , got it. Thank you! :D

Also, prisma-python-client looks really nice. How easy do you think it be to make a crud app example or maybe even a plugin with Robyn?

If it's not that hard, I will try to make some integrations this week.

@RobertCraigie
Copy link

Thank you :D

It should be fairly easy to make a crud app example. Here's a minimal example using Prisma with Robyn.

from robyn import Robyn
from prisma import Prisma
from prisma.models import User

app = Robyn(__file__)
prisma = Prisma(auto_register=True)

@app.startup_handler
async def startup_handler() -> None:
    await prisma.connect()

@app.shutdown_handler
async def shutdown_handler() -> None:
    if prisma.is_connected():
        await prisma.disconnect()

@app.get("/")
async def h():
    user = await User.prisma().create(
        data={
            "name": "Robert",
        },
    )
    return user.json(indent=2)

app.start(port=5000)

Using this Prisma Schema:

datasource db {
  provider = "sqlite"
  url      = "file:dev.db"
}

generator py {
  provider = "prisma-client-py"
}

model User {
  id   String @id @default(cuid())
  name String
}

Something I also forgot to mention is that pyright has support for automatically creating stub files which can help you save a lot of time but you'll still have to edit the auto generated stubs. You can try it out by running pyright --createstub robyn.

@sansyrox
Copy link
Member

sansyrox commented May 2, 2022

@RobertCraigie , wow! Thank you for both of them. :D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants