Skip to content

Commit 7b217d5

Browse files
committed
✨ Add (module): Create the ETL pipeline project
1 parent b8bf9f6 commit 7b217d5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

77 files changed

+158798
-159
lines changed

.env.sample.env

Lines changed: 0 additions & 20 deletions
This file was deleted.

.pre-commit-config.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ repos:
2929
- --keep-runtime-typing
3030

3131
- repo: https://github.com/astral-sh/ruff-pre-commit
32-
rev: v0.4.6
32+
rev: v0.4.8
3333
hooks:
3434
# Run the linter.
3535
- id: ruff
@@ -51,7 +51,7 @@ repos:
5151
args: [ "--config", "pyproject.toml" ]
5252

5353
- repo: https://github.com/astral-sh/ruff-pre-commit
54-
rev: v0.4.6
54+
rev: v0.4.8
5555
hooks:
5656
# Run the formatter.
5757
- id: ruff-format

app/config/init_settings.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ class InitSettings(BaseSettings):
105105
"value": {
106106
"username": "username",
107107
"email": "username",
108-
"password": "miclave123",
108+
"password": "Password123",
109109
"birthdate": date(95, 12, 31),
110110
"phone_number": PhoneNumber("5939876a4321"),
111111
},
@@ -141,7 +141,7 @@ class InitSettings(BaseSettings):
141141
"value": {
142142
"username": "username",
143143
"email": "username",
144-
"password": "miclave123",
144+
"password": "Password123",
145145
"birthdate": date(95, 12, 31),
146146
"phone_number": PhoneNumber("59398x54321"),
147147
},

introduction/pydantic_intro.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
contains both a first and last name separated by a space.
66
"""
77

8-
from typing import Optional
9-
108
from pydantic import BaseModel, PositiveInt, ValidationError, field_validator
119

1210

@@ -16,7 +14,7 @@ class User(BaseModel):
1614
"""
1715

1816
name: str
19-
age: Optional[PositiveInt] = None
17+
age: PositiveInt | None = None
2018

2119
@field_validator(
2220
"name",

pipeline/.env.sample

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
API_URL="https://api.openweathermap.org/data/3.0/onecall?lat="
2+
PATH_PARAMETER="&lon="
3+
ID_PATH_PARAMETER="&appid="
4+
API_KEY="YOUR_OPENWEATHERMAP_API_KEY"
5+
DEFAULT_LAT=-33.865143
6+
DEFAULT_LNG=151.209900
7+
LOWEST_TEMP=-273.15
8+
HIGHEST_TEMP=100.0
9+
HIGHEST_RAIN_DEPTH=1000.0
10+
LOWEST_HUMIDITY=0
11+
HIGHEST_HUMIDITY=100
12+
HIGHEST_EVAPORATION=150.0
13+
HIGHEST_SUNSHINE=24.0
14+
HIGHEST_WIND_SPEED=300
15+
LOWEST_PRESSURE=300.0
16+
HIGHEST_PRESSURE=1100.0
17+
HIGHEST_CLOUD_SCALE=9
18+
HIGHEST_CLOUDINESS_PCT=100.0
19+
HIGHEST_WIND_DEGREES=360
20+
21+
# Postgres
22+
POSTGRES_SCHEME="postgresql+psycopg"
23+
POSTGRES_HOST="localhost"
24+
POSTGRES_USER="postgres"
25+
POSTGRES_PASSWORD="Password1.-"
26+
POSTGRES_DB="pydantic_sqlalchemy"
27+
POSTGRES_PORT=5432

pipeline/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
"""
2+
Package pipeline initialization.
3+
"""

pipeline/config/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
"""
2+
Package pipeline.config initialization.
3+
"""

pipeline/config/init_settings.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
"""
2+
A module for init settings in the pipeline.config package.
3+
"""
4+
5+
from functools import lru_cache
6+
7+
from pydantic_settings import BaseSettings, SettingsConfigDict
8+
9+
10+
class InitSettings(BaseSettings):
11+
"""
12+
Init Settings class based on Pydantic Base Settings
13+
"""
14+
15+
model_config = SettingsConfigDict(
16+
case_sensitive=True,
17+
extra="allow",
18+
)
19+
20+
PROJECT_NAME: str = "pipeline"
21+
ENCODING: str = "UTF-8"
22+
DATE_FORMAT: str = "%Y-%m-%d"
23+
DATETIME_FORMAT: str = "%Y-%m-%d %H:%M:%S"
24+
FILE_DATE_FORMAT: str = "%d-%b-%Y-%H-%M-%S"
25+
LOG_FORMAT: str = (
26+
"[%(name)s][%(asctime)s][%(levelname)s][%(module)s]"
27+
"[%(funcName)s][%(lineno)d]: %(message)s"
28+
)
29+
30+
31+
@lru_cache
32+
def get_init_settings() -> InitSettings:
33+
"""
34+
Get init settings cached
35+
:return: The init settings instance
36+
:rtype: InitSettings
37+
"""
38+
return InitSettings()
39+
40+
41+
init_settings: InitSettings = get_init_settings()

pipeline/config/settings.py

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
"""
2+
A module for settings in the pipeline.config package.
3+
"""
4+
5+
from functools import lru_cache
6+
7+
from pydantic import (
8+
AnyHttpUrl,
9+
NegativeFloat,
10+
NonNegativeInt,
11+
PositiveFloat,
12+
PositiveInt,
13+
PostgresDsn,
14+
field_validator,
15+
)
16+
from pydantic_core import MultiHostUrl
17+
from pydantic_core.core_schema import ValidationInfo
18+
from pydantic_extra_types.coordinate import Latitude, Longitude
19+
from pydantic_settings import BaseSettings, SettingsConfigDict
20+
21+
22+
class Settings(BaseSettings):
23+
"""
24+
Settings class based on Pydantic Base Settings for environment variables
25+
"""
26+
27+
model_config = SettingsConfigDict(
28+
env_file=".env",
29+
env_file_encoding="utf-8",
30+
case_sensitive=True,
31+
extra="allow",
32+
)
33+
34+
API_URL: AnyHttpUrl
35+
PATH_PARAMETER: str
36+
ID_PATH_PARAMETER: str
37+
API_KEY: str
38+
DEFAULT_LAT: Latitude
39+
DEFAULT_LNG: Longitude
40+
RATE_LIMIT_THRESHOLD: PositiveInt = 120 # requests per minute
41+
RATE_LIMIT_RESET_TIME: PositiveInt = 60 # seconds
42+
PREFIX: str = "https://" # prefix used for mounting the HTTP session
43+
MAX_RETRIES: PositiveInt = 3
44+
POOL_CONNECTIONS: PositiveInt = 10 # connections pools to cache in terms
45+
# of endpoints
46+
POOL_MAXSIZE: PositiveInt = 20 # max connections to cache in the pool
47+
RETRY_BACKOFF_FACTOR: PositiveFloat = 0.5 # delay between retries [seconds]
48+
BACKOFF_MAX: PositiveInt = 60 # maximum delay between retries [seconds]
49+
RETRY_STATUS_FORCE_LIST: list[PositiveInt] = [
50+
429,
51+
502,
52+
503,
53+
504,
54+
]
55+
56+
POSTGRES_SCHEME: str
57+
POSTGRES_USER: str
58+
POSTGRES_PASSWORD: str
59+
POSTGRES_HOST: str
60+
POSTGRES_PORT: PositiveInt
61+
POSTGRES_DB: str
62+
SQLALCHEMY_DATABASE_URI: PostgresDsn | None = None
63+
64+
@field_validator("SQLALCHEMY_DATABASE_URI", mode="before")
65+
def assemble_postgresql_connection(
66+
cls,
67+
v: str | None,
68+
info: ValidationInfo,
69+
) -> PostgresDsn:
70+
"""
71+
Assemble the database connection as URI string
72+
:param v: Variables to consider
73+
:type v: str | NoneType
74+
:param info: The field validation info
75+
:type info: ValidationInfo
76+
:return: SQLAlchemy URI
77+
:rtype: PostgresDsn
78+
"""
79+
if info.config is None:
80+
raise ValueError("info.config cannot be None")
81+
uri: MultiHostUrl = MultiHostUrl.build(
82+
scheme=info.data.get("POSTGRES_SCHEME", "postgres"),
83+
username=info.data.get("POSTGRES_USER"),
84+
password=info.data.get("POSTGRES_PASSWORD"),
85+
host=info.data.get("POSTGRES_HOST"),
86+
port=info.data.get("POSTGRES_PORT"),
87+
path=info.data.get("POSTGRES_DB"),
88+
)
89+
return PostgresDsn(f"{uri}")
90+
91+
LOWEST_TEMP: NegativeFloat
92+
HIGHEST_TEMP: PositiveFloat
93+
HIGHEST_RAIN_DEPTH: PositiveFloat
94+
LOWEST_HUMIDITY: NonNegativeInt
95+
HIGHEST_HUMIDITY: PositiveInt
96+
HIGHEST_EVAPORATION: PositiveFloat
97+
HIGHEST_SUNSHINE: PositiveFloat
98+
HIGHEST_WIND_SPEED: PositiveInt
99+
LOWEST_PRESSURE: PositiveFloat
100+
HIGHEST_PRESSURE: PositiveFloat
101+
HIGHEST_CLOUD_SCALE: PositiveInt
102+
103+
HIGHEST_CLOUDINESS_PCT: PositiveFloat
104+
HIGHEST_WIND_DEGREES: PositiveInt
105+
106+
107+
@lru_cache
108+
def get_settings() -> Settings:
109+
"""
110+
Get settings cached
111+
:return: The settings instance
112+
:rtype: Settings
113+
"""
114+
return Settings()
115+
116+
117+
settings: Settings = get_settings()

pipeline/core/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
"""
2+
Package pipeline-core initialization.
3+
"""

0 commit comments

Comments
 (0)