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

[feat] Add ability to create reports #3189

Merged
merged 28 commits into from
Sep 27, 2024
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
347672d
Add reports CRUD api
mihran113 Jun 24, 2024
efdc9a9
Add reports migration file
mihran113 Jul 3, 2024
10caee2
Update kit v2
mihran113 Jul 3, 2024
cc72b1c
Import reports model in env.py
mihran113 Jul 3, 2024
78b69c6
Update stitches
mihran113 Jul 3, 2024
61ef2db
Update packages
mihran113 Jul 4, 2024
0ba9df8
Add reports list page
mihran113 Jul 4, 2024
f8599e2
Update icon set
mihran113 Jul 4, 2024
d80d956
Add reports/report routes
mihran113 Jul 4, 2024
464c2c0
Add custom boards
mihran113 Jul 14, 2024
7d768b8
Add single report page
mihran113 Jul 14, 2024
5e5f282
Update components
mihran113 Jul 14, 2024
6060b6e
Add boards and reports api services
mihran113 Jul 14, 2024
1c75fdb
Update base explorer components
mihran113 Jul 14, 2024
6817c40
Add pyodide integration
mihran113 Jul 14, 2024
9646c9b
Minor additions/fixes
mihran113 Jul 14, 2024
af9c9cf
Merge branch `main` into branch `feature/reports`
mihran113 Jul 14, 2024
8cec575
Fix formatting
mihran113 Jul 14, 2024
eb41edb
Update syntax for object retrieval
mihran113 Jul 16, 2024
def426b
Merge branch 'main' into feature/reports
mihran113 Jul 16, 2024
aca0536
Update changelog
mihran113 Jul 16, 2024
a4856b4
Merge branch 'main' into feature/reports
mihran113 Jul 17, 2024
a839272
Add comments to improve the readability of the `aim_ui_core.py` file
mihran113 Aug 25, 2024
80b5591
[fix] Fix the issue with multiple `aim` blocks visualizations
mihran113 Sep 15, 2024
7b56361
Merge branch 'main' into feature/reports
mihran113 Sep 15, 2024
f2e0875
Add documentation
mihran113 Sep 23, 2024
d418590
Merge branch 'main' into feature/reports
mihran113 Sep 26, 2024
796f2d4
Address PR comments.
mihran113 Sep 26, 2024
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
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## Unreleased

### Enhancements:
- Add ability to create reports (mihran113)

## 3.24.0 Aug 14, 2024

### Enhancements
Expand Down
3 changes: 2 additions & 1 deletion aim/storage/migrations/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

from logging.config import fileConfig

from aim.storage.structured.sql_engine.models import Base
from aim.storage.structured.db import DB
from aim.storage.structured.sql_engine.models import *
from aim.web.configs import AIM_ENV_MODE_KEY
from alembic import context
from alembic.config import Config
Expand Down
2 changes: 2 additions & 0 deletions aim/web/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ def create_app():
from aim.web.api.experiments.views import experiment_router
from aim.web.api.projects.project import Project
from aim.web.api.projects.views import projects_router
from aim.web.api.reports.views import reports_router
from aim.web.api.runs.views import add_api_routes, runs_router
from aim.web.api.tags.views import tags_router
from aim.web.api.utils import ResourceCleanupMiddleware
Expand Down Expand Up @@ -59,6 +60,7 @@ def create_app():
api_app.include_router(projects_router, prefix='/projects')
api_app.include_router(runs_router, prefix='/runs')
api_app.include_router(tags_router, prefix='/tags')
api_app.include_router(reports_router, prefix='/reports')

base_path = os.environ.get(AIM_UI_BASE_PATH, '')

Expand Down
Empty file added aim/web/api/reports/__init__.py
Empty file.
23 changes: 23 additions & 0 deletions aim/web/api/reports/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import uuid

import sqlalchemy as sa

from aim.web.api.db import Base
from aim.web.api.utils import datetime_now


class Report(Base):
__tablename__ = 'reports'
uuid = sa.Column(sa.Text, primary_key=True)
code = sa.Column(sa.Text)
name = sa.Column(sa.Text)
description = sa.Column(sa.Text)

created_at = sa.Column(sa.DateTime, default=datetime_now)
updated_at = sa.Column(sa.DateTime, default=datetime_now, onupdate=datetime_now)

def __init__(self, code, name, description):
self.uuid = str(uuid.uuid1())
self.code = code
self.name = name
self.description = description
31 changes: 31 additions & 0 deletions aim/web/api/reports/pydantic_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from datetime import datetime
from typing import List, Optional
from uuid import UUID

from pydantic import BaseModel


# response models
class ReportOut(BaseModel):
id: UUID
name: str
code: Optional[str] = None
description: Optional[str] = None
updated_at: datetime = 'Wed, 01 Jan 2021 16:12:07 GMT'
created_at: datetime = 'Wed, 01 Jan 2021 16:12:07 GMT'


# request models
class ReportUpdateIn(BaseModel):
name: Optional[str] = None
code: Optional[str] = None
description: Optional[str] = None


class ReportCreateIn(BaseModel):
name: str
code: Optional[str] = None
description: Optional[str] = None


ReportListOut = List[ReportOut]
17 changes: 17 additions & 0 deletions aim/web/api/reports/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from aim.web.api.reports.models import Report


def report_response_serializer(report_object):
if not isinstance(report_object, Report):
return None

response = {
'id': report_object.uuid,
'code': report_object.code,
'name': report_object.name,
'description': report_object.description,
'updated_at': report_object.updated_at,
'created_at': report_object.created_at,
}

return response
62 changes: 62 additions & 0 deletions aim/web/api/reports/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
from aim.web.api.db import get_session
from aim.web.api.reports.models import Report
from aim.web.api.reports.pydantic_models import (
ReportCreateIn,
ReportListOut,
ReportOut,
ReportUpdateIn,
)
from aim.web.api.reports.serializers import report_response_serializer
from aim.web.api.utils import APIRouter # wrapper for fastapi.APIRouter
from fastapi import Depends, HTTPException
from sqlalchemy.orm import Session


reports_router = APIRouter()


@reports_router.get('/', response_model=ReportListOut)
async def reports_list_api(session: Session = Depends(get_session)):
reports_query = session.query(Report).order_by(Report.updated_at)
result = [report_response_serializer(report) for report in reports_query]
return result


@reports_router.post('/', status_code=201, response_model=ReportOut)
async def reports_post_api(request_data: ReportCreateIn, session: Session = Depends(get_session)):
report = Report(request_data.code, request_data.name, request_data.description)
session.add(report)
session.commit()
return report_response_serializer(report)


@reports_router.get('/{report_id}/', response_model=ReportOut)
async def reports_get_api(report_id: str, session: Session = Depends(get_session)):
report = session.query(Report).filter(Report.uuid == report_id).first()
if not report:
raise HTTPException(status_code=404)
return report_response_serializer(report)


@reports_router.put('/{report_id}/', response_model=ReportOut)
async def reports_put_api(report_id: str, request_data: ReportUpdateIn, session: Session = Depends(get_session)):
report = session.query(Report).filter(Report.uuid == report_id).first()
if not report:
raise HTTPException(status_code=404)
if request_data.code is not None:
report.code = request_data.code
if request_data.name is not None:
report.name = request_data.name
if request_data.description is not None:
report.description = request_data.description
session.commit()
return report_response_serializer(report)


@reports_router.delete('/{report_id}/')
async def reports_delete_api(report_id: str, session: Session = Depends(get_session)):
report = session.query(Report).filter(Report.uuid == report_id).first()
if not report:
raise HTTPException(status_code=404)
session.delete(report)
session.commit()
4 changes: 4 additions & 0 deletions aim/web/migrations/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
from alembic import context
from alembic.config import Config

from aim.web.api.dashboards import models
from aim.web.api.dashboard_apps import models
from aim.web.api.reports import models


# this is the Alembic Config object, which provides
# access to the values within the .ini file in use.
Expand Down
36 changes: 36 additions & 0 deletions aim/web/migrations/versions/3d5fd76e8485_.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
"""empty message

Revision ID: 3d5fd76e8485
Revises: 517a45b2e62c
Create Date: 2024-07-03 20:56:10.622375

"""
from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = '3d5fd76e8485'
down_revision = '517a45b2e62c'
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('reports',
sa.Column('uuid', sa.Text(), nullable=False),
sa.Column('code', sa.Text(), nullable=True),
sa.Column('name', sa.Text(), nullable=True),
sa.Column('description', sa.Text(), nullable=True),
sa.Column('created_at', sa.DateTime(), nullable=True),
sa.Column('updated_at', sa.DateTime(), nullable=True),
sa.PrimaryKeyConstraint('uuid')
)
# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table('reports')
# ### end Alembic commands ###
Loading
Loading