diff --git a/Dockerfile b/Dockerfile index 2c069213c01db9478b4c709e340c0f852ce0e38f..19dc8c5025d7f6211c0b52b6f26c7bbf7e3d5354 100644 --- a/Dockerfile +++ b/Dockerfile @@ -46,4 +46,5 @@ COPY --chown=python:python . . EXPOSE 8000 -CMD ["gunicorn", "-k", "uvicorn.workers.UvicornWorker", "-c", "python:config.gunicorn", "hydws.main:app"] +# CMD ["gunicorn", "-k", "uvicorn.workers.UvicornWorker", "-c", "python:config.gunicorn", "hydws.main:app"] +CMD ["uvicorn", "hydws.main:app", "--port", "8000", "--workers", "1", "--timeout-keep-alive", "300", "--host", "0.0.0.0"] diff --git a/config/gunicorn.py b/config/gunicorn.py index fe4b2eab7b57ff3ab40343077255c4c563439090..4d6550d6160531a8bf3d0aac12f9d8d6715b2196 100644 --- a/config/gunicorn.py +++ b/config/gunicorn.py @@ -2,13 +2,14 @@ import multiprocessing import os - from distutils.util import strtobool bind = f"0.0.0.0:{os.getenv('PORT', '8000')}" accesslog = "-" access_log_format = "%(h)s %(l)s %(u)s %(t)s '%(r)s' %(s)s %(b)s '%(f)s' '%(a)s' in %(D)sµs" # noqa: E501 +timeout = "600" + workers = int(os.getenv("WEB_CONCURRENCY", multiprocessing.cpu_count() * 2)) threads = int(os.getenv("PYTHON_MAX_THREADS", 1)) diff --git a/db/init_function.sh b/db/init_function.sh new file mode 100755 index 0000000000000000000000000000000000000000..4fa41531d77a06b9c522c063bf1cbbc1eaa29f55 --- /dev/null +++ b/db/init_function.sh @@ -0,0 +1,14 @@ +#!/bin/bash +set -e + +set -a +. .env +set +a + +psql -d $DB_NAME -U $DB_USER --host $POSTGRES_HOST -f $(pwd)/db/partition.sql +psql -d $DB_NAME -U $DB_USER --host $POSTGRES_HOST -c "CREATE OR REPLACE TRIGGER partition_daily_function + BEFORE INSERT + ON hydraulicsample + FOR EACH ROW + WHEN (pg_trigger_depth() < 1) + EXECUTE FUNCTION partition_daily_function($DB_USER);" \ No newline at end of file diff --git a/db/partition.sql b/db/partition.sql index be8268a7910d7dd8590961340dd11d2fd5e9a4d1..8c5402bf588eb700896ddcd5b43cec369ee53394 100644 --- a/db/partition.sql +++ b/db/partition.sql @@ -1,5 +1,5 @@ --- CREATE TABLE hydraulicsample_default PARTITION OF hydraulicsample DEFAULT; +CREATE TABLE hydraulicsample_default PARTITION OF hydraulicsample DEFAULT; CREATE OR REPLACE FUNCTION partition_daily_function() RETURNS TRIGGER AS $$ @@ -21,6 +21,7 @@ THEN RAISE NOTICE 'A partition has been created'; BEGIN EXECUTE format(E'CREATE TABLE %I (LIKE hydraulicsample INCLUDING INDEXES)', partition_name); + EXECUTE format(E'ALTER TABLE %I OWNER TO %s', partition_name, TG_ARGV[0]); EXECUTE format(E'NOTIFY hydraulicsample, %L', partition_date); EXCEPTION WHEN duplicate_table THEN @@ -32,10 +33,3 @@ RETURN NULL; END; $$ LANGUAGE plpgsql; - -CREATE OR REPLACE TRIGGER partition_daily_function - BEFORE INSERT - ON hydraulicsample - FOR EACH ROW - WHEN (pg_trigger_depth() < 1) -EXECUTE FUNCTION partition_daily_function(); diff --git a/hydws/datamodel/base.py b/hydws/datamodel/base.py index afa8760ff004d45ba7396fc98121adbde5bc7750..01ee1adf2e476e10eb768808bf39b337f8c886b1 100644 --- a/hydws/datamodel/base.py +++ b/hydws/datamodel/base.py @@ -1,10 +1,10 @@ -import psycopg2 import asyncio import enum import functools import uuid from datetime import datetime, timedelta +import psycopg2 from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT from sqlalchemy import (Boolean, Column, DateTime, Float, Integer, String, create_engine) diff --git a/hydws/main.py b/hydws/main.py index ec0c5e37c878f447df78b33b56a8cb0cbcae6ad2..12a75d5259cfcf6d3ed3a3f5c7755455e26f3eb3 100644 --- a/hydws/main.py +++ b/hydws/main.py @@ -1,9 +1,23 @@ +# import logging + from fastapi import FastAPI +# from fastapi.logger import logger as fastapi_logger from fastapi.middleware.cors import CORSMiddleware -from hydws.datamodel.base import ORMBase, engine +from hydws.datamodel.base import ORMBase, engine from hydws.routers.v1 import boreholes +# gunicorn_error_logger = logging.getLogger("gunicorn.error") +# gunicorn_logger = logging.getLogger("gunicorn") +# uvicorn_access_logger = logging.getLogger("uvicorn.access") +# uvicorn_access_logger.handlers = gunicorn_error_logger.handlers + +# fastapi_logger.handlers = gunicorn_error_logger.handlers + +# if __name__ != "__main__": +# fastapi_logger.setLevel(gunicorn_logger.level) +# else: +# fastapi_logger.setLevel(logging.DEBUG) ORMBase.metadata.create_all(bind=engine) diff --git a/requirements.txt b/requirements.txt index e4e872af7d29250769df677c45d539b1b5ddcc6f..6f782a6c3307f2433c9b4bbc2b12cc5be56021e3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,6 +3,7 @@ autopep8>=1.6.0 fastapi[all]>=0.92.0 flake8>=4.0.1 gunicorn>=20.1.0 +orjson>=3.9.0 pandas>=2.0.0rc1 psycopg2>=2.9.3 pytest>=7.0.1