Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: update API and improves data retrieval. #1

Merged
merged 3 commits into from
Dec 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
version: 2
updates:
- package-ecosystem: "docker"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 99
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 99
allow:
- dependency-type: "direct"
- dependency-type: "indirect"
55 changes: 55 additions & 0 deletions .github/workflows/staging-deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: Staging Server Build Pipeline

on:
push:
branches:
- staging

jobs:
deploy:
name: Deploy to Staging Server
runs-on: ubuntu-latest
environment:
name: staging
steps:
- name: Execute Remote SSH Commands
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.KEY }}
script: |
set -e

echo "============================"
echo "Updating repository ..."
echo "============================"
if ! assembler clone --branch staging --project telemetry_aggregator; then
echo "❌ Error updating repository!"
exit 1
fi
echo "==============================="
echo "✅ Repository update complete"
echo "==============================="

echo "========================="
echo "Building project ..."
echo "========================="
if ! assembler deploy --project telemetry_aggregator; then
echo "❌ Error building project!"
exit 1
fi
echo "==========================="
echo "✅ Project build complete"
echo "==========================="

echo "============================="
echo "Cleaning up staging builds ..."
echo "============================="
if ! ${{ secrets.CLEANUP_CMD }}; then
echo "❌ Error cleaning up builds!"
exit 1
fi
echo "============================="
echo "✅ Cleanup complete"
echo "============================="
21 changes: 20 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,21 @@
# RelaySMS-Telemetry-Aggregator
# RelaySMS Telemetry Aggregator

Collects, analyzes, and exposes RelaySMS usage data via a unified API for transparent telemetry insights.

## References

4. [REST API V1 Resources](https://api.telemetry.smswithoutborders.com/docs)

## Contributing

To contribute:

1. Fork the repository.
2. Create a feature branch: `git checkout -b feature-branch`.
3. Commit your changes: `git commit -m 'Add a new feature'`.
4. Push to the branch: `git push origin feature-branch`.
5. Open a Pull Request.

## License

This project is licensed under the GNU General Public License (GPL). See the [LICENSE](LICENSE) file for details.
128 changes: 128 additions & 0 deletions api_data_schemas.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
"""
This program is free software: you can redistribute it under the terms
of the GNU General Public License, v. 3.0. If a copy of the GNU General
Public License was not distributed with this file, see <https://www.gnu.org/licenses/>.
"""

from typing import Literal, List, Union
from pydantic import BaseModel, Field
from fastapi import Query


class SummaryDetails(BaseModel):
"""Details of the summary metrics."""

total_signup_users: int
total_retained_users: int


class SummaryParams(BaseModel):
"""Parameters for filtering and grouping summary metrics."""

start_date: str = Field(description="Start date in 'YYYY-MM-DD' format.")
end_date: str = Field(description="End date in 'YYYY-MM-DD' format.")
country_code: str = Field(
default=None, description="2-character ISO region code.", max_length=2
)


class SummaryResponse(BaseModel):
"""Response model containing summary metrics."""

summary: SummaryDetails


class MetricsParams(BaseModel):
"""Parameters for filtering and grouping metrics."""

start_date: str = Field(description="Start date in 'YYYY-MM-DD' format.")
end_date: str = Field(description="End date in 'YYYY-MM-DD' format.")
country_code: str = Field(
default=None, description="2-character ISO region code.", max_length=2
)
granularity: Literal["day", "month"] = Field(
default="day", description="Granularity of data."
)
group_by: Literal["country", "date"] = Field(
default="date", description="Criteria to group results."
)
top: int = Field(
default=None,
description="Maximum number of results to return. "
"(cannot be used with 'page' or 'page_size')",
)
page: int = Query(default=1, ge=1, description="Page number for paginated results.")
page_size: int = Query(
default=10, ge=10, le=100, description="Number of records per page."
)


class PaginationDetails(BaseModel):
"""Pagination details for paginated responses."""

page: int
page_size: int
total_pages: int
total_records: int


class CountrySignupData(BaseModel):
"""Signup data grouped by country."""

country_code: str
signup_users: int


class TimeframeSignupData(BaseModel):
"""Signup data grouped by timeframe."""

timeframe: str
signup_users: int


class SignupDetails(BaseModel):
"""Details of the signup metrics."""

total_signup_users: int
pagination: PaginationDetails
data: List[Union[CountrySignupData, TimeframeSignupData]]


class SignupResponse(BaseModel):
"""Response model containing signup metrics."""

signup: SignupDetails


class CountryRetainedData(BaseModel):
"""Retained data grouped by country."""

country_code: str
retained_users: int


class TimeframeRetainedData(BaseModel):
"""Retained data grouped by timeframe."""

timeframe: str
retained_users: int


class RetainedDetails(BaseModel):
"""Details of the retained metrics."""

total_retained_users: int
pagination: PaginationDetails
data: List[Union[CountryRetainedData, TimeframeRetainedData]]


class RetainedResponse(BaseModel):
"""Response model containing retained metrics."""

retained: RetainedDetails


class ErrorResponse(BaseModel):
"""Response model for errors."""

error: str
Loading
Loading