SciPaperLoader/contents
Michael Beck 1a9bd7c0b1 init
2025-03-30 18:44:30 +02:00

362 lines
11 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

==> ./contents <==
==> ./setup.cfg <==
# flake8 doesn't support pyproject.toml yet:
# https://github.com/PyCQA/flake8/issues/234
[flake8]
exclude = setup.py,venv,build,dist
max-line-length = 88
==> ./.gitignore <==
# Python
__pycache__/
# Files created by this set up:
venv/
build/
dist/
*.egg-info/
.pytest_cache/
.mypy_cache/
==> ./Makefile <==
all: run
clean:
rm -rf venv build dist .pytest_cache .mypy_cache *.egg-info
venv:
python3 -m venv venv && \
venv/bin/pip install --upgrade pip setuptools && \
venv/bin/pip install --editable ".[dev]"
run: venv
venv/bin/flask --app scipaperloader --debug run
format: venv
venv/bin/black . && venv/bin/isort .
format-check: venv
venv/bin/black --check . && venv/bin/isort --check .
lint: venv
venv/bin/flake8 .
mypy: venv
venv/bin/mypy
test: venv
venv/bin/pytest
dist: venv format-check lint mypy test
venv/bin/pip wheel --wheel-dir dist --no-deps .
==> ./pyproject.toml <==
[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"
[project]
name = "scipaperloader"
version = "1.0.0"
requires-python = ">=3.8.1,<4"
dependencies = [
"Flask>=3.0.2,<4",
]
[project.optional-dependencies]
dev = [
"pytest>=8,<9",
"flake8>=7,<8",
"black>=24.2.0,<25",
"isort>=5.13.1,<6",
"mypy>=1.8.0,<2",
]
[tool.setuptools.package-data]
"*" = ["**/static/**/*", "**/templates/**/*"]
[tool.pytest.ini_options]
testpaths = ["tests"]
[tool.black]
line-length = 88
[tool.isort]
profile = "black"
[tool.mypy]
ignore_missing_imports = true
files = "scipaperloader,tests"
==> ./tests/test_scipaperloader.py <==
import pytest
from scipaperloader import create_app
@pytest.fixture
def app():
app = create_app({"TESTING": True})
# set up here
yield app
# tear down here
@pytest.fixture
def client(app):
return app.test_client()
def test_index(client):
response = client.get("/")
assert b"It works!" in response.data
==> ./scipaperloader/templates/index.html <==
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>SciPaperLoader</title>
<link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
</head>
<body class="message">
<h1>It works!</h1>
<h2>Next steps</h2>
<p>
The development environment is now set up and you can start coding! Check
out the <code>README.md</code> for the development environment usage.
</p>
<p>
If you are new to Flask, both
<a href="https://flask.palletsprojects.com/en/3.0.x/quickstart/">
Quickstart</a>
and
<a href="https://flask.palletsprojects.com/en/3.0.x/tutorial/">
Tutorial</a>
are great resources to get up and running quickly.
</p>
<p>
Check out Flask documentation for more
<a href="https://flask.palletsprojects.com/en/3.0.x/patterns/">
patterns</a>
such as using SQL DB or Mongo DB, making a single-page application and
many more features.
</p>
<p>
When you are ready to deploy, you may want to consider these:
</p>
<ul>
<li>
Depending on the target infrastructure, configure the
<a href="https://flask.palletsprojects.com/en/3.0.x/deploying/">
deployment,
</a>
</li>
<ul>
<li>
... and set a
<a href="https://flask.palletsprojects.com/en/3.0.x/tutorial/deploy/#configure-the-secret-key">
<code>SECRET_KEY</code></a>
in production.
</li>
</ul>
<li>
Depending on the deployment model, you may want to change the
<a href="https://flask.palletsprojects.com/en/3.0.x/logging/">
logging configuration</a>, and
<a href="https://flask.palletsprojects.com/en/3.0.x/config/">
how the configuration works</a>.
</li>
<li>Decide how to
<a href="https://flask.palletsprojects.com/en/3.0.x/errorhandling/">
handle errors</a>.
</li>
<li>
Consider your application
<a href="https://flask.palletsprojects.com/en/3.0.x/security/">
security</a>.
</li>
</ul>
</body>
</html>
==> ./scipaperloader/__pycache__/views.cpython-313.pyc <==
<EFBFBD>
<00>z<EFBFBD>g<EFBFBD><00><00>h<00>SSKJr SSKJr SSKJr \"S\5r\RS5S5rg)<08>)<01> Blueprint)<01> current_app)<01>render_template<74>root<6F>/c<00>V<00>[RRS5 [S5$)Nzsample messagez
index.html)<04>app<70>logger<65>warningr<00><00><00>5/home/michaelb/scipaperloader/scipaperloader/views.py<70>indexrs <00><00><07>J<EFBFBD>J<EFBFBD><16><16>'<27>(<28> <1A><<3C> (<28>(r
N) <09>flaskrrr r<00>__name__<5F>bp<62>routerr r
r<00><module>rs6<00><01><1B>$<24>!<21><0E>v<EFBFBD>x<EFBFBD> <20><02><04><18><18>#<23><1D>)<29><0F>)r
==> ./scipaperloader/__pycache__/logging.cpython-313.pyc <==
<EFBFBD>
<00>z<EFBFBD>g<EFBFBD><00><00> <00>SSKrSSKrSrSrg)<04>Nc<00>n<00>[R"SS5R5nUS:H=(d US:H$)N<> FLASK_DEBUG<55><00>true<75>1)<03>os<6F>getenv<6E>lower)<01>flags <20>7/home/michaelb/scipaperloader/scipaperloader/logging.py<70> _is_debugr
s.<00><00>
<EFBFBD>9<EFBFBD>9<EFBFBD>]<5D>B<EFBFBD> '<27> -<2D> -<2D> /<2F>D<EFBFBD> <0F>6<EFBFBD>><3E> (<28>T<EFBFBD>S<EFBFBD>[<5B>(<28>c <00><><00>Sn[RRSSSU00SSSSS.0[5(aS OS
S/S .S S
.5 g)Nz6[%(asctime)s] %(levelname)s in %(module)s: %(message)s<><00>default<6C>format<61>wsgizlogging.StreamHandlerzext://sys.stdout)<03>class<73>stream<61> formatter<65>DEBUG<55>INFO)<02>level<65>handlersF)<05>version<6F>
formattersr<00>root<6F>disable_existing_loggers)<04>logging<6E>config<69>
dictConfigr
)<01>msg_fmts r <00> init_loggingr# sg<00><00>F<>G<EFBFBD> <0B>N<EFBFBD>N<EFBFBD><1D><1D><18><19><1C>g<EFBFBD><12><0E> <17>4<>0<>!*<2A><12><0E>%.<2E>K<EFBFBD>K<EFBFBD><17>V<EFBFBD>#<23>H<EFBFBD><0E>).<2E>%
<EFBFBD>r)<05>logging.configrrr
r#<00>rr <00><module>r&s<00><01><15> <09>
)<29>
r
==> ./scipaperloader/__pycache__/__init__.cpython-313.pyc <==
<EFBFBD>
<00>z<EFBFBD>g<EFBFBD><00><00>:<00>SSKrSSKJr SSKJr SSKJr SSjrg)<07>N)<01>Flask)<01>views)<01> init_loggingc<00><00>[5 [[5nURR S5 URR 5 UbURR
U5 UR[R5 U$)Nzscipaperloader.defaults)
rr<00>__name__<5F>config<69> from_object<63>from_prefixed_env<6E> from_mapping<6E>register_blueprintr<00>bp)<02>config_overrides<65>apps <20>8/home/michaelb/scipaperloader/scipaperloader/__init__.py<70>
create_appr sc<00><00><10>N<EFBFBD>
<0F><08>/<2F>C<EFBFBD><07>J<EFBFBD>J<EFBFBD><1A><1A>4<>5<><07>J<EFBFBD>J<EFBFBD> <20> <20>"<22><17>#<23> <0B>
<EFBFBD>
<EFBFBD><1F><1F> 0<>1<><07><1A><1A>5<EFBFBD>8<EFBFBD>8<EFBFBD>$<24> <0E>J<EFBFBD>)N) <09>logging.config<69>logging<6E>flaskr<00>scipaperloaderr<00>scipaperloader.loggingrr<00>rr<00><module>rs<00><01><15><17> <20>/<2F> r
==> ./scipaperloader/__pycache__/defaults.cpython-313.pyc <==
<EFBFBD>
<00>z<EFBFBD>gL<00><00><00>Srg)FN)<01>DEBUG<55><00><00>8/home/michaelb/scipaperloader/scipaperloader/defaults.py<70><module>rs
<00><01>
<EFBFBD>r
==> ./scipaperloader/defaults.py <==
DEBUG = False # make sure DEBUG is off unless enabled explicitly otherwise
==> ./scipaperloader/__init__.py <==
import logging.config
from flask import Flask
from scipaperloader import views
from scipaperloader.logging import init_logging
def create_app(config_overrides=None):
init_logging() # should be configured before any access to app.logger
app = Flask(__name__)
app.config.from_object("scipaperloader.defaults")
app.config.from_prefixed_env()
if config_overrides is not None:
app.config.from_mapping(config_overrides)
app.register_blueprint(views.bp)
return app
==> ./scipaperloader/views.py <==
from flask import Blueprint
from flask import current_app as app
from flask import render_template
bp = Blueprint("root", __name__)
@bp.route("/")
def index():
app.logger.warning("sample message")
return render_template("index.html")
==> ./scipaperloader/logging.py <==
import logging.config
import os
# Since logging is initialized before the application, can't use
# app.debug here, relying on FLASK_DEBUG env var only.
def _is_debug():
flag = os.getenv("FLASK_DEBUG", "").lower()
return flag == "true" or flag == "1"
def init_logging():
msg_fmt = "[%(asctime)s] %(levelname)s in %(module)s: %(message)s"
logging.config.dictConfig(
{
"version": 1,
"formatters": {
"default": {
"format": msg_fmt,
}
},
"handlers": {
"wsgi": {
"class": "logging.StreamHandler",
"stream": "ext://sys.stdout",
"formatter": "default",
}
},
"root": {
"level": "DEBUG" if _is_debug() else "INFO",
"handlers": ["wsgi"],
},
"disable_existing_loggers": False,
}
)
==> ./scipaperloader/static/styles.css <==
.message {
padding: 10px;
font-size: 1.3em;
font-family: Arial, sans-serif;
}
==> ./setup.py <==
# This project uses pyproject.toml for all configuration.
# This file is for compatibility only.
# See https://setuptools.pypa.io/en/latest/userguide/quickstart.html#development-mode
from setuptools import setup
setup()
==> ./README.md <==
# SciPaperLoader
SciPaperLoader description
## Quick Start
Run the application:
make run
And open it in the browser at [http://localhost:5000/](http://localhost:5000/)
## Prerequisites
Python >=3.8
## Development environment
- `make venv`: creates a virtualenv with dependencies and this application
installed in [development mode](http://setuptools.readthedocs.io/en/latest/setuptools.html#development-mode)
- `make run`: runs a development server in debug mode (changes in source code
are reloaded automatically)
- `make format`: reformats code
- `make lint`: runs flake8
- `make mypy`: runs type checks by mypy
- `make test`: runs tests (see also: [Testing Flask Applications](https://flask.palletsprojects.com/en/3.0.x/testing/))
- `make dist`: creates a wheel distribution (will run tests first)
- `make clean`: removes virtualenv and build artifacts
- add application dependencies in `pyproject.toml` under `project.dependencies`;
add development dependencies under `project.optional-dependencies.*`; run
`make clean && make venv` to reinstall the environment
## Configuration
Default configuration is loaded from `scipaperloader.defaults` and can be
overriden by environment variables with a `FLASK_` prefix. See
[Configuring from Environment Variables](https://flask.palletsprojects.com/en/3.0.x/config/#configuring-from-environment-variables).
Consider using
[dotenv](https://flask.palletsprojects.com/en/3.0.x/cli/#environment-variables-from-dotenv).
## Deployment
See [Deploying to Production](https://flask.palletsprojects.com/en/3.0.x/deploying/).
You may use the distribution (`make dist`) to publish it to a package index,
deliver to your server, or copy in your `Dockerfile`, and insall it with `pip`.
You must set a
[SECRET_KEY](https://flask.palletsprojects.com/en/3.0.x/tutorial/deploy/#configure-the-secret-key)
in production to a secret and stable value.