picoapi icon indicating copy to clipboard operation
picoapi copied to clipboard

Error when service registration: TypeError: on_event() takes 2 positional arguments but 3 were given

Open BertKiv opened this issue 2 years ago • 4 comments

I am using Docker and docker-compose and cannot register a slave service. What am I doing wrong? Api Gateway (main service) works like a charm but slave service registration fails.

I am not a FastAPI and Python master ;-)

Service main.py:

from picoapi import PicoAPI
from core.config import settings

app = PicoAPI(
	title		= settings.API_TITLE,
	description	= settings.API_DESCRIPTION,
	version		= settings.API_VERSION,
	docs_url	= settings.API_DOCS_URL,
	responses	= {404: {"description": "Not found"}},
)


@app.get("/")
async def info():
	"""
	Info about API documentation.
	"""
	return { "message": "Welcome in %s microservice, version: %s. For more information go to /docs." % ( app.title, app.version ) }

.env file:

# API config
# ==========
API_TITLE="Example Service"
API_DESCRIPTION="Simple SaaS Boilerplate Example Service"
API_VERSION="0.0.1-alpha"
API_DOCS_URL="/docs"

API_BIND="0.0.0.0"
API_HOST="example-service"
API_PORT="8001"
API_TITLE="Example FastAPI Service"
API_TAGS="slave:microservice"

# microservice registration
# =========================
API_REGISTER_PATH="http://api-gateway:8000/register"
API_HEALTH_PATH="/health"
API_HEALTH_INTERVAL="300"

Dockerfiles:

FROM python:3.8.12

ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONBUFFERED 1
ENV PYTHONPATH=/app

RUN mkdir /app
WORKDIR /app/
ADD . /app

RUN pip install --no-cache-dir --upgrade pip
RUN pip install -r requirements.dev.txt --no-cache-dir

EXPOSE 8000

docker-compose.yml

version: '3.8'

services:
  api-gateway:
    image: api_gateway:dev
    build:
      context: ./app/api_gateway
      dockerfile: Dockerfile
    env_file:    
      - ./app/api_gateway/.env
    ports:    
      - 8000:8000
    volumes:    
      - ${PWD}/app/api_gateway/:/app
    command: sh -c "uvicorn main:app --reload --host 0.0.0.0"
    networks:
      - app


  example-service:
    image: example-service:dev
    build:
      context: ./app/custom_services/example_service
      dockerfile: Dockerfile
    env_file:    
      - ./app/custom_services/example_service/.env
    ports:    
      - 8001:8000
    volumes:    
      - ${PWD}/app/custom_services/example_service/:/app
    depends_on:
      - "api-gateway"
    command: sh -c "uvicorn main:app --reload --host 0.0.0.0"
    networks:
      - app

networks:
  app:
    external: true

Error:

example-service_1  | Traceback (most recent call last):
example-service_1  |   File "/usr/local/lib/python3.8/multiprocessing/process.py", line 315, in _bootstrap
example-service_1  |     self.run()
example-service_1  |   File "/usr/local/lib/python3.8/multiprocessing/process.py", line 108, in run
example-service_1  |     self._target(*self._args, **self._kwargs)
example-service_1  |   File "/usr/local/lib/python3.8/site-packages/uvicorn/subprocess.py", line 76, in subprocess_started
example-service_1  |     target(sockets=sockets)
example-service_1  |   File "/usr/local/lib/python3.8/site-packages/uvicorn/server.py", line 68, in run
example-service_1  |     return asyncio.run(self.serve(sockets=sockets))
example-service_1  |   File "/usr/local/lib/python3.8/asyncio/runners.py", line 44, in run
example-service_1  |     return loop.run_until_complete(main)
example-service_1  |   File "/usr/local/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete
example-service_1  |     return future.result()
example-service_1  |   File "/usr/local/lib/python3.8/site-packages/uvicorn/server.py", line 76, in serve
example-service_1  |     config.load()
example-service_1  |   File "/usr/local/lib/python3.8/site-packages/uvicorn/config.py", line 448, in load
example-service_1  |     self.loaded_app = import_from_string(self.app)
example-service_1  |   File "/usr/local/lib/python3.8/site-packages/uvicorn/importer.py", line 21, in import_from_string
example-service_1  |     module = importlib.import_module(module_str)
example-service_1  |   File "/usr/local/lib/python3.8/importlib/__init__.py", line 127, in import_module
example-service_1  |     return _bootstrap._gcd_import(name[level:], package, level)
example-service_1  |   File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
example-service_1  |   File "<frozen importlib._bootstrap>", line 991, in _find_and_load
example-service_1  |   File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
example-service_1  |   File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
example-service_1  |   File "<frozen importlib._bootstrap_external>", line 843, in exec_module
example-service_1  |   File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
example-service_1  |   File "/app/./main.py", line 4, in <module>
example-service_1  |     app = PicoAPI(
example-service_1  |   File "/usr/local/lib/python3.8/site-packages/picoapi/api.py", line 85, in __init__
example-service_1  |     self.router.on_event("startup", register_uservice)
example-service_1  | TypeError: on_event() takes 2 positional arguments but 3 were given

What I was checking

When I change the slave service from PicoAPI to FastAPI and manually register with CUrl everything looks fine.

curl -X 'GET' \
  'http://api-gateway:8000/register' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
  "name": "Example Service",
  "tags": [
    "slave:service"
  ],
  "host": "example-service",
  "port": 8001,
  "metadata": {},
  "healthcheck": {
    "url": "/health",
    "interval": 300
  }
}'

result: null

Checking status from gateway:

curl -X 'GET' 'http://api-gateway:8000/services/status' -H 'accept: application/json'

Result:

[{"name":"Example Service","status":"unhealthy"}]

"status": "unhealthy" has no meaning as there is no /health endpoint.

BertKiv avatar Oct 21 '21 19:10 BertKiv