diff --git a/.gitignore b/.gitignore index 5d381cc..50d0a68 100644 --- a/.gitignore +++ b/.gitignore @@ -160,3 +160,4 @@ cython_debug/ # option (not recommended) you can uncomment the following to ignore the entire idea folder. #.idea/ +secrets \ No newline at end of file diff --git a/amarillo/app/services/__init__.py b/amarillo/app/services/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/amarillo/app/services/secrets.py b/amarillo/app/services/secrets.py new file mode 100644 index 0000000..c3c85bb --- /dev/null +++ b/amarillo/app/services/secrets.py @@ -0,0 +1,14 @@ +from typing import Dict +from pydantic import Field +from pydantic_settings import BaseSettings + +# Example: secrets = { "mfdz": "some secret" } +class Secrets(BaseSettings): + ride2go_token: str = Field(None, env = 'RIDE2GO_TOKEN') + metrics_user: str = Field(None, env = 'METRICS_USER') + metrics_password: str = Field(None, env = 'METRICS_PASSWORD') + + +# Read if file exists, otherwise no error (it's in .gitignore) +secrets = Secrets(_env_file='secrets', _env_file_encoding='utf-8') + diff --git a/amarillo/main.py b/amarillo/main.py new file mode 100644 index 0000000..461b8de --- /dev/null +++ b/amarillo/main.py @@ -0,0 +1,107 @@ +import logging.config + +# from app.configuration import configure_enhancer_services, configure_services, configure_admin_token + +logging.config.fileConfig('logging.conf', disable_existing_loggers=False) +logger = logging.getLogger("main") + +import uvicorn +import mimetypes +from starlette.staticfiles import StaticFiles + + +# from app.routers import carpool, agency, agencyconf, metrics, region +from fastapi import FastAPI + +# https://pydantic-docs.helpmanual.io/usage/settings/ +# from app.views import home + +# from prometheus_fastapi_instrumentator import Instrumentator +# from prometheus_fastapi_instrumentator import metrics as pfi_metrics + +logger.info("Hello Amarillo!") + +app = FastAPI(title="Amarillo - The Carpooling Intermediary", + description="This service allows carpool agencies to publish " + "their trip offers, so routing services may suggest " + "them as trip options. For carpool offers, only the " + "minimum required information (origin/destination, " + "optionally intermediate stops, departure time and a " + "deep link for booking/contacting the driver) needs to " + "be published, booking/contact exchange is to be " + "handled by the publishing agency.", + version="0.0.1", + # TODO 404 + terms_of_service="http://mfdz.de/carpool-hub-terms/", + contact={ + # "name": "unused", + # "url": "http://unused", + "email": "info@mfdz.de", + }, + license_info={ + "name": "AGPL-3.0 License", + "url": "https://www.gnu.org/licenses/agpl-3.0.de.html", + }, + openapi_tags=[ + { + "name": "carpool", + # "description": "Find out more about Amarillo - the carpooling intermediary", + "externalDocs": { + "description": "Find out more about Amarillo - the carpooling intermediary", + "url": "https://github.com/mfdz/amarillo", + }, + }], + servers=[ + { + "description": "DABB bbnavi Amarillo service", + "url": "https://amarillo.bbnavi.de" + }, + { + "description": "Demo server by MFDZ", + "url": "https://amarillo.mfdz.de" + }, + { + "description": "Dev server for development", + "url": "https://amarillo-dev.mfdz.de" + }, + { + "description": "Localhost for development", + "url": "http://localhost:8000" + } + ], + redoc_url=None + ) + +# app.include_router(carpool.router) +# app.include_router(agency.router) +# app.include_router(agencyconf.router) +# app.include_router(region.router) +# app.include_router(metrics.router) + + +# instrumentator = Instrumentator().instrument(app) +# instrumentator.add(pfi_metrics.default()) +# instrumentator.add(metrics.amarillo_trips_number_total()) + + +# instrumentator.instrument(app) + +# def configure(): +# configure_admin_token() +# configure_services() +# configure_routing() + + +# def configure_routing(): +# mimetypes.add_type('application/x-protobuf', '.pbf') +# app.mount('/static', StaticFiles(directory='static'), name='static') +# app.mount('/gtfs', StaticFiles(directory='data/gtfs'), name='gtfs') +# app.include_router(home.router) + + +if __name__ == "__main__": + # configure() + uvicorn.run(app, host="0.0.0.0", port=8000) +else: + # configure() + pass diff --git a/amarillo/plugin_discovery.ipynb b/amarillo/plugin_discovery.ipynb new file mode 100644 index 0000000..830d6b4 --- /dev/null +++ b/amarillo/plugin_discovery.ipynb @@ -0,0 +1,121 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Test notebook for discovering and importing plugins" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'amarillo.plugins.metrics': }" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import importlib\n", + "import pkgutil\n", + "\n", + "import amarillo.plugins # FIXME this namespace does not exist if there are 0 plugins installed\n", + "\n", + "def iter_namespace(ns_pkg):\n", + " # Source: https://packaging.python.org/guides/creating-and-discovering-plugins/\n", + " return pkgutil.iter_modules(ns_pkg.__path__, ns_pkg.__name__ + \".\")\n", + "\n", + "discovered_plugins = {\n", + " name: importlib.import_module(name)\n", + " for finder, name, ispkg\n", + " in iter_namespace(amarillo.plugins)\n", + "}\n", + "\n", + "discovered_plugins" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['__name__',\n", + " '__doc__',\n", + " '__package__',\n", + " '__loader__',\n", + " '__spec__',\n", + " '__path__',\n", + " '__file__',\n", + " '__cached__',\n", + " '__builtins__',\n", + " 'metrics',\n", + " 'json',\n", + " 'logging',\n", + " 'os',\n", + " 'random',\n", + " 'Callable',\n", + " 'APIRouter',\n", + " 'HTTPException',\n", + " 'Depends',\n", + " 'Request',\n", + " 'datetime',\n", + " 'generate_latest',\n", + " 'Gauge',\n", + " 'Counter',\n", + " 'Info',\n", + " 'FastAPI',\n", + " 'HTTPBasic',\n", + " 'HTTPBasicCredentials',\n", + " 'PlainTextResponse',\n", + " 'secrets',\n", + " 'logger',\n", + " 'security',\n", + " 'amarillo_trips_number_total',\n", + " 'router']" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "metrics = discovered_plugins['amarillo.plugins.metrics']\n", + "\n", + "metrics.__dir__()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.2" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..6194a94 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,21 @@ +[project] +name = "amarillo-core" +version = "0.0.1" +dependencies = [ + "fastapi[all]==0.104.0", + "geopandas==0.14", + "uvicorn[standard]==0.23.2", + "pydantic[dotenv]==2.4.2", + "protobuf==3.20.3", + "rtree==1.1.0", + "schedule==1.2.1", + "setproctitle==1.3.3", + "starlette", + "pandas==2.1.1", + "requests==2.31.0", + "Shapely==2.0.2", + "pygeos==0.14", + "pyproj==3.6.1", + "geojson-pydantic==1.0.1", + "watchdog==3.0.0" +] \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..2479778 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,16 @@ +fastapi[all]==0.104.0 +geopandas==0.14 +uvicorn[standard]==0.23.2 +pydantic[dotenv]==2.4.2 +protobuf==3.20.3 +rtree==1.1.0 +schedule==1.2.1 +setproctitle==1.3.3 +starlette +pandas==2.1.1 +requests==2.31.0 +Shapely==2.0.2 +pygeos==0.14 +pyproj==3.6.1 +geojson-pydantic==1.0.1 +watchdog==3.0.0 \ No newline at end of file