Compare commits
No commits in common. "2da6e4379783bc65034d1a0fc1530b4e640f7387" and "484b0210bb999eef3ddad18c926be1ae1e2c3284" have entirely different histories.
2da6e43797
...
484b0210bb
17 changed files with 150 additions and 425 deletions
164
.gitignore
vendored
164
.gitignore
vendored
|
|
@ -1,22 +1,154 @@
|
||||||
# IDEs / editors
|
# ---> Python
|
||||||
.idea/
|
# Byte-compiled / optimized / DLL files
|
||||||
.vscode/
|
|
||||||
|
|
||||||
# General
|
|
||||||
/tmp
|
|
||||||
/_tmp
|
|
||||||
.cache
|
|
||||||
|
|
||||||
# Python
|
|
||||||
__pycache__/
|
__pycache__/
|
||||||
*.py[cod]
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
|
||||||
# Python packaging and dev environments
|
# C extensions
|
||||||
/.pip
|
*.so
|
||||||
/venv
|
|
||||||
|
|
||||||
# Python testing
|
# 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/
|
||||||
.coverage
|
.coverage
|
||||||
.coverage.*
|
.coverage.*
|
||||||
.pytest_cache
|
.cache
|
||||||
.tox/
|
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/
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
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"]
|
|
||||||
47
Makefile
47
Makefile
|
|
@ -1,47 +0,0 @@
|
||||||
# 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
|
|
||||||
15
Pipfile
15
Pipfile
|
|
@ -1,15 +0,0 @@
|
||||||
[[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"
|
|
||||||
162
Pipfile.lock
generated
162
Pipfile.lock
generated
|
|
@ -1,162 +0,0 @@
|
||||||
{
|
|
||||||
"_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 - REST API
|
# tofu-api
|
||||||
|
|
||||||
REST API backend for Tofu - a to-do list app with a twist.
|
REST API backend for Tofu - a to-do list app with a twist.
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
SECRET_KEY: 'development'
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
FLASK_APP=tofu_api.app
|
|
||||||
FLASK_ENV=development
|
|
||||||
FLASK_CONFIG_FILE=config.dev.yml
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
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:
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
from .rest_api import TofuApiBlueprint
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
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())
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
from .task_api import TaskApiBlueprint
|
|
||||||
|
|
@ -1,84 +0,0 @@
|
||||||
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
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
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
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
class DefaultConfig:
|
|
||||||
"""
|
|
||||||
This class defined default values for the app configuration.
|
|
||||||
"""
|
|
||||||
# TODO
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue