ci: add Dockerfile
This commit is contained in:
parent
72ee09b064
commit
65a56f2658
15 changed files with 382 additions and 70 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -6,6 +6,7 @@ apps/http/sls/.serverless/
|
||||||
apps/http/sls/.requirements.zip
|
apps/http/sls/.requirements.zip
|
||||||
__pycache__/
|
__pycache__/
|
||||||
.pdm-python
|
.pdm-python
|
||||||
|
.pdm-build/
|
||||||
.env
|
.env
|
||||||
.coverage
|
.coverage
|
||||||
htmlcov
|
htmlcov
|
||||||
41
Dockerfile
Normal file
41
Dockerfile
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
FROM python:3.11-slim AS base
|
||||||
|
|
||||||
|
ENV PYTHONDONTWRITEBYTECODE 1
|
||||||
|
ENV USERNAME "secretsanta"
|
||||||
|
ENV APP_HOME "/home/$USERNAME"
|
||||||
|
ENV APP_PATH "$APP_HOME/src"
|
||||||
|
|
||||||
|
ARG uid=1000
|
||||||
|
ARG gid=1000
|
||||||
|
|
||||||
|
# hadolint ignore=DL3001,DL3008
|
||||||
|
RUN apt-get -y update \
|
||||||
|
&& apt-get -y upgrade \
|
||||||
|
&& apt-get -y install git curl make python3-virtualenv --no-install-recommends \
|
||||||
|
&& rm -rf /var/lib/apt/lists/* \
|
||||||
|
&& groupadd -g "$gid" "$USERNAME" \
|
||||||
|
&& useradd -lu "$uid" -g "$gid" "$USERNAME" \
|
||||||
|
&& mkhomedir_helper "$USERNAME" \
|
||||||
|
&& mkdir "$APP_PATH" \
|
||||||
|
&& chown "$uid:$gid" "$APP_PATH"
|
||||||
|
|
||||||
|
USER "$USERNAME"
|
||||||
|
ENV PATH="${PATH}:$APP_HOME/.local/bin"
|
||||||
|
ENV PYTHONPATH "$APP_PATH"
|
||||||
|
|
||||||
|
RUN pip install pipx==1.2.0 --no-cache-dir \
|
||||||
|
&& pipx install pdm==2.10
|
||||||
|
|
||||||
|
WORKDIR "$APP_PATH"
|
||||||
|
ENV POETRY_VIRTUALENVS_IN_PROJECT=1
|
||||||
|
COPY --chown="$USERNAME" pyproject.toml pdm.lock Makefile README.md LICENSE ./
|
||||||
|
COPY --chown="$USERNAME" apps/ apps/
|
||||||
|
COPY --chown="$USERNAME" secretsanta/ secretsanta/
|
||||||
|
|
||||||
|
RUN pdm install
|
||||||
|
|
||||||
|
FROM base AS run
|
||||||
|
|
||||||
|
RUN pdm install -G litestar
|
||||||
|
WORKDIR "$APP_PATH/apps/http/litestar"
|
||||||
|
CMD ["pdm", "run", "litestar", "run"]
|
||||||
7
Makefile
7
Makefile
|
|
@ -1,7 +1,14 @@
|
||||||
|
build:
|
||||||
|
docker build --target run -t git.roboces.dev/catalin/secretsanta:latest .
|
||||||
|
|
||||||
run--sls:
|
run--sls:
|
||||||
@echo "Activating virtual environment and starting serverless offline"
|
@echo "Activating virtual environment and starting serverless offline"
|
||||||
@. .venv/bin/activate && cd apps/http/sls && npx sls offline
|
@. .venv/bin/activate && cd apps/http/sls && npx sls offline
|
||||||
|
|
||||||
|
run--litestar:
|
||||||
|
@echo "Starting litestar"
|
||||||
|
@. cd apps/http/litestar/ && pdm run litestar run
|
||||||
|
|
||||||
deploy--sls:
|
deploy--sls:
|
||||||
@echo "Deploying via serverless framework"
|
@echo "Deploying via serverless framework"
|
||||||
@. cd apps/http/sls && pdm export -G sls -f requirements --prod > requirements.txt && npx sls deploy
|
@. cd apps/http/sls && pdm export -G sls -f requirements --prod > requirements.txt && npx sls deploy
|
||||||
|
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
{
|
|
||||||
"version": "2.0",
|
|
||||||
"app_name": "secretsanta",
|
|
||||||
"stages": {
|
|
||||||
"dev": {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -4,8 +4,8 @@ from chalice import Chalice
|
||||||
from secretsanta.domain import Group
|
from secretsanta.domain import Group
|
||||||
from secretsanta.repo import S3Repo
|
from secretsanta.repo import S3Repo
|
||||||
from secretsanta.service import (
|
from secretsanta.service import (
|
||||||
GetGroupParticipantsService,
|
|
||||||
CreateGroupService,
|
CreateGroupService,
|
||||||
|
GetGroupParticipantsService,
|
||||||
GetPairService,
|
GetPairService,
|
||||||
)
|
)
|
||||||
from secretsanta.settings import get_config
|
from secretsanta.settings import get_config
|
||||||
|
|
@ -16,13 +16,6 @@ app = Chalice(app_name="secretsanta", debug=config.environment == "local")
|
||||||
repo = S3Repo()
|
repo = S3Repo()
|
||||||
|
|
||||||
|
|
||||||
def _participants2url(participants: list[str], group_uuid: str) -> list[str]:
|
|
||||||
return [
|
|
||||||
f"{config.server_url}/api/v1/groups/{group_uuid}/pair/{participant_name}"
|
|
||||||
for participant_name in participants
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
@app.route("/api/v1/groups/{group_uuid}")
|
@app.route("/api/v1/groups/{group_uuid}")
|
||||||
def get_participants(group_uuid: str):
|
def get_participants(group_uuid: str):
|
||||||
service = GetGroupParticipantsService(repo)
|
service = GetGroupParticipantsService(repo)
|
||||||
|
|
@ -34,8 +27,7 @@ def create_group(group_uuid: str):
|
||||||
request = app.current_request
|
request = app.current_request
|
||||||
body = request.json_body
|
body = request.json_body
|
||||||
service = CreateGroupService(repo)
|
service = CreateGroupService(repo)
|
||||||
participants = anyio.run(service.run, Group(uuid=group_uuid, **body)).participants
|
return anyio.run(service.run, Group(uuid=group_uuid, **body))
|
||||||
return _participants2url(participants, group_uuid)
|
|
||||||
|
|
||||||
|
|
||||||
@app.route("/api/v1/groups/{group_uuid}/pair/{participant}")
|
@app.route("/api/v1/groups/{group_uuid}/pair/{participant}")
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,15 @@
|
||||||
from dataclasses import dataclass, asdict
|
from dataclasses import asdict, dataclass
|
||||||
from typing import Literal, Annotated
|
from typing import Annotated, Literal
|
||||||
|
|
||||||
from litestar import Controller, get, Litestar, put, Request, Response, MediaType
|
from litestar import Controller, Litestar, MediaType, Request, Response, get, put
|
||||||
from litestar.params import Parameter
|
from litestar.params import Parameter
|
||||||
from pydantic import UUID4
|
from pydantic import UUID4
|
||||||
|
|
||||||
from secretsanta.domain import Group
|
from secretsanta.domain import Group
|
||||||
from secretsanta.repo import S3Repo
|
from secretsanta.repo import S3Repo
|
||||||
from secretsanta.service import (
|
from secretsanta.service import (
|
||||||
GetGroupParticipantsService,
|
|
||||||
CreateGroupService,
|
CreateGroupService,
|
||||||
|
GetGroupParticipantsService,
|
||||||
GetPairService,
|
GetPairService,
|
||||||
)
|
)
|
||||||
from secretsanta.settings import get_config
|
from secretsanta.settings import get_config
|
||||||
|
|
@ -46,10 +46,13 @@ class GroupController(Controller):
|
||||||
|
|
||||||
@put("/{group_uuid:uuid}")
|
@put("/{group_uuid:uuid}")
|
||||||
async def create_group(
|
async def create_group(
|
||||||
self, request: Request, group_uuid: UUID4, data: CreateGroup
|
self,
|
||||||
|
request: Request,
|
||||||
|
group_uuid: UUID4,
|
||||||
|
data: CreateGroup,
|
||||||
) -> list[str]:
|
) -> list[str]:
|
||||||
group = await self.create_group_service.run(
|
group = await self.create_group_service.run(
|
||||||
Group(uuid=group_uuid, **asdict(data))
|
Group(uuid=group_uuid, **asdict(data)),
|
||||||
)
|
)
|
||||||
return self._group2urls(group.participants, request.url)
|
return self._group2urls(group.participants, request.url)
|
||||||
|
|
||||||
|
|
@ -59,11 +62,13 @@ class GroupController(Controller):
|
||||||
group_uuid: UUID4,
|
group_uuid: UUID4,
|
||||||
participant_name: str,
|
participant_name: str,
|
||||||
response_type: Annotated[
|
response_type: Annotated[
|
||||||
Literal["json", "plain"], Parameter(query="type")
|
Literal["json", "plain"],
|
||||||
|
Parameter(query="type"),
|
||||||
] = "plain",
|
] = "plain",
|
||||||
) -> Response[str] | PairResponse:
|
) -> Response[str] | PairResponse:
|
||||||
pair = await self.get_pair_service.run(
|
pair = await self.get_pair_service.run(
|
||||||
group_uuid=group_uuid, participant=participant_name
|
group_uuid=group_uuid,
|
||||||
|
participant=participant_name,
|
||||||
)
|
)
|
||||||
if response_type == "json":
|
if response_type == "json":
|
||||||
return PairResponse(pair=pair)
|
return PairResponse(pair=pair)
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,9 @@ import anyio
|
||||||
from secretsanta.domain import Group
|
from secretsanta.domain import Group
|
||||||
from secretsanta.repo import S3Repo
|
from secretsanta.repo import S3Repo
|
||||||
from secretsanta.service import (
|
from secretsanta.service import (
|
||||||
|
CreateGroupService,
|
||||||
GetGroupParticipantsService,
|
GetGroupParticipantsService,
|
||||||
GetPairService,
|
GetPairService,
|
||||||
CreateGroupService,
|
|
||||||
)
|
)
|
||||||
from secretsanta.settings import get_config
|
from secretsanta.settings import get_config
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,16 +26,16 @@ custom:
|
||||||
dockerizePip: true
|
dockerizePip: true
|
||||||
zip: true
|
zip: true
|
||||||
slim: true
|
slim: true
|
||||||
layer: true
|
layer: false
|
||||||
prune:
|
#prune:
|
||||||
automatic: true
|
# automatic: true
|
||||||
includeLayers: true
|
# includeLayers: true
|
||||||
number: 1
|
# number: 1
|
||||||
apiGatewayCaching:
|
#apiGatewayCaching:
|
||||||
enabled: true
|
# enabled: true
|
||||||
apiGatewayThrottling:
|
#apiGatewayThrottling:
|
||||||
maxRequestsPerSecond: 100
|
# maxRequestsPerSecond: 100
|
||||||
maxConcurrentRequests: 5
|
# maxConcurrentRequests: 5
|
||||||
|
|
||||||
plugins:
|
plugins:
|
||||||
- serverless-python-requirements
|
- serverless-python-requirements
|
||||||
|
|
@ -47,27 +47,25 @@ plugins:
|
||||||
functions:
|
functions:
|
||||||
get_participants:
|
get_participants:
|
||||||
handler: app.get_participants
|
handler: app.get_participants
|
||||||
layers:
|
|
||||||
- Ref: PythonRequirementsLambdaLayer
|
|
||||||
events:
|
events:
|
||||||
- httpApi:
|
- httpApi:
|
||||||
path: /api/v1/groups/{group_uuid}
|
path: /api/v1/groups/{group_uuid}
|
||||||
method: get
|
method: get
|
||||||
|
|
||||||
create_group:
|
#create_group:
|
||||||
handler: app.create_group
|
# handler: app.create_group
|
||||||
layers:
|
# layers:
|
||||||
- Ref: PythonRequirementsLambdaLayer
|
# - Ref: PythonRequirementsLambdaLayer
|
||||||
events:
|
# events:
|
||||||
- httpApi:
|
# - httpApi:
|
||||||
path: /api/v1/groups/{group_uuid}
|
# path: /api/v1/groups/{group_uuid}
|
||||||
method: put
|
# method: put
|
||||||
|
|
||||||
get_pair:
|
#get_pair:
|
||||||
handler: app.get_pair
|
# handler: app.get_pair
|
||||||
layers:
|
# layers:
|
||||||
- Ref: PythonRequirementsLambdaLayer
|
# - Ref: PythonRequirementsLambdaLayer
|
||||||
events:
|
# events:
|
||||||
- httpApi:
|
# - httpApi:
|
||||||
path: /api/v1/groups/{group_uuid}/pair/{participant}
|
# path: /api/v1/groups/{group_uuid}/pair/{participant}
|
||||||
method: get
|
# method: get
|
||||||
|
|
|
||||||
262
pdm.lock
generated
262
pdm.lock
generated
|
|
@ -5,7 +5,7 @@
|
||||||
groups = ["default", "litestar", "testing", "dev", "linting", "chalice", "sls"]
|
groups = ["default", "litestar", "testing", "dev", "linting", "chalice", "sls"]
|
||||||
strategy = ["cross_platform"]
|
strategy = ["cross_platform"]
|
||||||
lock_version = "4.4"
|
lock_version = "4.4"
|
||||||
content_hash = "sha256:3047d1e2fc131623e2ccfaab7af28560d897f225b61904fed245930b74f43c61"
|
content_hash = "sha256:ba9863870aa9f5f47435713bc9ae20992b801a13bced3f58aad28f2a5685614d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aioboto3"
|
name = "aioboto3"
|
||||||
|
|
@ -193,6 +193,36 @@ files = [
|
||||||
{file = "boto3-1.28.64.tar.gz", hash = "sha256:a5cf93b202568e9d378afdc84be55a6dedf11d30156289fe829e23e6d7dccabb"},
|
{file = "boto3-1.28.64.tar.gz", hash = "sha256:a5cf93b202568e9d378afdc84be55a6dedf11d30156289fe829e23e6d7dccabb"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "boto3-stubs"
|
||||||
|
version = "1.33.10"
|
||||||
|
requires_python = ">=3.7"
|
||||||
|
summary = "Type annotations for boto3 1.33.10 generated with mypy-boto3-builder 7.21.0"
|
||||||
|
dependencies = [
|
||||||
|
"botocore-stubs",
|
||||||
|
"types-s3transfer",
|
||||||
|
"typing-extensions>=4.1.0; python_version < \"3.12\"",
|
||||||
|
]
|
||||||
|
files = [
|
||||||
|
{file = "boto3-stubs-1.33.10.tar.gz", hash = "sha256:9e29024bcb6ac12c220d8ea5bfe79c532c92e0c1d1170c14217165e1a8b09218"},
|
||||||
|
{file = "boto3_stubs-1.33.10-py3-none-any.whl", hash = "sha256:61d07f445f88d5cca0a66e23dfd83611ff947bac08e01a64908df3605c22aabc"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "boto3-stubs"
|
||||||
|
version = "1.33.10"
|
||||||
|
extras = ["s3"]
|
||||||
|
requires_python = ">=3.7"
|
||||||
|
summary = "Type annotations for boto3 1.33.10 generated with mypy-boto3-builder 7.21.0"
|
||||||
|
dependencies = [
|
||||||
|
"boto3-stubs==1.33.10",
|
||||||
|
"mypy-boto3-s3<1.34.0,>=1.33.0",
|
||||||
|
]
|
||||||
|
files = [
|
||||||
|
{file = "boto3-stubs-1.33.10.tar.gz", hash = "sha256:9e29024bcb6ac12c220d8ea5bfe79c532c92e0c1d1170c14217165e1a8b09218"},
|
||||||
|
{file = "boto3_stubs-1.33.10-py3-none-any.whl", hash = "sha256:61d07f445f88d5cca0a66e23dfd83611ff947bac08e01a64908df3605c22aabc"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "botocore"
|
name = "botocore"
|
||||||
version = "1.31.64"
|
version = "1.31.64"
|
||||||
|
|
@ -231,6 +261,39 @@ files = [
|
||||||
{file = "certifi-2023.11.17.tar.gz", hash = "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1"},
|
{file = "certifi-2023.11.17.tar.gz", hash = "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cffi"
|
||||||
|
version = "1.16.0"
|
||||||
|
requires_python = ">=3.8"
|
||||||
|
summary = "Foreign Function Interface for Python calling C code."
|
||||||
|
dependencies = [
|
||||||
|
"pycparser",
|
||||||
|
]
|
||||||
|
files = [
|
||||||
|
{file = "cffi-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404"},
|
||||||
|
{file = "cffi-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417"},
|
||||||
|
{file = "cffi-1.16.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627"},
|
||||||
|
{file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936"},
|
||||||
|
{file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d"},
|
||||||
|
{file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56"},
|
||||||
|
{file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e"},
|
||||||
|
{file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc"},
|
||||||
|
{file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb"},
|
||||||
|
{file = "cffi-1.16.0-cp311-cp311-win32.whl", hash = "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab"},
|
||||||
|
{file = "cffi-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba"},
|
||||||
|
{file = "cffi-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956"},
|
||||||
|
{file = "cffi-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e"},
|
||||||
|
{file = "cffi-1.16.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e"},
|
||||||
|
{file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2"},
|
||||||
|
{file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357"},
|
||||||
|
{file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6"},
|
||||||
|
{file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969"},
|
||||||
|
{file = "cffi-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520"},
|
||||||
|
{file = "cffi-1.16.0-cp312-cp312-win32.whl", hash = "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b"},
|
||||||
|
{file = "cffi-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235"},
|
||||||
|
{file = "cffi-1.16.0.tar.gz", hash = "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "chalice"
|
name = "chalice"
|
||||||
version = "1.29.0"
|
version = "1.29.0"
|
||||||
|
|
@ -252,6 +315,46 @@ files = [
|
||||||
{file = "chalice-1.29.0.tar.gz", hash = "sha256:f07aad9a2d4e5b06ef279cf668a48ec455b131168000b91efe7d841425599035"},
|
{file = "chalice-1.29.0.tar.gz", hash = "sha256:f07aad9a2d4e5b06ef279cf668a48ec455b131168000b91efe7d841425599035"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "charset-normalizer"
|
||||||
|
version = "3.3.2"
|
||||||
|
requires_python = ">=3.7.0"
|
||||||
|
summary = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
|
||||||
|
files = [
|
||||||
|
{file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"},
|
||||||
|
{file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"},
|
||||||
|
{file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"},
|
||||||
|
{file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"},
|
||||||
|
{file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"},
|
||||||
|
{file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"},
|
||||||
|
{file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"},
|
||||||
|
{file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"},
|
||||||
|
{file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"},
|
||||||
|
{file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"},
|
||||||
|
{file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"},
|
||||||
|
{file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"},
|
||||||
|
{file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"},
|
||||||
|
{file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"},
|
||||||
|
{file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"},
|
||||||
|
{file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"},
|
||||||
|
{file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"},
|
||||||
|
{file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"},
|
||||||
|
{file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"},
|
||||||
|
{file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"},
|
||||||
|
{file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"},
|
||||||
|
{file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"},
|
||||||
|
{file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"},
|
||||||
|
{file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"},
|
||||||
|
{file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"},
|
||||||
|
{file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"},
|
||||||
|
{file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"},
|
||||||
|
{file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"},
|
||||||
|
{file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"},
|
||||||
|
{file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"},
|
||||||
|
{file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"},
|
||||||
|
{file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "click"
|
name = "click"
|
||||||
version = "8.1.7"
|
version = "8.1.7"
|
||||||
|
|
@ -339,6 +442,40 @@ files = [
|
||||||
{file = "coverage-7.3.2.tar.gz", hash = "sha256:be32ad29341b0170e795ca590e1c07e81fc061cb5b10c74ce7203491484404ef"},
|
{file = "coverage-7.3.2.tar.gz", hash = "sha256:be32ad29341b0170e795ca590e1c07e81fc061cb5b10c74ce7203491484404ef"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cryptography"
|
||||||
|
version = "41.0.7"
|
||||||
|
requires_python = ">=3.7"
|
||||||
|
summary = "cryptography is a package which provides cryptographic recipes and primitives to Python developers."
|
||||||
|
dependencies = [
|
||||||
|
"cffi>=1.12",
|
||||||
|
]
|
||||||
|
files = [
|
||||||
|
{file = "cryptography-41.0.7-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:3c78451b78313fa81607fa1b3f1ae0a5ddd8014c38a02d9db0616133987b9cdf"},
|
||||||
|
{file = "cryptography-41.0.7-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:928258ba5d6f8ae644e764d0f996d61a8777559f72dfeb2eea7e2fe0ad6e782d"},
|
||||||
|
{file = "cryptography-41.0.7-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a1b41bc97f1ad230a41657d9155113c7521953869ae57ac39ac7f1bb471469a"},
|
||||||
|
{file = "cryptography-41.0.7-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:841df4caa01008bad253bce2a6f7b47f86dc9f08df4b433c404def869f590a15"},
|
||||||
|
{file = "cryptography-41.0.7-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:5429ec739a29df2e29e15d082f1d9ad683701f0ec7709ca479b3ff2708dae65a"},
|
||||||
|
{file = "cryptography-41.0.7-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:43f2552a2378b44869fe8827aa19e69512e3245a219104438692385b0ee119d1"},
|
||||||
|
{file = "cryptography-41.0.7-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:af03b32695b24d85a75d40e1ba39ffe7db7ffcb099fe507b39fd41a565f1b157"},
|
||||||
|
{file = "cryptography-41.0.7-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:49f0805fc0b2ac8d4882dd52f4a3b935b210935d500b6b805f321addc8177406"},
|
||||||
|
{file = "cryptography-41.0.7-cp37-abi3-win32.whl", hash = "sha256:f983596065a18a2183e7f79ab3fd4c475205b839e02cbc0efbbf9666c4b3083d"},
|
||||||
|
{file = "cryptography-41.0.7-cp37-abi3-win_amd64.whl", hash = "sha256:90452ba79b8788fa380dfb587cca692976ef4e757b194b093d845e8d99f612f2"},
|
||||||
|
{file = "cryptography-41.0.7-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:079b85658ea2f59c4f43b70f8119a52414cdb7be34da5d019a77bf96d473b960"},
|
||||||
|
{file = "cryptography-41.0.7-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:b640981bf64a3e978a56167594a0e97db71c89a479da8e175d8bb5be5178c003"},
|
||||||
|
{file = "cryptography-41.0.7-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e3114da6d7f95d2dee7d3f4eec16dacff819740bbab931aff8648cb13c5ff5e7"},
|
||||||
|
{file = "cryptography-41.0.7-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d5ec85080cce7b0513cfd233914eb8b7bbd0633f1d1703aa28d1dd5a72f678ec"},
|
||||||
|
{file = "cryptography-41.0.7-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:7a698cb1dac82c35fcf8fe3417a3aaba97de16a01ac914b89a0889d364d2f6be"},
|
||||||
|
{file = "cryptography-41.0.7-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:37a138589b12069efb424220bf78eac59ca68b95696fc622b6ccc1c0a197204a"},
|
||||||
|
{file = "cryptography-41.0.7-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:68a2dec79deebc5d26d617bfdf6e8aab065a4f34934b22d3b5010df3ba36612c"},
|
||||||
|
{file = "cryptography-41.0.7-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:09616eeaef406f99046553b8a40fbf8b1e70795a91885ba4c96a70793de5504a"},
|
||||||
|
{file = "cryptography-41.0.7-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:48a0476626da912a44cc078f9893f292f0b3e4c739caf289268168d8f4702a39"},
|
||||||
|
{file = "cryptography-41.0.7-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c7f3201ec47d5207841402594f1d7950879ef890c0c495052fa62f58283fde1a"},
|
||||||
|
{file = "cryptography-41.0.7-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c5ca78485a255e03c32b513f8c2bc39fedb7f5c5f8535545bdc223a03b24f248"},
|
||||||
|
{file = "cryptography-41.0.7-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:d6c391c021ab1f7a82da5d8d0b3cee2f4b2c455ec86c8aebbc84837a631ff309"},
|
||||||
|
{file = "cryptography-41.0.7.tar.gz", hash = "sha256:13f93ce9bea8016c253b34afc6bd6a75993e5c40672ed5405a9c832f0d4a00bc"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "editorconfig"
|
name = "editorconfig"
|
||||||
version = "0.12.3"
|
version = "0.12.3"
|
||||||
|
|
@ -648,6 +785,43 @@ files = [
|
||||||
{file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"},
|
{file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "moto"
|
||||||
|
version = "4.2.11"
|
||||||
|
requires_python = ">=3.7"
|
||||||
|
summary = ""
|
||||||
|
dependencies = [
|
||||||
|
"Jinja2>=2.10.1",
|
||||||
|
"boto3>=1.9.201",
|
||||||
|
"botocore>=1.12.201",
|
||||||
|
"cryptography>=3.3.1",
|
||||||
|
"python-dateutil<3.0.0,>=2.1",
|
||||||
|
"requests>=2.5",
|
||||||
|
"responses>=0.13.0",
|
||||||
|
"werkzeug!=2.2.0,!=2.2.1,>=0.5",
|
||||||
|
"xmltodict",
|
||||||
|
]
|
||||||
|
files = [
|
||||||
|
{file = "moto-4.2.11-py2.py3-none-any.whl", hash = "sha256:58c12ab9ee69b6a5d1cddf83611ba4071508f07894317c57844b3ae6dc5bcd38"},
|
||||||
|
{file = "moto-4.2.11.tar.gz", hash = "sha256:2da62d52eaa765dfe2762c920f0a88a58f3a09e04581c91db967d92faec848f1"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "moto"
|
||||||
|
version = "4.2.11"
|
||||||
|
extras = ["s3"]
|
||||||
|
requires_python = ">=3.7"
|
||||||
|
summary = ""
|
||||||
|
dependencies = [
|
||||||
|
"PyYAML>=5.1",
|
||||||
|
"moto==4.2.11",
|
||||||
|
"py-partiql-parser==0.4.2",
|
||||||
|
]
|
||||||
|
files = [
|
||||||
|
{file = "moto-4.2.11-py2.py3-none-any.whl", hash = "sha256:58c12ab9ee69b6a5d1cddf83611ba4071508f07894317c57844b3ae6dc5bcd38"},
|
||||||
|
{file = "moto-4.2.11.tar.gz", hash = "sha256:2da62d52eaa765dfe2762c920f0a88a58f3a09e04581c91db967d92faec848f1"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "msgspec"
|
name = "msgspec"
|
||||||
version = "0.18.4"
|
version = "0.18.4"
|
||||||
|
|
@ -695,6 +869,19 @@ files = [
|
||||||
{file = "multidict-6.0.4.tar.gz", hash = "sha256:3666906492efb76453c0e7b97f2cf459b0682e7402c0489a95484965dbc1da49"},
|
{file = "multidict-6.0.4.tar.gz", hash = "sha256:3666906492efb76453c0e7b97f2cf459b0682e7402c0489a95484965dbc1da49"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mypy-boto3-s3"
|
||||||
|
version = "1.33.2"
|
||||||
|
requires_python = ">=3.7"
|
||||||
|
summary = "Type annotations for boto3.S3 1.33.2 service generated with mypy-boto3-builder 7.20.3"
|
||||||
|
dependencies = [
|
||||||
|
"typing-extensions>=4.1.0; python_version < \"3.12\"",
|
||||||
|
]
|
||||||
|
files = [
|
||||||
|
{file = "mypy-boto3-s3-1.33.2.tar.gz", hash = "sha256:f54a3ad3288f4e4719ebada3dde68c320507b0fc451d59bc68af7e6ab15cbdad"},
|
||||||
|
{file = "mypy_boto3_s3-1.33.2-py3-none-any.whl", hash = "sha256:9d463df6def30de31a467d49ab92ff7795d46709d56eff6f52216a08bac27918"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "packaging"
|
name = "packaging"
|
||||||
version = "23.2"
|
version = "23.2"
|
||||||
|
|
@ -739,6 +926,25 @@ files = [
|
||||||
{file = "polyfactory-2.12.0.tar.gz", hash = "sha256:26dc3a52baae1ebd6386708d9a99f8ea4ef57c9d45e556815ee5e44a1cd27fc0"},
|
{file = "polyfactory-2.12.0.tar.gz", hash = "sha256:26dc3a52baae1ebd6386708d9a99f8ea4ef57c9d45e556815ee5e44a1cd27fc0"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "py-partiql-parser"
|
||||||
|
version = "0.4.2"
|
||||||
|
summary = "Pure Python PartiQL Parser"
|
||||||
|
files = [
|
||||||
|
{file = "py-partiql-parser-0.4.2.tar.gz", hash = "sha256:9c99d545be7897c6bfa97a107f6cfbcd92e359d394e4f3b95430e6409e8dd1e1"},
|
||||||
|
{file = "py_partiql_parser-0.4.2-py3-none-any.whl", hash = "sha256:f3f34de8dddf65ed2d47b4263560bbf97be1ecc6bd5c61da039ede90f26a10ce"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pycparser"
|
||||||
|
version = "2.21"
|
||||||
|
requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||||
|
summary = "C parser in Python"
|
||||||
|
files = [
|
||||||
|
{file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"},
|
||||||
|
{file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pydantic"
|
name = "pydantic"
|
||||||
version = "2.5.2"
|
version = "2.5.2"
|
||||||
|
|
@ -944,6 +1150,37 @@ files = [
|
||||||
{file = "readchar-4.0.5.tar.gz", hash = "sha256:08a456c2d7c1888cde3f4688b542621b676eb38cd6cfed7eb6cb2e2905ddc826"},
|
{file = "readchar-4.0.5.tar.gz", hash = "sha256:08a456c2d7c1888cde3f4688b542621b676eb38cd6cfed7eb6cb2e2905ddc826"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "requests"
|
||||||
|
version = "2.31.0"
|
||||||
|
requires_python = ">=3.7"
|
||||||
|
summary = "Python HTTP for Humans."
|
||||||
|
dependencies = [
|
||||||
|
"certifi>=2017.4.17",
|
||||||
|
"charset-normalizer<4,>=2",
|
||||||
|
"idna<4,>=2.5",
|
||||||
|
"urllib3<3,>=1.21.1",
|
||||||
|
]
|
||||||
|
files = [
|
||||||
|
{file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"},
|
||||||
|
{file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "responses"
|
||||||
|
version = "0.24.1"
|
||||||
|
requires_python = ">=3.8"
|
||||||
|
summary = "A utility library for mocking out the `requests` Python library."
|
||||||
|
dependencies = [
|
||||||
|
"pyyaml",
|
||||||
|
"requests<3.0,>=2.30.0",
|
||||||
|
"urllib3<3.0,>=1.25.10",
|
||||||
|
]
|
||||||
|
files = [
|
||||||
|
{file = "responses-0.24.1-py3-none-any.whl", hash = "sha256:a2b43f4c08bfb9c9bd242568328c65a34b318741d3fab884ac843c5ceeb543f9"},
|
||||||
|
{file = "responses-0.24.1.tar.gz", hash = "sha256:b127c6ca3f8df0eb9cc82fd93109a3007a86acb24871834c47b77765152ecf8c"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rich"
|
name = "rich"
|
||||||
version = "13.7.0"
|
version = "13.7.0"
|
||||||
|
|
@ -1301,6 +1538,19 @@ files = [
|
||||||
{file = "websockets-12.0.tar.gz", hash = "sha256:81df9cbcbb6c260de1e007e58c011bfebe2dafc8435107b0537f393dd38c8b1b"},
|
{file = "websockets-12.0.tar.gz", hash = "sha256:81df9cbcbb6c260de1e007e58c011bfebe2dafc8435107b0537f393dd38c8b1b"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "werkzeug"
|
||||||
|
version = "3.0.1"
|
||||||
|
requires_python = ">=3.8"
|
||||||
|
summary = "The comprehensive WSGI web application library."
|
||||||
|
dependencies = [
|
||||||
|
"MarkupSafe>=2.1.1",
|
||||||
|
]
|
||||||
|
files = [
|
||||||
|
{file = "werkzeug-3.0.1-py3-none-any.whl", hash = "sha256:90a285dc0e42ad56b34e696398b8122ee4c681833fb35b8334a095d82c56da10"},
|
||||||
|
{file = "werkzeug-3.0.1.tar.gz", hash = "sha256:507e811ecea72b18a404947aded4b3390e1db8f826b494d76550ef45bb3b1dcc"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wheel"
|
name = "wheel"
|
||||||
version = "0.42.0"
|
version = "0.42.0"
|
||||||
|
|
@ -1341,6 +1591,16 @@ files = [
|
||||||
{file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"},
|
{file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "xmltodict"
|
||||||
|
version = "0.13.0"
|
||||||
|
requires_python = ">=3.4"
|
||||||
|
summary = "Makes working with XML feel like you are working with JSON"
|
||||||
|
files = [
|
||||||
|
{file = "xmltodict-0.13.0-py2.py3-none-any.whl", hash = "sha256:aa89e8fd76320154a40d19a0df04a4695fb9dc5ba977cbb68ab3e4eb225e7852"},
|
||||||
|
{file = "xmltodict-0.13.0.tar.gz", hash = "sha256:341595a488e3e01a85a9d8911d8912fd922ede5fecc4dce437eb4b6c8d037e56"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "yarl"
|
name = "yarl"
|
||||||
version = "1.9.4"
|
version = "1.9.4"
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ testing = [
|
||||||
"polyfactory>=2.12.0",
|
"polyfactory>=2.12.0",
|
||||||
"pytest>=7.4.3",
|
"pytest>=7.4.3",
|
||||||
"pytest-cov>=4.1.0",
|
"pytest-cov>=4.1.0",
|
||||||
|
"moto[s3]>=4.2.11",
|
||||||
]
|
]
|
||||||
linting = [
|
linting = [
|
||||||
"ruff>=0.1.7",
|
"ruff>=0.1.7",
|
||||||
|
|
@ -41,4 +42,9 @@ build-backend = "pdm.backend"
|
||||||
[tool.pdm.dev-dependencies]
|
[tool.pdm.dev-dependencies]
|
||||||
dev = [
|
dev = [
|
||||||
"types-aioboto3-lite[s3]>=12.0.0",
|
"types-aioboto3-lite[s3]>=12.0.0",
|
||||||
|
"boto3-stubs[s3]>=1.33.10",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[tool.ruff]
|
||||||
|
extend-select = ["W", "C90", "I", "N", "UP", "S", "BLE", "B", "A", "COM", "C4", "DTZ", "T10", "EM", "ISC", "T20", "PT", "RSE", "RET", "SIM", "PTH", "ERA", "PGH", "PL", "TRY", "RUF"]
|
||||||
|
extend-ignore = ["S101", "ISC002", "ISC002", "COM812"]
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
from abc import ABC, abstractmethod
|
|
||||||
import random
|
import random
|
||||||
|
from abc import ABC, abstractmethod
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from pydantic import BaseModel, UUID4
|
from pydantic import UUID4, BaseModel
|
||||||
|
|
||||||
from secretsanta.settings import Config, get_config
|
from secretsanta.settings import Config, get_config
|
||||||
|
|
||||||
|
|
@ -42,3 +43,7 @@ class IService(ABC):
|
||||||
def __init__(self, repo: IRepo, config: Config | None = None):
|
def __init__(self, repo: IRepo, config: Config | None = None):
|
||||||
self.repo = repo
|
self.repo = repo
|
||||||
self.config = config or get_config()
|
self.config = config or get_config()
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
async def run(self, *args, **kwargs) -> Any:
|
||||||
|
... # pragma: no cover
|
||||||
|
|
|
||||||
|
|
@ -5,12 +5,12 @@ import aioboto3
|
||||||
from botocore.exceptions import ClientError
|
from botocore.exceptions import ClientError
|
||||||
|
|
||||||
from secretsanta.domain import Group, IRepo
|
from secretsanta.domain import Group, IRepo
|
||||||
from secretsanta.settings import get_config
|
from secretsanta.settings import Config, get_config
|
||||||
|
|
||||||
|
|
||||||
class S3Repo(IRepo):
|
class S3Repo(IRepo):
|
||||||
def __init__(self):
|
def __init__(self, config: Config | None = None):
|
||||||
self.config = get_config()
|
self.config = config or get_config()
|
||||||
self.session = aioboto3.Session(
|
self.session = aioboto3.Session(
|
||||||
aws_access_key_id=self.config.s3_access_key_id,
|
aws_access_key_id=self.config.s3_access_key_id,
|
||||||
aws_secret_access_key=self.config.s3_secret_access_key,
|
aws_secret_access_key=self.config.s3_secret_access_key,
|
||||||
|
|
@ -34,7 +34,7 @@ class S3Repo(IRepo):
|
||||||
Key=f"secretsanta/{group_uuid}.json",
|
Key=f"secretsanta/{group_uuid}.json",
|
||||||
)
|
)
|
||||||
except ClientError:
|
except ClientError:
|
||||||
return
|
return None
|
||||||
else:
|
else:
|
||||||
group_raw = await s3_obj["Body"].read()
|
group_raw = await s3_obj["Body"].read()
|
||||||
return Group(**json.loads(group_raw))
|
return Group(**json.loads(group_raw))
|
||||||
|
|
|
||||||
|
|
@ -32,12 +32,13 @@ class CreateGroupService(IService):
|
||||||
class GetGroupParticipantsService(IService):
|
class GetGroupParticipantsService(IService):
|
||||||
async def run(self, group_uuid: str) -> list[str] | None:
|
async def run(self, group_uuid: str) -> list[str] | None:
|
||||||
group = await self.repo.get(group_uuid)
|
group = await self.repo.get(group_uuid)
|
||||||
if group:
|
if not group:
|
||||||
return participants2url(
|
return None
|
||||||
participants=group.participants,
|
return participants2url(
|
||||||
group_uuid=group.uuid,
|
participants=group.participants,
|
||||||
server_url=self.config.server_url,
|
group_uuid=group.uuid,
|
||||||
)
|
server_url=self.config.server_url,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class GetPairService(IService):
|
class GetPairService(IService):
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ def repo_with_data(repo, group):
|
||||||
@pytest.fixture()
|
@pytest.fixture()
|
||||||
def config():
|
def config():
|
||||||
return get_config(
|
return get_config(
|
||||||
s3_bucket_name="foo", s3_secret_access_key="foo", s3_access_key_id="foo"
|
s3_bucket_name="foo", s3_secret_access_key="testing", s3_access_key_id="testing", s3_region="us-east-1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,10 @@ async def test_get_participants(get_participants_service, group, config):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def test_get_participants_returns_none(get_participants_service, group):
|
||||||
|
assert not await get_participants_service.run(group.uuid)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("repo_with_data")
|
@pytest.mark.usefixtures("repo_with_data")
|
||||||
async def test_get_pair(get_pair_service, group):
|
async def test_get_pair(get_pair_service, group):
|
||||||
assert group.pairs
|
assert group.pairs
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue