Skip to content
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
13 changes: 13 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
name: CI

on:
pull_request:

jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v6
- run: uvx --from ruff==0.16.9 ruff check .
- run: uvx --from ruff==0.16.9 ruff format --check .
6 changes: 6 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.16.9
hooks:
- id: ruff-check
- id: ruff-format
2 changes: 1 addition & 1 deletion __init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
from ._project_root import project_root as project_root
from ._env import env as env
from ._project_root import project_root as project_root
27 changes: 22 additions & 5 deletions _project_root.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,31 @@
import inspect
import os
import pathlib
from typing import TextIO, Optional
from typing import Optional, TextIO


def _find_project_root(path: pathlib.Path) -> pathlib.Path | None:
path = path.resolve()
while path != path.parent:
if "site-packages" not in path.parts and (path / "pyproject.toml").is_file():
return path
path = path.parent
return None


class ProjectRoot:
def __init__(self):
self.target = "pyproject.toml"
self.project_root = pathlib.Path(__file__).parent
while self.target not in os.listdir(str(self.project_root)):
self.project_root = self.project_root.parent
package_root = pathlib.Path(__file__).parent
if project_root := _find_project_root(package_root):
self.project_root = project_root
return
for frame in inspect.stack()[1:]:
caller = pathlib.Path(frame.filename)
if "site-packages" in caller.parts:
continue
self.project_root = _find_project_root(caller.parent) or caller.parent
return
self.project_root = package_root

def path(self, path: Optional[str] = None) -> str:
return os.path.join(self.project_root, path or "")
Expand Down
7 changes: 3 additions & 4 deletions app_factory.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import os.path
import tomllib
from contextlib import asynccontextmanager
from typing import Callable, Awaitable
from typing import Awaitable, Callable

from common import project_root
from common.exception import CommonException
from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse, Response

from common import project_root
from common.exception import CommonException


async def exception_handler(_: Request, e: Exception) -> Response:
if isinstance(e, CommonException):
Expand Down
15 changes: 7 additions & 8 deletions config_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,22 @@
from types import UnionType
from typing import (
Dict,
Type,
TypeVar,
Optional,
List,
Generic,
List,
Literal,
Optional,
Tuple,
get_origin,
get_args,
Type,
TypeVar,
Union,
get_args,
get_origin,
)

from common.logger import get_logger
from pydantic import BaseModel
from pydantic.fields import FieldInfo # noqa

from common.logger import get_logger

try:
import yaml
except ImportError:
Expand Down
40 changes: 40 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
[build-system]
requires = ["setuptools>=61"]
build-backend = "setuptools.build_meta"

[project]
name = "python-common"
version = "0.1.0"
description = "Shared Python utilities for OmniBox services"
readme = "README.md"
requires-python = ">=3.12"
dependencies = [
"chardet>=5.2.0",
"fastapi>=0.116.1",
"jinja2>=3.1.6",
"opentelemetry-api>=1.36.0",
"opentelemetry-exporter-otlp>=1.36.0",
"opentelemetry-instrumentation-fastapi>=0.57b0",
"opentelemetry-sdk>=1.36.0",
"pydantic>=2.11.7",
"pyyaml>=6.0.2",
"shortuuid>=1.0.13",
]

[tool.setuptools]
packages = ["common"]

[tool.setuptools.package-dir]
common = "."

[dependency-groups]
dev = [
"pre-commit>=4.5.0,<5.0.0",
"ruff>=0.16.9,<0.17.0",
]

[tool.ruff]
target-version = "py312"

[tool.ruff.lint]
select = ["E4", "E7", "E9", "F", "I"]
3 changes: 1 addition & 2 deletions template_parser.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import re
from datetime import datetime

from jinja2 import Environment, FileSystemLoader, Template

from common import project_root
from jinja2 import Environment, FileSystemLoader, Template

continuous_bl: re.Pattern = re.compile(r"\n\n+")
template_dir = project_root.path("wizard_common/resources/prompt_templates")
Expand Down
1 change: 0 additions & 1 deletion trace_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
from typing import Optional

import shortuuid

from common.logger import get_logger


Expand Down
2 changes: 1 addition & 1 deletion tracing.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from opentelemetry import trace
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
from opentelemetry.sdk.resources import Resource, SERVICE_NAME, DEPLOYMENT_ENVIRONMENT
from opentelemetry.sdk.resources import DEPLOYMENT_ENVIRONMENT, SERVICE_NAME, Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor

Expand Down
2 changes: 1 addition & 1 deletion utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import re
import json as jsonlib
import re
from functools import partial

json_dumps = partial(jsonlib.dumps, ensure_ascii=False, separators=(",", ":"))
Expand Down
Loading