This commit is contained in:
2024-04-15 22:03:02 +00:00
parent 3e57c393c2
commit e4c6d10781
19 changed files with 507 additions and 46 deletions

View File

@@ -1,6 +1,6 @@
from dataclasses import dataclass
from repository.config import RedisSettings
from flask_demo_api.repository.config import RedisSettings
@dataclass(frozen=True)

View File

@@ -0,0 +1,14 @@
from flask import Flask, jsonify
def not_found_error(e):
return jsonify(error=str(e)), 404
def bad_request_error(e):
return jsonify(error=str(e)), 400
def register_errors(app: Flask):
app.register_error_handler(404, not_found_error)
app.register_error_handler(400, bad_request_error)

View File

@@ -1,12 +1,14 @@
import redis # type: ignore
from config import Settings
from dishka import Container, Provider, Scope, make_container, provide
from protocols.repository import Repository
from repository.config import RedisSettings
from repository.redis import RedisRepository
from usecase.add import PostKey
from usecase.get import GetKey
from usecase.put import PutKey
from flask_demo_api.config import Settings
from flask_demo_api.protocols.repository import Repository
from flask_demo_api.repository.config import RedisSettings
from flask_demo_api.repository.redis import RedisRepository
from flask_demo_api.usecase.add import PostKey
from flask_demo_api.usecase.delete import DelKey
from flask_demo_api.usecase.get import GetKey
from flask_demo_api.usecase.put import PutKey
class RedisSettingsProvider(Provider):
@@ -39,6 +41,7 @@ class UseCasesProvider(Provider):
get = provide(GetKey)
post = provide(PostKey)
put = provide(PutKey)
delete = provide(DelKey)
def create_container() -> Container:

View File

@@ -1,20 +1,26 @@
from dishka.integrations.flask import setup_dishka
from flask import Flask
from ioc import create_container
from routers.key import key_bp
from flask_demo_api.error_handlers import register_errors
from flask_demo_api.ioc import create_container
from flask_demo_api.routers.key import key_bp
def app_factory() -> Flask:
app = Flask(__name__)
register_errors(app)
app.register_blueprint(key_bp)
return app
if __name__ == "__main__":
def run_app():
app = app_factory()
container = create_container()
setup_dishka(container=container, app=app, auto_inject=True)
try:
app.run(debug=True, host="0.0.0.0")
finally:
container.close()
app.run()
container.close()
if __name__ == "__main__":
run_app()

View File

@@ -1,7 +1,8 @@
from dataclasses import dataclass
from typing import Any
@dataclass(frozen=True)
class KeyDTO:
key: str
val: str | None = None
val: Any | None = None

View File

@@ -1,7 +1,7 @@
from abc import abstractmethod
from typing import Protocol
from protocols.models import KeyDTO
from flask_demo_api.protocols.models import KeyDTO
class Repository(Protocol):
@@ -16,3 +16,7 @@ class Repository(Protocol):
@abstractmethod
def put_key(self, obj: KeyDTO) -> KeyDTO:
raise NotImplementedError
@abstractmethod
def delete_key(self, obj: KeyDTO) -> None:
raise NotImplementedError

View File

@@ -3,4 +3,4 @@ from dataclasses import dataclass
@dataclass(frozen=True)
class RedisSettings:
url: str = "redis://redis:6379/0"
url: str = "redis://localhost:6379/0"

View File

@@ -1,6 +1,9 @@
import pickle
import redis # type: ignore
from protocols.models import KeyDTO
from protocols.repository import Repository
from flask_demo_api.protocols.models import KeyDTO
from flask_demo_api.protocols.repository import Repository
class RedisRepository(Repository):
@@ -8,14 +11,18 @@ class RedisRepository(Repository):
self.pool = redis_pool
def get_key(self, obj: KeyDTO) -> KeyDTO | None:
# data = self.pool.get(obj.key)
# if not data:
# return None
return KeyDTO(key="10", val="1")
data = self.pool.get(obj.key)
if not data:
return None
return KeyDTO(key=str(obj.key), val=data)
def add_key(self, obj: KeyDTO) -> KeyDTO:
self.pool.set(obj.key, obj.val)
return KeyDTO(key="3", val="4")
self.pool.set(str(obj.key), pickle.dumps(obj.val))
return obj
def put_key(self, obj: KeyDTO) -> KeyDTO:
return KeyDTO(key="5", val="6")
def delete_key(self, obj: KeyDTO) -> None:
self.pool.delete(str(obj.key))
return None

View File

@@ -1,22 +1,27 @@
from dishka.integrations.flask import FromDishka, inject
from flask import Blueprint, jsonify, request
from protocols.models import KeyDTO
from usecase.add import PostKey
from usecase.get import GetKey
from usecase.put import PutKey
from flask import Blueprint, abort, jsonify, request
from flask_demo_api.protocols.models import KeyDTO
from flask_demo_api.usecase.add import PostKey
from flask_demo_api.usecase.delete import DelKey
from flask_demo_api.usecase.get import GetKey
from flask_demo_api.usecase.put import PutKey
key_bp = Blueprint("key_bp", __name__)
@key_bp.route("/", methods=["POST"])
@inject
def past_key(usecase: FromDishka[PostKey]):
json_data = request.get_json()
if json_data:
result = usecase(request=KeyDTO(key=json_data))
result = usecase(
request=KeyDTO(key=json_data.get("key"), val=json_data.get("val"))
)
return (
jsonify({"message": "Received JSON data successfully", "data": result}),
200,
jsonify({"message": "Ok", "data": result}),
201,
)
else:
return jsonify({"message": "No JSON data received"}), 400
@@ -29,23 +34,43 @@ def get_key(usecase: FromDishka[GetKey]):
if request_data:
result = usecase(request=KeyDTO(key=request_data))
if result is None:
abort(404, "Key not found")
return (
jsonify({"message": "Received JSON data successfully", "data": result}),
jsonify({"message": "Ok", "data": result}),
200,
)
else:
return jsonify({"message": "No GET parameters received"}), 400
abort(400, "Invalid GET parameters")
@key_bp.route("/", methods=["PUT"])
@inject
def put_key(usecase: FromDishka[PutKey]):
json_data = request.get_json()
if json_data:
result = usecase(request=KeyDTO(key=json_data))
result = usecase(
request=KeyDTO(key=json_data.get("key"), val=json_data.get("val"))
)
return (
jsonify({"message": "Received JSON data successfully", "data": result}),
jsonify({"message": "Updated", "data": result}),
200,
)
else:
return jsonify({"message": "No JSON data received"}), 400
@key_bp.route("/", methods=["DELETE"])
@inject
def delete_key(usecase: FromDishka[DelKey]):
json_data = request.get_json()
if json_data:
usecase(request=KeyDTO(key=json_data.get("key"), val=json_data.get("val")))
return (
jsonify({"message": "Deleted"}),
200,
)
else:

View File

@@ -1,5 +1,5 @@
from protocols.models import KeyDTO
from protocols.repository import Repository
from flask_demo_api.protocols.models import KeyDTO
from flask_demo_api.protocols.repository import Repository
class PostKey:

View File

@@ -0,0 +1,13 @@
from flask_demo_api.protocols.models import KeyDTO
from flask_demo_api.protocols.repository import Repository
class DelKey:
def __init__(
self,
repository: Repository,
) -> None:
self.__repository = repository
def __call__(self, request: KeyDTO) -> KeyDTO:
return self.__repository.delete_key(obj=request)

View File

@@ -1,5 +1,5 @@
from protocols.models import KeyDTO
from protocols.repository import Repository
from flask_demo_api.protocols.models import KeyDTO
from flask_demo_api.protocols.repository import Repository
class GetKey:

View File

@@ -1,5 +1,5 @@
from protocols.models import KeyDTO
from protocols.repository import Repository
from flask_demo_api.protocols.models import KeyDTO
from flask_demo_api.protocols.repository import Repository
class PutKey: