You've already forked hotpocket
This commit is contained in:
25
services/packages/Dockerfile
Normal file
25
services/packages/Dockerfile
Normal file
@@ -0,0 +1,25 @@
|
||||
ARG APP_USER_UID=1000
|
||||
ARG APP_USER_GID=1000
|
||||
ARG IMAGE_ID=development.00000000
|
||||
|
||||
FROM docker-hosted.nexus.bthlabs.pl/hotpocket/base:build-python-20250819-01 AS development
|
||||
|
||||
ARG APP_USER_UID
|
||||
ARG APP_USER_GID
|
||||
ARG IMAGE_ID
|
||||
|
||||
USER root
|
||||
|
||||
# COPY --chown=$APP_USER_UID:$APP_USER_GID packages/ops/bin/*.sh /srv/bin/
|
||||
RUN chown -R ${APP_USER_UID}:${APP_USER_GID} /srv
|
||||
|
||||
USER app
|
||||
|
||||
VOLUME ["/srv/node_modules", "/srv/venv"]
|
||||
|
||||
FROM development AS ci
|
||||
|
||||
COPY --chown=$APP_USER_UID:$APP_USER_GID packages/ /srv/app/
|
||||
COPY --chown=$APP_USER_UID:$APP_USER_GID tls/ /srv/tls/
|
||||
|
||||
RUN chown -R $APP_USER_UID:$APP_USER_GID /srv
|
||||
3
services/packages/README.md
Normal file
3
services/packages/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# HotPocket by BTHLabs
|
||||
|
||||
This repository contains the _HotPocket Packages_ project.
|
||||
3
services/packages/common/README.md
Normal file
3
services/packages/common/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# HotPocket by BTHLabs
|
||||
|
||||
This repository contains the _HotPocket Common_ project.
|
||||
@@ -0,0 +1,2 @@
|
||||
from .associations import AssociationsSearchMode # noqa: F401
|
||||
from .core import NULL_UUID, App, Env # noqa: F401
|
||||
@@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
import enum
|
||||
|
||||
|
||||
class AssociationsSearchMode(enum.Enum):
|
||||
DEFAULT = ''
|
||||
STARRED = 'STARRED'
|
||||
ARCHIVED = 'ARCHIVED'
|
||||
19
services/packages/common/hotpocket_common/constants/core.py
Normal file
19
services/packages/common/hotpocket_common/constants/core.py
Normal file
@@ -0,0 +1,19 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
import enum
|
||||
import uuid
|
||||
|
||||
NULL_UUID = uuid.UUID('00000000-0000-0000-0000-000000000000')
|
||||
|
||||
|
||||
class Env(enum.Enum):
|
||||
METAL = 'metal'
|
||||
DOCKER = 'docker'
|
||||
DEPLOYMENT = 'deployment'
|
||||
AIO = 'aio'
|
||||
|
||||
|
||||
class App(enum.Enum):
|
||||
ADMIN = 'admin'
|
||||
WEBAPP = 'webapp'
|
||||
53
services/packages/common/hotpocket_common/db/postgres.py
Normal file
53
services/packages/common/hotpocket_common/db/postgres.py
Normal file
@@ -0,0 +1,53 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
import typing
|
||||
|
||||
from django.db.models.fields import Field
|
||||
from django.db.models.lookups import PatternLookup
|
||||
|
||||
|
||||
class BaseLikeLookup(PatternLookup):
|
||||
"""
|
||||
This class provides base for custom LIKE/ILIKE lookups for PostgreSQL.
|
||||
Unlike the builtin `contains` and `icontains`, these lookups do not do
|
||||
any DB-side processing of parameters. This opens up the ability to use
|
||||
index ops provided by `pg_trgm` to better index text columns for pattern
|
||||
searches.
|
||||
|
||||
These lookups currently support only PostgreSQL 15+.
|
||||
"""
|
||||
|
||||
# This is the pattern operator used to generate SQL for the lookup
|
||||
# when the right hand side isn't a raw string. Subclasses must specify this
|
||||
# or the whole thing will blow up ;).
|
||||
PATTERN_OP: str | None = None
|
||||
|
||||
# This is the rhs operator used to generate SQL for the lookup when the
|
||||
# right hand side is a raw string. Subclasses must specify this or the
|
||||
# whole thing will blow up ;).
|
||||
RHS_OP: str | None = None
|
||||
|
||||
def get_rhs_op(self, connection: typing.Any, rhs: typing.Any) -> typing.Any:
|
||||
if hasattr(self.rhs, 'as_sql') or self.bilateral_transforms:
|
||||
pattern = typing.cast(str, self.PATTERN_OP).format(
|
||||
connection.pattern_esc,
|
||||
)
|
||||
|
||||
return pattern.format(rhs)
|
||||
else:
|
||||
return typing.cast(str, self.RHS_OP)
|
||||
|
||||
|
||||
@Field.register_lookup
|
||||
class Like(BaseLikeLookup):
|
||||
PATTERN_OP = "LIKE '%%' || {} || '%%'"
|
||||
RHS_OP = 'LIKE %s'
|
||||
lookup_name = 'like'
|
||||
|
||||
|
||||
@Field.register_lookup
|
||||
class ILike(BaseLikeLookup):
|
||||
PATTERN_OP = "ILIKE '%%' || {} || '%%'"
|
||||
RHS_OP = 'ILIKE %s'
|
||||
lookup_name = 'ilike'
|
||||
15
services/packages/common/hotpocket_common/loader.py
Normal file
15
services/packages/common/hotpocket_common/loader.py
Normal file
@@ -0,0 +1,15 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
import importlib
|
||||
import typing
|
||||
|
||||
|
||||
def load_module_attribute(import_path: str) -> typing.Any:
|
||||
module_path, attribute = import_path.split(':')
|
||||
|
||||
module = importlib.import_module(module_path)
|
||||
if attribute is not None:
|
||||
return getattr(module, attribute)
|
||||
|
||||
return module
|
||||
0
services/packages/common/hotpocket_common/py.typed
Normal file
0
services/packages/common/hotpocket_common/py.typed
Normal file
164
services/packages/common/hotpocket_common/url.py
Normal file
164
services/packages/common/hotpocket_common/url.py
Normal file
@@ -0,0 +1,164 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
import pathlib
|
||||
import typing
|
||||
import urllib.parse
|
||||
|
||||
|
||||
class URL:
|
||||
"""
|
||||
The URL class.
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
url = URL('https://ziomek.dog/').\
|
||||
set_path('/index_old.html').\
|
||||
set_query({
|
||||
'test': 'true',
|
||||
}).\
|
||||
to_string()
|
||||
|
||||
The *encoding* argument will be used to decode *initial* if it's
|
||||
```bytes``. Also, it'll be used when decoding QS.
|
||||
"""
|
||||
def __init__(self,
|
||||
initial: str | bytes | pathlib.Path | urllib.parse.ParseResult,
|
||||
encoding: str = 'utf-8'):
|
||||
self.encoding = encoding
|
||||
self.parsed_url: urllib.parse.ParseResult
|
||||
|
||||
if isinstance(initial, urllib.parse.ParseResult):
|
||||
self.parsed_url = initial
|
||||
elif isinstance(initial, pathlib.Path):
|
||||
self.parsed_url = urllib.parse.urlparse(str(initial))
|
||||
elif isinstance(initial, bytes):
|
||||
self.parsed_url = urllib.parse.urlparse(
|
||||
initial.decode(self.encoding),
|
||||
)
|
||||
else:
|
||||
self.parsed_url = urllib.parse.urlparse(initial)
|
||||
|
||||
def replace_parsed_url_field(self, field: str, value: typing.Any):
|
||||
self.parsed_url = self.parsed_url._replace(**{field: value})
|
||||
|
||||
return self
|
||||
|
||||
def append_path_component(self, component: str | pathlib.Path) -> URL:
|
||||
_ = self.set_path(self.path / component)
|
||||
|
||||
return self
|
||||
|
||||
@property
|
||||
def scheme(self) -> str:
|
||||
return self.parsed_url.scheme
|
||||
|
||||
def set_scheme(self, new_scheme: str) -> URL:
|
||||
self.replace_parsed_url_field('scheme', new_scheme)
|
||||
|
||||
return self
|
||||
|
||||
@property
|
||||
def netloc(self) -> str:
|
||||
return self.parsed_url.netloc
|
||||
|
||||
def set_netloc(self, new_netloc: str) -> URL:
|
||||
self.replace_parsed_url_field('netloc', new_netloc)
|
||||
|
||||
return self
|
||||
|
||||
@property
|
||||
def hostname(self) -> str | None:
|
||||
return self.parsed_url.hostname
|
||||
|
||||
@property
|
||||
def port(self) -> int | None:
|
||||
return self.parsed_url.port
|
||||
|
||||
@property
|
||||
def username(self) -> str | None:
|
||||
return self.parsed_url.username
|
||||
|
||||
@property
|
||||
def password(self) -> str | None:
|
||||
return self.parsed_url.password
|
||||
|
||||
@property
|
||||
def path(self) -> pathlib.PurePosixPath:
|
||||
return pathlib.PurePosixPath(self.parsed_url.path)
|
||||
|
||||
def set_path(self, new_path: str | pathlib.Path | pathlib.PurePath) -> URL:
|
||||
self.replace_parsed_url_field(
|
||||
'path', str(pathlib.PurePosixPath(new_path)),
|
||||
)
|
||||
|
||||
return self
|
||||
|
||||
@property
|
||||
def params(self) -> str:
|
||||
return self.parsed_url.params
|
||||
|
||||
def set_params(self, new_params: str) -> URL:
|
||||
self.replace_parsed_url_field('params', new_params)
|
||||
|
||||
return self
|
||||
|
||||
@property
|
||||
def query(self) -> dict[typing.AnyStr, list[typing.AnyStr]]:
|
||||
if self.parsed_url.query == '':
|
||||
return {}
|
||||
|
||||
return urllib.parse.parse_qs(
|
||||
self.parsed_url.query, encoding=self.encoding, # type: ignore[arg-type]
|
||||
)
|
||||
|
||||
def set_query(self,
|
||||
new_query: dict[typing.AnyStr, list[typing.AnyStr]] | list,
|
||||
) -> URL:
|
||||
self.replace_parsed_url_field(
|
||||
'query', urllib.parse.urlencode(new_query, doseq=True),
|
||||
)
|
||||
|
||||
return self
|
||||
|
||||
@property
|
||||
def query_string(self) -> str:
|
||||
return self.parsed_url.query
|
||||
|
||||
def set_query_string(self, new_query_string: str) -> URL:
|
||||
self.replace_parsed_url_field('query', new_query_string)
|
||||
|
||||
return self
|
||||
|
||||
@property
|
||||
def fragment(self) -> str:
|
||||
return self.parsed_url.fragment
|
||||
|
||||
def set_fragment(self, new_fragment: str) -> URL:
|
||||
self.replace_parsed_url_field('fragment', new_fragment)
|
||||
|
||||
return self
|
||||
|
||||
def to_string(self) -> str:
|
||||
return urllib.parse.urlunparse(self.parsed_url)
|
||||
|
||||
def __truediv__(self, component: str | pathlib.Path) -> URL:
|
||||
return self.append_path_component(component)
|
||||
|
||||
def __mod__(self,
|
||||
query: dict[typing.AnyStr, list[typing.AnyStr]],
|
||||
) -> URL:
|
||||
return self.set_query(
|
||||
{**self.query, **query},
|
||||
)
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self.to_string()
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f'<URL {self}>'
|
||||
|
||||
def __bytes__(self) -> bytes:
|
||||
return self.__str__().encode(self.encoding)
|
||||
14
services/packages/common/hotpocket_common/uuid.py
Normal file
14
services/packages/common/hotpocket_common/uuid.py
Normal file
@@ -0,0 +1,14 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
import secrets
|
||||
|
||||
from uuid6 import UUID
|
||||
|
||||
|
||||
def uuid7_from_timestamp(timestamp: int) -> UUID:
|
||||
# The code below was shamelessly taken from `uuid6-python` package.
|
||||
# Copyright (c) 2021 oittaa | MIT License
|
||||
uuid_int = ((timestamp * 1_000) & 0xFFFFFFFFFFFF) << 80
|
||||
uuid_int |= secrets.randbits(76)
|
||||
return UUID(int=uuid_int, version=7)
|
||||
16
services/packages/common/pyproject.toml
Normal file
16
services/packages/common/pyproject.toml
Normal file
@@ -0,0 +1,16 @@
|
||||
[tool.poetry]
|
||||
name = "hotpocket-common"
|
||||
version = "1.0.0.dev0"
|
||||
description = "HotPocket Common"
|
||||
authors = ["Tomek Wójcik <contact@bthlabs.pl>"]
|
||||
license = "Apache-2.0"
|
||||
readme = "README.md"
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.12"
|
||||
django = "5.2.3"
|
||||
uuid6 = "2025.0.0"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
23
services/packages/docker-compose-ci.yaml
Normal file
23
services/packages/docker-compose-ci.yaml
Normal file
@@ -0,0 +1,23 @@
|
||||
services:
|
||||
packages-ci:
|
||||
build:
|
||||
context: ".."
|
||||
dockerfile: "packages/Dockerfile"
|
||||
target: "development"
|
||||
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/packages:ci-local"
|
||||
command: "echo 'NOOP'"
|
||||
environment:
|
||||
PYTHONBREAKPOINT: "ipdb.set_trace"
|
||||
HOTPOCKET_PACKAGES_ENV: "${HOTPOCKET_PACKAGES_ENV:-docker}"
|
||||
# REQUESTS_CA_BUNDLE: "/srv/tls/requests_ca_bundle.pem"
|
||||
RUN_POETRY_INSTALL: "true"
|
||||
RUN_YARN_INSTALL: "false"
|
||||
SETUP_BACKEND: "true"
|
||||
SETUP_FRONTEND: "false"
|
||||
volumes:
|
||||
- "packages_venv:/srv/venv"
|
||||
- "packages_node_modules:/srv/node_modules"
|
||||
- "../tls:/srv/tls"
|
||||
restart: "no"
|
||||
stdin_open: true
|
||||
tty: true
|
||||
28
services/packages/docker-compose.yaml
Normal file
28
services/packages/docker-compose.yaml
Normal file
@@ -0,0 +1,28 @@
|
||||
services:
|
||||
packages-management:
|
||||
build:
|
||||
context: ".."
|
||||
dockerfile: "packages/Dockerfile"
|
||||
target: "development"
|
||||
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/packages:local"
|
||||
command: "echo 'NOOP'"
|
||||
environment: &packages-env
|
||||
PYTHONBREAKPOINT: "ipdb.set_trace"
|
||||
HOTPOCKET_PACKAGES_ENV: "${HOTPOCKET_PACKAGES_ENV:-docker}"
|
||||
REQUESTS_CA_BUNDLE: "/srv/tls/requests_ca_bundle.pem"
|
||||
RUN_POETRY_INSTALL: "true"
|
||||
RUN_YARN_INSTALL: "false"
|
||||
SETUP_BACKEND: "true"
|
||||
SETUP_FRONTEND: "false"
|
||||
volumes:
|
||||
- "packages_venv:/srv/venv"
|
||||
- "packages_node_modules:/srv/node_modules"
|
||||
- ".:/srv/app"
|
||||
- "../tls:/srv/tls"
|
||||
restart: "no"
|
||||
stdin_open: true
|
||||
tty: true
|
||||
|
||||
volumes:
|
||||
packages_venv:
|
||||
packages_node_modules:
|
||||
3
services/packages/invoke.yaml
Normal file
3
services/packages/invoke.yaml
Normal file
@@ -0,0 +1,3 @@
|
||||
run:
|
||||
echo: true
|
||||
pty: true
|
||||
905
services/packages/poetry.lock
generated
Normal file
905
services/packages/poetry.lock
generated
Normal file
@@ -0,0 +1,905 @@
|
||||
# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand.
|
||||
|
||||
[[package]]
|
||||
name = "annotated-types"
|
||||
version = "0.7.0"
|
||||
description = "Reusable constraint types to use with typing.Annotated"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"},
|
||||
{file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "asgiref"
|
||||
version = "3.9.1"
|
||||
description = "ASGI specs, helper code, and adapters"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "asgiref-3.9.1-py3-none-any.whl", hash = "sha256:f3bba7092a48005b5f5bacd747d36ee4a5a61f4a269a6df590b43144355ebd2c"},
|
||||
{file = "asgiref-3.9.1.tar.gz", hash = "sha256:a5ab6582236218e5ef1648f242fd9f10626cfd4de8dc377db215d5d5098e3142"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
tests = ["mypy (>=1.14.0)", "pytest", "pytest-asyncio"]
|
||||
|
||||
[[package]]
|
||||
name = "asttokens"
|
||||
version = "3.0.0"
|
||||
description = "Annotate AST trees with source code positions"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "asttokens-3.0.0-py3-none-any.whl", hash = "sha256:e3078351a059199dd5138cb1c706e6430c05eff2ff136af5eb4790f9d28932e2"},
|
||||
{file = "asttokens-3.0.0.tar.gz", hash = "sha256:0dcd8baa8d62b0c1d118b399b2ddba3c4aff271d0d7a9e0d4c1681c79035bbc7"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
astroid = ["astroid (>=2,<4)"]
|
||||
test = ["astroid (>=2,<4)", "pytest", "pytest-cov", "pytest-xdist"]
|
||||
|
||||
[[package]]
|
||||
name = "colorama"
|
||||
version = "0.4.6"
|
||||
description = "Cross-platform colored terminal text."
|
||||
optional = false
|
||||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
|
||||
files = [
|
||||
{file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
|
||||
{file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "decorator"
|
||||
version = "5.2.1"
|
||||
description = "Decorators for Humans"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "decorator-5.2.1-py3-none-any.whl", hash = "sha256:d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a"},
|
||||
{file = "decorator-5.2.1.tar.gz", hash = "sha256:65f266143752f734b0a7cc83c46f4618af75b8c5911b00ccb61d0ac9b6da0360"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "django"
|
||||
version = "5.2.3"
|
||||
description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design."
|
||||
optional = false
|
||||
python-versions = ">=3.10"
|
||||
files = [
|
||||
{file = "django-5.2.3-py3-none-any.whl", hash = "sha256:c517a6334e0fd940066aa9467b29401b93c37cec2e61365d663b80922542069d"},
|
||||
{file = "django-5.2.3.tar.gz", hash = "sha256:335213277666ab2c5cac44a792a6d2f3d58eb79a80c14b6b160cd4afc3b75684"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
asgiref = ">=3.8.1"
|
||||
sqlparse = ">=0.3.1"
|
||||
tzdata = {version = "*", markers = "sys_platform == \"win32\""}
|
||||
|
||||
[package.extras]
|
||||
argon2 = ["argon2-cffi (>=19.1.0)"]
|
||||
bcrypt = ["bcrypt"]
|
||||
|
||||
[[package]]
|
||||
name = "executing"
|
||||
version = "2.2.0"
|
||||
description = "Get the currently executing AST node of a frame, and other information"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "executing-2.2.0-py2.py3-none-any.whl", hash = "sha256:11387150cad388d62750327a53d3339fad4888b39a6fe233c3afbb54ecffd3aa"},
|
||||
{file = "executing-2.2.0.tar.gz", hash = "sha256:5d108c028108fe2551d1a7b2e8b713341e2cb4fc0aa7dcf966fa4327a5226755"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich"]
|
||||
|
||||
[[package]]
|
||||
name = "factory-boy"
|
||||
version = "3.3.3"
|
||||
description = "A versatile test fixtures replacement based on thoughtbot's factory_bot for Ruby."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "factory_boy-3.3.3-py2.py3-none-any.whl", hash = "sha256:1c39e3289f7e667c4285433f305f8d506efc2fe9c73aaea4151ebd5cdea394fc"},
|
||||
{file = "factory_boy-3.3.3.tar.gz", hash = "sha256:866862d226128dfac7f2b4160287e899daf54f2612778327dd03d0e2cb1e3d03"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
Faker = ">=0.7.0"
|
||||
|
||||
[package.extras]
|
||||
dev = ["Django", "Pillow", "SQLAlchemy", "coverage", "flake8", "isort", "mongoengine", "mongomock", "mypy", "tox", "wheel (>=0.32.0)", "zest.releaser[recommended]"]
|
||||
doc = ["Sphinx", "sphinx-rtd-theme", "sphinxcontrib-spelling"]
|
||||
|
||||
[[package]]
|
||||
name = "faker"
|
||||
version = "37.4.0"
|
||||
description = "Faker is a Python package that generates fake data for you."
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "faker-37.4.0-py3-none-any.whl", hash = "sha256:cb81c09ebe06c32a10971d1bbdb264bb0e22b59af59548f011ac4809556ce533"},
|
||||
{file = "faker-37.4.0.tar.gz", hash = "sha256:7f69d579588c23d5ce671f3fa872654ede0e67047820255f43a4aa1925b89780"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
tzdata = "*"
|
||||
|
||||
[[package]]
|
||||
name = "flake8"
|
||||
version = "7.3.0"
|
||||
description = "the modular source code checker: pep8 pyflakes and co"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "flake8-7.3.0-py2.py3-none-any.whl", hash = "sha256:b9696257b9ce8beb888cdbe31cf885c90d31928fe202be0889a7cdafad32f01e"},
|
||||
{file = "flake8-7.3.0.tar.gz", hash = "sha256:fe044858146b9fc69b551a4b490d69cf960fcb78ad1edcb84e7fbb1b4a8e3872"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
mccabe = ">=0.7.0,<0.8.0"
|
||||
pycodestyle = ">=2.14.0,<2.15.0"
|
||||
pyflakes = ">=3.4.0,<3.5.0"
|
||||
|
||||
[[package]]
|
||||
name = "flake8-commas"
|
||||
version = "4.0.0"
|
||||
description = "Flake8 lint for trailing commas."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "flake8_commas-4.0.0-py3-none-any.whl", hash = "sha256:cad476d71ba72e8b941a8508d5b9ffb6b03e50f7102982474f085ad0d674b685"},
|
||||
{file = "flake8_commas-4.0.0.tar.gz", hash = "sha256:a68834b42a9a31c94ca790efe557a932c0eae21a3479c6b9a23c4dc077e3ea96"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
flake8 = ">=5"
|
||||
|
||||
[[package]]
|
||||
name = "freezegun"
|
||||
version = "1.5.2"
|
||||
description = "Let your Python tests travel through time"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "freezegun-1.5.2-py3-none-any.whl", hash = "sha256:5aaf3ba229cda57afab5bd311f0108d86b6fb119ae89d2cd9c43ec8c1733c85b"},
|
||||
{file = "freezegun-1.5.2.tar.gz", hash = "sha256:a54ae1d2f9c02dbf42e02c18a3ab95ab4295818b549a34dac55592d72a905181"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
python-dateutil = ">=2.7"
|
||||
|
||||
[[package]]
|
||||
name = "hotpocket-common"
|
||||
version = "1.0.0.dev0"
|
||||
description = "HotPocket Common"
|
||||
optional = false
|
||||
python-versions = "^3.12"
|
||||
files = []
|
||||
develop = true
|
||||
|
||||
[package.dependencies]
|
||||
django = "5.2.3"
|
||||
uuid6 = "2025.0.0"
|
||||
|
||||
[package.source]
|
||||
type = "directory"
|
||||
url = "common"
|
||||
|
||||
[[package]]
|
||||
name = "hotpocket-soa"
|
||||
version = "1.0.0.dev0"
|
||||
description = "HotPocket SOA"
|
||||
optional = false
|
||||
python-versions = "^3.12"
|
||||
files = []
|
||||
develop = true
|
||||
|
||||
[package.dependencies]
|
||||
pydantic = "2.11.7"
|
||||
|
||||
[package.source]
|
||||
type = "directory"
|
||||
url = "soa"
|
||||
|
||||
[[package]]
|
||||
name = "hotpocket-testing"
|
||||
version = "1.0.0.dev0"
|
||||
description = "HotPocket Testing"
|
||||
optional = false
|
||||
python-versions = "^3.12"
|
||||
files = []
|
||||
develop = true
|
||||
|
||||
[package.dependencies]
|
||||
python-dateutil = "2.9.0.post0"
|
||||
|
||||
[package.source]
|
||||
type = "directory"
|
||||
url = "testing"
|
||||
|
||||
[[package]]
|
||||
name = "hotpocket-workspace-tools"
|
||||
version = "1.0.0.dev0"
|
||||
description = "HotPocket Workspace Tools"
|
||||
optional = false
|
||||
python-versions = "^3.12"
|
||||
files = []
|
||||
develop = true
|
||||
|
||||
[package.source]
|
||||
type = "directory"
|
||||
url = "workspace_tools"
|
||||
|
||||
[[package]]
|
||||
name = "iniconfig"
|
||||
version = "2.1.0"
|
||||
description = "brain-dead simple config-ini parsing"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760"},
|
||||
{file = "iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "invoke"
|
||||
version = "2.2.0"
|
||||
description = "Pythonic task execution"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
{file = "invoke-2.2.0-py3-none-any.whl", hash = "sha256:6ea924cc53d4f78e3d98bc436b08069a03077e6f85ad1ddaa8a116d7dad15820"},
|
||||
{file = "invoke-2.2.0.tar.gz", hash = "sha256:ee6cbb101af1a859c7fe84f2a264c059020b0cb7fe3535f9424300ab568f6bd5"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ipdb"
|
||||
version = "0.13.13"
|
||||
description = "IPython-enabled pdb"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
files = [
|
||||
{file = "ipdb-0.13.13-py3-none-any.whl", hash = "sha256:45529994741c4ab6d2388bfa5d7b725c2cf7fe9deffabdb8a6113aa5ed449ed4"},
|
||||
{file = "ipdb-0.13.13.tar.gz", hash = "sha256:e3ac6018ef05126d442af680aad863006ec19d02290561ac88b8b1c0b0cfc726"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
decorator = {version = "*", markers = "python_version >= \"3.11\""}
|
||||
ipython = {version = ">=7.31.1", markers = "python_version >= \"3.11\""}
|
||||
|
||||
[[package]]
|
||||
name = "ipython"
|
||||
version = "9.3.0"
|
||||
description = "IPython: Productive Interactive Computing"
|
||||
optional = false
|
||||
python-versions = ">=3.11"
|
||||
files = [
|
||||
{file = "ipython-9.3.0-py3-none-any.whl", hash = "sha256:1a0b6dd9221a1f5dddf725b57ac0cb6fddc7b5f470576231ae9162b9b3455a04"},
|
||||
{file = "ipython-9.3.0.tar.gz", hash = "sha256:79eb896f9f23f50ad16c3bc205f686f6e030ad246cc309c6279a242b14afe9d8"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
colorama = {version = "*", markers = "sys_platform == \"win32\""}
|
||||
decorator = "*"
|
||||
ipython-pygments-lexers = "*"
|
||||
jedi = ">=0.16"
|
||||
matplotlib-inline = "*"
|
||||
pexpect = {version = ">4.3", markers = "sys_platform != \"win32\" and sys_platform != \"emscripten\""}
|
||||
prompt_toolkit = ">=3.0.41,<3.1.0"
|
||||
pygments = ">=2.4.0"
|
||||
stack_data = "*"
|
||||
traitlets = ">=5.13.0"
|
||||
|
||||
[package.extras]
|
||||
all = ["ipython[doc,matplotlib,test,test-extra]"]
|
||||
black = ["black"]
|
||||
doc = ["docrepr", "exceptiongroup", "intersphinx_registry", "ipykernel", "ipython[test]", "matplotlib", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "sphinx_toml (==0.0.4)", "typing_extensions"]
|
||||
matplotlib = ["matplotlib"]
|
||||
test = ["packaging", "pytest", "pytest-asyncio (<0.22)", "testpath"]
|
||||
test-extra = ["curio", "ipykernel", "ipython[test]", "jupyter_ai", "matplotlib (!=3.2.0)", "nbclient", "nbformat", "numpy (>=1.23)", "pandas", "trio"]
|
||||
|
||||
[[package]]
|
||||
name = "ipython-pygments-lexers"
|
||||
version = "1.1.1"
|
||||
description = "Defines a variety of Pygments lexers for highlighting IPython code."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "ipython_pygments_lexers-1.1.1-py3-none-any.whl", hash = "sha256:a9462224a505ade19a605f71f8fa63c2048833ce50abc86768a0d81d876dc81c"},
|
||||
{file = "ipython_pygments_lexers-1.1.1.tar.gz", hash = "sha256:09c0138009e56b6854f9535736f4171d855c8c08a563a0dcd8022f78355c7e81"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
pygments = "*"
|
||||
|
||||
[[package]]
|
||||
name = "isort"
|
||||
version = "6.0.1"
|
||||
description = "A Python utility / library to sort Python imports."
|
||||
optional = false
|
||||
python-versions = ">=3.9.0"
|
||||
files = [
|
||||
{file = "isort-6.0.1-py3-none-any.whl", hash = "sha256:2dc5d7f65c9678d94c88dfc29161a320eec67328bc97aad576874cb4be1e9615"},
|
||||
{file = "isort-6.0.1.tar.gz", hash = "sha256:1cb5df28dfbc742e490c5e41bad6da41b805b0a8be7bc93cd0fb2a8a890ac450"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
colors = ["colorama"]
|
||||
plugins = ["setuptools"]
|
||||
|
||||
[[package]]
|
||||
name = "jedi"
|
||||
version = "0.19.2"
|
||||
description = "An autocompletion tool for Python that can be used for text editors."
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
{file = "jedi-0.19.2-py2.py3-none-any.whl", hash = "sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9"},
|
||||
{file = "jedi-0.19.2.tar.gz", hash = "sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
parso = ">=0.8.4,<0.9.0"
|
||||
|
||||
[package.extras]
|
||||
docs = ["Jinja2 (==2.11.3)", "MarkupSafe (==1.1.1)", "Pygments (==2.8.1)", "alabaster (==0.7.12)", "babel (==2.9.1)", "chardet (==4.0.0)", "commonmark (==0.8.1)", "docutils (==0.17.1)", "future (==0.18.2)", "idna (==2.10)", "imagesize (==1.2.0)", "mock (==1.0.1)", "packaging (==20.9)", "pyparsing (==2.4.7)", "pytz (==2021.1)", "readthedocs-sphinx-ext (==2.1.4)", "recommonmark (==0.5.0)", "requests (==2.25.1)", "six (==1.15.0)", "snowballstemmer (==2.1.0)", "sphinx (==1.8.5)", "sphinx-rtd-theme (==0.4.3)", "sphinxcontrib-serializinghtml (==1.1.4)", "sphinxcontrib-websupport (==1.2.4)", "urllib3 (==1.26.4)"]
|
||||
qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"]
|
||||
testing = ["Django", "attrs", "colorama", "docopt", "pytest (<9.0.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "matplotlib-inline"
|
||||
version = "0.1.7"
|
||||
description = "Inline Matplotlib backend for Jupyter"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "matplotlib_inline-0.1.7-py3-none-any.whl", hash = "sha256:df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca"},
|
||||
{file = "matplotlib_inline-0.1.7.tar.gz", hash = "sha256:8423b23ec666be3d16e16b60bdd8ac4e86e840ebd1dd11a30b9f117f2fa0ab90"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
traitlets = "*"
|
||||
|
||||
[[package]]
|
||||
name = "mccabe"
|
||||
version = "0.7.0"
|
||||
description = "McCabe checker, plugin for flake8"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
{file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"},
|
||||
{file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mypy"
|
||||
version = "1.16.1"
|
||||
description = "Optional static typing for Python"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "mypy-1.16.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b4f0fed1022a63c6fec38f28b7fc77fca47fd490445c69d0a66266c59dd0b88a"},
|
||||
{file = "mypy-1.16.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:86042bbf9f5a05ea000d3203cf87aa9d0ccf9a01f73f71c58979eb9249f46d72"},
|
||||
{file = "mypy-1.16.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ea7469ee5902c95542bea7ee545f7006508c65c8c54b06dc2c92676ce526f3ea"},
|
||||
{file = "mypy-1.16.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:352025753ef6a83cb9e7f2427319bb7875d1fdda8439d1e23de12ab164179574"},
|
||||
{file = "mypy-1.16.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ff9fa5b16e4c1364eb89a4d16bcda9987f05d39604e1e6c35378a2987c1aac2d"},
|
||||
{file = "mypy-1.16.1-cp310-cp310-win_amd64.whl", hash = "sha256:1256688e284632382f8f3b9e2123df7d279f603c561f099758e66dd6ed4e8bd6"},
|
||||
{file = "mypy-1.16.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:472e4e4c100062488ec643f6162dd0d5208e33e2f34544e1fc931372e806c0cc"},
|
||||
{file = "mypy-1.16.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ea16e2a7d2714277e349e24d19a782a663a34ed60864006e8585db08f8ad1782"},
|
||||
{file = "mypy-1.16.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:08e850ea22adc4d8a4014651575567b0318ede51e8e9fe7a68f25391af699507"},
|
||||
{file = "mypy-1.16.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:22d76a63a42619bfb90122889b903519149879ddbf2ba4251834727944c8baca"},
|
||||
{file = "mypy-1.16.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2c7ce0662b6b9dc8f4ed86eb7a5d505ee3298c04b40ec13b30e572c0e5ae17c4"},
|
||||
{file = "mypy-1.16.1-cp311-cp311-win_amd64.whl", hash = "sha256:211287e98e05352a2e1d4e8759c5490925a7c784ddc84207f4714822f8cf99b6"},
|
||||
{file = "mypy-1.16.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:af4792433f09575d9eeca5c63d7d90ca4aeceda9d8355e136f80f8967639183d"},
|
||||
{file = "mypy-1.16.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:66df38405fd8466ce3517eda1f6640611a0b8e70895e2a9462d1d4323c5eb4b9"},
|
||||
{file = "mypy-1.16.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:44e7acddb3c48bd2713994d098729494117803616e116032af192871aed80b79"},
|
||||
{file = "mypy-1.16.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0ab5eca37b50188163fa7c1b73c685ac66c4e9bdee4a85c9adac0e91d8895e15"},
|
||||
{file = "mypy-1.16.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dedb6229b2c9086247e21a83c309754b9058b438704ad2f6807f0d8227f6ebdd"},
|
||||
{file = "mypy-1.16.1-cp312-cp312-win_amd64.whl", hash = "sha256:1f0435cf920e287ff68af3d10a118a73f212deb2ce087619eb4e648116d1fe9b"},
|
||||
{file = "mypy-1.16.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ddc91eb318c8751c69ddb200a5937f1232ee8efb4e64e9f4bc475a33719de438"},
|
||||
{file = "mypy-1.16.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:87ff2c13d58bdc4bbe7dc0dedfe622c0f04e2cb2a492269f3b418df2de05c536"},
|
||||
{file = "mypy-1.16.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a7cfb0fe29fe5a9841b7c8ee6dffb52382c45acdf68f032145b75620acfbd6f"},
|
||||
{file = "mypy-1.16.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:051e1677689c9d9578b9c7f4d206d763f9bbd95723cd1416fad50db49d52f359"},
|
||||
{file = "mypy-1.16.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d5d2309511cc56c021b4b4e462907c2b12f669b2dbeb68300110ec27723971be"},
|
||||
{file = "mypy-1.16.1-cp313-cp313-win_amd64.whl", hash = "sha256:4f58ac32771341e38a853c5d0ec0dfe27e18e27da9cdb8bbc882d2249c71a3ee"},
|
||||
{file = "mypy-1.16.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7fc688329af6a287567f45cc1cefb9db662defeb14625213a5b7da6e692e2069"},
|
||||
{file = "mypy-1.16.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e198ab3f55924c03ead626ff424cad1732d0d391478dfbf7bb97b34602395da"},
|
||||
{file = "mypy-1.16.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:09aa4f91ada245f0a45dbc47e548fd94e0dd5a8433e0114917dc3b526912a30c"},
|
||||
{file = "mypy-1.16.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:13c7cd5b1cb2909aa318a90fd1b7e31f17c50b242953e7dd58345b2a814f6383"},
|
||||
{file = "mypy-1.16.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:58e07fb958bc5d752a280da0e890c538f1515b79a65757bbdc54252ba82e0b40"},
|
||||
{file = "mypy-1.16.1-cp39-cp39-win_amd64.whl", hash = "sha256:f895078594d918f93337a505f8add9bd654d1a24962b4c6ed9390e12531eb31b"},
|
||||
{file = "mypy-1.16.1-py3-none-any.whl", hash = "sha256:5fc2ac4027d0ef28d6ba69a0343737a23c4d1b83672bf38d1fe237bdc0643b37"},
|
||||
{file = "mypy-1.16.1.tar.gz", hash = "sha256:6bd00a0a2094841c5e47e7374bb42b83d64c527a502e3334e1173a0c24437bab"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
mypy_extensions = ">=1.0.0"
|
||||
pathspec = ">=0.9.0"
|
||||
typing_extensions = ">=4.6.0"
|
||||
|
||||
[package.extras]
|
||||
dmypy = ["psutil (>=4.0)"]
|
||||
faster-cache = ["orjson"]
|
||||
install-types = ["pip"]
|
||||
mypyc = ["setuptools (>=50)"]
|
||||
reports = ["lxml"]
|
||||
|
||||
[[package]]
|
||||
name = "mypy-extensions"
|
||||
version = "1.1.0"
|
||||
description = "Type system extensions for programs checked with the mypy type checker."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505"},
|
||||
{file = "mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "packaging"
|
||||
version = "25.0"
|
||||
description = "Core utilities for Python packages"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484"},
|
||||
{file = "packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parso"
|
||||
version = "0.8.4"
|
||||
description = "A Python Parser"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
{file = "parso-0.8.4-py2.py3-none-any.whl", hash = "sha256:a418670a20291dacd2dddc80c377c5c3791378ee1e8d12bffc35420643d43f18"},
|
||||
{file = "parso-0.8.4.tar.gz", hash = "sha256:eb3a7b58240fb99099a345571deecc0f9540ea5f4dd2fe14c2a99d6b281ab92d"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"]
|
||||
testing = ["docopt", "pytest"]
|
||||
|
||||
[[package]]
|
||||
name = "pathspec"
|
||||
version = "0.12.1"
|
||||
description = "Utility library for gitignore style pattern matching of file paths."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"},
|
||||
{file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pexpect"
|
||||
version = "4.9.0"
|
||||
description = "Pexpect allows easy control of interactive console applications."
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523"},
|
||||
{file = "pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
ptyprocess = ">=0.5"
|
||||
|
||||
[[package]]
|
||||
name = "pluggy"
|
||||
version = "1.6.0"
|
||||
description = "plugin and hook calling mechanisms for python"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746"},
|
||||
{file = "pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
dev = ["pre-commit", "tox"]
|
||||
testing = ["coverage", "pytest", "pytest-benchmark"]
|
||||
|
||||
[[package]]
|
||||
name = "prompt-toolkit"
|
||||
version = "3.0.51"
|
||||
description = "Library for building powerful interactive command lines in Python"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "prompt_toolkit-3.0.51-py3-none-any.whl", hash = "sha256:52742911fde84e2d423e2f9a4cf1de7d7ac4e51958f648d9540e0fb8db077b07"},
|
||||
{file = "prompt_toolkit-3.0.51.tar.gz", hash = "sha256:931a162e3b27fc90c86f1b48bb1fb2c528c2761475e57c9c06de13311c7b54ed"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
wcwidth = "*"
|
||||
|
||||
[[package]]
|
||||
name = "ptyprocess"
|
||||
version = "0.7.0"
|
||||
description = "Run a subprocess in a pseudo terminal"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"},
|
||||
{file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pure-eval"
|
||||
version = "0.2.3"
|
||||
description = "Safely evaluate AST nodes without side effects"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0"},
|
||||
{file = "pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
tests = ["pytest"]
|
||||
|
||||
[[package]]
|
||||
name = "pycodestyle"
|
||||
version = "2.14.0"
|
||||
description = "Python style guide checker"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "pycodestyle-2.14.0-py2.py3-none-any.whl", hash = "sha256:dd6bf7cb4ee77f8e016f9c8e74a35ddd9f67e1d5fd4184d86c3b98e07099f42d"},
|
||||
{file = "pycodestyle-2.14.0.tar.gz", hash = "sha256:c4b5b517d278089ff9d0abdec919cd97262a3367449ea1c8b49b91529167b783"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pydantic"
|
||||
version = "2.11.7"
|
||||
description = "Data validation using Python type hints"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "pydantic-2.11.7-py3-none-any.whl", hash = "sha256:dde5df002701f6de26248661f6835bbe296a47bf73990135c7d07ce741b9623b"},
|
||||
{file = "pydantic-2.11.7.tar.gz", hash = "sha256:d989c3c6cb79469287b1569f7447a17848c998458d49ebe294e975b9baf0f0db"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
annotated-types = ">=0.6.0"
|
||||
pydantic-core = "2.33.2"
|
||||
typing-extensions = ">=4.12.2"
|
||||
typing-inspection = ">=0.4.0"
|
||||
|
||||
[package.extras]
|
||||
email = ["email-validator (>=2.0.0)"]
|
||||
timezone = ["tzdata"]
|
||||
|
||||
[[package]]
|
||||
name = "pydantic-core"
|
||||
version = "2.33.2"
|
||||
description = "Core functionality for Pydantic validation and serialization"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "pydantic_core-2.33.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2b3d326aaef0c0399d9afffeb6367d5e26ddc24d351dbc9c636840ac355dc5d8"},
|
||||
{file = "pydantic_core-2.33.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0e5b2671f05ba48b94cb90ce55d8bdcaaedb8ba00cc5359f6810fc918713983d"},
|
||||
{file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0069c9acc3f3981b9ff4cdfaf088e98d83440a4c7ea1bc07460af3d4dc22e72d"},
|
||||
{file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d53b22f2032c42eaaf025f7c40c2e3b94568ae077a606f006d206a463bc69572"},
|
||||
{file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0405262705a123b7ce9f0b92f123334d67b70fd1f20a9372b907ce1080c7ba02"},
|
||||
{file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4b25d91e288e2c4e0662b8038a28c6a07eaac3e196cfc4ff69de4ea3db992a1b"},
|
||||
{file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bdfe4b3789761f3bcb4b1ddf33355a71079858958e3a552f16d5af19768fef2"},
|
||||
{file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:efec8db3266b76ef9607c2c4c419bdb06bf335ae433b80816089ea7585816f6a"},
|
||||
{file = "pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:031c57d67ca86902726e0fae2214ce6770bbe2f710dc33063187a68744a5ecac"},
|
||||
{file = "pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:f8de619080e944347f5f20de29a975c2d815d9ddd8be9b9b7268e2e3ef68605a"},
|
||||
{file = "pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:73662edf539e72a9440129f231ed3757faab89630d291b784ca99237fb94db2b"},
|
||||
{file = "pydantic_core-2.33.2-cp310-cp310-win32.whl", hash = "sha256:0a39979dcbb70998b0e505fb1556a1d550a0781463ce84ebf915ba293ccb7e22"},
|
||||
{file = "pydantic_core-2.33.2-cp310-cp310-win_amd64.whl", hash = "sha256:b0379a2b24882fef529ec3b4987cb5d003b9cda32256024e6fe1586ac45fc640"},
|
||||
{file = "pydantic_core-2.33.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:4c5b0a576fb381edd6d27f0a85915c6daf2f8138dc5c267a57c08a62900758c7"},
|
||||
{file = "pydantic_core-2.33.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e799c050df38a639db758c617ec771fd8fb7a5f8eaaa4b27b101f266b216a246"},
|
||||
{file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dc46a01bf8d62f227d5ecee74178ffc448ff4e5197c756331f71efcc66dc980f"},
|
||||
{file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a144d4f717285c6d9234a66778059f33a89096dfb9b39117663fd8413d582dcc"},
|
||||
{file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:73cf6373c21bc80b2e0dc88444f41ae60b2f070ed02095754eb5a01df12256de"},
|
||||
{file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3dc625f4aa79713512d1976fe9f0bc99f706a9dee21dfd1810b4bbbf228d0e8a"},
|
||||
{file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:881b21b5549499972441da4758d662aeea93f1923f953e9cbaff14b8b9565aef"},
|
||||
{file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bdc25f3681f7b78572699569514036afe3c243bc3059d3942624e936ec93450e"},
|
||||
{file = "pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:fe5b32187cbc0c862ee201ad66c30cf218e5ed468ec8dc1cf49dec66e160cc4d"},
|
||||
{file = "pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:bc7aee6f634a6f4a95676fcb5d6559a2c2a390330098dba5e5a5f28a2e4ada30"},
|
||||
{file = "pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:235f45e5dbcccf6bd99f9f472858849f73d11120d76ea8707115415f8e5ebebf"},
|
||||
{file = "pydantic_core-2.33.2-cp311-cp311-win32.whl", hash = "sha256:6368900c2d3ef09b69cb0b913f9f8263b03786e5b2a387706c5afb66800efd51"},
|
||||
{file = "pydantic_core-2.33.2-cp311-cp311-win_amd64.whl", hash = "sha256:1e063337ef9e9820c77acc768546325ebe04ee38b08703244c1309cccc4f1bab"},
|
||||
{file = "pydantic_core-2.33.2-cp311-cp311-win_arm64.whl", hash = "sha256:6b99022f1d19bc32a4c2a0d544fc9a76e3be90f0b3f4af413f87d38749300e65"},
|
||||
{file = "pydantic_core-2.33.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a7ec89dc587667f22b6a0b6579c249fca9026ce7c333fc142ba42411fa243cdc"},
|
||||
{file = "pydantic_core-2.33.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3c6db6e52c6d70aa0d00d45cdb9b40f0433b96380071ea80b09277dba021ddf7"},
|
||||
{file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e61206137cbc65e6d5256e1166f88331d3b6238e082d9f74613b9b765fb9025"},
|
||||
{file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eb8c529b2819c37140eb51b914153063d27ed88e3bdc31b71198a198e921e011"},
|
||||
{file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c52b02ad8b4e2cf14ca7b3d918f3eb0ee91e63b3167c32591e57c4317e134f8f"},
|
||||
{file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:96081f1605125ba0855dfda83f6f3df5ec90c61195421ba72223de35ccfb2f88"},
|
||||
{file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f57a69461af2a5fa6e6bbd7a5f60d3b7e6cebb687f55106933188e79ad155c1"},
|
||||
{file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:572c7e6c8bb4774d2ac88929e3d1f12bc45714ae5ee6d9a788a9fb35e60bb04b"},
|
||||
{file = "pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:db4b41f9bd95fbe5acd76d89920336ba96f03e149097365afe1cb092fceb89a1"},
|
||||
{file = "pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:fa854f5cf7e33842a892e5c73f45327760bc7bc516339fda888c75ae60edaeb6"},
|
||||
{file = "pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5f483cfb75ff703095c59e365360cb73e00185e01aaea067cd19acffd2ab20ea"},
|
||||
{file = "pydantic_core-2.33.2-cp312-cp312-win32.whl", hash = "sha256:9cb1da0f5a471435a7bc7e439b8a728e8b61e59784b2af70d7c169f8dd8ae290"},
|
||||
{file = "pydantic_core-2.33.2-cp312-cp312-win_amd64.whl", hash = "sha256:f941635f2a3d96b2973e867144fde513665c87f13fe0e193c158ac51bfaaa7b2"},
|
||||
{file = "pydantic_core-2.33.2-cp312-cp312-win_arm64.whl", hash = "sha256:cca3868ddfaccfbc4bfb1d608e2ccaaebe0ae628e1416aeb9c4d88c001bb45ab"},
|
||||
{file = "pydantic_core-2.33.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:1082dd3e2d7109ad8b7da48e1d4710c8d06c253cbc4a27c1cff4fbcaa97a9e3f"},
|
||||
{file = "pydantic_core-2.33.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f517ca031dfc037a9c07e748cefd8d96235088b83b4f4ba8939105d20fa1dcd6"},
|
||||
{file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a9f2c9dd19656823cb8250b0724ee9c60a82f3cdf68a080979d13092a3b0fef"},
|
||||
{file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2b0a451c263b01acebe51895bfb0e1cc842a5c666efe06cdf13846c7418caa9a"},
|
||||
{file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ea40a64d23faa25e62a70ad163571c0b342b8bf66d5fa612ac0dec4f069d916"},
|
||||
{file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fb2d542b4d66f9470e8065c5469ec676978d625a8b7a363f07d9a501a9cb36a"},
|
||||
{file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdac5d6ffa1b5a83bca06ffe7583f5576555e6c8b3a91fbd25ea7780f825f7d"},
|
||||
{file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:04a1a413977ab517154eebb2d326da71638271477d6ad87a769102f7c2488c56"},
|
||||
{file = "pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c8e7af2f4e0194c22b5b37205bfb293d166a7344a5b0d0eaccebc376546d77d5"},
|
||||
{file = "pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:5c92edd15cd58b3c2d34873597a1e20f13094f59cf88068adb18947df5455b4e"},
|
||||
{file = "pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:65132b7b4a1c0beded5e057324b7e16e10910c106d43675d9bd87d4f38dde162"},
|
||||
{file = "pydantic_core-2.33.2-cp313-cp313-win32.whl", hash = "sha256:52fb90784e0a242bb96ec53f42196a17278855b0f31ac7c3cc6f5c1ec4811849"},
|
||||
{file = "pydantic_core-2.33.2-cp313-cp313-win_amd64.whl", hash = "sha256:c083a3bdd5a93dfe480f1125926afcdbf2917ae714bdb80b36d34318b2bec5d9"},
|
||||
{file = "pydantic_core-2.33.2-cp313-cp313-win_arm64.whl", hash = "sha256:e80b087132752f6b3d714f041ccf74403799d3b23a72722ea2e6ba2e892555b9"},
|
||||
{file = "pydantic_core-2.33.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:61c18fba8e5e9db3ab908620af374db0ac1baa69f0f32df4f61ae23f15e586ac"},
|
||||
{file = "pydantic_core-2.33.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95237e53bb015f67b63c91af7518a62a8660376a6a0db19b89acc77a4d6199f5"},
|
||||
{file = "pydantic_core-2.33.2-cp313-cp313t-win_amd64.whl", hash = "sha256:c2fc0a768ef76c15ab9238afa6da7f69895bb5d1ee83aeea2e3509af4472d0b9"},
|
||||
{file = "pydantic_core-2.33.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a2b911a5b90e0374d03813674bf0a5fbbb7741570dcd4b4e85a2e48d17def29d"},
|
||||
{file = "pydantic_core-2.33.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6fa6dfc3e4d1f734a34710f391ae822e0a8eb8559a85c6979e14e65ee6ba2954"},
|
||||
{file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c54c939ee22dc8e2d545da79fc5381f1c020d6d3141d3bd747eab59164dc89fb"},
|
||||
{file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:53a57d2ed685940a504248187d5685e49eb5eef0f696853647bf37c418c538f7"},
|
||||
{file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09fb9dd6571aacd023fe6aaca316bd01cf60ab27240d7eb39ebd66a3a15293b4"},
|
||||
{file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0e6116757f7959a712db11f3e9c0a99ade00a5bbedae83cb801985aa154f071b"},
|
||||
{file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d55ab81c57b8ff8548c3e4947f119551253f4e3787a7bbc0b6b3ca47498a9d3"},
|
||||
{file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c20c462aa4434b33a2661701b861604913f912254e441ab8d78d30485736115a"},
|
||||
{file = "pydantic_core-2.33.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:44857c3227d3fb5e753d5fe4a3420d6376fa594b07b621e220cd93703fe21782"},
|
||||
{file = "pydantic_core-2.33.2-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:eb9b459ca4df0e5c87deb59d37377461a538852765293f9e6ee834f0435a93b9"},
|
||||
{file = "pydantic_core-2.33.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9fcd347d2cc5c23b06de6d3b7b8275be558a0c90549495c699e379a80bf8379e"},
|
||||
{file = "pydantic_core-2.33.2-cp39-cp39-win32.whl", hash = "sha256:83aa99b1285bc8f038941ddf598501a86f1536789740991d7d8756e34f1e74d9"},
|
||||
{file = "pydantic_core-2.33.2-cp39-cp39-win_amd64.whl", hash = "sha256:f481959862f57f29601ccced557cc2e817bce7533ab8e01a797a48b49c9692b3"},
|
||||
{file = "pydantic_core-2.33.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5c4aa4e82353f65e548c476b37e64189783aa5384903bfea4f41580f255fddfa"},
|
||||
{file = "pydantic_core-2.33.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d946c8bf0d5c24bf4fe333af284c59a19358aa3ec18cb3dc4370080da1e8ad29"},
|
||||
{file = "pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87b31b6846e361ef83fedb187bb5b4372d0da3f7e28d85415efa92d6125d6e6d"},
|
||||
{file = "pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa9d91b338f2df0508606f7009fde642391425189bba6d8c653afd80fd6bb64e"},
|
||||
{file = "pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2058a32994f1fde4ca0480ab9d1e75a0e8c87c22b53a3ae66554f9af78f2fe8c"},
|
||||
{file = "pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:0e03262ab796d986f978f79c943fc5f620381be7287148b8010b4097f79a39ec"},
|
||||
{file = "pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:1a8695a8d00c73e50bff9dfda4d540b7dee29ff9b8053e38380426a85ef10052"},
|
||||
{file = "pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:fa754d1850735a0b0e03bcffd9d4b4343eb417e47196e4485d9cca326073a42c"},
|
||||
{file = "pydantic_core-2.33.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a11c8d26a50bfab49002947d3d237abe4d9e4b5bdc8846a63537b6488e197808"},
|
||||
{file = "pydantic_core-2.33.2-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:dd14041875d09cc0f9308e37a6f8b65f5585cf2598a53aa0123df8b129d481f8"},
|
||||
{file = "pydantic_core-2.33.2-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:d87c561733f66531dced0da6e864f44ebf89a8fba55f31407b00c2f7f9449593"},
|
||||
{file = "pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f82865531efd18d6e07a04a17331af02cb7a651583c418df8266f17a63c6612"},
|
||||
{file = "pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bfb5112df54209d820d7bf9317c7a6c9025ea52e49f46b6a2060104bba37de7"},
|
||||
{file = "pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:64632ff9d614e5eecfb495796ad51b0ed98c453e447a76bcbeeb69615079fc7e"},
|
||||
{file = "pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:f889f7a40498cc077332c7ab6b4608d296d852182211787d4f3ee377aaae66e8"},
|
||||
{file = "pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:de4b83bb311557e439b9e186f733f6c645b9417c84e2eb8203f3f820a4b988bf"},
|
||||
{file = "pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:82f68293f055f51b51ea42fafc74b6aad03e70e191799430b90c13d643059ebb"},
|
||||
{file = "pydantic_core-2.33.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:329467cecfb529c925cf2bbd4d60d2c509bc2fb52a20c1045bf09bb70971a9c1"},
|
||||
{file = "pydantic_core-2.33.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:87acbfcf8e90ca885206e98359d7dca4bcbb35abdc0ff66672a293e1d7a19101"},
|
||||
{file = "pydantic_core-2.33.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:7f92c15cd1e97d4b12acd1cc9004fa092578acfa57b67ad5e43a197175d01a64"},
|
||||
{file = "pydantic_core-2.33.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3f26877a748dc4251cfcfda9dfb5f13fcb034f5308388066bcfe9031b63ae7d"},
|
||||
{file = "pydantic_core-2.33.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dac89aea9af8cd672fa7b510e7b8c33b0bba9a43186680550ccf23020f32d535"},
|
||||
{file = "pydantic_core-2.33.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:970919794d126ba8645f3837ab6046fb4e72bbc057b3709144066204c19a455d"},
|
||||
{file = "pydantic_core-2.33.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:3eb3fe62804e8f859c49ed20a8451342de53ed764150cb14ca71357c765dc2a6"},
|
||||
{file = "pydantic_core-2.33.2-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:3abcd9392a36025e3bd55f9bd38d908bd17962cc49bc6da8e7e96285336e2bca"},
|
||||
{file = "pydantic_core-2.33.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:3a1c81334778f9e3af2f8aeb7a960736e5cab1dfebfb26aabca09afd2906c039"},
|
||||
{file = "pydantic_core-2.33.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2807668ba86cb38c6817ad9bc66215ab8584d1d304030ce4f0887336f28a5e27"},
|
||||
{file = "pydantic_core-2.33.2.tar.gz", hash = "sha256:7cb8bc3605c29176e1b105350d2e6474142d7c1bd1d9327c4a9bdb46bf827acc"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0"
|
||||
|
||||
[[package]]
|
||||
name = "pyflakes"
|
||||
version = "3.4.0"
|
||||
description = "passive checker of Python programs"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "pyflakes-3.4.0-py2.py3-none-any.whl", hash = "sha256:f742a7dbd0d9cb9ea41e9a24a918996e8170c799fa528688d40dd582c8265f4f"},
|
||||
{file = "pyflakes-3.4.0.tar.gz", hash = "sha256:b24f96fafb7d2ab0ec5075b7350b3d2d2218eab42003821c06344973d3ea2f58"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pygments"
|
||||
version = "2.19.2"
|
||||
description = "Pygments is a syntax highlighting package written in Python."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b"},
|
||||
{file = "pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
windows-terminal = ["colorama (>=0.4.6)"]
|
||||
|
||||
[[package]]
|
||||
name = "pytest"
|
||||
version = "8.4.1"
|
||||
description = "pytest: simple powerful testing with Python"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "pytest-8.4.1-py3-none-any.whl", hash = "sha256:539c70ba6fcead8e78eebbf1115e8b589e7565830d7d006a8723f19ac8a0afb7"},
|
||||
{file = "pytest-8.4.1.tar.gz", hash = "sha256:7c67fd69174877359ed9371ec3af8a3d2b04741818c51e5e99cc1742251fa93c"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
colorama = {version = ">=0.4", markers = "sys_platform == \"win32\""}
|
||||
iniconfig = ">=1"
|
||||
packaging = ">=20"
|
||||
pluggy = ">=1.5,<2"
|
||||
pygments = ">=2.7.2"
|
||||
|
||||
[package.extras]
|
||||
dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "requests", "setuptools", "xmlschema"]
|
||||
|
||||
[[package]]
|
||||
name = "pytest-env"
|
||||
version = "1.1.5"
|
||||
description = "pytest plugin that allows you to add environment variables."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "pytest_env-1.1.5-py3-none-any.whl", hash = "sha256:ce90cf8772878515c24b31cd97c7fa1f4481cd68d588419fd45f10ecaee6bc30"},
|
||||
{file = "pytest_env-1.1.5.tar.gz", hash = "sha256:91209840aa0e43385073ac464a554ad2947cc2fd663a9debf88d03b01e0cc1cf"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
pytest = ">=8.3.3"
|
||||
|
||||
[package.extras]
|
||||
testing = ["covdefaults (>=2.3)", "coverage (>=7.6.1)", "pytest-mock (>=3.14)"]
|
||||
|
||||
[[package]]
|
||||
name = "pytest-mock"
|
||||
version = "3.14.1"
|
||||
description = "Thin-wrapper around the mock package for easier use with pytest"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "pytest_mock-3.14.1-py3-none-any.whl", hash = "sha256:178aefcd11307d874b4cd3100344e7e2d888d9791a6a1d9bfe90fbc1b74fd1d0"},
|
||||
{file = "pytest_mock-3.14.1.tar.gz", hash = "sha256:159e9edac4c451ce77a5cdb9fc5d1100708d2dd4ba3c3df572f14097351af80e"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
pytest = ">=6.2.5"
|
||||
|
||||
[package.extras]
|
||||
dev = ["pre-commit", "pytest-asyncio", "tox"]
|
||||
|
||||
[[package]]
|
||||
name = "python-dateutil"
|
||||
version = "2.9.0.post0"
|
||||
description = "Extensions to the standard Python datetime module"
|
||||
optional = false
|
||||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7"
|
||||
files = [
|
||||
{file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"},
|
||||
{file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
six = ">=1.5"
|
||||
|
||||
[[package]]
|
||||
name = "six"
|
||||
version = "1.17.0"
|
||||
description = "Python 2 and 3 compatibility utilities"
|
||||
optional = false
|
||||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7"
|
||||
files = [
|
||||
{file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"},
|
||||
{file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sqlparse"
|
||||
version = "0.5.3"
|
||||
description = "A non-validating SQL parser."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "sqlparse-0.5.3-py3-none-any.whl", hash = "sha256:cf2196ed3418f3ba5de6af7e82c694a9fbdbfecccdfc72e281548517081f16ca"},
|
||||
{file = "sqlparse-0.5.3.tar.gz", hash = "sha256:09f67787f56a0b16ecdbde1bfc7f5d9c3371ca683cfeaa8e6ff60b4807ec9272"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
dev = ["build", "hatch"]
|
||||
doc = ["sphinx"]
|
||||
|
||||
[[package]]
|
||||
name = "stack-data"
|
||||
version = "0.6.3"
|
||||
description = "Extract data from python stack frames and tracebacks for informative displays"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695"},
|
||||
{file = "stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
asttokens = ">=2.1.0"
|
||||
executing = ">=1.2.0"
|
||||
pure-eval = "*"
|
||||
|
||||
[package.extras]
|
||||
tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"]
|
||||
|
||||
[[package]]
|
||||
name = "traitlets"
|
||||
version = "5.14.3"
|
||||
description = "Traitlets Python configuration system"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f"},
|
||||
{file = "traitlets-5.14.3.tar.gz", hash = "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"]
|
||||
test = ["argcomplete (>=3.0.3)", "mypy (>=1.7.0)", "pre-commit", "pytest (>=7.0,<8.2)", "pytest-mock", "pytest-mypy-testing"]
|
||||
|
||||
[[package]]
|
||||
name = "typing-extensions"
|
||||
version = "4.14.0"
|
||||
description = "Backported and Experimental Type Hints for Python 3.9+"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "typing_extensions-4.14.0-py3-none-any.whl", hash = "sha256:a1514509136dd0b477638fc68d6a91497af5076466ad0fa6c338e44e359944af"},
|
||||
{file = "typing_extensions-4.14.0.tar.gz", hash = "sha256:8676b788e32f02ab42d9e7c61324048ae4c6d844a399eebace3d4979d75ceef4"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typing-inspection"
|
||||
version = "0.4.1"
|
||||
description = "Runtime typing introspection tools"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "typing_inspection-0.4.1-py3-none-any.whl", hash = "sha256:389055682238f53b04f7badcb49b989835495a96700ced5dab2d8feae4b26f51"},
|
||||
{file = "typing_inspection-0.4.1.tar.gz", hash = "sha256:6ae134cc0203c33377d43188d4064e9b357dba58cff3185f22924610e70a9d28"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
typing-extensions = ">=4.12.0"
|
||||
|
||||
[[package]]
|
||||
name = "tzdata"
|
||||
version = "2025.2"
|
||||
description = "Provider of IANA time zone data"
|
||||
optional = false
|
||||
python-versions = ">=2"
|
||||
files = [
|
||||
{file = "tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8"},
|
||||
{file = "tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uuid6"
|
||||
version = "2025.0.0"
|
||||
description = "New time-based UUID formats which are suited for use as a database key"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "uuid6-2025.0.0-py3-none-any.whl", hash = "sha256:2c73405ff5333c7181443958c6865e0d1b9b816bb160549e8d80ba186263cb3a"},
|
||||
{file = "uuid6-2025.0.0.tar.gz", hash = "sha256:bb78aa300e29db89b00410371d0c1f1824e59e29995a9daa3dedc8033d1d84ec"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wcwidth"
|
||||
version = "0.2.13"
|
||||
description = "Measures the displayed width of unicode strings in a terminal"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"},
|
||||
{file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"},
|
||||
]
|
||||
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.12"
|
||||
content-hash = "02c9f754b0dbe7e7b2f24d576f294be52027f4267b9a8ea3ac316f2eba1b881b"
|
||||
33
services/packages/pyproject.toml
Normal file
33
services/packages/pyproject.toml
Normal file
@@ -0,0 +1,33 @@
|
||||
[tool.poetry]
|
||||
name = "hotpocket-packages"
|
||||
version = "1.0.0.dev0"
|
||||
description = "HotPocket Packages"
|
||||
authors = ["Tomek Wójcik <contact@bthlabs.pl>"]
|
||||
license = "Apache-2.0"
|
||||
readme = "README.md"
|
||||
package-mode = false
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.12"
|
||||
hotpocket-common = {path = "common", develop = true}
|
||||
hotpocket-soa = {path = "soa", develop = true}
|
||||
hotpocket-testing = {path = "testing", develop = true}
|
||||
hotpocket-workspace-tools = {path = "workspace_tools", develop = true}
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
factory-boy = "3.3.3"
|
||||
flake8 = "7.3.0"
|
||||
flake8-commas = "4.0.0"
|
||||
freezegun = "1.5.2"
|
||||
invoke = "2.2.0"
|
||||
ipdb = "0.13.13"
|
||||
ipython = "9.3.0"
|
||||
isort = "6.0.1"
|
||||
mypy = "1.16.1"
|
||||
pytest = "8.4.1"
|
||||
pytest-env = "1.1.5"
|
||||
pytest-mock = "3.14.1"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
28
services/packages/setup.cfg
Normal file
28
services/packages/setup.cfg
Normal file
@@ -0,0 +1,28 @@
|
||||
[flake8]
|
||||
extend-exclude =
|
||||
skel/*.py
|
||||
skel/*/*.py
|
||||
ignore = E131
|
||||
max-line-length = 119
|
||||
hang-closing = False
|
||||
|
||||
[isort]
|
||||
known_first_party=hotpocket_backend,hotpocket_backend_testing,hotpocket_common,hotpocket_soa,hotpocket_testing
|
||||
multi_line_output=3
|
||||
include_trailing_comma=true
|
||||
force_sort_within_sections=true
|
||||
line_length=80
|
||||
use_parentheses=true
|
||||
combine_as_imports=true
|
||||
star_first=true
|
||||
|
||||
[mypy]
|
||||
|
||||
[mypy-dateutil.*]
|
||||
ignore_missing_imports = true
|
||||
|
||||
[mypy-django.*]
|
||||
ignore_missing_imports = true
|
||||
|
||||
[mypy-hotpocket_backend.*]
|
||||
ignore_missing_imports = true
|
||||
3
services/packages/soa/README.md
Normal file
3
services/packages/soa/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# HotPocket by BTHLabs
|
||||
|
||||
This repository contains the _HotPocket SOA_ project.
|
||||
0
services/packages/soa/hotpocket_soa/__init__.py
Normal file
0
services/packages/soa/hotpocket_soa/__init__.py
Normal file
2
services/packages/soa/hotpocket_soa/dto/__init__.py
Normal file
2
services/packages/soa/hotpocket_soa/dto/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
from .bot import BotResultOut # noqa: F401
|
||||
from .saves import SaveIn, SaveOut # noqa: F401
|
||||
76
services/packages/soa/hotpocket_soa/dto/associations.py
Normal file
76
services/packages/soa/hotpocket_soa/dto/associations.py
Normal file
@@ -0,0 +1,76 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
import datetime
|
||||
import uuid
|
||||
|
||||
import pydantic
|
||||
|
||||
from hotpocket_common.constants import AssociationsSearchMode
|
||||
|
||||
from .base import ModelOut, Query
|
||||
from .saves import SaveOut
|
||||
|
||||
|
||||
class AssociationOut(ModelOut):
|
||||
archived_at: datetime.datetime | None
|
||||
starred_at: datetime.datetime | None
|
||||
target_uuid: uuid.UUID = pydantic.Field(alias='target_id')
|
||||
target_meta: dict
|
||||
target_title: str | None
|
||||
target_description: str | None
|
||||
|
||||
@property
|
||||
def is_starred(self) -> bool:
|
||||
return self.starred_at is not None
|
||||
|
||||
def get_title(self) -> str | None:
|
||||
return (
|
||||
self.target_title
|
||||
if self.target_title is not None
|
||||
else self.target_meta.get('title', None)
|
||||
)
|
||||
|
||||
def get_description(self) -> str | None:
|
||||
return (
|
||||
self.target_description
|
||||
if self.target_description is not None
|
||||
else self.target_meta.get('description', None)
|
||||
)
|
||||
|
||||
@property
|
||||
def title(self) -> str | None:
|
||||
return self.get_title()
|
||||
|
||||
@property
|
||||
def description(self) -> str | None:
|
||||
return self.get_description()
|
||||
|
||||
|
||||
class AssociationWithTargetOut(AssociationOut):
|
||||
target: SaveOut
|
||||
|
||||
@property
|
||||
def title(self) -> str | None:
|
||||
return self.get_title() or self.target.title
|
||||
|
||||
@property
|
||||
def description(self) -> str | None:
|
||||
return self.get_description() or self.target.description
|
||||
|
||||
|
||||
class AssociationIn(pydantic.BaseModel):
|
||||
archived_at: datetime.datetime | None
|
||||
|
||||
|
||||
class AssociationsQuery(Query):
|
||||
account_uuid: uuid.UUID
|
||||
before: uuid.UUID | None = pydantic.Field(default=None)
|
||||
after: uuid.UUID | None = pydantic.Field(default=None)
|
||||
search: str | None = pydantic.Field(default=None)
|
||||
mode: AssociationsSearchMode = pydantic.Field(default=AssociationsSearchMode.DEFAULT)
|
||||
|
||||
|
||||
class AssociationUpdateIn(pydantic.BaseModel):
|
||||
target_title: str | None = pydantic.Field(default=None)
|
||||
target_description: str | None = pydantic.Field(default=None)
|
||||
24
services/packages/soa/hotpocket_soa/dto/base.py
Normal file
24
services/packages/soa/hotpocket_soa/dto/base.py
Normal file
@@ -0,0 +1,24 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
import datetime
|
||||
import uuid
|
||||
|
||||
import pydantic
|
||||
|
||||
|
||||
class ModelOut(pydantic.BaseModel):
|
||||
id: uuid.UUID
|
||||
account_uuid: uuid.UUID
|
||||
created_at: datetime.datetime
|
||||
updated_at: datetime.datetime
|
||||
deleted_at: datetime.datetime | None
|
||||
is_active: bool
|
||||
|
||||
@property
|
||||
def pk(self) -> uuid.UUID:
|
||||
return self.id
|
||||
|
||||
|
||||
class Query(pydantic.BaseModel):
|
||||
pass
|
||||
10
services/packages/soa/hotpocket_soa/dto/bot.py
Normal file
10
services/packages/soa/hotpocket_soa/dto/bot.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
import pydantic
|
||||
|
||||
|
||||
class BotResultOut(pydantic.BaseModel):
|
||||
title: str | None
|
||||
description: str | None
|
||||
is_netloc_banned: bool
|
||||
8
services/packages/soa/hotpocket_soa/dto/celery.py
Normal file
8
services/packages/soa/hotpocket_soa/dto/celery.py
Normal file
@@ -0,0 +1,8 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
import pydantic
|
||||
|
||||
|
||||
class AsyncResultOut(pydantic.BaseModel):
|
||||
id: str
|
||||
65
services/packages/soa/hotpocket_soa/dto/saves.py
Normal file
65
services/packages/soa/hotpocket_soa/dto/saves.py
Normal file
@@ -0,0 +1,65 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
import datetime
|
||||
import urllib.parse
|
||||
|
||||
import pydantic
|
||||
|
||||
from .base import ModelOut, Query
|
||||
|
||||
|
||||
class SaveOut(ModelOut):
|
||||
key: str
|
||||
url: str
|
||||
title: str | None
|
||||
description: str | None
|
||||
last_processed_at: datetime.datetime | None
|
||||
is_netloc_banned: bool
|
||||
|
||||
@property
|
||||
def parsed_url(self) -> urllib.parse.SplitResult:
|
||||
if hasattr(self, '_parsed_url') is False:
|
||||
self._parsed_url = urllib.parse.urlsplit(self.url)
|
||||
|
||||
return self._parsed_url
|
||||
|
||||
@property
|
||||
def parsed_url_query(self) -> dict:
|
||||
if hasattr(self, '_parsed_url_query') is False:
|
||||
self._parsed_url_query = urllib.parse.parse_qs(
|
||||
self.parsed_url.query,
|
||||
)
|
||||
|
||||
return self._parsed_url_query
|
||||
|
||||
@property
|
||||
def netloc(self) -> str:
|
||||
return self.parsed_url.netloc
|
||||
|
||||
@property
|
||||
def is_youtube_video(self) -> bool:
|
||||
return any((
|
||||
all((
|
||||
self.netloc.endswith('youtube.com'),
|
||||
'v' in self.parsed_url_query,
|
||||
)),
|
||||
all((
|
||||
self.netloc.endswith('youtube.com'),
|
||||
self.parsed_url.path.startswith('/live'),
|
||||
)),
|
||||
self.netloc.endswith('youtu.be'),
|
||||
))
|
||||
|
||||
|
||||
class SaveIn(pydantic.BaseModel):
|
||||
url: str
|
||||
is_netloc_banned: bool | None = pydantic.Field(default=None)
|
||||
|
||||
|
||||
class ImportedSaveIn(SaveIn):
|
||||
title: str
|
||||
|
||||
|
||||
class SavesQuery(Query):
|
||||
pass
|
||||
0
services/packages/soa/hotpocket_soa/py.typed
Normal file
0
services/packages/soa/hotpocket_soa/py.typed
Normal file
4
services/packages/soa/hotpocket_soa/services/__init__.py
Normal file
4
services/packages/soa/hotpocket_soa/services/__init__.py
Normal file
@@ -0,0 +1,4 @@
|
||||
from .associations import AssociationsService # noqa: F401
|
||||
from .bot import BotService # noqa: F401
|
||||
from .save_processor import SaveProcessorService # noqa: F401
|
||||
from .saves import SavesService # noqa: F401
|
||||
161
services/packages/soa/hotpocket_soa/services/associations.py
Normal file
161
services/packages/soa/hotpocket_soa/services/associations.py
Normal file
@@ -0,0 +1,161 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
import datetime
|
||||
import uuid
|
||||
|
||||
from hotpocket_backend.apps.saves.services import (
|
||||
AssociationsService as BackendAssociationsService,
|
||||
)
|
||||
from hotpocket_soa.dto.associations import (
|
||||
AssociationOut,
|
||||
AssociationsQuery,
|
||||
AssociationUpdateIn,
|
||||
AssociationWithTargetOut,
|
||||
)
|
||||
from hotpocket_soa.dto.saves import SaveOut
|
||||
|
||||
from .base import ProxyService, SOAError
|
||||
|
||||
|
||||
class AssociationsService(ProxyService):
|
||||
class AssociationsServiceError(SOAError):
|
||||
pass
|
||||
|
||||
class AssociationNotFound(AssociationsServiceError):
|
||||
pass
|
||||
|
||||
class AssociationAccessDenied(AssociationsServiceError):
|
||||
pass
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.backend_associations_service = BackendAssociationsService()
|
||||
|
||||
def wrap_exception(self, exception: Exception) -> Exception:
|
||||
new_exception_args = []
|
||||
if len(exception.args) > 0:
|
||||
new_exception_args = [exception.args[0]]
|
||||
|
||||
return self.AssociationsServiceError(*new_exception_args)
|
||||
|
||||
def create(self,
|
||||
*,
|
||||
account_uuid: uuid.UUID,
|
||||
target: SaveOut,
|
||||
pk: uuid.UUID | None = None,
|
||||
created_at: datetime.datetime | None = None,
|
||||
) -> AssociationOut:
|
||||
return AssociationOut.model_validate(
|
||||
self.call(
|
||||
self.backend_associations_service,
|
||||
'create',
|
||||
account_uuid=account_uuid,
|
||||
save_uuid=target.pk,
|
||||
pk=pk,
|
||||
created_at=created_at,
|
||||
),
|
||||
from_attributes=True,
|
||||
)
|
||||
|
||||
def get(self,
|
||||
*,
|
||||
account_uuid: uuid.UUID | None,
|
||||
pk: uuid.UUID,
|
||||
with_target: bool = False,
|
||||
allow_archived: bool = False,
|
||||
) -> AssociationOut | AssociationWithTargetOut:
|
||||
try:
|
||||
model: type[AssociationOut] = AssociationOut
|
||||
if with_target is True:
|
||||
model = AssociationWithTargetOut
|
||||
|
||||
result = model.model_validate(
|
||||
self.call(
|
||||
self.backend_associations_service,
|
||||
'get',
|
||||
pk=pk,
|
||||
with_target=with_target,
|
||||
),
|
||||
from_attributes=True,
|
||||
)
|
||||
|
||||
if allow_archived is False and result.archived_at is not None:
|
||||
raise self.AssociationNotFound(f'pk=`{pk}`')
|
||||
|
||||
if account_uuid is not None and result.account_uuid != account_uuid:
|
||||
raise self.AssociationAccessDenied(
|
||||
f'account_uuid=`{account_uuid}` pk=`{pk}`',
|
||||
)
|
||||
|
||||
return result
|
||||
except SOAError as exception:
|
||||
if isinstance(exception.__cause__, BackendAssociationsService.AssociationNotFound) is True:
|
||||
raise self.AssociationNotFound(f'pk=`{pk}`') from exception
|
||||
else:
|
||||
raise
|
||||
|
||||
def search(self,
|
||||
*,
|
||||
query: AssociationsQuery,
|
||||
limit: int,
|
||||
) -> list[AssociationWithTargetOut]:
|
||||
return [
|
||||
AssociationWithTargetOut.model_validate(row, from_attributes=True)
|
||||
for row
|
||||
in self.call(
|
||||
self.backend_associations_service,
|
||||
'search',
|
||||
query=query,
|
||||
limit=limit,
|
||||
)
|
||||
]
|
||||
|
||||
def archive(self, *, association: AssociationOut) -> bool:
|
||||
return self.call(
|
||||
self.backend_associations_service,
|
||||
'archive',
|
||||
pk=association.pk,
|
||||
)
|
||||
|
||||
def star(self, *, association: AssociationOut) -> AssociationOut:
|
||||
return AssociationOut.model_validate(
|
||||
self.call(
|
||||
self.backend_associations_service,
|
||||
'star',
|
||||
pk=association.pk,
|
||||
),
|
||||
from_attributes=True,
|
||||
)
|
||||
|
||||
def unstar(self, *, association: AssociationOut) -> AssociationOut:
|
||||
return AssociationOut.model_validate(
|
||||
self.call(
|
||||
self.backend_associations_service,
|
||||
'unstar',
|
||||
pk=association.pk,
|
||||
),
|
||||
from_attributes=True,
|
||||
)
|
||||
|
||||
def update(self,
|
||||
*,
|
||||
association: AssociationOut,
|
||||
update: AssociationUpdateIn,
|
||||
) -> AssociationOut:
|
||||
return AssociationOut.model_validate(
|
||||
self.call(
|
||||
self.backend_associations_service,
|
||||
'update',
|
||||
pk=association.pk,
|
||||
update=update,
|
||||
),
|
||||
from_attributes=True,
|
||||
)
|
||||
|
||||
def delete(self, *, association: AssociationOut) -> bool:
|
||||
return self.call(
|
||||
self.backend_associations_service,
|
||||
'delete',
|
||||
pk=association.pk,
|
||||
)
|
||||
24
services/packages/soa/hotpocket_soa/services/base.py
Normal file
24
services/packages/soa/hotpocket_soa/services/base.py
Normal file
@@ -0,0 +1,24 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
import typing
|
||||
|
||||
|
||||
class SOAError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class Service:
|
||||
def wrap_exception(self, exception: Exception) -> Exception:
|
||||
return SOAError(exception.args[0])
|
||||
|
||||
|
||||
class ProxyService(Service):
|
||||
def call(self, service: typing.Any, method: str, *args, **kwargs) -> typing.Any:
|
||||
handler = getattr(service, method, None)
|
||||
assert handler is not None, f'Unknown method: method=`{method}`'
|
||||
|
||||
try:
|
||||
return handler(*args, **kwargs)
|
||||
except Exception as exception:
|
||||
raise self.wrap_exception(exception) from exception
|
||||
40
services/packages/soa/hotpocket_soa/services/bot.py
Normal file
40
services/packages/soa/hotpocket_soa/services/bot.py
Normal file
@@ -0,0 +1,40 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
from hotpocket_backend.apps.bot.services import BotService as BackendBotService
|
||||
from hotpocket_soa.dto import BotResultOut
|
||||
|
||||
from .base import ProxyService, SOAError
|
||||
|
||||
|
||||
class BotService(ProxyService):
|
||||
class BotServiceError(SOAError):
|
||||
pass
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.backend_associations_service = BackendBotService()
|
||||
|
||||
def wrap_exception(self, exception: Exception) -> Exception:
|
||||
new_exception_args = []
|
||||
if len(exception.args) > 0:
|
||||
new_exception_args = [exception.args[0]]
|
||||
|
||||
return self.BotServiceError(*new_exception_args)
|
||||
|
||||
def is_netloc_banned(self, *, url: str) -> bool:
|
||||
return self.call(
|
||||
self.backend_associations_service,
|
||||
'is_netloc_banned',
|
||||
url=url,
|
||||
)
|
||||
|
||||
def handle(self, *, url: str) -> BotResultOut:
|
||||
return BotResultOut.model_validate(
|
||||
self.call(
|
||||
self.backend_associations_service,
|
||||
'handle',
|
||||
url=url,
|
||||
),
|
||||
from_attributes=True,
|
||||
)
|
||||
@@ -0,0 +1,44 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
|
||||
from hotpocket_backend.apps.saves.services import (
|
||||
SaveProcessorService as BackendSaveProcessorService,
|
||||
)
|
||||
from hotpocket_soa.dto.celery import AsyncResultOut
|
||||
from hotpocket_soa.dto.saves import SaveOut
|
||||
|
||||
from .base import ProxyService, SOAError
|
||||
|
||||
LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SaveProcessorService(ProxyService):
|
||||
class SaveProcessorServiceError(SOAError):
|
||||
pass
|
||||
|
||||
def wrap_exception(self, exception: Exception) -> Exception:
|
||||
new_exception_args = []
|
||||
if len(exception.args) > 0:
|
||||
new_exception_args = [exception.args[0]]
|
||||
|
||||
return self.SaveProcessorServiceError(*new_exception_args)
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.backend_save_processor_service = BackendSaveProcessorService()
|
||||
|
||||
def schedule_process_save(self, *, save: SaveOut) -> AsyncResultOut:
|
||||
result = AsyncResultOut.model_validate(
|
||||
self.call(
|
||||
self.backend_save_processor_service,
|
||||
'schedule_process_save',
|
||||
pk=save.pk,
|
||||
),
|
||||
from_attributes=True,
|
||||
)
|
||||
|
||||
LOGGER.debug('Scheduled processing task: id=`%s`', result.id)
|
||||
|
||||
return result
|
||||
59
services/packages/soa/hotpocket_soa/services/saves.py
Normal file
59
services/packages/soa/hotpocket_soa/services/saves.py
Normal file
@@ -0,0 +1,59 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
import uuid
|
||||
|
||||
from hotpocket_backend.apps.saves.services import (
|
||||
SavesService as BackendSavesService,
|
||||
)
|
||||
from hotpocket_soa.dto.saves import SaveIn, SaveOut
|
||||
|
||||
from .base import ProxyService, SOAError
|
||||
|
||||
|
||||
class SavesService(ProxyService):
|
||||
class SavesServiceError(SOAError):
|
||||
pass
|
||||
|
||||
class SaveNotFound(SavesServiceError):
|
||||
pass
|
||||
|
||||
def wrap_exception(self, exception: Exception) -> Exception:
|
||||
new_exception_args = []
|
||||
if len(exception.args) > 0:
|
||||
new_exception_args = [exception.args[0]]
|
||||
|
||||
return self.SavesServiceError(*new_exception_args)
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.backend_saves_service = BackendSavesService()
|
||||
|
||||
def create(self, *, account_uuid: uuid.UUID, save: SaveIn) -> SaveOut:
|
||||
return SaveOut.model_validate(
|
||||
self.call(
|
||||
self.backend_saves_service,
|
||||
'create',
|
||||
account_uuid=account_uuid,
|
||||
save=save,
|
||||
),
|
||||
from_attributes=True,
|
||||
)
|
||||
|
||||
def get(self, *, pk: uuid.UUID) -> SaveOut:
|
||||
try:
|
||||
result = SaveOut.model_validate(
|
||||
self.call(
|
||||
self.backend_saves_service,
|
||||
'get',
|
||||
pk=pk,
|
||||
),
|
||||
from_attributes=True,
|
||||
)
|
||||
|
||||
return result
|
||||
except SOAError as exception:
|
||||
if isinstance(exception.__cause__, BackendSavesService.SaveNotFound) is True:
|
||||
raise self.SaveNotFound(f'pk=`{pk}`') from exception
|
||||
else:
|
||||
raise
|
||||
15
services/packages/soa/pyproject.toml
Normal file
15
services/packages/soa/pyproject.toml
Normal file
@@ -0,0 +1,15 @@
|
||||
[tool.poetry]
|
||||
name = "hotpocket-soa"
|
||||
version = "1.0.0.dev0"
|
||||
description = "HotPocket SOA"
|
||||
authors = ["Tomek Wójcik <contact@bthlabs.pl>"]
|
||||
license = "Apache-2.0"
|
||||
readme = "README.md"
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.12"
|
||||
pydantic = "2.11.7"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
97
services/packages/tasks.py
Normal file
97
services/packages/tasks.py
Normal file
@@ -0,0 +1,97 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# type: ignore
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from invoke import task
|
||||
from invoke.exceptions import UnexpectedExit
|
||||
|
||||
from hotpocket_workspace_tools import get_workspace_mode
|
||||
|
||||
WORKSPACE_MODE = get_workspace_mode()
|
||||
|
||||
|
||||
@task
|
||||
def clean(ctx):
|
||||
print('NOOP')
|
||||
|
||||
|
||||
@task
|
||||
def test(ctx):
|
||||
# ctx.run('pytest -v --disable-warnings')
|
||||
print('NOOP')
|
||||
|
||||
|
||||
@task
|
||||
def flake8(ctx):
|
||||
ctx.run('flake8')
|
||||
|
||||
|
||||
@task
|
||||
def isort(ctx, check=False, diff=False):
|
||||
command_parts = [
|
||||
'isort',
|
||||
]
|
||||
|
||||
if check is True:
|
||||
command_parts.append('--check')
|
||||
|
||||
if diff is True:
|
||||
command_parts.append('--diff')
|
||||
|
||||
command_parts.append('.')
|
||||
|
||||
ctx.run(' '.join(command_parts))
|
||||
|
||||
|
||||
@task
|
||||
def lint(ctx):
|
||||
ihazsuccess = True
|
||||
|
||||
try:
|
||||
flake8(ctx)
|
||||
except UnexpectedExit:
|
||||
ihazsuccess = False
|
||||
|
||||
try:
|
||||
isort(ctx, check=True)
|
||||
except UnexpectedExit:
|
||||
ihazsuccess = False
|
||||
|
||||
if ihazsuccess is False:
|
||||
raise RuntimeError('FIAL')
|
||||
|
||||
|
||||
@task
|
||||
def typecheck(ctx):
|
||||
ctx.run('mypy .')
|
||||
|
||||
|
||||
@task
|
||||
def django_shell(ctx):
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
@task
|
||||
def ci(ctx):
|
||||
ihazsuccess = True
|
||||
|
||||
ci_tasks = [test, lint, typecheck]
|
||||
for ci_task in ci_tasks:
|
||||
try:
|
||||
ci_task(ctx)
|
||||
except UnexpectedExit:
|
||||
ihazsuccess = False
|
||||
|
||||
if ihazsuccess is False:
|
||||
raise RuntimeError('FIAL')
|
||||
|
||||
|
||||
@task
|
||||
def setup(ctx):
|
||||
print('NOOP')
|
||||
|
||||
|
||||
@task
|
||||
def start_web(ctx):
|
||||
raise NotImplementedError()
|
||||
3
services/packages/testing/README.md
Normal file
3
services/packages/testing/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# HotPocket by BTHLabs
|
||||
|
||||
This repository contains the _HotPocket Testing_ project.
|
||||
@@ -0,0 +1 @@
|
||||
from .datetime import assert_datetimes_are_really_close # noqa: F401,F403
|
||||
@@ -0,0 +1,14 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
import datetime
|
||||
|
||||
import dateutil
|
||||
|
||||
DELTA = datetime.timedelta(microseconds=100_000) # 100ms
|
||||
|
||||
|
||||
def assert_datetimes_are_really_close(datetime1: datetime.datetime,
|
||||
datetime2: datetime.datetime,
|
||||
):
|
||||
assert dateutil.utils.within_delta(datetime1, datetime2, DELTA)
|
||||
@@ -0,0 +1,2 @@
|
||||
from .celery import * # noqa: F401,F403
|
||||
from .common import * # noqa: F401,F403
|
||||
@@ -0,0 +1,16 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# type: ignore
|
||||
from __future__ import annotations
|
||||
|
||||
from unittest import mock
|
||||
|
||||
from celery.result import AsyncResult
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def async_result(null_uuid) -> mock.Mock:
|
||||
result = mock.Mock(spec=AsyncResult)
|
||||
result.id = str(null_uuid)
|
||||
|
||||
return result
|
||||
@@ -0,0 +1,12 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# type: ignore
|
||||
from __future__ import annotations
|
||||
|
||||
import uuid
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def null_uuid():
|
||||
return uuid.UUID('00000000-0000-0000-0000-000000000000')
|
||||
4
services/packages/testing/hotpocket_testing/plugin.py
Normal file
4
services/packages/testing/hotpocket_testing/plugin.py
Normal file
@@ -0,0 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
from .fixtures import * # noqa: F401,F403
|
||||
18
services/packages/testing/pyproject.toml
Normal file
18
services/packages/testing/pyproject.toml
Normal file
@@ -0,0 +1,18 @@
|
||||
[tool.poetry]
|
||||
name = "hotpocket-testing"
|
||||
version = "1.0.0.dev0"
|
||||
description = "HotPocket Testing"
|
||||
authors = ["Tomek Wójcik <contact@bthlabs.pl>"]
|
||||
license = "Apache-2.0"
|
||||
readme = "README.md"
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.12"
|
||||
python-dateutil = "2.9.0.post0"
|
||||
|
||||
[tool.poetry.plugins.pytest11]
|
||||
hotpocket_testing = "hotpocket_testing.plugin"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
3
services/packages/workspace_tools/README.md
Normal file
3
services/packages/workspace_tools/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# HotPocket by BTHLabs
|
||||
|
||||
This repository contains the _HotPocket Workspace Tools_ project.
|
||||
@@ -0,0 +1,2 @@
|
||||
from .constants import WorkspaceMode # noqa: F401
|
||||
from .workspace_mode import get_workspace_mode # noqa: F401
|
||||
@@ -0,0 +1,11 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
import enum
|
||||
|
||||
DEFAULT_WORKSPACE_MODE = 'docker'
|
||||
|
||||
|
||||
class WorkspaceMode(enum.Enum):
|
||||
DOCKER = 'docker'
|
||||
METAL = 'metal'
|
||||
@@ -0,0 +1,17 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
|
||||
from .constants import DEFAULT_WORKSPACE_MODE, WorkspaceMode
|
||||
|
||||
|
||||
def get_workspace_mode(default: str | None = None) -> WorkspaceMode:
|
||||
return WorkspaceMode(os.getenv(
|
||||
'HOTPOCKET_WORKSPACE_MODE',
|
||||
(
|
||||
default
|
||||
if default is not None
|
||||
else DEFAULT_WORKSPACE_MODE
|
||||
),
|
||||
))
|
||||
14
services/packages/workspace_tools/pyproject.toml
Normal file
14
services/packages/workspace_tools/pyproject.toml
Normal file
@@ -0,0 +1,14 @@
|
||||
[tool.poetry]
|
||||
name = "hotpocket-workspace-tools"
|
||||
version = "1.0.0.dev0"
|
||||
description = "HotPocket Workspace Tools"
|
||||
authors = ["Tomek Wójcik <contact@bthlabs.pl>"]
|
||||
license = "Apache-2.0"
|
||||
readme = "README.md"
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.12"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
Reference in New Issue
Block a user