Tribler/py-ipv8

How to interact with a community from an api/app like fastapi or flask

adagrad opened this issue · 2 comments

It is unclear to me how I am supposed to interact (send messages, await response) with the community object from a different application like a fastAPI univicon app.

async def start_communities() -> None:
    builder = ConfigBuilder().clear_keys().clear_overlays()
    # builder stuff
    await IPv8(builder.finalize(), extra_communities={'Lala': Lala}).start()
    await run_forever()


@asynccontextmanager
async def lifespan(app: FastAPI):
    print("starting communitys ... ")
    asyncio.create_task(start_communities())
    yield


app = FastAPI(lifespan=lifespan)


@app.get("/")
async def root():
    return # how can is send a message to my Lala community and return the response


if __name__ == '__main__':
    check_upgrade_yfinance()
    uvicorn.run(app, **CONFIG["api"])

Not the comment in the async def root() function.

PS I think this might also be worth to be added to the documentation

Strictly speaking, IPv8 is only a networking library (by design) and you can hook into it however you like. We do not enforce or hook in any higher-level API like Flask or FastAPI. However, if you choose to run the stand-alone ipv8_service.py, we provide a (Swagger) REST API to interact with Community instances.

If you want to adopt this approach, you'll need to spawn a RESTManager (extended to provide the desired interface for your Community) for every IPv8 instance you create:

self.ipv8 = IPv8(get_default_configuration(), enable_statistics=statistics)
await self.ipv8.start()
if not no_rest_api:
# Load the certificate/key file. A new one can be generated as follows:
# openssl req \
# -newkey rsa:2048 -nodes -keyout private.key \
# -x509 -days 365 -out certfile.pem
# cat private.key >> certfile.pem
# rm private.key
ssl_context = None
if cert_file:
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
ssl_context.load_cert_chain(cert_file)
self.restapi = RESTManager(self.ipv8)
await self.restapi.start(api_key=api_key, ssl_context=ssl_context)

By default, this opens a REST API on port 8085 and you can view the Swagger API at http://localhost:8085/docs.

You can find further information on the API key here and on the optional SSLContext here.

Thanks, that got me started.