// PRJ_013 · 2024
Reportes GA4 · Factory MethodGA4 Reports · Factory Method
Patrón de diseño · PythonDesign pattern · Python
Reportes diarios de Google Analytics 4 exportados automáticamente, fáciles de extender con nuevos tipos de reporte.Daily Google Analytics 4 reports exported automatically, easy to extend with new report types.
En detalleIn detailGenerador de reportes de Google Analytics 4 (Data API v1beta) que exporta métricas diarias a CSV. Usa el patrón Factory Method para construir distintos tipos de reporte, con arquitectura por capas, tests (pytest) y CI.Google Analytics 4 report generator (Data API v1beta) that exports daily metrics to CSV. Uses the Factory Method pattern to build different report types, with layered architecture, tests (pytest) and CI.
// IMPACTO// IMPACT
El problemaThe problem
Quería generar varios tipos de reporte de GA4 sin duplicar código ni acoplar la creación de cada query a la lógica de ejecución. Un caso ideal para aplicar un patrón de diseño.I wanted to generate several GA4 report types without duplicating code or coupling each query's creation to the execution logic. An ideal case for a design pattern.
Cómo lo resolvíHow I solved it
Apliqué el patrón Factory Method: cada tipo de reporte es un producto que sabe construir su query, y una factory resuelve la clase concreta por su identificador. Arquitectura por capas, cliente de la GA4 Data API v1beta aislado, tests con pytest y CI.Applied the Factory Method pattern: each report type is a product that builds its own query, and a factory resolves the concrete class by its identifier. Layered architecture, an isolated GA4 Data API v1beta client, pytest tests and CI.
Arquitectura y stackArchitecture & stack
- [01]Factory
- [02]GA4Report (producto)
- [03]Use Case
- [04]GA4 Data API v1beta
- [05]CSV
- Python
- GA4 Data API
- pandas
- Factory Method
# domain/ga4_report_domain.py — Factory Method
class GA4ReportFactory:
_registry = {
"activeUserspPerDay": ActiveUsersPerDayReport,
"users": UsersReport,
"page_views": PageViewsReport,
}
@staticmethod
def create_report(report_type, start_date, end_date):
report_cls = GA4ReportFactory._registry.get(report_type)
if report_cls is None:
raise ValueError("Invalid report type")
return report_cls().create_query_report(start_date, end_date) Lo que aprendíWhat I learned
01 //
Factory Method
Agregar un reporte nuevo es solo crear una clase y registrarla: el resto del código no cambia.
02 //
Desacoplar la API
Mover la excepción al dominio permite testear el caso de uso sin importar las dependencias de Google.
03 //
requirements honesto
El proyecto no corría tras un install limpio: faltaban pandas y python-dotenv en requirements.
01 //
Factory Method
Adding a new report is just creating a class and registering it: the rest of the code stays the same.
02 //
Decoupling the API
Moving the exception to the domain lets you test the use case without importing Google's dependencies.
03 //
Honest requirements
The project didn't run after a clean install: pandas and python-dotenv were missing from requirements.