new: documentation

fix: config env parsing
This commit is contained in:
L-Nafaryus 2024-09-06 11:13:25 +05:00
parent 8d03a3e3b0
commit 714a9d0879
Signed by: L-Nafaryus
GPG Key ID: 553C97999B363D38
26 changed files with 638 additions and 25 deletions

3
.gitignore vendored
View File

@ -13,3 +13,6 @@ __pycache__/
.pytest_cache .pytest_cache
.coverage .coverage
/site
src/materia/docs

52
docs/api.md Normal file
View File

@ -0,0 +1,52 @@
---
hide:
- navigation
- toc
---
<style>
.md-typeset h1,
.md-content__button {
display: none;
}
.md-main__inner {
max-width: 100%; /* or 100%, if you want to stretch to full-width */
margin-top: 0;
}
.md-content__inner {
margin: 0;
padding-top: 0;
}
.md-content__inner > p {
margin: 0;
}
.md-content__inner::before {
display: none;
}
.md-footer__inner {
display: none;
}
.md-footer__inner:not([hidden]) {
display: none;
}
</style>
<rapi-doc
spec-url="/api/openapi.json"
theme = "dark"
show-header = "false"
show-info = "false"
allow-authentication = "true"
allow-server-selection = "true"
allow-api-list-style-selection = "true"
theme = "dark"
render-style = "focused"
bg-color="#1e2129"
primary-color="#a47bea"
regular-font="Roboto"
mono-font="Roboto Mono"
show-method-in-nav-bar="as-colored-text">
<img slot="logo" style="display: none"/>
</rapi-doc>
<script
type="module"
src="https://unpkg.com/rapidoc/dist/rapidoc-min.js"
></script>

BIN
docs/img/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

BIN
docs/img/logo-full.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

12
docs/index.md Normal file
View File

@ -0,0 +1,12 @@
# Materia
<style>
.md-content .md-typeset h1 { display: none; }
</style>
<p align="center">
<a href="https://materia.elnafo.ru"><img src="img/logo-full.png" alt="Materia"></a>
</p>
<p align="center">
<em>Materia is easy and fast cloud storage</em>
</p>

1
docs/reference/app.md Normal file
View File

@ -0,0 +1 @@
::: materia.app

1
docs/reference/core.md Normal file
View File

@ -0,0 +1 @@
::: materia.core

5
docs/reference/index.md Normal file
View File

@ -0,0 +1,5 @@
# Reference
Here's the reference or code API, the classes, functions, parameters, attributes, and
all the Materia parts.

1
docs/reference/models.md Normal file
View File

@ -0,0 +1 @@
::: materia.models

View File

@ -0,0 +1 @@
::: materia.routers

View File

@ -0,0 +1 @@
::: materia.security

1
docs/reference/tasks.md Normal file
View File

@ -0,0 +1 @@
::: materia.tasks

View File

@ -164,6 +164,49 @@
postgresql-devel = bonfire.packages.x86_64-linux.postgresql; postgresql-devel = bonfire.packages.x86_64-linux.postgresql;
redis-devel = bonfire.packages.x86_64-linux.redis; redis-devel = bonfire.packages.x86_64-linux.redis;
materia-devel = let
user = "materia";
dataDir = "/var/lib/materia";
entryPoint = pkgs.writeTextDir "entrypoint.sh" ''
materia start
'';
in
pkgs.dockerTools.buildImage {
name = "materia";
tag = "latest";
copyToRoot = pkgs.buildEnv {
name = "image-root";
pathsToLink = ["/bin" "/etc" "/"];
paths = with pkgs; [
bash
self.packages.x86_64-linux.materia
entryPoint
];
};
runAsRoot = with pkgs; ''
#!${runtimeShell}
${dockerTools.shadowSetup}
groupadd -r ${user}
useradd -r -g ${user} --home-dir=${dataDir} ${user}
mkdir -p ${dataDir}
chown -R ${user}:${user} ${dataDir}
'';
config = {
Entrypoint = ["bash" "/entrypoint.sh"];
StopSignal = "SIGINT";
User = "${user}:${user}";
WorkingDir = dataDir;
ExposedPorts = {
"54601/tcp" = {};
};
Env = [
"MATERIA_APPLICATION__WORKING_DIRECTORY=${dataDir}"
];
};
};
}; };
devShells.x86_64-linux.default = pkgs.mkShell { devShells.x86_64-linux.default = pkgs.mkShell {

89
mkdocs.yml Normal file
View File

@ -0,0 +1,89 @@
site_name: Materia Documentation
site_description: Materia cloud storage
#site_url:
repo_name: L-Nafaryus/materia
repo_url: https://vcs.elnafo.ru/L-Nafaryus/materia
copyright: Copyright &copy; 2024 L-Nafaryus
theme:
name: material
features:
- content.code.annotate
- content.code.copy
# - content.code.select
- content.footnote.tooltips
- content.tabs.link
- content.tooltips
- navigation.footer
- navigation.indexes
- navigation.instant
- navigation.instant.prefetch
# - navigation.instant.preview
- navigation.instant.progress
- navigation.path
- navigation.tabs
- navigation.tabs.sticky
- navigation.top
- navigation.tracking
- search.highlight
- search.share
- search.suggest
- toc.follow
logo: img/favicon.png
favicon: img/favicon.png
palette:
- media: "(prefers-color-scheme: light)"
scheme: slate
primary: deep purple
accent: deep purple
toggle:
icon: material/weather-sunny
name: Switch to light mode
- media: "(prefers-color-scheme: dark)"
scheme: default
primary: deep purple
accent: deep purple
toggle:
icon: material/weather-night
name: Switch to dark mode
plugins:
- search:
- mkdocstrings:
handlers:
python:
paths: [src] # search packages in the src folder
options:
extensions:
- griffe_typingdoc
#preload_modules:
#- sqlalchemy
#docstring_style: sphinx
show_submodules: true
show_source: true
show_if_no_docstring: true
show_symbol_type_heading: true
show_symbol_type_toc: true
show_root_heading: true
unwrap_annotated: true
merge_init_into_class: true
docstring_section_style: spacy
signature_crossrefs: true
inherited_members: true
members_order: source
separate_signature: true
filters:
- '!^_'
nav:
- Materia: index.md
- Reference:
- reference/index.md
- reference/app.md
- reference/core.md
- reference/models.md
- reference/routers.md
- reference/security.md
- reference/tasks.md
- API: api.md

332
pdm.lock
View File

@ -5,7 +5,7 @@
groups = ["default", "dev"] groups = ["default", "dev"]
strategy = ["cross_platform", "inherit_metadata"] strategy = ["cross_platform", "inherit_metadata"]
lock_version = "4.4.1" lock_version = "4.4.1"
content_hash = "sha256:ba7a816a8bfe503b899a8eba3e5ca58e2d751a278c19b1c1db6e647f83fcd62d" content_hash = "sha256:764de758c9c4b274659cef493a76abb117253e6ccf30dce9f4e61a74afce2228"
[[package]] [[package]]
name = "aiofiles" name = "aiofiles"
@ -157,6 +157,17 @@ files = [
{file = "authlib-1.3.1.tar.gz", hash = "sha256:7ae843f03c06c5c0debd63c9db91f9fda64fa62a42a77419fa15fbb7e7a58917"}, {file = "authlib-1.3.1.tar.gz", hash = "sha256:7ae843f03c06c5c0debd63c9db91f9fda64fa62a42a77419fa15fbb7e7a58917"},
] ]
[[package]]
name = "babel"
version = "2.16.0"
requires_python = ">=3.8"
summary = "Internationalization utilities"
groups = ["dev"]
files = [
{file = "babel-2.16.0-py3-none-any.whl", hash = "sha256:368b5b98b37c06b7daf6696391c3240c938b37767d4584413e8438c5c435fa8b"},
{file = "babel-2.16.0.tar.gz", hash = "sha256:d1f3554ca26605fe173f3de0c65f750f5a42f924499bf134de6423582298e316"},
]
[[package]] [[package]]
name = "bcrypt" name = "bcrypt"
version = "4.1.2" version = "4.1.2"
@ -264,7 +275,7 @@ name = "certifi"
version = "2024.7.4" version = "2024.7.4"
requires_python = ">=3.6" requires_python = ">=3.6"
summary = "Python package for providing Mozilla's CA Bundle." summary = "Python package for providing Mozilla's CA Bundle."
groups = ["default"] groups = ["default", "dev"]
files = [ files = [
{file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"}, {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"},
{file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"}, {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"},
@ -310,7 +321,7 @@ name = "charset-normalizer"
version = "3.3.2" version = "3.3.2"
requires_python = ">=3.7.0" requires_python = ">=3.7.0"
summary = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." summary = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
groups = ["default"] groups = ["default", "dev"]
files = [ files = [
{file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"},
{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_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"},
@ -393,7 +404,6 @@ version = "0.4.6"
requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
summary = "Cross-platform colored terminal text." summary = "Cross-platform colored terminal text."
groups = ["default", "dev"] groups = ["default", "dev"]
marker = "sys_platform == \"win32\" or platform_system == \"Windows\""
files = [ files = [
{file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
{file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
@ -584,6 +594,19 @@ files = [
{file = "fastapi-0.112.0.tar.gz", hash = "sha256:d262bc56b7d101d1f4e8fc0ad2ac75bb9935fec504d2b7117686cec50710cf05"}, {file = "fastapi-0.112.0.tar.gz", hash = "sha256:d262bc56b7d101d1f4e8fc0ad2ac75bb9935fec504d2b7117686cec50710cf05"},
] ]
[[package]]
name = "ghp-import"
version = "2.1.0"
summary = "Copy your docs directly to the gh-pages branch."
groups = ["dev"]
dependencies = [
"python-dateutil>=2.8.1",
]
files = [
{file = "ghp-import-2.1.0.tar.gz", hash = "sha256:9c535c4c61193c2df8871222567d7fd7e5014d835f97dc7b7439069e2413d343"},
{file = "ghp_import-2.1.0-py3-none-any.whl", hash = "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619"},
]
[[package]] [[package]]
name = "greenlet" name = "greenlet"
version = "3.0.3" version = "3.0.3"
@ -603,6 +626,35 @@ files = [
{file = "greenlet-3.0.3.tar.gz", hash = "sha256:43374442353259554ce33599da8b692d5aa96f8976d567d4badf263371fbe491"}, {file = "greenlet-3.0.3.tar.gz", hash = "sha256:43374442353259554ce33599da8b692d5aa96f8976d567d4badf263371fbe491"},
] ]
[[package]]
name = "griffe"
version = "1.2.0"
requires_python = ">=3.8"
summary = "Signatures for entire Python programs. Extract the structure, the frame, the skeleton of your project, to generate API documentation or find breaking changes in your API."
groups = ["dev"]
dependencies = [
"colorama>=0.4",
]
files = [
{file = "griffe-1.2.0-py3-none-any.whl", hash = "sha256:a8b2fcb1ecdc5a412e646b0b4375eb20a5d2eac3a11dd8c10c56967a4097663c"},
{file = "griffe-1.2.0.tar.gz", hash = "sha256:1c9f6ef7455930f3f9b0c4145a961c90385d1e2cbc496f7796fbff560ec60d31"},
]
[[package]]
name = "griffe-typingdoc"
version = "0.2.6"
requires_python = ">=3.8"
summary = "Griffe extension for PEP 727 Documentation Metadata in Typing."
groups = ["dev"]
dependencies = [
"griffe>=0.49",
"typing-extensions>=4.7",
]
files = [
{file = "griffe_typingdoc-0.2.6-py3-none-any.whl", hash = "sha256:2726e6cf1e986f42fe9cab4a95cef103a745327f035a32055816849ca47893e4"},
{file = "griffe_typingdoc-0.2.6.tar.gz", hash = "sha256:852a17c1e2d29bbbf14a287e7cc5982669343cf60a4ea1618e486eb57aba3248"},
]
[[package]] [[package]]
name = "gunicorn" name = "gunicorn"
version = "22.0.0" version = "22.0.0"
@ -726,7 +778,7 @@ name = "idna"
version = "3.7" version = "3.7"
requires_python = ">=3.5" requires_python = ">=3.5"
summary = "Internationalized Domain Names in Applications (IDNA)" summary = "Internationalized Domain Names in Applications (IDNA)"
groups = ["default"] groups = ["default", "dev"]
files = [ files = [
{file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"},
{file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"},
@ -748,7 +800,7 @@ name = "jinja2"
version = "3.1.4" version = "3.1.4"
requires_python = ">=3.7" requires_python = ">=3.7"
summary = "A very fast and expressive template engine." summary = "A very fast and expressive template engine."
groups = ["default"] groups = ["default", "dev"]
dependencies = [ dependencies = [
"MarkupSafe>=2.0", "MarkupSafe>=2.0",
] ]
@ -856,12 +908,23 @@ files = [
{file = "Mako-1.3.5.tar.gz", hash = "sha256:48dbc20568c1d276a2698b36d968fa76161bf127194907ea6fc594fa81f943bc"}, {file = "Mako-1.3.5.tar.gz", hash = "sha256:48dbc20568c1d276a2698b36d968fa76161bf127194907ea6fc594fa81f943bc"},
] ]
[[package]]
name = "markdown"
version = "3.7"
requires_python = ">=3.8"
summary = "Python implementation of John Gruber's Markdown."
groups = ["dev"]
files = [
{file = "Markdown-3.7-py3-none-any.whl", hash = "sha256:7eb6df5690b81a1d7942992c97fad2938e956e79df20cbc6186e9c3a77b1c803"},
{file = "markdown-3.7.tar.gz", hash = "sha256:2ae2471477cfd02dbbf038d5d9bc226d40def84b4fe2986e49b59b6b472bbed2"},
]
[[package]] [[package]]
name = "markupsafe" name = "markupsafe"
version = "2.1.5" version = "2.1.5"
requires_python = ">=3.7" requires_python = ">=3.7"
summary = "Safely add untrusted strings to HTML/XML markup." summary = "Safely add untrusted strings to HTML/XML markup."
groups = ["default"] groups = ["default", "dev"]
files = [ files = [
{file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"},
{file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"},
@ -888,6 +951,147 @@ dependencies = [
"loguru<1.0.0,>=0.7.2", "loguru<1.0.0,>=0.7.2",
] ]
[[package]]
name = "mergedeep"
version = "1.3.4"
requires_python = ">=3.6"
summary = "A deep merge function for 🐍."
groups = ["dev"]
files = [
{file = "mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307"},
{file = "mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8"},
]
[[package]]
name = "mkdocs"
version = "1.6.1"
requires_python = ">=3.8"
summary = "Project documentation with Markdown."
groups = ["dev"]
dependencies = [
"click>=7.0",
"colorama>=0.4; platform_system == \"Windows\"",
"ghp-import>=1.0",
"jinja2>=2.11.1",
"markdown>=3.3.6",
"markupsafe>=2.0.1",
"mergedeep>=1.3.4",
"mkdocs-get-deps>=0.2.0",
"packaging>=20.5",
"pathspec>=0.11.1",
"pyyaml-env-tag>=0.1",
"pyyaml>=5.1",
"watchdog>=2.0",
]
files = [
{file = "mkdocs-1.6.1-py3-none-any.whl", hash = "sha256:db91759624d1647f3f34aa0c3f327dd2601beae39a366d6e064c03468d35c20e"},
{file = "mkdocs-1.6.1.tar.gz", hash = "sha256:7b432f01d928c084353ab39c57282f29f92136665bdd6abf7c1ec8d822ef86f2"},
]
[[package]]
name = "mkdocs-autorefs"
version = "1.2.0"
requires_python = ">=3.8"
summary = "Automatically link across pages in MkDocs."
groups = ["dev"]
dependencies = [
"Markdown>=3.3",
"markupsafe>=2.0.1",
"mkdocs>=1.1",
]
files = [
{file = "mkdocs_autorefs-1.2.0-py3-none-any.whl", hash = "sha256:d588754ae89bd0ced0c70c06f58566a4ee43471eeeee5202427da7de9ef85a2f"},
{file = "mkdocs_autorefs-1.2.0.tar.gz", hash = "sha256:a86b93abff653521bda71cf3fc5596342b7a23982093915cb74273f67522190f"},
]
[[package]]
name = "mkdocs-get-deps"
version = "0.2.0"
requires_python = ">=3.8"
summary = "MkDocs extension that lists all dependencies according to a mkdocs.yml file"
groups = ["dev"]
dependencies = [
"mergedeep>=1.3.4",
"platformdirs>=2.2.0",
"pyyaml>=5.1",
]
files = [
{file = "mkdocs_get_deps-0.2.0-py3-none-any.whl", hash = "sha256:2bf11d0b133e77a0dd036abeeb06dec8775e46efa526dc70667d8863eefc6134"},
{file = "mkdocs_get_deps-0.2.0.tar.gz", hash = "sha256:162b3d129c7fad9b19abfdcb9c1458a651628e4b1dea628ac68790fb3061c60c"},
]
[[package]]
name = "mkdocs-material"
version = "9.5.34"
requires_python = ">=3.8"
summary = "Documentation that simply works"
groups = ["dev"]
dependencies = [
"babel~=2.10",
"colorama~=0.4",
"jinja2~=3.0",
"markdown~=3.2",
"mkdocs-material-extensions~=1.3",
"mkdocs~=1.6",
"paginate~=0.5",
"pygments~=2.16",
"pymdown-extensions~=10.2",
"regex>=2022.4",
"requests~=2.26",
]
files = [
{file = "mkdocs_material-9.5.34-py3-none-any.whl", hash = "sha256:54caa8be708de2b75167fd4d3b9f3d949579294f49cb242515d4653dbee9227e"},
{file = "mkdocs_material-9.5.34.tar.gz", hash = "sha256:1e60ddf716cfb5679dfd65900b8a25d277064ed82d9a53cd5190e3f894df7840"},
]
[[package]]
name = "mkdocs-material-extensions"
version = "1.3.1"
requires_python = ">=3.8"
summary = "Extension pack for Python Markdown and MkDocs Material."
groups = ["dev"]
files = [
{file = "mkdocs_material_extensions-1.3.1-py3-none-any.whl", hash = "sha256:adff8b62700b25cb77b53358dad940f3ef973dd6db797907c49e3c2ef3ab4e31"},
{file = "mkdocs_material_extensions-1.3.1.tar.gz", hash = "sha256:10c9511cea88f568257f960358a467d12b970e1f7b2c0e5fb2bb48cab1928443"},
]
[[package]]
name = "mkdocstrings"
version = "0.26.0"
requires_python = ">=3.8"
summary = "Automatic documentation from sources, for MkDocs."
groups = ["dev"]
dependencies = [
"Jinja2>=2.11.1",
"Markdown>=3.6",
"MarkupSafe>=1.1",
"click>=7.0",
"mkdocs-autorefs>=1.2",
"mkdocs>=1.4",
"platformdirs>=2.2",
"pymdown-extensions>=6.3",
]
files = [
{file = "mkdocstrings-0.26.0-py3-none-any.whl", hash = "sha256:1aa227fe94f88e80737d37514523aacd473fc4b50a7f6852ce41447ab23f2654"},
{file = "mkdocstrings-0.26.0.tar.gz", hash = "sha256:ff9d0de28c8fa877ed9b29a42fe407cfe6736d70a1c48177aa84fcc3dc8518cd"},
]
[[package]]
name = "mkdocstrings-python"
version = "1.10.9"
requires_python = ">=3.8"
summary = "A Python handler for mkdocstrings."
groups = ["dev"]
dependencies = [
"griffe>=0.49",
"mkdocs-autorefs>=1.0",
"mkdocstrings>=0.25",
]
files = [
{file = "mkdocstrings_python-1.10.9-py3-none-any.whl", hash = "sha256:cbe98710a6757dfd4dff79bf36cb9731908fb4c69dd2736b15270ae7a488243d"},
{file = "mkdocstrings_python-1.10.9.tar.gz", hash = "sha256:f344aaa47e727d8a2dc911e063025e58e2b7fb31a41110ccc3902aa6be7ca196"},
]
[[package]] [[package]]
name = "more-itertools" name = "more-itertools"
version = "10.3.0" version = "10.3.0"
@ -932,6 +1136,16 @@ files = [
{file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"},
] ]
[[package]]
name = "paginate"
version = "0.5.7"
summary = "Divides large result sets into pages for easier browsing"
groups = ["dev"]
files = [
{file = "paginate-0.5.7-py2.py3-none-any.whl", hash = "sha256:b885e2af73abcf01d9559fd5216b57ef722f8c42affbb63942377668e35c7591"},
{file = "paginate-0.5.7.tar.gz", hash = "sha256:22bd083ab41e1a8b4f3690544afb2c60c25e5c9a63a30fa2f483f6c60c8e5945"},
]
[[package]] [[package]]
name = "pathspec" name = "pathspec"
version = "0.12.1" version = "0.12.1"
@ -1166,6 +1380,17 @@ files = [
{file = "pyflakes-3.2.0.tar.gz", hash = "sha256:1c61603ff154621fb2a9172037d84dca3500def8c8b630657d1701f026f8af3f"}, {file = "pyflakes-3.2.0.tar.gz", hash = "sha256:1c61603ff154621fb2a9172037d84dca3500def8c8b630657d1701f026f8af3f"},
] ]
[[package]]
name = "pygments"
version = "2.18.0"
requires_python = ">=3.8"
summary = "Pygments is a syntax highlighting package written in Python."
groups = ["dev"]
files = [
{file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"},
{file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"},
]
[[package]] [[package]]
name = "pyjwt" name = "pyjwt"
version = "2.9.0" version = "2.9.0"
@ -1177,6 +1402,21 @@ files = [
{file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"},
] ]
[[package]]
name = "pymdown-extensions"
version = "10.9"
requires_python = ">=3.8"
summary = "Extension pack for Python Markdown."
groups = ["dev"]
dependencies = [
"markdown>=3.6",
"pyyaml",
]
files = [
{file = "pymdown_extensions-10.9-py3-none-any.whl", hash = "sha256:d323f7e90d83c86113ee78f3fe62fc9dee5f56b54d912660703ea1816fed5626"},
{file = "pymdown_extensions-10.9.tar.gz", hash = "sha256:6ff740bcd99ec4172a938970d42b96128bdc9d4b9bcad72494f29921dc69b753"},
]
[[package]] [[package]]
name = "pyright" name = "pyright"
version = "1.1.374" version = "1.1.374"
@ -1242,7 +1482,7 @@ name = "python-dateutil"
version = "2.9.0.post0" version = "2.9.0.post0"
requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7"
summary = "Extensions to the standard Python datetime module" summary = "Extensions to the standard Python datetime module"
groups = ["default"] groups = ["default", "dev"]
dependencies = [ dependencies = [
"six>=1.5", "six>=1.5",
] ]
@ -1278,7 +1518,7 @@ name = "pyyaml"
version = "6.0.1" version = "6.0.1"
requires_python = ">=3.6" requires_python = ">=3.6"
summary = "YAML parser and emitter for Python" summary = "YAML parser and emitter for Python"
groups = ["default"] groups = ["default", "dev"]
files = [ files = [
{file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"},
{file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"},
@ -1290,6 +1530,20 @@ files = [
{file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"},
] ]
[[package]]
name = "pyyaml-env-tag"
version = "0.1"
requires_python = ">=3.6"
summary = "A custom YAML tag for referencing environment variables in YAML files. "
groups = ["dev"]
dependencies = [
"pyyaml",
]
files = [
{file = "pyyaml_env_tag-0.1-py3-none-any.whl", hash = "sha256:af31106dec8a4d68c60207c1886031cbf839b68aa7abccdb19868200532c2069"},
{file = "pyyaml_env_tag-0.1.tar.gz", hash = "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb"},
]
[[package]] [[package]]
name = "redis" name = "redis"
version = "5.0.8" version = "5.0.8"
@ -1317,12 +1571,37 @@ files = [
{file = "redis-5.0.8.tar.gz", hash = "sha256:0c5b10d387568dfe0698c6fad6615750c24170e548ca2deac10c649d463e9870"}, {file = "redis-5.0.8.tar.gz", hash = "sha256:0c5b10d387568dfe0698c6fad6615750c24170e548ca2deac10c649d463e9870"},
] ]
[[package]]
name = "regex"
version = "2024.7.24"
requires_python = ">=3.8"
summary = "Alternative regular expression module, to replace re."
groups = ["dev"]
files = [
{file = "regex-2024.7.24-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:fe4ebef608553aff8deb845c7f4f1d0740ff76fa672c011cc0bacb2a00fbde86"},
{file = "regex-2024.7.24-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:74007a5b25b7a678459f06559504f1eec2f0f17bca218c9d56f6a0a12bfffdad"},
{file = "regex-2024.7.24-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7df9ea48641da022c2a3c9c641650cd09f0cd15e8908bf931ad538f5ca7919c9"},
{file = "regex-2024.7.24-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a1141a1dcc32904c47f6846b040275c6e5de0bf73f17d7a409035d55b76f289"},
{file = "regex-2024.7.24-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80c811cfcb5c331237d9bad3bea2c391114588cf4131707e84d9493064d267f9"},
{file = "regex-2024.7.24-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7214477bf9bd195894cf24005b1e7b496f46833337b5dedb7b2a6e33f66d962c"},
{file = "regex-2024.7.24-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d55588cba7553f0b6ec33130bc3e114b355570b45785cebdc9daed8c637dd440"},
{file = "regex-2024.7.24-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:558a57cfc32adcf19d3f791f62b5ff564922942e389e3cfdb538a23d65a6b610"},
{file = "regex-2024.7.24-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a512eed9dfd4117110b1881ba9a59b31433caed0c4101b361f768e7bcbaf93c5"},
{file = "regex-2024.7.24-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:86b17ba823ea76256b1885652e3a141a99a5c4422f4a869189db328321b73799"},
{file = "regex-2024.7.24-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5eefee9bfe23f6df09ffb6dfb23809f4d74a78acef004aa904dc7c88b9944b05"},
{file = "regex-2024.7.24-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:731fcd76bbdbf225e2eb85b7c38da9633ad3073822f5ab32379381e8c3c12e94"},
{file = "regex-2024.7.24-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:eaef80eac3b4cfbdd6de53c6e108b4c534c21ae055d1dbea2de6b3b8ff3def38"},
{file = "regex-2024.7.24-cp312-cp312-win32.whl", hash = "sha256:185e029368d6f89f36e526764cf12bf8d6f0e3a2a7737da625a76f594bdfcbfc"},
{file = "regex-2024.7.24-cp312-cp312-win_amd64.whl", hash = "sha256:2f1baff13cc2521bea83ab2528e7a80cbe0ebb2c6f0bfad15be7da3aed443908"},
{file = "regex-2024.7.24.tar.gz", hash = "sha256:9cfd009eed1a46b27c14039ad5bbc5e71b6367c5b2e6d5f5da0ea91600817506"},
]
[[package]] [[package]]
name = "requests" name = "requests"
version = "2.32.3" version = "2.32.3"
requires_python = ">=3.8" requires_python = ">=3.8"
summary = "Python HTTP for Humans." summary = "Python HTTP for Humans."
groups = ["default"] groups = ["default", "dev"]
dependencies = [ dependencies = [
"certifi>=2017.4.17", "certifi>=2017.4.17",
"charset-normalizer<4,>=2", "charset-normalizer<4,>=2",
@ -1339,7 +1618,7 @@ name = "six"
version = "1.16.0" version = "1.16.0"
requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
summary = "Python 2 and 3 compatibility utilities" summary = "Python 2 and 3 compatibility utilities"
groups = ["default"] groups = ["default", "dev"]
files = [ files = [
{file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
{file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
@ -1471,7 +1750,7 @@ name = "typing-extensions"
version = "4.12.2" version = "4.12.2"
requires_python = ">=3.8" requires_python = ">=3.8"
summary = "Backported and Experimental Type Hints for Python 3.8+" summary = "Backported and Experimental Type Hints for Python 3.8+"
groups = ["default"] groups = ["default", "dev"]
files = [ files = [
{file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"},
{file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"},
@ -1493,7 +1772,7 @@ name = "urllib3"
version = "2.2.2" version = "2.2.2"
requires_python = ">=3.8" requires_python = ">=3.8"
summary = "HTTP library with thread-safe connection pooling, file post, and more." summary = "HTTP library with thread-safe connection pooling, file post, and more."
groups = ["default"] groups = ["default", "dev"]
files = [ files = [
{file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"}, {file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"},
{file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"}, {file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"},
@ -1579,6 +1858,33 @@ files = [
{file = "vine-5.1.0.tar.gz", hash = "sha256:8b62e981d35c41049211cf62a0a1242d8c1ee9bd15bb196ce38aefd6799e61e0"}, {file = "vine-5.1.0.tar.gz", hash = "sha256:8b62e981d35c41049211cf62a0a1242d8c1ee9bd15bb196ce38aefd6799e61e0"},
] ]
[[package]]
name = "watchdog"
version = "5.0.0"
requires_python = ">=3.9"
summary = "Filesystem events monitoring"
groups = ["dev"]
files = [
{file = "watchdog-5.0.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:1e26f570dd7f5178656affb24d6f0e22ce66c8daf88d4061a27bfb9ac866b40d"},
{file = "watchdog-5.0.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d146331e6b206baa9f6dd40f72b5783ad2302c240df68e7fce196d30588ccf7b"},
{file = "watchdog-5.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6c96b1706430839872a3e33b9370ee3f7a0079f6b828129d88498ad1f96a0f45"},
{file = "watchdog-5.0.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:bc16d448a74a929b896ed9578c25756b2125400b19b3258be8d9a681c7ae8e71"},
{file = "watchdog-5.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:7e6b0e9b8a9dc3865d65888b5f5222da4ba9c4e09eab13cff5e305e7b7e7248f"},
{file = "watchdog-5.0.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:4fe6780915000743074236b21b6c37419aea71112af62237881bc265589fe463"},
{file = "watchdog-5.0.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:0710e9502727f688a7e06d48078545c54485b3d6eb53b171810879d8223c362a"},
{file = "watchdog-5.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:d76efab5248aafbf8a2c2a63cd7b9545e6b346ad1397af8b862a3bb3140787d8"},
{file = "watchdog-5.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:ff4e957c45c446de34c513eadce01d0b65da7eee47c01dce472dd136124552c9"},
{file = "watchdog-5.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:16c1aa3377bb1f82c5e24277fcbf4e2cac3c4ce46aaaf7212d53caa9076eb7b7"},
{file = "watchdog-5.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:22fcad6168fc43cf0e709bd854be5b8edbb0b260f0a6f28f1ea9baa53c6907f7"},
{file = "watchdog-5.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:0120b2fa65732797ffa65fa8ee5540c288aa861d91447df298626d6385a24658"},
{file = "watchdog-5.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:2aa59fab7ff75281778c649557275ca3085eccbdf825a0e2a5ca3810e977afe5"},
{file = "watchdog-5.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:78db0fe0336958fc0e1269545c980b6f33d04d184ba191b2800a8b71d3e971a9"},
{file = "watchdog-5.0.0-py3-none-win32.whl", hash = "sha256:d1acef802916083f2ad7988efc7decf07e46e266916c0a09d8fb9d387288ea12"},
{file = "watchdog-5.0.0-py3-none-win_amd64.whl", hash = "sha256:3c2d50fdb86aa6df3973313272f5a17eb26eab29ff5a0bf54b6d34597b4dc4e4"},
{file = "watchdog-5.0.0-py3-none-win_ia64.whl", hash = "sha256:1d17ec7e022c34fa7ddc72aa41bf28c9d1207ffb193df18ba4f6fde453725b3c"},
{file = "watchdog-5.0.0.tar.gz", hash = "sha256:990aedb9e2f336b45a70aed9c014450e7c4a70fd99c5f5b1834d57e1453a177e"},
]
[[package]] [[package]]
name = "watchfiles" name = "watchfiles"
version = "0.22.0" version = "0.22.0"

View File

@ -48,7 +48,7 @@ requires = ["pdm-backend"]
build-backend = "pdm.backend" build-backend = "pdm.backend"
[project.scripts] [project.scripts]
materia = "materia.main:main" materia = "materia.app.cli:cli"
[tool.pyright] [tool.pyright]
reportGeneralTypeIssues = false reportGeneralTypeIssues = false
@ -70,6 +70,9 @@ dev = [
"pytest-asyncio>=0.23.7", "pytest-asyncio>=0.23.7",
"asgi-lifespan>=2.1.0", "asgi-lifespan>=2.1.0",
"pytest-cov>=5.0.0", "pytest-cov>=5.0.0",
"mkdocs-material>=9.5.34",
"mkdocstrings-python>=1.10.9",
"griffe-typingdoc>=0.2.6",
] ]
[tool.pdm.build] [tool.pdm.build]

View File

@ -2,11 +2,13 @@ from contextlib import _AsyncGeneratorContextManager, asynccontextmanager
import os import os
import sys import sys
from typing import AsyncIterator, TypedDict, Self, Optional from typing import AsyncIterator, TypedDict, Self, Optional
from pathlib import Path
import uvicorn import uvicorn
from fastapi import FastAPI from fastapi import FastAPI
from fastapi.routing import APIRoute from fastapi.routing import APIRoute
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from materia.core import ( from materia.core import (
Config, Config,
Logger, Logger,
@ -78,8 +80,9 @@ class Application:
async def prepare_working_directory(self): async def prepare_working_directory(self):
try: try:
self.logger.debug("Changing working directory") path = self.config.application.working_directory.resolve()
os.chdir(self.config.application.working_directory.resolve()) self.logger.debug(f"Changing working directory to {path}")
os.chdir(path)
except FileNotFoundError as e: except FileNotFoundError as e:
self.logger.error("Failed to change working directory: {}", e) self.logger.error("Failed to change working directory: {}", e)
sys.exit() sys.exit()
@ -117,7 +120,11 @@ class Application:
self.backend = FastAPI( self.backend = FastAPI(
title="materia", title="materia",
version="0.1.0", version="0.1.0",
docs_url="/api/docs", docs_url=None,
redoc_url=None,
swagger_ui_init_oauth=None,
swagger_ui_oauth2_redirect_url=None,
openapi_url="/api/openapi.json",
lifespan=lifespan, lifespan=lifespan,
) )
self.backend.add_middleware( self.backend.add_middleware(
@ -127,6 +134,7 @@ class Application:
allow_methods=["*"], allow_methods=["*"],
allow_headers=["*"], allow_headers=["*"],
) )
self.backend.include_router(routers.docs.router)
self.backend.include_router(routers.api.router) self.backend.include_router(routers.api.router)
self.backend.include_router(routers.resources.router) self.backend.include_router(routers.resources.router)
self.backend.include_router(routers.root.router) self.backend.include_router(routers.root.router)

View File

@ -15,7 +15,8 @@ def cli():
@cli.command() @cli.command()
@click.option("--config", type=Path) @click.option("--config", type=Path)
def start(config: Path): @click.option("--debug", "-d", is_flag=True, default=False, help="Enable debug output.")
def start(config: Path, debug: bool):
config_path = config config_path = config
logger = Logger.new() logger = Logger.new()
@ -48,6 +49,9 @@ def start(config: Path):
logger.info("Using the default configuration.") logger.info("Using the default configuration.")
config = Config() config = Config()
if debug:
config.log.level = "debug"
async def main(): async def main():
app = await Application.new(config) app = await Application.new(config)
await app.start() await app.start()

View File

@ -150,7 +150,7 @@ class Repository(BaseModel):
capacity: int = 5 << 30 capacity: int = 5 << 30
class Config(BaseSettings, env_prefix="materia_", env_nested_delimiter="_"): class Config(BaseSettings, env_prefix="materia_", env_nested_delimiter="__"):
application: Application = Application() application: Application = Application()
log: Log = Log() log: Log = Log()
server: Server = Server() server: Server = Server()

View File

@ -77,7 +77,9 @@ class Database:
async with database.connection() as connection: async with database.connection() as connection:
await connection.rollback() await connection.rollback()
except Exception as e: except Exception as e:
raise DatabaseError(f"Failed to connect to database: {url}") from e raise DatabaseError(
f"Failed to connect to database '{url}': {e}"
) from e
return database return database

View File

@ -1 +1 @@
from materia.routers import middleware, api, resources, root from materia.routers import middleware, api, resources, root, docs

View File

@ -1,11 +1,17 @@
from fastapi import APIRouter from fastapi import APIRouter, HTTPException
from materia.routers.api.auth import auth, oauth from materia.routers.api.auth import auth, oauth
from materia.routers.api import user, repository, directory, file from materia.routers.api import docs, user, repository, directory, file
router = APIRouter(prefix="/api") router = APIRouter(prefix="/api")
router.include_router(docs.router)
router.include_router(auth.router) router.include_router(auth.router)
router.include_router(oauth.router) router.include_router(oauth.router)
router.include_router(user.router) router.include_router(user.router)
router.include_router(repository.router) router.include_router(repository.router)
router.include_router(directory.router) router.include_router(directory.router)
router.include_router(file.router) router.include_router(file.router)
@router.get("/api/{catchall:path}", status_code=404, include_in_schema=False)
def not_found():
raise HTTPException(status_code=404)

View File

View File

@ -0,0 +1,40 @@
from fastapi import APIRouter, Request
from fastapi.responses import HTMLResponse
router = APIRouter()
@router.get("/docs", response_class=HTMLResponse, include_in_schema=False)
async def rapidoc(request: Request):
return f"""
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<link href='http://fonts.googleapis.com/css?family=Roboto' rel='stylesheet' type='text/css'>
<script
type="module"
src="https://unpkg.com/rapidoc/dist/rapidoc-min.js"
></script>
</head>
<body>
<rapi-doc
spec-url="{request.app.openapi_url}"
theme = "dark"
show-header = "false"
show-info = "true"
allow-authentication = "true"
allow-server-selection = "true"
allow-api-list-style-selection = "true"
theme = "dark"
render-style = "focused"
bg-color="#1e2129"
primary-color="#a47bea"
regular-font="Roboto"
mono-font="Roboto Mono"
show-method-in-nav-bar="as-colored-text">
<img slot="logo" style="display: none"/>
</rapi-doc>
</body>
</html>
"""

View File

@ -0,0 +1,33 @@
from fastapi import APIRouter, Request, Response, status, HTTPException, Depends
from fastapi.responses import HTMLResponse, FileResponse
from fastapi.templating import Jinja2Templates
from fastapi.staticfiles import StaticFiles
import mimetypes
from pathlib import Path
from materia.core.misc import optional
from materia.routers import middleware
from materia import docs as materia_docs
router = APIRouter()
# templates = Jinja2Templates(directory=Path(materia_docs.__path__[0]))
# p = Path(__file__).parent.joinpath("..", "docs").resolve()
# router.mount("/docs", StaticFiles(directory="doces", html=True), name="docs")
@router.get("/docs/{catchall:path}", include_in_schema=False)
async def docs(request: Request, ctx: middleware.Context = Depends()):
docs_directory = Path(materia_docs.__path__[0]).resolve()
target = docs_directory.joinpath(request.path_params["catchall"]).resolve()
if not optional(target.relative_to, docs_directory):
raise HTTPException(status.HTTP_403_FORBIDDEN)
if target.is_dir() and (index := target.joinpath("index.html")).is_file():
return FileResponse(index)
if not target.is_file():
raise HTTPException(status.HTTP_404_NOT_FOUND)
return FileResponse(target)

View File

@ -1,5 +1,5 @@
from pathlib import Path from pathlib import Path
from fastapi import APIRouter, Request from fastapi import APIRouter, Request, HTTPException
from fastapi.responses import HTMLResponse from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates from fastapi.templating import Jinja2Templates
@ -13,6 +13,7 @@ else:
templates = Jinja2Templates(directory=Path(materia_frontend.__path__[0]) / "dist") templates = Jinja2Templates(directory=Path(materia_frontend.__path__[0]) / "dist")
@router.get("/{spa:path}", response_class=HTMLResponse) @router.get("/{spa:path}", response_class=HTMLResponse, include_in_schema=False)
async def root(request: Request): async def root(request: Request):
# raise HTTPException(404)
return templates.TemplateResponse(request, "base.html", {"view": "app"}) return templates.TemplateResponse(request, "base.html", {"view": "app"})