-
Notifications
You must be signed in to change notification settings - Fork 77
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Design: 1. CRA + tailwind (they don't like CRA but I really don't care) 2. prettier + eslint 3. Add to pre-commit-config.yaml rahte rthan husky (which is very painful IMO)
- Loading branch information
1 parent
1d228f7
commit 0ed7eab
Showing
86 changed files
with
24,394 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,29 +4,80 @@ | |
# $ cd /PATH/TO/REPO | ||
# $ pre-commit install | ||
|
||
exclude: '^telemetry/ui' | ||
repos: | ||
- repo: https://github.com/ambv/black | ||
- repo: https://github.com/ambv/black | ||
rev: 23.11.0 | ||
hooks: | ||
- id: black | ||
args: [--line-length=100] | ||
- repo: https://github.com/pre-commit/pre-commit-hooks | ||
- id: black | ||
args: [--line-length=100] | ||
- repo: https://github.com/pre-commit/pre-commit-hooks | ||
rev: v4.5.0 | ||
hooks: | ||
- id: trailing-whitespace | ||
# ensures files are either empty or end with a blank line | ||
- id: end-of-file-fixer | ||
# sorts requirements | ||
- id: requirements-txt-fixer | ||
# valid python file | ||
- id: check-ast | ||
# isort python package import sorting | ||
- repo: https://github.com/pycqa/isort | ||
- id: trailing-whitespace | ||
# ensures files are either empty or end with a blank line | ||
- id: end-of-file-fixer | ||
# sorts requirements | ||
- id: requirements-txt-fixer | ||
# valid python file | ||
- id: check-ast | ||
# isort python package import sorting | ||
- repo: https://github.com/pycqa/isort | ||
rev: '5.12.0' | ||
hooks: | ||
- id: isort | ||
args: ["--profile", "black", "--line-length=100", "--known-local-folder", "tests", "-p", "hamilton"] | ||
- repo: https://github.com/pycqa/flake8 | ||
- id: isort | ||
args: | ||
[ | ||
'--profile', | ||
'black', | ||
'--line-length=100', | ||
'--known-local-folder', | ||
'tests', | ||
'-p', | ||
'hamilton' | ||
] | ||
- repo: https://github.com/pycqa/flake8 | ||
rev: 6.1.0 | ||
hooks: | ||
- id: flake8 | ||
- id: flake8 | ||
- repo: local | ||
# This is a bit of a hack, but its the easiest way to get it to all run together | ||
# https://stackoverflow.com/questions/64001471/pylint-with-pre-commit-and-esllint-with-husky | ||
hooks: | ||
- id: frontend-lint-staged | ||
name: frontend-lint-staged | ||
language: system | ||
entry: npx --prefix telemetry/ui lint-staged | ||
pass_filenames: false | ||
always_run: true | ||
# - repo: https://github.com/pre-commit/mirrors-eslint | ||
# rev: v8.56.0 | ||
# hooks: | ||
# - id: eslint | ||
# # Specify files to include, using regex to match the path | ||
# # Optionally specify additional arguments to ESLint | ||
# args: | ||
# [ | ||
# '--config', | ||
# 'telemetry/ui/.eslintrc.js', | ||
# '--ignore-path', | ||
# 'telemetry/ui/.eslintignore' | ||
# ] | ||
# files: '\.[jt]sx?$' | ||
# additional_dependencies: | ||
# - [email protected] | ||
# - [email protected] | ||
# - [email protected] | ||
# - [email protected] | ||
# - repo: https://github.com/pre-commit/mirrors-prettier | ||
# rev: v3.1.0 | ||
# hooks: | ||
# - id: prettier | ||
# args: | ||
# [ | ||
# '--config', | ||
# 'telemetry/ui/.prettierrc.json', | ||
# '--ignore-path', | ||
# 'telemetry/ui/.prettierignore' | ||
# ] | ||
# files: '^telemetry/ui/.*\.(ts|tsx)$' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
import abc | ||
import json | ||
import os.path | ||
from typing import Sequence, TypeVar | ||
|
||
import aiofiles | ||
import aiofiles.os as aiofilesos | ||
import fastapi | ||
|
||
from burr.tracking.common.models import BeginEntryModel, EndEntryModel | ||
from burr.tracking.server import schema | ||
from burr.tracking.server.schema import ApplicationLogs, ApplicationSummary | ||
|
||
T = TypeVar("T") | ||
|
||
|
||
class BackendBase(abc.ABC): | ||
@abc.abstractmethod | ||
async def list_projects(self, request: fastapi.Request) -> Sequence[schema.Project]: | ||
"""Lists out all projects -- this relies on the paginate function to work properly. | ||
:param request: The request object, used for authentication/authorization if needed | ||
:return: the next page | ||
""" | ||
pass | ||
|
||
@abc.abstractmethod | ||
async def list_apps( | ||
self, request: fastapi.Request, project_id: str | ||
) -> Sequence[schema.ApplicationSummary]: | ||
"""Lists out all apps (continual state machine runs with shared state) for a given project. | ||
:param request: The request object, used for authentication/authorization if needed | ||
:param project_id: | ||
:return: | ||
""" | ||
pass | ||
|
||
@abc.abstractmethod | ||
async def get_application_logs( | ||
self, request: fastapi.Request, project_id: str, app_id: str | ||
) -> Sequence[schema.Step]: | ||
"""Lists out all steps for a given app. | ||
:param request: The request object, used for authentication/authorization if needed | ||
:param app_id: | ||
:return: | ||
""" | ||
pass | ||
|
||
|
||
class LocalBackend(BackendBase): | ||
DEFAULT_PATH = os.path.expanduser("~/.burr") | ||
|
||
def __init__(self, path: str = DEFAULT_PATH): | ||
self.path = path | ||
|
||
async def list_projects(self, request: fastapi.Request) -> Sequence[schema.Project]: | ||
out = [] | ||
if not os.path.exists(self.path): | ||
return out | ||
for entry in await aiofilesos.listdir(self.path): | ||
full_path = os.path.join(self.path, entry) | ||
if os.path.isdir(full_path): | ||
out.append( | ||
schema.Project( | ||
name=entry, | ||
id=entry, | ||
uri=full_path, # TODO -- figure out what | ||
last_written=await aiofilesos.path.getmtime(full_path), | ||
created=await aiofilesos.path.getctime(full_path), | ||
num_apps=len(await aiofilesos.listdir(full_path)), | ||
) | ||
) | ||
return out | ||
|
||
async def count_lines(self, file_path: str) -> int: | ||
"""Quick tool to count lines""" | ||
count = 0 | ||
async with aiofiles.open(file_path, "rb") as f: | ||
async for _ in f: | ||
count += 1 | ||
return count | ||
|
||
async def list_apps( | ||
self, request: fastapi.Request, project_id: str | ||
) -> Sequence[ApplicationSummary]: | ||
project_filepath = os.path.join(self.path, project_id) | ||
if not os.path.exists(project_filepath): | ||
raise fastapi.HTTPException(status_code=404, detail=f"Project: {project_id} not found") | ||
out = [] | ||
for entry in await aiofilesos.listdir(project_filepath): | ||
full_path = os.path.join(project_filepath, entry) | ||
log_path = os.path.join(full_path, "log.jsonl") | ||
if os.path.isdir(full_path): | ||
out.append( | ||
schema.ApplicationSummary( | ||
app_id=entry, | ||
first_written=await aiofilesos.path.getctime(full_path), | ||
last_written=await aiofilesos.path.getmtime(full_path), | ||
num_steps=await self.count_lines(log_path) // 2, | ||
tags={}, | ||
) | ||
) | ||
return out | ||
|
||
async def get_application_logs( | ||
self, request: fastapi.Request, project_id: str, app_id: str | ||
) -> ApplicationLogs: | ||
app_filepath = os.path.join(self.path, project_id, app_id) | ||
if not os.path.exists(app_filepath): | ||
raise fastapi.HTTPException( | ||
status_code=404, detail=f"App: {app_id} from project: {project_id} not found" | ||
) | ||
log_file = os.path.join(app_filepath, "log.jsonl") | ||
graph_file = os.path.join(app_filepath, "graph.json") | ||
if not os.path.exists(graph_file): | ||
raise fastapi.HTTPException( | ||
status_code=404, | ||
detail=f"Graph file not found for app: " | ||
f"{app_id} from project: {project_id}. " | ||
f"Was this properly executed?", | ||
) | ||
steps = [] | ||
if os.path.exists(log_file): | ||
steps = [] | ||
async with aiofiles.open(log_file) as f: | ||
for i, line in enumerate(await f.readlines()): | ||
json_line = json.loads(line) | ||
if json_line["type"] == "begin_entry": | ||
begin_step = BeginEntryModel.parse_obj(json_line) | ||
steps.append( | ||
schema.Step( | ||
step_start_log=begin_step, | ||
step_end_log=None, | ||
step_sequence_id=i // 2, | ||
) | ||
) | ||
else: | ||
steps[-1].step_end_log = EndEntryModel.parse_obj(json_line) | ||
|
||
async with aiofiles.open(graph_file) as f: | ||
str_graph = await f.read() | ||
return ApplicationLogs( | ||
application=schema.ApplicationModel.parse_raw(str_graph), steps=steps | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
from typing import Sequence | ||
|
||
from fastapi import FastAPI, Request | ||
|
||
from burr.tracking.server import backend, schema | ||
from burr.tracking.server.schema import ApplicationLogs | ||
|
||
app = FastAPI() | ||
|
||
backend = backend.LocalBackend() | ||
|
||
|
||
@app.get("/api/v0/projects", response_model=Sequence[schema.Project]) | ||
async def get_projects(request: Request) -> Sequence[schema.Project]: | ||
"""Gets all projects visible by the user. | ||
:param request: FastAPI request | ||
:return: a list of projects visible by the user | ||
""" | ||
return await backend.list_projects(request) | ||
|
||
|
||
@app.get("/api/v0/{project_id}/apps", response_model=Sequence[schema.ApplicationSummary]) | ||
async def get_apps(request: Request, project_id: str) -> Sequence[schema.ApplicationSummary]: | ||
"""Gets all apps visible by the user | ||
:param request: FastAPI request | ||
:param project_id: project name | ||
:return: a list of projects visible by the user | ||
""" | ||
return await backend.list_apps(request, project_id) | ||
|
||
|
||
@app.get("/api/v0/{project_id}/{app_id}/apps") | ||
async def get_application_logs(request: Request, project_id: str, app_id: str) -> ApplicationLogs: | ||
"""Lists steps for a given App. | ||
TODO: add streaming capabilities for bi-directional communication | ||
TODO: add pagination for quicker loading | ||
:param request: FastAPI | ||
:param project_id: ID of the project | ||
:param app_id: ID of the associated application | ||
:return: A list of steps with all associated step data | ||
""" | ||
return await backend.get_application_logs(request, project_id=project_id, app_id=app_id) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
uvicorn run:app --host 0.0.0.0 --port 7241 |
Oops, something went wrong.