Skip to content

Commit 27dec74

Browse files
JacobCoffeeclaudesourcery-ai[bot]
authored
feat: Phase 0 - Microservices Migration Foundation (#103)
Co-authored-by: Claude <[email protected]> Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
1 parent f8c2b70 commit 27dec74

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+3810
-1039
lines changed

.coveragerc

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Coverage configuration file
2+
# This complements the pyproject.toml coverage settings
3+
4+
[run]
5+
source =
6+
byte_bot
7+
packages/byte-common/src/byte_common
8+
omit =
9+
*/tests/*
10+
*/__init__.py
11+
*/migrations/*
12+
*/.venv/*
13+
*/site-packages/*
14+
branch = True
15+
parallel = True
16+
17+
[report]
18+
precision = 2
19+
show_missing = True
20+
skip_covered = False
21+
exclude_lines =
22+
pragma: no cover
23+
if TYPE_CHECKING:
24+
except ImportError as e:
25+
except ImportError:
26+
def __repr__
27+
raise NotImplementedError
28+
raise AssertionError
29+
if __name__ == "__main__":
30+
@abstractmethod
31+
@abc.abstractmethod
32+
33+
[html]
34+
directory = htmlcov
35+
36+
[xml]
37+
output = coverage.xml

.pre-commit-config.yaml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ default_language_version:
33
default_install_hook_types: [commit-msg, pre-commit]
44
repos:
55
- repo: https://github.com/compilerla/conventional-pre-commit
6-
rev: v4.2.0
6+
rev: v4.3.0
77
hooks:
88
- id: conventional-pre-commit
99
stages: [commit-msg]
1010
- repo: https://github.com/pre-commit/pre-commit-hooks
11-
rev: v5.0.0
11+
rev: v6.0.0
1212
hooks:
1313
- id: check-ast
1414
- id: check-case-conflict
@@ -18,13 +18,13 @@ repos:
1818
- id: mixed-line-ending
1919
- id: trailing-whitespace
2020
- repo: https://github.com/astral-sh/ruff-pre-commit
21-
rev: "v0.11.13"
21+
rev: "v0.14.6"
2222
hooks:
2323
- id: ruff-check
2424
args: ["--fix"]
2525
- id: ruff-format
2626
- repo: https://github.com/sourcery-ai/sourcery
27-
rev: v1.37.0
27+
rev: v1.40.0
2828
hooks:
2929
- id: sourcery
3030
args: [--diff=git diff HEAD, --no-summary]
@@ -39,7 +39,7 @@ repos:
3939
.*\.json |.*\.svg |docs/changelog.rst
4040
)$
4141
- repo: https://github.com/asottile/blacken-docs
42-
rev: 1.19.1
42+
rev: 1.20.0
4343
hooks:
4444
- id: blacken-docs
4545
- repo: https://github.com/pre-commit/mirrors-prettier
@@ -88,7 +88,7 @@ repos:
8888
# discord-py,
8989
# ]
9090
- repo: https://github.com/RobertCraigie/pyright-python
91-
rev: v1.1.402
91+
rev: v1.1.407
9292
hooks:
9393
- id: pyright
9494
additional_dependencies:
@@ -144,6 +144,6 @@ repos:
144144
discord-py,
145145
]
146146
- repo: https://github.com/sphinx-contrib/sphinx-lint
147-
rev: "v1.0.0"
147+
rev: "v1.0.2"
148148
hooks:
149149
- id: sphinx-lint

byte_bot/byte/lib/utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ def run_ruff_format(code: str) -> str:
107107
Returns:
108108
str: The formatted code.
109109
"""
110-
result = subprocess.run( # noqa: S603
110+
result = subprocess.run(
111111
["ruff", "format", "-"], # noqa: S607
112112
input=code,
113113
capture_output=True,

byte_bot/cli.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def frontend() -> None:
3333
log.config.configure()
3434
logger.info("🎨 Starting Tailwind Compiler.")
3535
try:
36-
subprocess.run( # noqa: S603
36+
subprocess.run(
3737
[ # noqa: S607
3838
"tailwindcss",
3939
"-i",
@@ -56,7 +56,7 @@ def bot() -> None:
5656
log.config.configure()
5757
logger.info("🤖 Starting Byte.")
5858
try:
59-
subprocess.run(["python", "byte_bot/byte/bot.py"], check=True) # noqa: S603, S607
59+
subprocess.run(["python", "byte_bot/byte/bot.py"], check=True) # noqa: S607
6060
finally:
6161
for process in multiprocessing.active_children():
6262
process.terminate()

packages/byte-common/README.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# Byte Common Package
2+
3+
Shared code package for all Byte Bot services.
4+
5+
## Overview
6+
7+
This package contains shared utilities, models, and configurations used across all Byte Bot services (bot, api, worker).
8+
9+
## Contents
10+
11+
The package will include:
12+
13+
- **Models**: Shared Pydantic models and database schemas
14+
- **Configuration**: Environment configuration and settings
15+
- **Utilities**: Common helper functions and utilities
16+
- **Constants**: Shared constants and enums
17+
- **Types**: Shared type definitions
18+
- **Database**: Shared database models and migrations
19+
20+
## Technology Stack
21+
22+
- Python 3.12+
23+
- Pydantic for models
24+
- Pydantic Settings for configuration
25+
- Advanced Alchemy for database models
26+
27+
## Status
28+
29+
**Phase 0.2**: Package implementation complete. All core modules extracted.
30+
31+
## Structure
32+
33+
```
34+
packages/byte-common/
35+
├── src/
36+
│ └── byte_common/
37+
│ ├── __init__.py
38+
│ ├── models/ # SQLAlchemy database models
39+
│ │ ├── __init__.py
40+
│ │ ├── guild.py
41+
│ │ ├── github_config.py
42+
│ │ ├── forum_config.py
43+
│ │ ├── sotags_config.py
44+
│ │ ├── allowed_users_config.py
45+
│ │ └── user.py
46+
│ ├── schemas/ # Pydantic schemas for API
47+
│ │ ├── __init__.py
48+
│ │ ├── guild.py
49+
│ │ └── github.py
50+
│ ├── settings/ # Settings base classes
51+
│ │ ├── __init__.py
52+
│ │ ├── base.py
53+
│ │ └── database.py
54+
│ ├── clients/ # External service clients
55+
│ │ ├── __init__.py
56+
│ │ └── github.py
57+
│ ├── utils/ # Shared utilities
58+
│ │ ├── __init__.py
59+
│ │ ├── strings.py
60+
│ │ └── encoding.py
61+
│ └── constants.py # Shared constants
62+
├── tests/ # Package tests (TODO)
63+
├── pyproject.toml # Package configuration
64+
└── README.md # This file
65+
```
66+
67+
## Development
68+
69+
This package was created in Phase 0.2 by extracting shared code from the existing monolith.
70+
71+
## Usage
72+
73+
Services will depend on this package in their `pyproject.toml`:
74+
75+
```toml
76+
dependencies = [
77+
"byte-common",
78+
# ... other dependencies
79+
]
80+
```
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
[project]
2+
name = "byte-common"
3+
version = "0.2.0"
4+
description = "Shared code package for all Byte Bot services"
5+
authors = [
6+
{ name = "Jacob Coffee", email = "[email protected]" },
7+
]
8+
dependencies = [
9+
"pydantic>=2.5.2",
10+
"pydantic-settings>=2.1.0",
11+
"sqlalchemy>=2.0.23",
12+
"advanced-alchemy>=0.6.1",
13+
"githubkit[auth-app] @ git+https://github.com/yanyongyu/githubkit.git",
14+
"python-dotenv>=1.0.0",
15+
]
16+
requires-python = ">=3.12,<4.0"
17+
readme = "README.md"
18+
license = { text = "MIT" }
19+
20+
[build-system]
21+
requires = ["hatchling"]
22+
build-backend = "hatchling.build"
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
"""Byte Common - Shared code package for all Byte Bot services."""
2+
3+
from __future__ import annotations
4+
5+
__version__ = "0.2.0"
6+
7+
__all__ = ["__version__"]
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
"""External service clients."""
2+
3+
from __future__ import annotations
4+
5+
from byte_common.clients.github import create_github_client
6+
7+
__all__ = ("create_github_client",)
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
"""GitHub client factory."""
2+
3+
from __future__ import annotations
4+
5+
from githubkit import AppInstallationAuthStrategy, GitHub # type: ignore[reportMissingImports]
6+
7+
__all__ = ("create_github_client",)
8+
9+
10+
def create_github_client(
11+
app_id: int,
12+
private_key: str,
13+
installation_id: int,
14+
client_id: str,
15+
client_secret: str,
16+
) -> GitHub:
17+
"""Create a GitHub client for an app installation.
18+
19+
This factory function creates a GitHub client authenticated as a GitHub App installation.
20+
Unlike the hardcoded client in the monolith, this allows for dynamic installation IDs
21+
so different guilds can use different GitHub App installations.
22+
23+
Args:
24+
app_id: GitHub App ID.
25+
private_key: GitHub App private key (PEM format).
26+
installation_id: GitHub App installation ID.
27+
client_id: GitHub App client ID.
28+
client_secret: GitHub App client secret.
29+
30+
Returns:
31+
Configured GitHub client instance.
32+
33+
Example:
34+
```python
35+
from byte_common.clients import create_github_client
36+
37+
client = create_github_client(
38+
app_id=480575,
39+
private_key=settings.github.APP_PRIVATE_KEY,
40+
installation_id=guild_installation_id,
41+
client_id=settings.github.APP_CLIENT_ID,
42+
client_secret=settings.github.APP_CLIENT_SECRET,
43+
)
44+
45+
# Use the client
46+
repo = await client.rest.repos.async_get("owner", "repo")
47+
```
48+
"""
49+
return GitHub(
50+
AppInstallationAuthStrategy(
51+
app_id=app_id,
52+
private_key=private_key,
53+
installation_id=installation_id,
54+
client_id=client_id,
55+
client_secret=client_secret,
56+
)
57+
)
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
"""Shared constants for all Byte services."""
2+
3+
from __future__ import annotations
4+
5+
__all__ = (
6+
"DEFAULT_GUILD_PREFIX",
7+
"MAX_GUILD_NAME_LENGTH",
8+
"MAX_PREFIX_LENGTH",
9+
"MAX_TAG_NAME_LENGTH",
10+
"MAX_USER_NAME_LENGTH",
11+
)
12+
13+
# Guild constants
14+
DEFAULT_GUILD_PREFIX = "!"
15+
"""Default command prefix for guilds."""
16+
17+
MAX_GUILD_NAME_LENGTH = 100
18+
"""Maximum length for guild names."""
19+
20+
MAX_PREFIX_LENGTH = 5
21+
"""Maximum length for command prefixes."""
22+
23+
# Tag constants
24+
MAX_TAG_NAME_LENGTH = 50
25+
"""Maximum length for Stack Overflow tag names."""
26+
27+
# User constants
28+
MAX_USER_NAME_LENGTH = 100
29+
"""Maximum length for user names."""

0 commit comments

Comments
 (0)