diff --git a/app/__init__.py b/app/__init__.py index 3e04420..9e5f6b2 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1,4 +1,4 @@ """Python° - FastAPI, Postgres, tsvector""" # Current Version -__version__ = "3.0.1" +__version__ = "3.0.3" diff --git a/app/api/github/README.md b/app/api/github/README.md new file mode 100644 index 0000000..c780d36 --- /dev/null +++ b/app/api/github/README.md @@ -0,0 +1,38 @@ +## GitHub + +We are going to use this route to get data from our GitHub account using their API. We'll be storing that info in the Postgres DB, but have not created any tables yet. + +### Create Table Route + +**POST /api/github/createtable** + +Hits this URL to create the GitHub tables in Postgres. Each table is created with `IF NOT EXISTS`, so it is safe to call multiple times — existing tables and data will not be affected. + +### Proposed Table Design + +1. github_accounts +- One row per GitHub account/user profile. +- Stores account identity fields and full raw payload. + +2. github_repos +- One row per repository. +- Stores common repo analytics fields plus raw JSON payload. + +3. github_gists +- One row per gist. +- Stores gist metadata plus raw JSON payload. + +4. github_projects +- One row per project. +- Stores project metadata plus raw JSON payload. + +5. github_resources +- Generic catch-all for any future GitHub resource type. +- Supports "everything else" from the API without migrations for every new object type. + +### Why this shape works + +- Normalized for common entities you asked for: repos, gists, projects. +- Flexible for all additional GitHub objects through jsonb payload storage. +- Indexes on resource type, account, and payload for filtering and search. + diff --git a/app/api/github/__init__.py b/app/api/github/__init__.py new file mode 100644 index 0000000..ccd498c --- /dev/null +++ b/app/api/github/__init__.py @@ -0,0 +1,9 @@ +"""GitHub Routes""" + +from fastapi import APIRouter +from .github import router as _github_router +from .sql.create_tables import router as _create_tables_router + +github_router = APIRouter() +github_router.include_router(_github_router) +github_router.include_router(_create_tables_router) diff --git a/app/api/github/github.py b/app/api/github/github.py new file mode 100644 index 0000000..a30a63e --- /dev/null +++ b/app/api/github/github.py @@ -0,0 +1,48 @@ +from fastapi import APIRouter, Depends +from app.utils.make_meta import make_meta +from app.utils.db import get_db_connection_direct +from app.utils.api_key_auth import get_api_key + +router = APIRouter() + +_TABLES = [ + "github_accounts", + "github_repos", + "github_gists", + "github_projects", + "github_resources", +] + + +def _fetch_table(cur, table: str) -> dict: + cur.execute(f"SELECT COUNT(*) FROM {table};") + row = cur.fetchone() + count = row[0] if row and row[0] is not None else 0 + cur.execute(f"SELECT * FROM {table} ORDER BY id DESC LIMIT 100;") + if cur.description: + columns = [desc[0] for desc in cur.description] + rows = [dict(zip(columns, r)) for r in cur.fetchall()] + else: + rows = [] + return {"count": count, "rows": rows} + + +@router.get("/github") +def get_github(api_key: str = Depends(get_api_key)) -> dict: + """GET /github: Return counts and records from all GitHub tables.""" + conn = None + cur = None + try: + conn = get_db_connection_direct() + cur = conn.cursor() + data = {table: _fetch_table(cur, table) for table in _TABLES} + return {"meta": make_meta("success", "GitHub data"), "data": data} + except Exception as e: + return {"meta": make_meta("error", f"DB error: {str(e)}"), "data": {}} + finally: + if cur is not None: + cur.close() + if conn is not None: + conn.close() + + diff --git a/app/api/github/sql/create_tables.py b/app/api/github/sql/create_tables.py new file mode 100644 index 0000000..522232d --- /dev/null +++ b/app/api/github/sql/create_tables.py @@ -0,0 +1,156 @@ +from fastapi import APIRouter, HTTPException, Depends +from app.utils.make_meta import make_meta +from app.utils.db import get_db_connection_direct +from app.utils.api_key_auth import get_api_key + +router = APIRouter() + +_SQL = [ + """ + CREATE TABLE IF NOT EXISTS github_accounts ( + id SERIAL PRIMARY KEY, + github_user_id BIGINT UNIQUE, + login TEXT UNIQUE, + name TEXT, + email TEXT, + company TEXT, + blog TEXT, + location TEXT, + bio TEXT, + avatar_url TEXT, + html_url TEXT, + payload JSONB NOT NULL DEFAULT '{}'::jsonb, + last_synced_at TIMESTAMPTZ, + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() + ); + """, + """ + CREATE TABLE IF NOT EXISTS github_repos ( + id BIGSERIAL PRIMARY KEY, + github_repo_id BIGINT UNIQUE NOT NULL, + account_login TEXT, + name TEXT NOT NULL, + full_name TEXT, + private BOOLEAN NOT NULL DEFAULT FALSE, + fork BOOLEAN NOT NULL DEFAULT FALSE, + archived BOOLEAN NOT NULL DEFAULT FALSE, + disabled BOOLEAN NOT NULL DEFAULT FALSE, + default_branch TEXT, + language TEXT, + stargazers_count INTEGER, + watchers_count INTEGER, + forks_count INTEGER, + open_issues_count INTEGER, + size_kb INTEGER, + pushed_at TIMESTAMPTZ, + created_at_github TIMESTAMPTZ, + updated_at_github TIMESTAMPTZ, + html_url TEXT, + api_url TEXT, + payload JSONB NOT NULL DEFAULT '{}'::jsonb, + synced_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() + ); + """, + """ + CREATE TABLE IF NOT EXISTS github_gists ( + id BIGSERIAL PRIMARY KEY, + gist_id TEXT UNIQUE NOT NULL, + owner_login TEXT, + description TEXT, + public BOOLEAN, + files_count INTEGER, + comments_count INTEGER, + html_url TEXT, + api_url TEXT, + created_at_github TIMESTAMPTZ, + updated_at_github TIMESTAMPTZ, + payload JSONB NOT NULL DEFAULT '{}'::jsonb, + synced_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() + ); + """, + """ + CREATE TABLE IF NOT EXISTS github_projects ( + id BIGSERIAL PRIMARY KEY, + github_project_id BIGINT UNIQUE NOT NULL, + owner_login TEXT, + owner_type TEXT, + name TEXT NOT NULL, + body TEXT, + state TEXT, + number INTEGER, + html_url TEXT, + api_url TEXT, + created_at_github TIMESTAMPTZ, + updated_at_github TIMESTAMPTZ, + payload JSONB NOT NULL DEFAULT '{}'::jsonb, + synced_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() + ); + """, + """ + CREATE TABLE IF NOT EXISTS github_resources ( + id BIGSERIAL PRIMARY KEY, + account_login TEXT, + resource_type TEXT NOT NULL, + resource_id TEXT NOT NULL, + resource_name TEXT, + resource_url TEXT, + is_private BOOLEAN, + state TEXT, + created_at_github TIMESTAMPTZ, + updated_at_github TIMESTAMPTZ, + payload JSONB NOT NULL DEFAULT '{}'::jsonb, + synced_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + UNIQUE (resource_type, resource_id) + ); + """, + "CREATE INDEX IF NOT EXISTS idx_github_resources_type ON github_resources (resource_type);", + "CREATE INDEX IF NOT EXISTS idx_github_resources_account ON github_resources (account_login);", + "CREATE INDEX IF NOT EXISTS idx_github_resources_payload ON github_resources USING GIN (payload);", + "CREATE INDEX IF NOT EXISTS idx_github_repos_payload ON github_repos USING GIN (payload);", + "CREATE INDEX IF NOT EXISTS idx_github_gists_payload ON github_gists USING GIN (payload);", + "CREATE INDEX IF NOT EXISTS idx_github_projects_payload ON github_projects USING GIN (payload);", +] + + +@router.post("/api/github/createtable") +def create_github_tables(api_key: str = Depends(get_api_key)) -> dict: + """POST /api/github/createtable: Create GitHub ingestion tables.""" + conn = None + cur = None + try: + conn = get_db_connection_direct() + cur = conn.cursor() + for statement in _SQL: + cur.execute(statement) + conn.commit() + meta = make_meta("success", "GitHub tables created") + return { + "meta": meta, + "data": { + "tables": [ + "github_accounts", + "github_repos", + "github_gists", + "github_projects", + "github_resources", + ] + }, + } + except Exception as e: + if conn is not None: + conn.rollback() + raise HTTPException(status_code=500, detail=str(e)) + finally: + if cur is not None: + cur.close() + if conn is not None: + conn.close() diff --git a/app/api/github/sql/seed.py b/app/api/github/sql/seed.py new file mode 100644 index 0000000..abc9c11 --- /dev/null +++ b/app/api/github/sql/seed.py @@ -0,0 +1,332 @@ +"""Seed GitHub tables with realistic fake data.""" + +from app.utils.db import get_db_connection_direct +import json + +_ACCOUNTS = [ + { + "github_user_id": 1024001, + "login": "milkyway-dev", + "name": "Alex Milky", + "email": "alex@milkyway.dev", + "company": "Milky Way Digital", + "blog": "https://milkyway.dev", + "location": "San Francisco, CA", + "bio": "Full-stack developer. Open source enthusiast.", + "avatar_url": "https://avatars.githubusercontent.com/u/1024001", + "html_url": "https://github.com/milkyway-dev", + "payload": {"public_repos": 42, "followers": 318, "following": 97}, + }, + { + "github_user_id": 1024002, + "login": "nova-studios", + "name": "Nova Studios", + "email": "hello@novastudios.io", + "company": "Nova Studios LLC", + "blog": "https://novastudios.io", + "location": "Austin, TX", + "bio": "We build tools for creative teams.", + "avatar_url": "https://avatars.githubusercontent.com/u/1024002", + "html_url": "https://github.com/nova-studios", + "payload": {"public_repos": 17, "followers": 540, "following": 12}, + }, + { + "github_user_id": 1024003, + "login": "byte-foundry", + "name": "Byte Foundry", + "email": "team@bytefoundry.io", + "company": "Byte Foundry Inc.", + "blog": "https://bytefoundry.io", + "location": "London, UK", + "bio": "Crafting high-performance APIs since 2015.", + "avatar_url": "https://avatars.githubusercontent.com/u/1024003", + "html_url": "https://github.com/byte-foundry", + "payload": {"public_repos": 29, "followers": 210, "following": 45}, + }, +] + +_REPOS = [ + { + "github_repo_id": 5001001, + "account_login": "milkyway-dev", + "name": "fastapi-starter", + "full_name": "milkyway-dev/fastapi-starter", + "private": False, + "fork": False, + "archived": False, + "disabled": False, + "default_branch": "main", + "language": "Python", + "stargazers_count": 284, + "watchers_count": 284, + "forks_count": 61, + "open_issues_count": 4, + "size_kb": 1240, + "pushed_at": "2026-04-20T14:32:00Z", + "created_at_github": "2023-06-01T09:00:00Z", + "updated_at_github": "2026-04-20T14:32:00Z", + "html_url": "https://github.com/milkyway-dev/fastapi-starter", + "api_url": "https://api.github.com/repos/milkyway-dev/fastapi-starter", + "payload": {"topics": ["fastapi", "python", "starter-template"]}, + }, + { + "github_repo_id": 5001002, + "account_login": "nova-studios", + "name": "canvas-kit", + "full_name": "nova-studios/canvas-kit", + "private": False, + "fork": False, + "archived": False, + "disabled": False, + "default_branch": "main", + "language": "TypeScript", + "stargazers_count": 912, + "watchers_count": 912, + "forks_count": 143, + "open_issues_count": 11, + "size_kb": 8800, + "pushed_at": "2026-04-25T10:15:00Z", + "created_at_github": "2022-11-14T08:00:00Z", + "updated_at_github": "2026-04-25T10:15:00Z", + "html_url": "https://github.com/nova-studios/canvas-kit", + "api_url": "https://api.github.com/repos/nova-studios/canvas-kit", + "payload": {"topics": ["canvas", "design-system", "typescript"]}, + }, + { + "github_repo_id": 5001003, + "account_login": "byte-foundry", + "name": "pg-lightning", + "full_name": "byte-foundry/pg-lightning", + "private": False, + "fork": False, + "archived": False, + "disabled": False, + "default_branch": "main", + "language": "Go", + "stargazers_count": 1537, + "watchers_count": 1537, + "forks_count": 220, + "open_issues_count": 7, + "size_kb": 4300, + "pushed_at": "2026-04-22T18:45:00Z", + "created_at_github": "2021-03-08T12:00:00Z", + "updated_at_github": "2026-04-22T18:45:00Z", + "html_url": "https://github.com/byte-foundry/pg-lightning", + "api_url": "https://api.github.com/repos/byte-foundry/pg-lightning", + "payload": {"topics": ["postgres", "performance", "go"]}, + }, +] + +_GISTS = [ + { + "gist_id": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4", + "owner_login": "milkyway-dev", + "description": "FastAPI dependency injection pattern for Postgres", + "public": True, + "files_count": 2, + "comments_count": 5, + "html_url": "https://gist.github.com/milkyway-dev/a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4", + "api_url": "https://api.github.com/gists/a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4", + "created_at_github": "2025-09-10T11:00:00Z", + "updated_at_github": "2025-09-12T08:30:00Z", + "payload": {"forks_count": 3, "files": ["db.py", "example.py"]}, + }, + { + "gist_id": "b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5", + "owner_login": "nova-studios", + "description": "Tailwind CSS dark mode toggle snippet", + "public": True, + "files_count": 1, + "comments_count": 2, + "html_url": "https://gist.github.com/nova-studios/b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5", + "api_url": "https://api.github.com/gists/b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5", + "created_at_github": "2025-12-01T15:20:00Z", + "updated_at_github": "2025-12-03T09:00:00Z", + "payload": {"forks_count": 1, "files": ["dark-mode.js"]}, + }, + { + "gist_id": "c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6", + "owner_login": "byte-foundry", + "description": "Go connection pool tuning for high-throughput Postgres", + "public": False, + "files_count": 3, + "comments_count": 0, + "html_url": "https://gist.github.com/byte-foundry/c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6", + "api_url": "https://api.github.com/gists/c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6", + "created_at_github": "2026-01-18T07:45:00Z", + "updated_at_github": "2026-01-18T07:45:00Z", + "payload": {"forks_count": 0, "files": ["pool.go", "config.go", "README.md"]}, + }, +] + +_PROJECTS = [ + { + "github_project_id": 9001001, + "owner_login": "milkyway-dev", + "owner_type": "user", + "name": "API Roadmap 2026", + "body": "Tracking all planned API features and improvements for 2026.", + "state": "open", + "number": 1, + "html_url": "https://github.com/users/milkyway-dev/projects/1", + "api_url": "https://api.github.com/projects/9001001", + "created_at_github": "2025-12-15T10:00:00Z", + "updated_at_github": "2026-04-18T14:00:00Z", + "payload": {"columns_count": 4}, + }, + { + "github_project_id": 9001002, + "owner_login": "nova-studios", + "owner_type": "organization", + "name": "Canvas Kit v3", + "body": "Planning board for the Canvas Kit v3 major release.", + "state": "open", + "number": 3, + "html_url": "https://github.com/orgs/nova-studios/projects/3", + "api_url": "https://api.github.com/projects/9001002", + "created_at_github": "2026-01-05T09:30:00Z", + "updated_at_github": "2026-04-23T11:00:00Z", + "payload": {"columns_count": 5}, + }, + { + "github_project_id": 9001003, + "owner_login": "byte-foundry", + "owner_type": "organization", + "name": "Q2 Infrastructure Sprint", + "body": "DevOps and infrastructure tasks for Q2 2026.", + "state": "closed", + "number": 7, + "html_url": "https://github.com/orgs/byte-foundry/projects/7", + "api_url": "https://api.github.com/projects/9001003", + "created_at_github": "2026-03-01T08:00:00Z", + "updated_at_github": "2026-04-01T17:30:00Z", + "payload": {"columns_count": 3}, + }, +] + +_RESOURCES = [ + { + "account_login": "milkyway-dev", + "resource_type": "release", + "resource_id": "rel-milkyway-001", + "resource_name": "v2.4.0", + "resource_url": "https://github.com/milkyway-dev/fastapi-starter/releases/tag/v2.4.0", + "is_private": False, + "state": "published", + "created_at_github": "2026-03-10T12:00:00Z", + "updated_at_github": "2026-03-10T12:00:00Z", + "payload": {"tag_name": "v2.4.0", "prerelease": False, "assets_count": 2}, + }, + { + "account_login": "nova-studios", + "resource_type": "workflow", + "resource_id": "wf-nova-042", + "resource_name": "CI / Test Suite", + "resource_url": "https://github.com/nova-studios/canvas-kit/actions/workflows/ci.yml", + "is_private": False, + "state": "active", + "created_at_github": "2023-01-20T09:00:00Z", + "updated_at_github": "2026-04-25T10:15:00Z", + "payload": {"path": ".github/workflows/ci.yml", "badge_url": "https://github.com/nova-studios/canvas-kit/actions/workflows/ci.yml/badge.svg"}, + }, + { + "account_login": "byte-foundry", + "resource_type": "discussion", + "resource_id": "disc-byte-019", + "resource_name": "RFC: Connection pool strategy", + "resource_url": "https://github.com/byte-foundry/pg-lightning/discussions/19", + "is_private": False, + "state": "open", + "created_at_github": "2026-02-14T16:00:00Z", + "updated_at_github": "2026-04-10T08:20:00Z", + "payload": {"category": "Ideas", "answer_chosen": False, "comments_count": 12}, + }, +] + + +def seed(): + conn = get_db_connection_direct() + cur = conn.cursor() + + for r in _ACCOUNTS: + cur.execute( + """ + INSERT INTO github_accounts + (github_user_id, login, name, email, company, blog, location, bio, + avatar_url, html_url, payload) + VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s) + ON CONFLICT (github_user_id) DO NOTHING; + """, + (r["github_user_id"], r["login"], r["name"], r["email"], r["company"], + r["blog"], r["location"], r["bio"], r["avatar_url"], r["html_url"], + json.dumps(r["payload"])), + ) + + for r in _REPOS: + cur.execute( + """ + INSERT INTO github_repos + (github_repo_id, account_login, name, full_name, private, fork, archived, + disabled, default_branch, language, stargazers_count, watchers_count, + forks_count, open_issues_count, size_kb, pushed_at, + created_at_github, updated_at_github, html_url, api_url, payload) + VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s) + ON CONFLICT (github_repo_id) DO NOTHING; + """, + (r["github_repo_id"], r["account_login"], r["name"], r["full_name"], + r["private"], r["fork"], r["archived"], r["disabled"], r["default_branch"], + r["language"], r["stargazers_count"], r["watchers_count"], r["forks_count"], + r["open_issues_count"], r["size_kb"], r["pushed_at"], r["created_at_github"], + r["updated_at_github"], r["html_url"], r["api_url"], json.dumps(r["payload"])), + ) + + for r in _GISTS: + cur.execute( + """ + INSERT INTO github_gists + (gist_id, owner_login, description, public, files_count, comments_count, + html_url, api_url, created_at_github, updated_at_github, payload) + VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s) + ON CONFLICT (gist_id) DO NOTHING; + """, + (r["gist_id"], r["owner_login"], r["description"], r["public"], + r["files_count"], r["comments_count"], r["html_url"], r["api_url"], + r["created_at_github"], r["updated_at_github"], json.dumps(r["payload"])), + ) + + for r in _PROJECTS: + cur.execute( + """ + INSERT INTO github_projects + (github_project_id, owner_login, owner_type, name, body, state, number, + html_url, api_url, created_at_github, updated_at_github, payload) + VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s) + ON CONFLICT (github_project_id) DO NOTHING; + """, + (r["github_project_id"], r["owner_login"], r["owner_type"], r["name"], + r["body"], r["state"], r["number"], r["html_url"], r["api_url"], + r["created_at_github"], r["updated_at_github"], json.dumps(r["payload"])), + ) + + for r in _RESOURCES: + cur.execute( + """ + INSERT INTO github_resources + (account_login, resource_type, resource_id, resource_name, resource_url, + is_private, state, created_at_github, updated_at_github, payload) + VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s) + ON CONFLICT (resource_type, resource_id) DO NOTHING; + """, + (r["account_login"], r["resource_type"], r["resource_id"], r["resource_name"], + r["resource_url"], r["is_private"], r["state"], r["created_at_github"], + r["updated_at_github"], json.dumps(r["payload"])), + ) + + conn.commit() + cur.close() + conn.close() + print("Seeded 3 rows into each GitHub table.") + + +if __name__ == "__main__": + seed() diff --git a/app/api/queue/csv/linkedin.py b/app/api/queue/csv/linkedin.py index 5d1c43a..0efc35e 100644 --- a/app/api/queue/csv/linkedin.py +++ b/app/api/queue/csv/linkedin.py @@ -10,7 +10,7 @@ @router.post("/queue/csv/linkedin") def import_linkedin_csv() -> dict: """POST /queue/csv/linkedin: Import data from linkedin.csv into the queue table, robust for large files.""" - csv_path = os.path.join(os.path.dirname(__file__), "../csv/linkedin/linkedin_sample.csv") + csv_path = os.path.join(os.path.dirname(__file__), "../csv/linkedin/linkedin.csv") if not os.path.exists(csv_path): raise HTTPException(status_code=404, detail="linkedin.csv not found") try: diff --git a/app/api/root.py b/app/api/root.py index 5ed493d..129aa50 100644 --- a/app/api/root.py +++ b/app/api/root.py @@ -11,12 +11,10 @@ def root() -> dict: """"Python°""" load_dotenv() base_url = os.getenv("BASE_URL", "http://localhost:8000") - epoch = int(time.time() * 1000) meta = { "title": "Python°", "version": __version__, - "base_url": base_url, - "time": epoch, + "base": base_url, } return {"meta": meta} diff --git a/app/api/routes.py b/app/api/routes.py index 82234f3..b85cdf8 100644 --- a/app/api/routes.py +++ b/app/api/routes.py @@ -13,6 +13,7 @@ from app.api.prospects.prospects import router as prospects_router from app.api.orders.orders import router as orders_router from app.api.queue import router as queue_router +from app.api.github import github_router router.include_router(root_router) router.include_router(resend_router) @@ -21,4 +22,5 @@ router.include_router(prompts_empty_router) router.include_router(prospects_router) router.include_router(orders_router) -router.include_router(queue_router) \ No newline at end of file +router.include_router(queue_router) +router.include_router(github_router) \ No newline at end of file diff --git a/app/utils/make_meta.py b/app/utils/make_meta.py index 0a5e3bd..3107d87 100644 --- a/app/utils/make_meta.py +++ b/app/utils/make_meta.py @@ -2,14 +2,14 @@ import time from app import __version__ -def make_meta(severity: str, title: str) -> dict: - """Create a standard meta dictionary for API responses.""" +def make_meta(severity: str, message: str) -> dict: + """Creates a standard meta dictionary for API responses.""" base_url = os.getenv("BASE_URL", "http://localhost:8000") epoch = int(time.time() * 1000) return { "version": __version__, "time": epoch, "severity": severity, - "title": title, + "message": message, "base": base_url, }