Skip to content

Latest commit

 

History

History
175 lines (116 loc) · 7.76 KB

File metadata and controls

175 lines (116 loc) · 7.76 KB
title Python
description Turn a Python module into a remotely callable backend service with Graftcode Gateway - no frameworks, no REST routes, no OpenAPI specs. Any public method becomes instantly available to call from any language.

Goal

Turn a Python module into a remotely callable backend service using Graftcode Gateway - no frameworks, no REST routes, no OpenAPI specs needed.

What You'll See

  • Create a small Python module with public methods.
  • Host it through Graftcode Gateway using Docker.
  • Explore the exposed methods in Graftcode Vision - your service is now accessible from any app as a strongly-typed client.

Prerequisites

  • Docker installed and running
  • Python only if you run the PyPI consumer locally - Docker alone is enough to build and host the service

Step 1. Create a project folder

Create a new folder and initialize a Python project:

mkdir py-energy-service
cd py-energy-service

Step 2. Write a Python module with public methods

Create a file energy_price_calculator.py:

import random

class EnergyPriceCalculator:
    @staticmethod
    def get_price() -> int:        
        return random.randint(100, 104)

Create module meta data file pyproject.toml:

[project]
name = "energy-service"
version = "1.0.0"
requires-python = ">=3.8"
description = "Test module for local directory analysis"

This is a plain Python class - no decorators, no frameworks, no special annotations. Any public method you write here will automatically become available for remote consumption once hosted through Graftcode Gateway.

Step 3. Host it with Graftcode Gateway

Create a Dockerfile in the project root:

FROM python:3.13-bookworm

WORKDIR /usr/app

COPY ./energy_price_calculator.py /usr/app/energy-service/
COPY ./pyproject.toml /usr/app/energy-service/

RUN apt-get update \
 && apt-get install -y wget \
 && wget -O /usr/app/gg.deb https://github.com/grft-dev/graftcode-gateway/releases/latest/download/gg_linux_amd64.deb \
 && dpkg -i /usr/app/gg.deb \
 && rm /usr/app/gg.deb \
 && apt-get clean \
 && rm -rf /var/lib/apt/lists/*

EXPOSE 80
EXPOSE 81

CMD ["gg","--modules","./energy-service/"]

The key line is the last one - gg (Graftcode Gateway) reads the module directory passed via --modules (./energy-service/, which includes your pyproject.toml), discovers all public methods in your module, and exposes them automatically. Port 80 handles service calls, port 81 serves Graftcode Vision.

  • FROM python:3.13-bookworm - Uses the official Python 3.13 image as the base runtime environment.
  • COPY ./energy_price_calculator.py /usr/app/energy-service/ and COPY ./pyproject.toml /usr/app/energy-service/ - Copies the module source and pyproject.toml into /usr/app/energy-service/ inside the container.
  • RUN apt-get update && apt-get install -y wget - Installs tools needed to download Graftcode Gateway.
  • wget -O /usr/app/gg.deb ... && dpkg -i /usr/app/gg.deb - Downloads and installs the latest Graftcode Gateway package.
  • EXPOSE 80 - Declares the port used for service communication (Grafts connect here).
  • EXPOSE 81 - Declares the port used by Graftcode Vision, the live portal for exploring and testing exposed methods.
  • CMD ["gg", "--modules", "./energy-service/"] - Runs Graftcode Gateway. --modules points Gateway at the module directory to analyze; it discovers public methods and makes them callable. --modules is optional when the same directory as gg contains only one target module.

Build and run the container:

docker build --no-cache --pull -t myenergyservice-py:test .
docker run -d -p 80:80 -p 81:81 --name graftcode_demo_py myenergyservice-py:test

Your Python service is now running and exposed through Graftcode Gateway.

Step 4. Explore the service in Graftcode Vision

Open http://localhost:81/GV in your browser.

You will see all public methods from your Python module - their names, parameter types, and return types. Graftcode Vision also provides:

  • A "Try it out" button to call methods live, directly from the browser.
  • A package manager command (npm, NuGet, PyPI, etc.) to install this service as a strongly-typed client in any other application.

Step 5. Run with a Project Key (recommended for real-world usage)

Everything above works without any account - perfect for learning and local development. When you're ready for real-world usage, create a free account at portal.graftcode.com, set up a project, and copy its Project Key.

Then pass the key when starting your gateway:

CMD ["gg", "--modules", "./energy-service/", "--projectKey", "YOUR_PROJECT_KEY"]

A Project Key gives you:

  • Stable registry URL - consumers always find and update your Graft through a permanent address, so install commands don't change when you redeploy.
  • Portal visibility - see all your gateways and exposed services in one place at gateways.graftcode.com.
  • Access control - decide who can download your Grafts using package manager authentication and permissions.
  • MCP endpoint - Graftcode Gateway automatically exposes an MCP (Model Context Protocol) endpoint alongside your service, making your methods callable by AI agents and LLM-based tools out of the box.

Step 6. Call it from another app

Your service is now accessible from any application. From Graftcode Vision, select your target package type - for example PyPI - and copy the generated install command. That installs a Graft: a strongly-typed client that lets any app call your service methods directly.

Use the package and import paths from Vision or Gateway logs (for this sample the package is typically graft-pypi-energy-service==1.0.0). get_price() is synchronous and returns an int:

from graft_pypi_energy_service.energy_price_calculator import EnergyPriceCalculator
from graft_pypi_energy_service.graft_config import GraftConfig

GraftConfig.host = "ws://localhost:80/ws"

price = EnergyPriceCalculator.get_price()
print(price)

The generated PyPI Graft uses a flat module layout: import energy_price_calculator and graft_config (snake_case file names), not a nested energypricecalculator path.

No REST clients, no request/response models, no endpoint URLs in your code. When you add or update a public method, consumers update their Graft with a single package manager command.

Without Graftcode

Exposing backend logic for remote consumption typically requires:

  • Designing and implementing REST or gRPC endpoints for each operation
  • Defining request and response DTOs / schemas
  • Writing or generating an OpenAPI / Protobuf spec
  • Building or generating client SDKs for each consumer technology
  • Maintaining and versioning the API contract over time
  • Updating all clients whenever the backend changes

With Graftcode

  • Write your business logic as plain public methods - no frameworks, no routes, no specs
  • Run it on Graftcode Gateway with one Dockerfile
  • Consumers install a typed Graft via their package manager and call methods directly
  • When you add or change a method, consumers update with one command - like any other dependency

Your Python module is now a fully accessible backend service - with one Dockerfile and two commands. Any public method you add is instantly discoverable and callable from any language and any platform. No endpoint design, no client SDK maintenance, no integration code.

Old Way vs Graftcode