Compare commits
2 Commits
484b0210bb
...
2da6e43797
| Author | SHA1 | Date |
|---|---|---|
|
|
2da6e43797 | |
|
|
0be947b3d1 |
|
|
@ -1,154 +1,22 @@
|
|||
# ---> Python
|
||||
# Byte-compiled / optimized / DLL files
|
||||
# IDEs / editors
|
||||
.idea/
|
||||
.vscode/
|
||||
|
||||
# General
|
||||
/tmp
|
||||
/_tmp
|
||||
.cache
|
||||
|
||||
# Python
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
# Python packaging and dev environments
|
||||
/.pip
|
||||
/venv
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
# Python testing
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
cover/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
.pybuilder/
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
# For a library or package, you might want to ignore these files since the code is
|
||||
# intended to run in multiple environments; otherwise, check them in:
|
||||
# .python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# poetry
|
||||
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
||||
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||
# commonly ignored for libraries.
|
||||
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
||||
#poetry.lock
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
# pytype static type analyzer
|
||||
.pytype/
|
||||
|
||||
# Cython debug symbols
|
||||
cython_debug/
|
||||
|
||||
# PyCharm
|
||||
# JetBrains specific template is maintainted in a separate JetBrains.gitignore that can
|
||||
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||
#.idea/
|
||||
|
||||
.pytest_cache
|
||||
.tox/
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
FROM python:3.10
|
||||
|
||||
# Install pipenv container-wide as root
|
||||
RUN pip install pipenv
|
||||
|
||||
# Create unprivileged user with UID as specified by the build argument DEV_USER_UID, defaulting to 1000.
|
||||
# (This should match the UID of your local user. If it doesn't, use an ".env" file to overwrite this variable.)
|
||||
ARG DEV_USER_UID=1000
|
||||
RUN echo Creating dev user with UID $DEV_USER_UID && \
|
||||
useradd -m -u $DEV_USER_UID dev
|
||||
USER dev
|
||||
|
||||
## Create virtual environment using pipenv
|
||||
WORKDIR /app
|
||||
COPY Pipfile Pipfile.lock ./
|
||||
RUN pipenv install --dev --deploy
|
||||
|
||||
# Set entrypoint to always run commands inside virtual environment
|
||||
ENTRYPOINT ["pipenv", "run"]
|
||||
|
||||
# Set default command
|
||||
CMD ["bash"]
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
# Define variables
|
||||
DOCKER_COMPOSE = docker-compose
|
||||
DOCKER_RUN = $(DOCKER_COMPOSE) run --rm backend
|
||||
|
||||
# Default target
|
||||
.PHONY: all
|
||||
all: docker-up
|
||||
|
||||
|
||||
# Container management
|
||||
# --------------------
|
||||
|
||||
.PHONY: docker-up
|
||||
docker-up:
|
||||
$(DOCKER_COMPOSE) up --build
|
||||
|
||||
.PHONY: docker-down
|
||||
docker-down:
|
||||
$(DOCKER_COMPOSE) down
|
||||
|
||||
.PHONY: docker-build
|
||||
docker-build:
|
||||
$(DOCKER_COMPOSE) build
|
||||
|
||||
.PHONY: docker-rebuild
|
||||
docker-rebuild:
|
||||
$(DOCKER_COMPOSE) build --pull --no-cache
|
||||
|
||||
.PHONY: docker-purge
|
||||
docker-purge:
|
||||
$(DOCKER_COMPOSE) down --volumes
|
||||
|
||||
.PHONY: docker-restart
|
||||
docker-restart:
|
||||
$(DOCKER_COMPOSE) restart $(SERVICE)
|
||||
|
||||
.PHONY: docker-logs
|
||||
docker-logs:
|
||||
$(DOCKER_COMPOSE) logs -f $(SERVICE) || true
|
||||
|
||||
.PHONY: docker-run
|
||||
docker-run:
|
||||
$(DOCKER_RUN) $(CMD)
|
||||
|
||||
.PHONY: docker-shell
|
||||
docker-shell:
|
||||
$(DOCKER_RUN) bash
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
[[source]]
|
||||
url = "https://pypi.org/simple"
|
||||
verify_ssl = true
|
||||
name = "pypi"
|
||||
|
||||
[packages]
|
||||
gunicorn = "~=20.1"
|
||||
werkzeug = "~=2.0"
|
||||
flask = "~=2.0"
|
||||
pyyaml = "*"
|
||||
|
||||
[dev-packages]
|
||||
|
||||
[requires]
|
||||
python_version = "3.10"
|
||||
|
|
@ -0,0 +1,162 @@
|
|||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "57e212392ff70382ed9ae0637e05f3696fa1d815f226e564910d296f7e2b5027"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
"python_version": "3.10"
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"name": "pypi",
|
||||
"url": "https://pypi.org/simple",
|
||||
"verify_ssl": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"default": {
|
||||
"click": {
|
||||
"hashes": [
|
||||
"sha256:6a7a62563bbfabfda3a38f3023a1db4a35978c0abd76f6c9605ecd6554d6d9b1",
|
||||
"sha256:8458d7b1287c5fb128c90e23381cf99dcde74beaf6c7ff6384ce84d6fe090adb"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==8.0.4"
|
||||
},
|
||||
"flask": {
|
||||
"hashes": [
|
||||
"sha256:59da8a3170004800a2837844bfa84d49b022550616070f7cb1a659682b2e7c9f",
|
||||
"sha256:e1120c228ca2f553b470df4a5fa927ab66258467526069981b3eb0a91902687d"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.0.3"
|
||||
},
|
||||
"gunicorn": {
|
||||
"hashes": [
|
||||
"sha256:9dcc4547dbb1cb284accfb15ab5667a0e5d1881cc443e0677b4882a4067a807e",
|
||||
"sha256:e0a968b5ba15f8a328fdfd7ab1fcb5af4470c28aaf7e55df02a99bc13138e6e8"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==20.1.0"
|
||||
},
|
||||
"itsdangerous": {
|
||||
"hashes": [
|
||||
"sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44",
|
||||
"sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==2.1.2"
|
||||
},
|
||||
"jinja2": {
|
||||
"hashes": [
|
||||
"sha256:a2f09a92f358b96b5f6ca6ecb4502669c4acb55d8733bbb2b2c9c4af5564c605",
|
||||
"sha256:da424924c069a4013730d8dd010cbecac7e7bb752be388db3741688bffb48dc6"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==3.1.0"
|
||||
},
|
||||
"markupsafe": {
|
||||
"hashes": [
|
||||
"sha256:0212a68688482dc52b2d45013df70d169f542b7394fc744c02a57374a4207003",
|
||||
"sha256:089cf3dbf0cd6c100f02945abeb18484bd1ee57a079aefd52cffd17fba910b88",
|
||||
"sha256:10c1bfff05d95783da83491be968e8fe789263689c02724e0c691933c52994f5",
|
||||
"sha256:33b74d289bd2f5e527beadcaa3f401e0df0a89927c1559c8566c066fa4248ab7",
|
||||
"sha256:3799351e2336dc91ea70b034983ee71cf2f9533cdff7c14c90ea126bfd95d65a",
|
||||
"sha256:3ce11ee3f23f79dbd06fb3d63e2f6af7b12db1d46932fe7bd8afa259a5996603",
|
||||
"sha256:421be9fbf0ffe9ffd7a378aafebbf6f4602d564d34be190fc19a193232fd12b1",
|
||||
"sha256:43093fb83d8343aac0b1baa75516da6092f58f41200907ef92448ecab8825135",
|
||||
"sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247",
|
||||
"sha256:4a33dea2b688b3190ee12bd7cfa29d39c9ed176bda40bfa11099a3ce5d3a7ac6",
|
||||
"sha256:4b9fe39a2ccc108a4accc2676e77da025ce383c108593d65cc909add5c3bd601",
|
||||
"sha256:56442863ed2b06d19c37f94d999035e15ee982988920e12a5b4ba29b62ad1f77",
|
||||
"sha256:671cd1187ed5e62818414afe79ed29da836dde67166a9fac6d435873c44fdd02",
|
||||
"sha256:694deca8d702d5db21ec83983ce0bb4b26a578e71fbdbd4fdcd387daa90e4d5e",
|
||||
"sha256:6a074d34ee7a5ce3effbc526b7083ec9731bb3cbf921bbe1d3005d4d2bdb3a63",
|
||||
"sha256:6d0072fea50feec76a4c418096652f2c3238eaa014b2f94aeb1d56a66b41403f",
|
||||
"sha256:6fbf47b5d3728c6aea2abb0589b5d30459e369baa772e0f37a0320185e87c980",
|
||||
"sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b",
|
||||
"sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812",
|
||||
"sha256:8dc1c72a69aa7e082593c4a203dcf94ddb74bb5c8a731e4e1eb68d031e8498ff",
|
||||
"sha256:8e3dcf21f367459434c18e71b2a9532d96547aef8a871872a5bd69a715c15f96",
|
||||
"sha256:8e576a51ad59e4bfaac456023a78f6b5e6e7651dcd383bcc3e18d06f9b55d6d1",
|
||||
"sha256:96e37a3dc86e80bf81758c152fe66dbf60ed5eca3d26305edf01892257049925",
|
||||
"sha256:97a68e6ada378df82bc9f16b800ab77cbf4b2fada0081794318520138c088e4a",
|
||||
"sha256:99a2a507ed3ac881b975a2976d59f38c19386d128e7a9a18b7df6fff1fd4c1d6",
|
||||
"sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e",
|
||||
"sha256:b09bf97215625a311f669476f44b8b318b075847b49316d3e28c08e41a7a573f",
|
||||
"sha256:b7bd98b796e2b6553da7225aeb61f447f80a1ca64f41d83612e6139ca5213aa4",
|
||||
"sha256:b87db4360013327109564f0e591bd2a3b318547bcef31b468a92ee504d07ae4f",
|
||||
"sha256:bcb3ed405ed3222f9904899563d6fc492ff75cce56cba05e32eff40e6acbeaa3",
|
||||
"sha256:d4306c36ca495956b6d568d276ac11fdd9c30a36f1b6eb928070dc5360b22e1c",
|
||||
"sha256:d5ee4f386140395a2c818d149221149c54849dfcfcb9f1debfe07a8b8bd63f9a",
|
||||
"sha256:dda30ba7e87fbbb7eab1ec9f58678558fd9a6b8b853530e176eabd064da81417",
|
||||
"sha256:e04e26803c9c3851c931eac40c695602c6295b8d432cbe78609649ad9bd2da8a",
|
||||
"sha256:e1c0b87e09fa55a220f058d1d49d3fb8df88fbfab58558f1198e08c1e1de842a",
|
||||
"sha256:e72591e9ecd94d7feb70c1cbd7be7b3ebea3f548870aa91e2732960fa4d57a37",
|
||||
"sha256:e8c843bbcda3a2f1e3c2ab25913c80a3c5376cd00c6e8c4a86a89a28c8dc5452",
|
||||
"sha256:efc1913fd2ca4f334418481c7e595c00aad186563bbc1ec76067848c7ca0a933",
|
||||
"sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a",
|
||||
"sha256:fc7b548b17d238737688817ab67deebb30e8073c95749d55538ed473130ec0c7"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==2.1.1"
|
||||
},
|
||||
"pyyaml": {
|
||||
"hashes": [
|
||||
"sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293",
|
||||
"sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b",
|
||||
"sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57",
|
||||
"sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b",
|
||||
"sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4",
|
||||
"sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07",
|
||||
"sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba",
|
||||
"sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9",
|
||||
"sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287",
|
||||
"sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513",
|
||||
"sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0",
|
||||
"sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0",
|
||||
"sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92",
|
||||
"sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f",
|
||||
"sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2",
|
||||
"sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc",
|
||||
"sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c",
|
||||
"sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86",
|
||||
"sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4",
|
||||
"sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c",
|
||||
"sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34",
|
||||
"sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b",
|
||||
"sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c",
|
||||
"sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb",
|
||||
"sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737",
|
||||
"sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3",
|
||||
"sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d",
|
||||
"sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53",
|
||||
"sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78",
|
||||
"sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803",
|
||||
"sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a",
|
||||
"sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174",
|
||||
"sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==6.0"
|
||||
},
|
||||
"setuptools": {
|
||||
"hashes": [
|
||||
"sha256:6221e37dc86fcdc9dad9d9eb2002e9f9798fe4aca1bf18f280e66e50c0eb7fca",
|
||||
"sha256:ad88b13f3dc60420259c9877486908ddad12c7befaff0d624c7190f742abd64f"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==61.0.0"
|
||||
},
|
||||
"werkzeug": {
|
||||
"hashes": [
|
||||
"sha256:1421ebfc7648a39a5c58c601b154165d05cf47a3cd0ccb70857cbdacf6c8f2b8",
|
||||
"sha256:b863f8ff057c522164b6067c9e28b041161b4be5ba4d0daceeaa50a163822d3c"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.0.3"
|
||||
}
|
||||
},
|
||||
"develop": {}
|
||||
}
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
# tofu-api
|
||||
# Tofu - REST API
|
||||
|
||||
REST API backend for Tofu - a to-do list app with a twist.
|
||||
|
|
@ -0,0 +1 @@
|
|||
SECRET_KEY: 'development'
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
FLASK_APP=tofu_api.app
|
||||
FLASK_ENV=development
|
||||
FLASK_CONFIG_FILE=config.dev.yml
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
version: '3'
|
||||
|
||||
services:
|
||||
backend:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.dev
|
||||
args:
|
||||
# Use an ".env" file to overwrite this variable if your local user's UID is not 1000.
|
||||
DEV_USER_UID: ${DEV_USER_UID:-1000}
|
||||
ports:
|
||||
- '5000:5000'
|
||||
volumes:
|
||||
- ./:/app/
|
||||
env_file:
|
||||
- development.env
|
||||
command: flask run --host=0.0.0.0
|
||||
|
||||
volumes:
|
||||
mariadb_data:
|
||||
|
|
@ -0,0 +1 @@
|
|||
from .rest_api import TofuApiBlueprint
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
from flask import Blueprint
|
||||
|
||||
from .tasks import TaskApiBlueprint
|
||||
|
||||
|
||||
class TofuApiBlueprint(Blueprint):
|
||||
"""
|
||||
Main blueprint for the Tofu REST API.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__('rest_api', __name__, url_prefix='/api')
|
||||
|
||||
self.register_blueprint(TaskApiBlueprint())
|
||||
|
|
@ -0,0 +1 @@
|
|||
from .task_api import TaskApiBlueprint
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
from flask import Blueprint, jsonify
|
||||
from flask.views import MethodView
|
||||
|
||||
|
||||
class TaskApiBlueprint(Blueprint):
|
||||
"""
|
||||
Blueprint for the tasks REST API.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__('rest_api_tasks', __name__, url_prefix='/tasks')
|
||||
|
||||
self.add_url_rule(
|
||||
'/',
|
||||
view_func=TaskCollectionView.as_view(TaskCollectionView.__name__),
|
||||
methods=['GET', 'POST'],
|
||||
)
|
||||
self.add_url_rule(
|
||||
'/<int:task_id>',
|
||||
view_func=TaskItemView.as_view(TaskItemView.__name__),
|
||||
methods=['GET', 'PATCH', 'DELETE'],
|
||||
)
|
||||
|
||||
|
||||
class TaskCollectionView(MethodView):
|
||||
"""
|
||||
View class for `/tasks` endpoint.
|
||||
"""
|
||||
|
||||
def get(self):
|
||||
"""
|
||||
Get list of all tasks.
|
||||
"""
|
||||
# TODO: Get actual data
|
||||
return jsonify({
|
||||
'count': 1,
|
||||
'items': [
|
||||
{
|
||||
'id': 1,
|
||||
'title': 'Do stuff',
|
||||
'description': '',
|
||||
'status': 'open',
|
||||
},
|
||||
],
|
||||
}), 200
|
||||
|
||||
def post(self):
|
||||
"""
|
||||
Create a new task.
|
||||
"""
|
||||
# TODO: Implement
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class TaskItemView(MethodView):
|
||||
"""
|
||||
View class for `/tasks/<int:task_id>` endpoint.
|
||||
"""
|
||||
|
||||
def get(self, task_id: int):
|
||||
"""
|
||||
Get a single task by ID.
|
||||
"""
|
||||
# TODO: Get actual data
|
||||
return jsonify({
|
||||
'id': task_id,
|
||||
'title': 'Do stuff',
|
||||
'description': '',
|
||||
'status': 'open',
|
||||
}), 200
|
||||
|
||||
def patch(self, task_id: int):
|
||||
"""
|
||||
Update a single task by ID.
|
||||
"""
|
||||
# TODO: Implement
|
||||
raise NotImplementedError
|
||||
|
||||
def delete(self, task_id: int):
|
||||
"""
|
||||
Delete a single task by ID.
|
||||
"""
|
||||
# TODO: Implement
|
||||
raise NotImplementedError
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
import os
|
||||
|
||||
import yaml
|
||||
from flask import Flask
|
||||
|
||||
from tofu_api.api import TofuApiBlueprint
|
||||
from tofu_api.config import DefaultConfig
|
||||
|
||||
|
||||
def create_app() -> Flask:
|
||||
"""
|
||||
App factory, returns a Flask app object.
|
||||
"""
|
||||
# Set instance path to the project root directory
|
||||
project_root_dir = os.path.abspath('.')
|
||||
|
||||
# Create and configure the app
|
||||
app = Flask(
|
||||
'tofu_api',
|
||||
instance_path=project_root_dir,
|
||||
instance_relative_config=True,
|
||||
)
|
||||
app.config.from_object(DefaultConfig)
|
||||
|
||||
# Load app configuration from YAML file
|
||||
app.config.from_file(os.getenv('FLASK_CONFIG_FILE', default='config.yml'), load=yaml.safe_load)
|
||||
|
||||
# Register blueprints
|
||||
app.register_blueprint(TofuApiBlueprint())
|
||||
|
||||
# Return WSGI app
|
||||
return app
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
class DefaultConfig:
|
||||
"""
|
||||
This class defined default values for the app configuration.
|
||||
"""
|
||||
# TODO
|
||||
Loading…
Reference in New Issue