Skip to content

Commit 50c435b

Browse files
committed
Hotfix: corrección en configuración o dependencias
1 parent 00fadb5 commit 50c435b

File tree

838 files changed

+3707
-1430
lines changed

Some content is hidden

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

838 files changed

+3707
-1430
lines changed

.github/workflows/ci.yml

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
name: CI
2+
3+
on:
4+
pull_request:
5+
branches: [ "**" ]
6+
push:
7+
branches: [ "feature/**", "fix/**", "chore/**" ]
8+
9+
jobs:
10+
test-and-lint:
11+
runs-on: ubuntu-latest
12+
defaults:
13+
run:
14+
working-directory: .
15+
steps:
16+
- uses: actions/checkout@v4
17+
18+
- name: Set up Python
19+
uses: actions/setup-python@v5
20+
with:
21+
python-version: "3.11"
22+
23+
- name: Cache pip
24+
uses: actions/cache@v4
25+
with:
26+
path: ~/.cache/pip
27+
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements*.txt') }}
28+
restore-keys: ${{ runner.os }}-pip-
29+
30+
- name: Install deps (root + services)
31+
run: |
32+
pip install -U pip wheel
33+
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
34+
for svc in trading_ai_system/ingestion_service trading_ai_system/inference_service trading_ai_system/control_service; do
35+
if [ -f "$svc/requirements.txt" ]; then pip install -r "$svc/requirements.txt"; fi
36+
done
37+
pip install pytest flake8
38+
39+
- name: Lint
40+
run: flake8 .
41+
42+
- name: Test
43+
run: |
44+
if [ -d tests ]; then pytest -q; else echo "No tests dir"; fi
45+
46+
build-check:
47+
name: Docker build (no push)
48+
runs-on: ubuntu-latest
49+
strategy:
50+
fail-fast: false
51+
matrix:
52+
service:
53+
- { name: ingestion_service, path: trading_ai_system/ingestion_service }
54+
- { name: inference_service, path: trading_ai_system/inference_service }
55+
- { name: control_service, path: trading_ai_system/control_service }
56+
steps:
57+
- uses: actions/checkout@v4
58+
- name: Build ${{ matrix.service.name }}
59+
run: docker build -t neurobank/${{ matrix.service.name }}:ci ${{ matrix.service.path }}
60+
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
name: Deploy Prod (ECS)
2+
3+
on:
4+
push:
5+
tags:
6+
- "prod-*"
7+
8+
env:
9+
AWS_REGION: ${{ secrets.AWS_REGION }}
10+
AWS_ACCOUNT_ID: ${{ secrets.AWS_ACCOUNT_ID }}
11+
ECR_REGISTRY: ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.${{ secrets.AWS_REGION }}.amazonaws.com
12+
13+
jobs:
14+
build-and-push:
15+
runs-on: ubuntu-latest
16+
permissions:
17+
id-token: write
18+
contents: read
19+
strategy:
20+
fail-fast: false
21+
matrix:
22+
service:
23+
- { name: api-gateway, path: . } # Ajusta si API tiene Dockerfile propio en raíz/otra ruta
24+
- { name: ingestion, path: trading_ai_system/ingestion_service }
25+
- { name: inference, path: trading_ai_system/inference_service }
26+
- { name: control, path: trading_ai_system/control_service }
27+
steps:
28+
- uses: actions/checkout@v4
29+
30+
- name: Configure AWS credentials (OIDC)
31+
uses: aws-actions/configure-aws-credentials@v4
32+
with:
33+
role-to-assume: ${{ secrets.AWS_OIDC_ROLE_ARN }} # IAM Role con trust para GitHub
34+
aws-region: ${{ env.AWS_REGION }}
35+
36+
- name: Login to ECR
37+
id: ecr
38+
uses: aws-actions/amazon-ecr-login@v2
39+
40+
- name: Build & Push ${{ matrix.service.name }}
41+
run: |
42+
IMAGE=${{ env.ECR_REGISTRY }}/neurobank/${{ matrix.service.name }}:${{ github.ref_name }}
43+
docker build -t "$IMAGE" ${{ matrix.service.path }}
44+
docker push "$IMAGE"
45+
46+
deploy-ecs:
47+
needs: build-and-push
48+
runs-on: ubuntu-latest
49+
permissions:
50+
id-token: write
51+
contents: read
52+
strategy:
53+
fail-fast: false
54+
matrix:
55+
svc:
56+
- { ecs_service: api-gateway-svc, taskdef: trading_ai_system/ecs/api-gateway-task.json, container: api-gateway, image_repo: neurobank/api-gateway }
57+
- { ecs_service: ingestion-svc, taskdef: trading_ai_system/ecs/ingestion-service-task.json, container: ingestion, image_repo: neurobank/ingestion }
58+
- { ecs_service: inference-svc, taskdef: trading_ai_system/ecs/inference-service-task.json, container: inference, image_repo: neurobank/inference }
59+
- { ecs_service: control-svc, taskdef: trading_ai_system/ecs/control-service-task.json, container: control, image_repo: neurobank/control }
60+
steps:
61+
- uses: actions/checkout@v4
62+
63+
- name: Configure AWS credentials (OIDC)
64+
uses: aws-actions/configure-aws-credentials@v4
65+
with:
66+
role-to-assume: ${{ secrets.AWS_OIDC_ROLE_ARN }}
67+
aws-region: ${{ env.AWS_REGION }}
68+
69+
- name: Render Task Definition
70+
id: taskdef
71+
uses: aws-actions/amazon-ecs-render-task-definition@v1
72+
with:
73+
task-definition: ${{ matrix.svc.taskdef }}
74+
container-name: ${{ matrix.svc.container }}
75+
image: ${{ env.ECR_REGISTRY }}/${{ matrix.svc.image_repo }}:${{ github.ref_name }}
76+
77+
- name: Deploy to ECS
78+
uses: aws-actions/amazon-ecs-deploy-task-definition@v2
79+
with:
80+
task-definition: ${{ steps.taskdef.outputs.task-definition }}
81+
service: ${{ matrix.svc.ecs_service }}
82+
cluster: neurobank-prod
83+
wait-for-service-stability: true
84+
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
name: Deploy Staging (Railway)
2+
3+
on:
4+
push:
5+
branches: [ "main" ]
6+
7+
concurrency:
8+
group: staging-railway
9+
cancel-in-progress: true
10+
11+
jobs:
12+
deploy:
13+
runs-on: ubuntu-latest
14+
env:
15+
RAILWAY_TOKEN: ${{ secrets.RAILWAY_TOKEN }}
16+
steps:
17+
- uses: actions/checkout@v4
18+
19+
- name: Setup Node (Railway CLI)
20+
uses: actions/setup-node@v4
21+
with:
22+
node-version: "20"
23+
24+
- name: Install Railway CLI
25+
run: npm i -g @railway/cli
26+
27+
- name: Auth
28+
run: railway login --token "$RAILWAY_TOKEN"
29+
30+
# Si tienes railway.toml en la raíz con todos los servicios:
31+
- name: Deploy API Gateway
32+
run: railway up --service api-gateway --yes
33+
34+
- name: Deploy Ingestion
35+
run: railway up --service ingestion-service --yes
36+
37+
- name: Deploy Inference
38+
run: railway up --service inference-service --yes
39+
40+
- name: Deploy Control
41+
run: railway up --service control-service --yes
42+
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{
2+
"family": "api-gateway-task",
3+
"networkMode": "awsvpc",
4+
"requiresCompatibilities": ["FARGATE"],
5+
"cpu": "512",
6+
"memory": "1024",
7+
"executionRoleArn": "arn:aws:iam::<ACCOUNT_ID>:role/ecsTaskExecutionRole",
8+
"taskRoleArn": "arn:aws:iam::<ACCOUNT_ID>:role/ecsTaskAppRole",
9+
"containerDefinitions": [
10+
{
11+
"name": "api-gateway",
12+
"image": "<ACCOUNT_ID>.dkr.ecr.<AWS_REGION>.amazonaws.com/neurobank/api-gateway:latest",
13+
"portMappings": [{ "containerPort": 8000, "protocol": "tcp" }],
14+
"environment": [
15+
{ "name": "ENVIRONMENT", "value": "production" },
16+
{ "name": "LOG_LEVEL", "value": "INFO" },
17+
{ "name": "OTEL_SERVICE_NAME", "value": "api_gateway" }
18+
],
19+
"secrets": [
20+
{ "name": "SECRET_KEY", "valueFrom": "arn:aws:ssm:<AWS_REGION>:<ACCOUNT_ID>:parameter/neurobank/secret_key" },
21+
{ "name": "API_KEY", "valueFrom": "arn:aws:ssm:<AWS_REGION>:<ACCOUNT_ID>:parameter/neurobank/api_key" }
22+
],
23+
"logConfiguration": {
24+
"logDriver": "awslogs",
25+
"options": {
26+
"awslogs-group": "/ecs/api-gateway",
27+
"awslogs-region": "<AWS_REGION>",
28+
"awslogs-stream-prefix": "ecs"
29+
}
30+
}
31+
},
32+
{
33+
"name": "otel-collector",
34+
"image": "otel/opentelemetry-collector:latest",
35+
"command": ["--config=/etc/otelcol-config.yaml"],
36+
"essential": false
37+
}
38+
]
39+
}
40+
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
name: Infra (Terraform)
2+
3+
on:
4+
workflow_dispatch:
5+
push:
6+
paths:
7+
- "infra/**.tf"
8+
9+
jobs:
10+
terraform:
11+
runs-on: ubuntu-latest
12+
permissions:
13+
contents: read
14+
id-token: write
15+
env:
16+
AWS_REGION: ${{ secrets.AWS_REGION }}
17+
steps:
18+
- uses: actions/checkout@v4
19+
- uses: hashicorp/setup-terraform@v3
20+
with:
21+
terraform_version: 1.9.5
22+
23+
- name: AWS Credentials (OIDC)
24+
uses: aws-actions/configure-aws-credentials@v4
25+
with:
26+
role-to-assume: ${{ secrets.AWS_OIDC_ROLE_ARN }}
27+
aws-region: ${{ env.AWS_REGION }}
28+
29+
- name: Terraform Init/Plan
30+
working-directory: infra
31+
run: |
32+
terraform init
33+
terraform plan -out=tfplan
34+
35+
- name: Terraform Apply (manual gate)
36+
if: github.event_name == 'workflow_dispatch'
37+
working-directory: infra
38+
run: terraform apply -auto-approve tfplan
39+

Makefile.deploy

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
AWS_REGION ?= eu-west-1
2+
AWS_ACCOUNT_ID ?= 000000000000
3+
ECR = $(AWS_ACCOUNT_ID).dkr.ecr.$(AWS_REGION).amazonaws.com
4+
5+
login:
6+
aws ecr get-login-password --region $(AWS_REGION) | docker login --username AWS --password-stdin $(ECR)
7+
8+
build-all:
9+
docker build -t $(ECR)/neurobank/api-gateway:local .
10+
docker build -t $(ECR)/neurobank/ingestion:local trading_ai_system/ingestion_service
11+
docker build -t $(ECR)/neurobank/inference:local trading_ai_system/inference_service
12+
docker build -t $(ECR)/neurobank/control:local trading_ai_system/control_service
13+

NeuroBank-FastAPI-Toolkit

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Subproject commit 00fadb5889a0f15d6116383a5a782a6ae415991b

NeuroBank-FastAPI-Toolkit-1

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Subproject commit f0c60eb3ca5d19fa101884318f72015a6aa94884

app/config.py

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import os
2+
import json
23
import sys
34
from functools import lru_cache
45
from typing import List, Optional
@@ -17,15 +18,19 @@ class Settings(BaseSettings):
1718
# Server Configuration
1819
host: str = "0.0.0.0"
1920
port: int = int(os.getenv("PORT", 8000))
21+
workers: int = int(os.getenv("WORKERS", 1))
22+
23+
# Security / Secrets
24+
secret_key: Optional[str] = os.getenv("SECRET_KEY")
2025

2126
# Environment Configuration
2227
environment: str = os.getenv(
2328
"ENVIRONMENT", "development"
2429
) # Default to development, not production
2530
debug: bool = os.getenv("DEBUG", "false").lower() == "true"
2631

27-
# CORS Configuration - usando el dominio privado de Railway
28-
cors_origins: List[str] = []
32+
# CORS Configuration: definir como string para evitar parseo JSON automático
33+
cors_origins: Optional[str] = os.getenv("CORS_ORIGINS")
2934

3035
# AWS Configuration
3136
aws_region: str = os.getenv("AWS_REGION", "eu-west-1")
@@ -46,9 +51,18 @@ class Settings(BaseSettings):
4651

4752
def _get_cors_origins(self) -> List[str]:
4853
"""Configura CORS origins usando variables de Railway"""
49-
# Si hay CORS_ORIGINS configurado manualmente, usarlo
50-
if os.getenv("CORS_ORIGINS"):
51-
return os.getenv("CORS_ORIGINS").split(",")
54+
# Si hay CORS_ORIGINS configurado manualmente, usarlo con parseo robusto
55+
raw = self.cors_origins
56+
if raw is not None:
57+
raw_str = raw.strip()
58+
if raw_str == "":
59+
return []
60+
try:
61+
parsed = json.loads(raw_str)
62+
if isinstance(parsed, list):
63+
return [str(x).strip() for x in parsed if str(x).strip()]
64+
except Exception:
65+
return [part.strip() for part in raw_str.split(",") if part.strip()]
5266

5367
# Si no, construir automáticamente desde Railway
5468
origins = ["https://*.railway.app"]

0 commit comments

Comments
 (0)