|
1 | 1 | """
|
2 | 2 | TiMVT config.
|
3 | 3 |
|
4 |
| -TiVTiler uses starlette.config to either get settings from `.env` or environment variables |
5 |
| -see: https://www.starlette.io/config/ |
| 4 | +TiVTiler uses pydantic.BaseSettings to either get settings from `.env` or environment variables |
| 5 | +see: https://pydantic-docs.helpmanual.io/usage/settings/ |
6 | 6 |
|
7 | 7 | """
|
| 8 | +from functools import lru_cache |
| 9 | +from typing import Any, Dict, Optional |
8 | 10 |
|
9 |
| -from starlette.config import Config |
10 |
| - |
11 |
| -config = Config(".env") |
12 |
| - |
13 |
| -# API config |
14 |
| -APP_NAME = config("APP_NAME", cast=str, default="TiMVT") |
15 |
| -DEBUG = config("DEBUG", cast=bool, default=False) |
16 |
| -CORS_ORIGINS = config("CORS_ORIGINS", cast=str, default="*") |
17 |
| - |
18 |
| -# Database config |
19 |
| -DATABASE_URL = config("DATABASE_URL", cast=str, default="") |
20 |
| -if not DATABASE_URL: |
21 |
| - POSTGRES_USER = config("POSTGRES_USER", cast=str) |
22 |
| - POSTGRES_PASS = config("POSTGRES_PASS", cast=str) |
23 |
| - POSTGRES_DBNAME = config("POSTGRES_DBNAME", cast=str) |
24 |
| - POSTGRES_PORT = config("POSTGRES_PORT", cast=str) |
25 |
| - POSTGRES_HOST = config("POSTGRES_HOST", cast=str) |
26 |
| - |
27 |
| - DATABASE_URL = ( |
28 |
| - f"postgresql://{POSTGRES_USER}:" |
29 |
| - f"{POSTGRES_PASS}@{POSTGRES_HOST}:" |
30 |
| - f"{POSTGRES_PORT}/{POSTGRES_DBNAME}" |
31 |
| - ) |
32 |
| - |
33 |
| -DB_MIN_CONN_SIZE = config("DB_MIN_CONN_SIZE", cast=int, default=1) |
34 |
| -DB_MAX_CONN_SIZE = config("DB_MAX_CONN_SIZE", cast=int, default=10) |
35 |
| -DB_MAX_QUERIES = config("DB_MAX_QUERIES", cast=int, default=50000) |
36 |
| -DB_MAX_INACTIVE_CONN_LIFETIME = config( |
37 |
| - "DB_MAX_INACTIVE_CONN_LIFETIME", cast=float, default=300.0 |
38 |
| -) |
39 |
| - |
40 |
| -# Tile / Table config |
41 |
| -TILE_RESOLUTION = config("TILE_RESOLUTION", cast=int, default=4096) |
42 |
| -TILE_BUFFER = config("TILE_BUFFER", cast=int, default=256) |
43 |
| -MAX_FEATURES_PER_TILE = config("MAX_FEATURES_PER_TILE", cast=int, default=10000) |
44 |
| -DEFAULT_MINZOOM = config("DEFAULT_MINZOOM", cast=int, default=0) |
45 |
| -DEFAULT_MAXZOOM = config("DEFAULT_MAXZOOM", cast=int, default=22) |
| 11 | +import pydantic |
| 12 | + |
| 13 | + |
| 14 | +class _ApiSettings(pydantic.BaseSettings): |
| 15 | + """API settings""" |
| 16 | + |
| 17 | + name: str = "TiMVT" |
| 18 | + cors_origins: str = "*" |
| 19 | + debug: bool = False |
| 20 | + |
| 21 | + @pydantic.validator("cors_origins") |
| 22 | + def parse_cors_origin(cls, v): |
| 23 | + """Parse CORS origins.""" |
| 24 | + return [origin.strip() for origin in v.split(",")] |
| 25 | + |
| 26 | + class Config: |
| 27 | + """model config""" |
| 28 | + |
| 29 | + env_prefix = "TIMVT_" |
| 30 | + env_file = ".env" |
| 31 | + |
| 32 | + |
| 33 | +@lru_cache() |
| 34 | +def ApiSettings() -> _ApiSettings: |
| 35 | + """ |
| 36 | + This function returns a cached instance of the APISettings object. |
| 37 | + Caching is used to prevent re-reading the environment every time the API settings are used in an endpoint. |
| 38 | + If you want to change an environment variable and reset the cache (e.g., during testing), this can be done |
| 39 | + using the `lru_cache` instance method `get_api_settings.cache_clear()`. |
| 40 | +
|
| 41 | + From https://github.com/dmontagu/fastapi-utils/blob/af95ff4a8195caaa9edaa3dbd5b6eeb09691d9c7/fastapi_utils/api_settings.py#L60-L69 |
| 42 | + """ |
| 43 | + return _ApiSettings() |
| 44 | + |
| 45 | + |
| 46 | +class _TileSettings(pydantic.BaseSettings): |
| 47 | + """MVT settings""" |
| 48 | + |
| 49 | + tile_resolution: int = 4096 |
| 50 | + tile_buffer: int = 256 |
| 51 | + max_features_per_tile: int = 10000 |
| 52 | + default_minzoom: int = 0 |
| 53 | + default_maxzoom: int = 22 |
| 54 | + |
| 55 | + class Config: |
| 56 | + """model config""" |
| 57 | + |
| 58 | + env_prefix = "TIMVT_" |
| 59 | + env_file = ".env" |
| 60 | + |
| 61 | + |
| 62 | +@lru_cache() |
| 63 | +def TileSettings() -> _TileSettings: |
| 64 | + """Cache settings.""" |
| 65 | + return _TileSettings() |
| 66 | + |
| 67 | + |
| 68 | +class _PostgresSettings(pydantic.BaseSettings): |
| 69 | + """Postgres-specific API settings. |
| 70 | +
|
| 71 | + Attributes: |
| 72 | + postgres_user: postgres username. |
| 73 | + postgres_pass: postgres password. |
| 74 | + postgres_host: hostname for the connection. |
| 75 | + postgres_port: database port. |
| 76 | + postgres_dbname: database name. |
| 77 | + """ |
| 78 | + |
| 79 | + postgres_user: Optional[str] |
| 80 | + postgres_pass: Optional[str] |
| 81 | + postgres_host: Optional[str] |
| 82 | + postgres_port: Optional[str] |
| 83 | + postgres_dbname: Optional[str] |
| 84 | + |
| 85 | + database_url: Optional[pydantic.PostgresDsn] = None |
| 86 | + |
| 87 | + db_min_conn_size: int = 1 |
| 88 | + db_max_conn_size: int = 10 |
| 89 | + db_max_queries: int = 50000 |
| 90 | + db_max_inactive_conn_lifetime: float = 300 |
| 91 | + |
| 92 | + class Config: |
| 93 | + """model config""" |
| 94 | + |
| 95 | + env_file = ".env" |
| 96 | + |
| 97 | + # https://github.com/tiangolo/full-stack-fastapi-postgresql/blob/master/%7B%7Bcookiecutter.project_slug%7D%7D/backend/app/app/core/config.py#L42 |
| 98 | + @pydantic.validator("database_url", pre=True) |
| 99 | + def assemble_db_connection(cls, v: Optional[str], values: Dict[str, Any]) -> Any: |
| 100 | + if isinstance(v, str): |
| 101 | + return v |
| 102 | + |
| 103 | + return pydantic.PostgresDsn.build( |
| 104 | + scheme="postgresql", |
| 105 | + user=values.get("postgres_user"), |
| 106 | + password=values.get("postgres_pass"), |
| 107 | + host=values.get("postgres_host", ""), |
| 108 | + port=values.get("postgres_port", 5432), |
| 109 | + path=f"/{values.get('postgres_dbname') or ''}", |
| 110 | + ) |
| 111 | + |
| 112 | + |
| 113 | +@lru_cache() |
| 114 | +def PostgresSettings() -> _PostgresSettings: |
| 115 | + """ |
| 116 | + This function returns a cached instance of the APISettings object. |
| 117 | + Caching is used to prevent re-reading the environment every time the API settings are used in an endpoint. |
| 118 | + If you want to change an environment variable and reset the cache (e.g., during testing), this can be done |
| 119 | + using the `lru_cache` instance method `get_api_settings.cache_clear()`. |
| 120 | +
|
| 121 | + From https://github.com/dmontagu/fastapi-utils/blob/af95ff4a8195caaa9edaa3dbd5b6eeb09691d9c7/fastapi_utils/api_settings.py#L60-L69 |
| 122 | + """ |
| 123 | + return _PostgresSettings() |
0 commit comments