Create CPython components using Hops in Grasshopper

Thanks, Steve. I copied the script from the Github repo and I’m getting the same error. I also have Python 3.7.2 installed, but 3.9.1 is set as the interpreter in VSCode. Not sure if that makes a difference.

Here was the script I originally used:

from flask import Flask
import ghhops_server as hs
import rhino3dm

app = Flask(__name__)
hops = hs.Hops(app)

    @hops.component(
        "/pointat",
        name="PointAt",
        description="Get point along curve",
        icon="pointat.png",
        inputs=[
            hs.HopsCurve("Curve", "C", "Curve to evaluate"),
            hs.HopsNumber("t", "t", "Parameter on Curve to evaluate"),
        ], 
        outputs=[
            hs.HopsPoint("p", "p", "Point on curve at t"),
            ],
    )
    def pointat(curve, t):
        return curve.PointAt(t)

    if __name__ == "__main__":
        app.run()

When I open the URL in the browser VSCode reports the following:
[INFO] 127.0.0.1 - - [17/Mar/2021 09:07:17] "GET /pointat HTTP/1.1" 200 -

No message is shown when adding the path to the Hops component. Alternatively, when I change HTTP to HTTPS in the Hops component I get the following in VSCode:

[ERROR] 127.0.0.1 - - [17/Mar/2021 09:07:41] code 400, message Bad request version ("Ä<\x98AÔdì2y©ïÔ\x00\x00*À,À+À0À/\x00\x9f\x00\x9eÀ$À#À(À'À")
[INFO] 127.0.0.1 - - [17/Mar/2021 09:07:41] "▬♥♥☺♥`Qÿ↔½Á♣ëKzè¦∟^-¾:       Ä<dì2y©ïÔ*À,À+À0À/$À#À(À'À" HTTPStatus.BAD_REQUE
ST -

Which makes sense. Just not sure why nothing happens with HTTP. I checked my Firewall just in case and opened port 5000, but no change.

If you go to http://localhost:5000/ in your browser with this python script running, do you get a bunch of text back? This text should look something like

[{“Description”: “Get point along curve”, “Inputs”: [{“Name”: “Curve”, “Nickname”: “C”, “Description”: “Curve to evaluate”, “ParamType”: “Curve”, “ResultType”: “Rhino.Geometry.Curve”, “AtLeast”: 1, “AtMost”: 1}, {“Name”: “t”, “Nickname”: “t”, “Description”: “Parameter on Curve to evaluate”, “ParamType”: “Number”, “ResultType”: “System.Double”, “AtLeast”: 1, “AtMost”: 1}], “Outputs”: [{“Name”: “p”, “Nickname”: “p”, “Description”: “Point on curve at t”, “ParamType”: “Point”, “ResultType”: “Rhino.Geometry.Point3d”, “AtLeast”: 1, “AtMost”: 1}]}]

My mistake; I forgot that you need to explicitly push both a V8 version to the package manager in order for Hops to show up in V8. @will, I’m assuming this is still the case that I need to perform two pushes to the package manager for V7 and V8.

I just put a V8 version upon the package manager; please let me know if it works for you.

Yes, with the Python script from the Github Repo, I get this response at http://localhost:5000/

[{"Description": null, "Inputs": [{"Name": "A", "Nickname": null, "Description": null, "ParamType": "Number", "ResultType": "System.Double", "AtLeast": 1, "AtMost": 1}, {"Name": "B", "Nickname": null, "Description": null, "ParamType": "Number", "ResultType": "System.Double", "AtLeast": 1, "AtMost": 1}], "Outputs": [{"Name": "Multiply", "Nickname": null, "Description": null, "ParamType": "Number", "ResultType": "System.Double", "AtLeast": 1, "AtMost": 1}]}, {"Description": "Add numbers with CPython", "Inputs": [{"Name": "A", "Nickname": "A", "Description": "First number", "ParamType": "Number", "ResultType": "System.Double", "AtLeast": 1, "AtMost": 1}, {"Name": "B", "Nickname": "B", "Description": "Second number", "ParamType": "Number", "ResultType": "System.Double", "AtLeast": 1, "AtMost": 1}], "Outputs": [{"Name": "Sum", "Nickname": "S", "Description": "A + B", "ParamType": "Number", "ResultType": "System.Double", "AtLeast": 1, "AtMost": 1}]}, {"Description": "Get point along curve", "Inputs": [{"Name": "Curve", "Nickname": "C", "Description": "Curve to evaluate", "ParamType": "Curve", "ResultType": "Rhino.Geometry.Curve", "AtLeast": 1, "AtMost": 1}, {"Name": "t", "Nickname": "t", "Description": "Parameter on Curve to evaluate", "ParamType": "Number", "ResultType": "System.Double", "AtLeast": 1, "AtMost": 1, "Default": 0.0}], "Outputs": [{"Name": "P", "Nickname": "P", "Description": "Point on curve at t", "ParamType": "Point", "ResultType": "Rhino.Geometry.Point3d", "AtLeast": 1, "AtMost": 1}], "Icon": "iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAAHdElNRQfgCRALOQ37+ZoqAAAAB3RFWHRBdXRob3IAqa7MSAAAAAx0RVh0RGVzY3JpcHRpb24AEwkhIwAAAAp0RVh0Q29weXJpZ2h0AKwPzDoAAAAOdEVYdENyZWF0aW9uIHRpbWUANfcPCQAAAAl0RVh0U29mdHdhcmUAXXD/OgAAAAt0RVh0RGlzY2xhaW1lcgC3wLSPAAAACHRFWHRXYXJuaW5nAMAb5ocAAAAHdEVYdFNvdXJjZQD1/4PrAAAACHRFWHRDb21tZW50APbMlr8AAAAGdEVYdFRpdGxlAKju0icAABDLSURBVGhDNdkFsFVlFAXg/d4RG8UWi7ADCyQsEFHEwMZCERMLlQEMZvSogAXqKMZgg4kKKgo2CKJgd7egGBiIifo83545d+bNu+/cc/5/77XXWnv/9zXsvPPOTUVRxFJLLRU//fRTLLfccvHRRx/FeuutF6usskr+fvrpp2PJJZeMXXfdNdZYY4245ZZborGxMU466aT45ptvYvfdd48hQ4bERhttFJ988klstdVW+fmiRYvi3Xffje+//z769u0bn332WSxYsCBatGgRF1xwQZRlGQceeGBcfPHF0aVLl/j444/j+uuvj4ULF8aRRx4Zyy67bDQ0NMQ+++wTL7zwQnzwwQex5ZZbxk033RQXXnhhvPTSS9Hoph9++CF++eWXWLx4cay77rqxww475INVcrH++uvHyiuvHKuuumrce++9MW3atDj88MMzuIkTJ8Zrr72WAT3wwAOZpOc7d+4c//33X667/PLLR48ePeLxxx+PTz/9ND7//PMAGHA6dOiQ673xxhuxyy67xEorrRTXXHNNDB06NLbZZpto2bJlbLzxxvHee+/Fn3/+GRtssEHGImYJNW/ePBo322yzOPnkkxOBFVZYIbPcdtttE7V///03pk+fnpWB7GqrrZbBCPqggw6KP/74I+bOnRvDhw/PAAT7yiuvZBDu8YLY6quvHl999VVWxvtvv/02g7ntttuiWbNm8eqrr8aaa66ZFfjtt99i6623TgDcZ4899tgjq6SCBx98cPz66695/++//x5FFVT59ttvR8eOHePLL7+MVq1aRadOnfLhOXPmZCWOOeaYePnll2PfffeNqVOnZtBHH310PP/889G2bdv4+++/M9hNN900KShI16B9/PHHZ3UlJtATTjgh11YFlfvxxx/z/WWXXRZdu3ZNukoKaOgKMPuj6DLLLJMgAee5555LEIp11lmnFHTv3r3jrbfeShTQoVu3brmIcr3//vtZbu/nz5+fv5Ue6v/880+WXuBvvvlmUkOCXrvttltcccUVMW/evKzwWWedlagLuk+fPklDSKOHykvaNfr57rvvEmm/VZj+JLr22mvHnXfemcnQUyPxqsDs2bOjXbt2KUol3HDDDRORpZdeOn7++ecUEh4r2+DBg5Pn3bt3z6BdV0Gcfeyxx3ITgaga3Qjk9ddfT5S33377XBsgAvr666+Tz23atEnxMgLv0RkoTODQQw9NYN95550YN25cxmAN9CoqsZQQJVg3KT93mDVrVorrgAMOyBsnT56cNBAAChBkU1NTBgzlqpIpMMjMmDEjllhiiaSUJIhecK5JDM+fffbZDK5169ZxzjnnxH333ZcAqjAAAckN0cieYsSQQw45JMULELEWO+20U0nlzzzzTFZBUErvN6uyKFE/+uij0a9fv3wPPYGNGjUqRS44ZiAxz9IOWtIUiyXqTTbZJKlhXZS0Dqf58MMP85pkoE5zgpMAGgsSQ9ByxRVXzJ/Ro0fH5ZdfnpUtqmxLiCgX2/OAlwXQgjVSvuD0BAJCC0hJWuAVCHHllVfGiy++mCIkWtWgq5rfAwYMyEAEOXDgwKzE7bffnkIkyD333DO1IkAVoY2HHnoodUgzkiV6OrK/eFLEFd9K5YeiTXFbYL169coNHnzwwVwM73bccceYNGlSbLHFFkkroqMR3H/iiSfyPVELhHN4VtAQ5liCAcAjjzySBkB/Z5xxRtKRWAXldccdd2RP8iyU0Qg1H3744bTPJ598MiviuaIKuMR9iBKl4FAAIioiYGWFMiQEwwotZBPefuuttyYAqnjYYYdlFxXk1VdfHZtvvnlWRkOkM0laj770GUJGLcmouoqzaGtwNE6jgmjHQlXcWgBlAEUVQGkBwfiBhBaNs9zhqquuSq+fMGFCPqxKRKTR4apuLCni2n///TMQwduQfiSgguPHj8+A1lprrQTIbxWxlyaJOpwFCOLx89RTT2Xz5D5i03CZBm0aOaxfVKiXsrGYjoc6FhWIjC0EEdzTVLiHLsw98NimKIOfhM6v99prr7zviy++yHU5mutcpGfPnukymiULPuWUU1JrKoOWxMxK8V9cNAUMNDKmiMs1BoFySaGam8OGDUv0iFXgAoL6ueeem+4iKOUkRIhxIAIUgGQgjYpKbHHupoqAUCX0tJcKAgXHNU0aUiFJoBl0DXmcSo9ROZRFSeBgARqqYlFlXbqA8xa+6667MigirMvrB1J0gHcCx1fBHHvssTkyWJCWIIgiPoMgnktIMoR49913Z0Wg6T5Ba5QoCSwB2uuGG25ISqIvoaMwgMVHF+YiexTbbbddKUDNghXyeL8tKFClE4B70IgznXbaaSl4iXMDDqTskBQkvt544435HnqSYq0qh2q6ut6gWkSsctxLwmgHnHvuuSd1JTnTMZBUiyuZjHVrVW+ouNkkEJRBHUjhmekRb1Vm5syZOX+gAO7pFYMGDcpzARq4Dmmez118Tow0ZWMDILeiFW7FfgUF8f79+6dIVc99f/31V3Z8WmSTEmMs7rWWfYCiUvZrdINyCPz+++/PNq+seoMbLKzUxGo0hpiFDVgCrSqYSamQv7V8SCuvakFyv/32yz00I2hzFg4jSGjaa1w141gf+vqNZDkY/ZiCVRHFVdkgSeQSKSoulmYUQbdv3z75pQLKazMzCpESo9lEwmhFCwRHaFBRBZugzsiRI9N+XRM4LaGmsQG/9Rc9RRWAZN4yINIRIFk46jAPlPFeXPaxv6bIUnX3opocS9xWVsHSglZ90UUXxVFHHZULai4QcZTTlCDOg1WFFeoHksFJ7yVvVvKZwG1ufVSoG6ZKu4YK3EWSmqaKApAGgUYXqIxekgH2mWeemQDmLFSVuxSgtk/x5nat3G8P83vldo/ABYkmtYv4XCJs2KZeDiRGEhogPJuig/e0gS6e2XvvvTMQieE+XXEbtAKcQ4zjpc5PKwJmz+LwjGGvkWMQKX7iH5p4eVjQSqzkUFMZ/La5PuA6WqCOAz6klVjwkjG7QBPX0QTqeouEpkyZkhR1HweTAOAkQehGEm5FW3qA/uRE54zsmkqrcCOqEIbsiNBF9ke8Z599dpZLw9BF0cTimovzAYGhFvQhwpUkrUIoxKFQjQ4gaTrleEzAMAdtgtR3gCIwzxtPHIrEZHTmkHqQSUAjZSQ0a1QvKo6WskcNbsGqLA4di7NW4oEy8erI+oLPa7uEkITM6AJELWvxfhXU7NBCA+PfEvPbM5yF2N0nMU5EJ/RmSKQ516wpTqCiI/qhUlE1otJ3No5tMpM1+sjOQyhDCx7QtFCGDULdJpxDQhCCuvcOMw7zqqUybPK4445LQGrxCkpDVE0u47rK+9va6MhEAMQdJSpxldIM0VdyjW5SOnZoXqED7/HRPOJFqChlY62cwFRMsOgCXXMSYbM4Jzufua6bopaGSIAOR0DhNirmZYhDE/szD9XwvHEChU899dRspHwfwJLzNYuu3VCJqen8889POyO2Sy65JAXkYZz3kNGC4j3gb8gStYXYH54LCkKQUZUxY8bkxl4+lzwq0o0T2YknnphBG0NQy9oYYD0HFskzBJVBHeBojhLwvp6Giwr9Euccz1zgJgYuCeG5jqeEFlJqaOGq4DmMyiizcYBOBEgrujrqqAbHQiFVFZi/PYuavmLUKDmXxgYEVBSLRiUhY4T96E9crJcxSKyoHi75NlXjaD1re9CPahCbBTkO/teHDKgrO72gh0DYoiq4xzxFcNDXpHRblfEc+xass4UeBCTXxIDGkPacwIGmqtbzrD0AJc5GgdiMK/Bn5faQVo2HbMwg5gGbOxEJEJIW5kA25D5cCU14NZQh7DDifnqCrEraS5WJlvjpyN++7EIrPYm1i8dI4prgJeiswGKhT9gNVVBNBAJhiTgtsVIjBa5deumluZBeoEq4r2MLQuWIU9AoqNGgjeuCEqBNcFcj8kJRn6Ob/WiKDjgXICRhpPHS/Hi/UYedoybu6+SGSYAWVRlLKCiZH9n5+g/3oa8nQFoDgbYvrbiQ74Q0PdaqOtwCjZRXUF7W8pzr1113XaIscPpQIZxni5qXE5m9uAsGSBxlGYs1VR4FJU13QNNciyrzUsMxdOGZL698L6P0AqEDv9GAS3hJFKqQNIaghgMKyuknFkYnlawbmueZhQoTPUqxVwBAH0VYtEqyWLRl74yDaKGvRzCCWq800lCdTZuMr9o5WpgAOQQKyJxIUcZC9OHAgm7Q1aSIlI6U2DO0w3YlAVFoCwYIGiYLlbyR2+gtMMmxTM3SnnqKqgKUUOkNIAI3q6ExVgCsqEpRyhC3TH0Cs4AXlHi+m+mAA/BrQxbR4qyk6IO11qOwWV+SqsddlBtNNCnURA80UEG0dAJDTc+qgvXFUgdJ+LRlXc+i5emnn55Vb6hOO00mwLFjx6ba8dpGkDFG46qXBKCsjBARrGpZFFr+1kHRhpjrsUJnlrhkACMom6OeYFGXv+M2gfP5a6+9Np/3W1IqRUeAoCGHfZpDxaISbElMHhCQwI844ogUmHGYcKDIUUaMGJGUkowgNTquoeyeJzrHQQF7xkyjG0MYDSUPPbxHM/dLxN8aniTyq5JKa/VXjtZynX26n/4AbX9NsKiyKGWibHhuA0OcIH21ojo4qtQWkyTbM8fgLJHqsqilEj43bDEBwuRwENasVLBuWNakPecDVOpfHVgELDhnBQJ1v2TEp7rorNLG7dqNimqxUmltQJBKrmwWkjHETaA2haRKSNbXezZUdokRLfszP3mvO0MXjdwHMS4kMHSQqPdefgtKwCYBTazWCJ0BVnMkfnMSCllT1YvqkJGzEL/1UkpzCQQtTKSC0Ow0LQ4gUS/JeZleiVPiRnHNxznWf3icBegIgiqDnqoiEN1U8nqKBAUObQlKRlycTBXwn77qzi8W9C2qYEoXHdEcnNkdWvi/FzRVxuDku0zXTKsaWS1SVIA8L6+Pl17sj0bQDL1Yrso5pDgrMwsUQh3akDykXZeIdRx0gMi6zVn2cQ+qOk/Qa1GJq6R2nutD4wNbJT7isqEHPCwBnVOwNKKk/o3kTOF/CvhJPwCR+HnnnZfitSZeu19VfFeEAtwOHQyL/B1QEjFDoaA962sqyKGcJ8RTn/waqjm/SQMysuoFqKKMspcl33We1R90SdqQKIrdfPPN+SWtBaGmxKqimugiWY2LJnRVSPpMU/Lj1EZbE6qzMderbRtFVJN9MgxUtT4A6UKMkgJwQ9XamyBEVBJQMnyzgWChgYt4i+u+mRAM/yY0NHCPqnlOZfxIHPqQRTN0RCsB6h0SREXVZL1GA5MARzM3obJK6Rk06Xta99Rg0w0dNCqFADzM9kyhbrKBrztYqU1wUnfV8DQyaGj/npOsctOJAFFI90Qt7uLEZXqEmuRVV5dHWxUzK7mf+PUetHG/7us+ItYfgGvAdJb2Em9RUSj/S8ktBON9/Z96FMBdJYWqQ7TFawqxtnqwg7aSAoC7uA5p6+Cvz4iaNQuIWP1NnKhpFuNMeG5EIG5xSFhFjCIcCw3F6F/BYiqqzfL/xNDANxfxD+cFazOfoYAEBWoo4/ECQzPUIEYW617V8j+ueqzQRc06ELa251BEtxWQHzRWXQCorDOBz02smhYKs28VRTnOJbGiKnl+uWtTjmJx5dSoUIPoOIcDicDrbyUkaK6hA83MP7MtqNmhF0FKRqBAQFUnLfbLJIwfzgfWsp9qCVSnNshprq6pOjpLiOvoV6jouXnz5sX/itWo5RRH2B4AAAAASUVORK5CYII="}, {"Description": "Create ruled surface from four points", "Inputs": [{"Name": "Corner A", "Nickname": "A", "Description": "First corner", "ParamType": "Point", "ResultType": "Rhino.Geometry.Point3d", "AtLeast": 1, "AtMost": 1}, {"Name": "Corner B", "Nickname": "B", "Description": "Second corner", "ParamType": "Point", "ResultType": "Rhino.Geometry.Point3d", "AtLeast": 1, "AtMost": 1}, {"Name": "Corner C", "Nickname": "C", "Description": "Third corner", "ParamType": "Point", "ResultType": "Rhino.Geometry.Point3d", "AtLeast": 1, "AtMost": 1}, {"Name": "Corner D", "Nickname": "D", "Description": "Fourth corner", "ParamType": "Point", "ResultType": "Rhino.Geometry.Point3d", "AtLeast": 1, "AtMost": 1}], "Outputs": [{"Name": "Surface", "Nickname": "S", "Description": "Resulting surface", "ParamType": "Surface", "ResultType": "Rhino.Geometry.Brep", "AtLeast": 1, "AtMost": 1}]}]

Good, so we know that part is working. Do you get the error message right after you enter http://localhost:5000/pointat in the Hops component’s path?

1 Like

Oh wow, for some reason http://localhost:5000/pointat works and loads properly with Hops in Grasshopper, but http://127.0.0.1:5000/pointat does not.

Both addresses return the same responses in the browser. :thinking:

Happy that I can use this as a workaround for now. Thanks, Steve.

Congratulation guys, this is a brilliant idea!
This will allow companies/individuals to create custom components and services and share them with others.

From what I understood, we can expose application endpoints as Grasshopper components via Hops Component.
Is it possible to share a set of components (hops server endpoints) as a plugin that collaborators could download, that would automatically load the correct URL for each endpoint?

Great to hear this is working for you now. We’ll probably need to spend a little time on stackoverflow to get a better understanding of what is happening on your system.

1 Like

Definitely not today, but I can imagine this being a long term goal for this project.

2 Likes

Sounds good. I’ll test on a couple other machines to see if I can reproduce the issue. I will loop back and update this thread if I figure it out.

Wow. Things are about to get wild in Grasshopper land.

2 Likes

Thanks, I uninstalled python 3.8 and it all worked :slight_smile:

Not sure why I had 32-bit installed in the first place…

That’s great. Thanks for letting me know

Hi, i think this error related to Python but i don’t figure how to solve it
I try to use Pymaxwell module from Maxwell render but i get this error about input file (inPath)


Update: problem solved and it is very useful :slight_smile:

What did you do to solve the problem?

I add inputs to run_maxwell_render

3 Likes

Hello, can we use PyQt6 to create a window with a button to execute the script?

Is the component used for one time?
When i save the definition with component created and try to use it again don’t work

Using http server don’t work with hops

localhost:5000/add

image

try http://localhost:5000/add

1 Like