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

Can we use setuptools entry points to expose ethpm packages from python packages. #147

Open
pipermerriam opened this issue Feb 13, 2019 · 6 comments

Comments

@pipermerriam
Copy link
Member

What is wrong

I stumbled across ethereum/web3.py#1242 and though: "Wouldn't it be neat if we could distribute smart contract packages in a first class way from using python packaging."

Which made me think of how pytest does it for plugins.

https://docs.pytest.org/en/latest/writing_plugins.html#making-your-plugin-installable-by-others

So suppose that we used the same API. Here's a sketch of how it might work.

Suppose we create a new project, vyper-registry. It's a python package that contains the various manifests for the vyper implementation of the registry contract. That package would ship with those JSON documents as part of the files it installs. Here's a simple example source tree.

vyper_registry
└── assets
    ├── 1.0.0.json
    └── 1.1.0.json

So this is nice and all, and from another library like web3.py we could get at the by 1) knowing where they are and 2) loading them from the filesystem. This works for individual cases, but it fails as a general solution since you have to know how the files are laid out and each project does this differently.

This is where setuptools entry points come in. Here's a simple idea of what this might looks like in the setup.py of the vyper-registry package.

#  ./setup.py file
from setuptools import setup

setup(
    name="vyper_registry",
    packages=["vyper_registry"],
    # the following is what would make the plugin available to py-ethpm
    entry_points={"ethpm11": ["./assets/1.0.0.json", "./assets/1.1.0.json"]},
)

The specifics of the various strings don't matter much at this point. ethpm11 could really be any string as long as we are pretty sure it isn't going to accidentally collide with some other project. The file paths could also be any strings we wanted as long as they allowed py-ethpm to find the manifests.

I haven't dug into the distutils APIs to figure out how we get at these entry points but... lets pretend it looks something like this.

# this isn't real code, I don't know what the actual `distutils` APIs are.
from distutils import get_entry_points

def get_from_python_package(identifier):
    all_entry_points = get_entry_points("ethpm11")
    manifest = ... # filter and find the *right* one.
    return manifest

With this, a project like web3 could then do the following.

from ethpm import get_package

manifest = get_from_python_package('vyper-registry>=1.1.0,<2')

# do things with it...

Whatcha think?

@pipermerriam
Copy link
Member Author

pipermerriam commented Feb 13, 2019

Maybe instead of a special API it might just be a different URI format that could be used with the primary package retrieval APIs

@njgheorghita
Copy link
Contributor

Is this more or less a better/more efficient way to install any # of packages, as opposed to fetching them via an on-chain registry?

@pipermerriam
Copy link
Member Author

It's worse or not clearly better than using an on-chain registry if you only want the manifest. However, suppose the python package ships with some python classes that wrap the Contract APIs (custom classes that add convenience methods). In that model, having the manifests available via this mechanism allow them to be delivered alongside that python code.

BTW, I'm in no way convinced this is something that should be prioritized, just an idea that I wanted to write down.

@pipermerriam
Copy link
Member Author

After a bit more thought, I think this mechanism is objectively better in cases like web3.py where

  • there is a contract API we want to interact with
  • we want to use an ethpm manifest to interface with the contract (i.e. to get the proper contract address and ABI).
  • we need the manifest to be reliably available to the library code, i.e. we can't or don't want to rely on fetching the manifest from a registry.

I think in this case, it is superior.

@njgheorghita
Copy link
Contributor

suppose the python package ships with some python classes that wrap the Contract APIs (custom classes that add convenience methods).

Ahh yes that seems like it could be very useful

@pipermerriam
Copy link
Member Author

https://setuptools.readthedocs.io/en/latest/pkg_resources.html#basic-workingset-methods

import pkg_resources

pkg_resources.iter_entry_points('ethpm11')

That returns a generator of whatever entry points have been declared under the given name.

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

No branches or pull requests

2 participants