docs: initial/basic project docs

This commit is contained in:
Lance Edgar 2026-02-08 12:51:54 -06:00
parent 3290a9936e
commit 4c0754ee01
46 changed files with 531 additions and 0 deletions

20
docs/Makefile Normal file
View file

@ -0,0 +1,20 @@
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = .
BUILDDIR = _build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

0
docs/_static/.keepme vendored Normal file
View file

View file

@ -0,0 +1,6 @@
``wuttafarm.app``
=================
.. automodule:: wuttafarm.app
:members:

View file

@ -0,0 +1,6 @@
``wuttafarm.auth``
==================
.. automodule:: wuttafarm.auth
:members:

View file

@ -0,0 +1,6 @@
``wuttafarm.cli``
=================
.. automodule:: wuttafarm.cli
:members:

View file

@ -0,0 +1,6 @@
``wuttafarm.config``
====================
.. automodule:: wuttafarm.config
:members:

View file

@ -0,0 +1,6 @@
``wuttafarm.db.model``
======================
.. automodule:: wuttafarm.db.model
:members:

View file

@ -0,0 +1,6 @@
``wuttafarm.db``
================
.. automodule:: wuttafarm.db
:members:

View file

@ -0,0 +1,6 @@
``wuttafarm.farmos.handler``
============================
.. automodule:: wuttafarm.farmos.handler
:members:

View file

@ -0,0 +1,6 @@
``wuttafarm.farmos``
====================
.. automodule:: wuttafarm.farmos
:members:

View file

@ -0,0 +1,6 @@
``wuttafarm.install``
=====================
.. automodule:: wuttafarm.install
:members:

6
docs/api/wuttafarm.rst Normal file
View file

@ -0,0 +1,6 @@
``wuttafarm``
=============
.. automodule:: wuttafarm
:members:

View file

@ -0,0 +1,6 @@
``wuttafarm.web.app``
=====================
.. automodule:: wuttafarm.web.app
:members:

View file

@ -0,0 +1,6 @@
``wuttafarm.web.forms``
=======================
.. automodule:: wuttafarm.web.forms
:members:

View file

@ -0,0 +1,6 @@
``wuttafarm.web.forms.schema``
==============================
.. automodule:: wuttafarm.web.forms.schema
:members:

View file

@ -0,0 +1,6 @@
``wuttafarm.web.forms.widgets``
===============================
.. automodule:: wuttafarm.web.forms.widgets
:members:

View file

@ -0,0 +1,6 @@
``wuttafarm.web.menus``
=======================
.. automodule:: wuttafarm.web.menus
:members:

View file

@ -0,0 +1,6 @@
``wuttafarm.web``
=================
.. automodule:: wuttafarm.web
:members:

View file

@ -0,0 +1,6 @@
``wuttafarm.web.static``
========================
.. automodule:: wuttafarm.web.static
:members:

View file

@ -0,0 +1,6 @@
``wuttafarm.web.subscribers``
=============================
.. automodule:: wuttafarm.web.subscribers
:members:

View file

@ -0,0 +1,6 @@
``wuttafarm.web.util``
======================
.. automodule:: wuttafarm.web.util
:members:

View file

@ -0,0 +1,6 @@
``wuttafarm.web.views.auth``
============================
.. automodule:: wuttafarm.web.views.auth
:members:

View file

@ -0,0 +1,6 @@
``wuttafarm.web.views.common``
==============================
.. automodule:: wuttafarm.web.views.common
:members:

View file

@ -0,0 +1,6 @@
``wuttafarm.web.views.farmos.animal_types``
===========================================
.. automodule:: wuttafarm.web.views.farmos.animal_types
:members:

View file

@ -0,0 +1,6 @@
``wuttafarm.web.views.farmos.animals``
======================================
.. automodule:: wuttafarm.web.views.farmos.animals
:members:

View file

@ -0,0 +1,6 @@
``wuttafarm.web.views.farmos.asset_types``
==========================================
.. automodule:: wuttafarm.web.views.farmos.asset_types
:members:

View file

@ -0,0 +1,6 @@
``wuttafarm.web.views.farmos.groups``
=====================================
.. automodule:: wuttafarm.web.views.farmos.groups
:members:

View file

@ -0,0 +1,6 @@
``wuttafarm.web.views.farmos.land_assets``
==========================================
.. automodule:: wuttafarm.web.views.farmos.land_assets
:members:

View file

@ -0,0 +1,6 @@
``wuttafarm.web.views.farmos.land_types``
=========================================
.. automodule:: wuttafarm.web.views.farmos.land_types
:members:

View file

@ -0,0 +1,6 @@
``wuttafarm.web.views.farmos.log_types``
========================================
.. automodule:: wuttafarm.web.views.farmos.log_types
:members:

View file

@ -0,0 +1,6 @@
``wuttafarm.web.views.farmos.logs_activity``
============================================
.. automodule:: wuttafarm.web.views.farmos.logs_activity
:members:

View file

@ -0,0 +1,6 @@
``wuttafarm.web.views.farmos.master``
=====================================
.. automodule:: wuttafarm.web.views.farmos.master
:members:

View file

@ -0,0 +1,6 @@
``wuttafarm.web.views.farmos``
==============================
.. automodule:: wuttafarm.web.views.farmos
:members:

View file

@ -0,0 +1,6 @@
``wuttafarm.web.views.farmos.structure_types``
==============================================
.. automodule:: wuttafarm.web.views.farmos.structure_types
:members:

View file

@ -0,0 +1,6 @@
``wuttafarm.web.views.farmos.structures``
=========================================
.. automodule:: wuttafarm.web.views.farmos.structures
:members:

View file

@ -0,0 +1,6 @@
``wuttafarm.web.views.farmos.users``
====================================
.. automodule:: wuttafarm.web.views.farmos.users
:members:

View file

@ -0,0 +1,6 @@
``wuttafarm.web.views``
=======================
.. automodule:: wuttafarm.web.views
:members:

39
docs/conf.py Normal file
View file

@ -0,0 +1,39 @@
# Configuration file for the Sphinx documentation builder.
#
# For the full list of built-in configuration values, see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Project information -----------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
from importlib.metadata import version as get_version
project = "WuttaFarm"
copyright = "2026, Lance Edgar"
author = "Lance Edgar"
release = get_version("WuttaFarm")
# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
extensions = [
"sphinx.ext.autodoc",
"sphinx.ext.intersphinx",
"sphinx.ext.viewcode",
"sphinx.ext.todo",
]
templates_path = ["_templates"]
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
intersphinx_mapping = {
"wuttjamaican": ("https://docs.wuttaproject.org/wuttjamaican/", None),
"wutta-continuum": ("https://docs.wuttaproject.org/wutta-continuum/", None),
}
# -- Options for HTML output -------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
html_theme = "furo"
html_static_path = ["_static"]

78
docs/index.rst Normal file
View file

@ -0,0 +1,78 @@
WuttaFarm
=========
This is a Python web app (built with `WuttaWeb`_), to integrate with
and extend `farmOS`_.
.. _WuttaWeb: https://wuttaproject.org
.. _farmOS: https://farmos.org
.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
:target: https://github.com/psf/black
It is just an experiment so far; the ideas I hope to play with
include:
- display farmOS data directly, via real-time API fetch
- add "mirror" schema and sync data from farmOS to app DB (and display it)
- possibly add more schema / extra features
- possibly sync data back to farmOS
.. toctree::
:maxdepth: 2
:caption: Documentation:
narr/install
narr/auth
narr/features
.. toctree::
:maxdepth: 1
:caption: Package API:
api/wuttafarm
api/wuttafarm.app
api/wuttafarm.auth
api/wuttafarm.cli
api/wuttafarm.config
api/wuttafarm.db
api/wuttafarm.db.model
api/wuttafarm.farmos
api/wuttafarm.farmos.handler
api/wuttafarm.install
api/wuttafarm.web
api/wuttafarm.web.app
api/wuttafarm.web.forms
api/wuttafarm.web.forms.schema
api/wuttafarm.web.forms.widgets
api/wuttafarm.web.menus
api/wuttafarm.web.static
api/wuttafarm.web.subscribers
api/wuttafarm.web.util
api/wuttafarm.web.views
api/wuttafarm.web.views.auth
api/wuttafarm.web.views.common
api/wuttafarm.web.views.farmos
api/wuttafarm.web.views.farmos.animals
api/wuttafarm.web.views.farmos.animal_types
api/wuttafarm.web.views.farmos.asset_types
api/wuttafarm.web.views.farmos.groups
api/wuttafarm.web.views.farmos.land_assets
api/wuttafarm.web.views.farmos.land_types
api/wuttafarm.web.views.farmos.logs_activity
api/wuttafarm.web.views.farmos.log_types
api/wuttafarm.web.views.farmos.master
api/wuttafarm.web.views.farmos.structures
api/wuttafarm.web.views.farmos.structure_types
api/wuttafarm.web.views.farmos.users
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

35
docs/make.bat Normal file
View file

@ -0,0 +1,35 @@
@ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=.
set BUILDDIR=_build
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.https://www.sphinx-doc.org/
exit /b 1
)
if "%1" == "" goto help
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
:end
popd

52
docs/narr/auth.rst Normal file
View file

@ -0,0 +1,52 @@
==============
Authentication
==============
At the moment, the expected user login process is as follows:
First Launch
------------
When you first visit the app, it will not have any user accounts so
you will be shown a form to create one.
The username should ideally match your main (daily driver) username
within farmOS. The password you give can be anything though, does not
need to (and perhaps should not) match farmOS.
This account will belong to the Administrator role within WuttaFarm,
which means it can "become root" (same concept as ``sudo`` basically).
Once the account is created you will be shown the normal login page.
Go ahead and login with this account using the username and password
you gave it. But then you should logout again, for the next step.
OAuth2
------
The assumption (for now) is that users will login via farmOS / OAuth2
for normal operations. Doing so will embed the access token within
the WuttaFarm app user session, which means the user can actually
browse farmOS data within the WuttaFarm views.
.. note::
If you login to WuttaFarm directly with username/password, then
your user session will not have a farmOS access token and so the
farmOS data views in WuttaFarm will not work.
On the login page, click the "Login via farmOS / OAuth2" button. This
will initiate the OAuth2 workflow, at which point you may be asked to
login to farmOS (if you're not already) and if you wish to grant
access to the 3rd party app (WuttaFarm; if you didn't already).
If all goes well you should be back in WuttaFarm, logged in as the
same username you have in farmOS.
Note that your first admin user in WuttaFarm ideally *should* have the
same username as farmOS, but regardless when you login via OAuth2, a
user account will be automatically created if necessary in WuttaFarm,
with that same username.

21
docs/narr/features.rst Normal file
View file

@ -0,0 +1,21 @@
========
Features
========
Here is the list of features currently supported:
* login via farmOS / OAuth2 workflows
* Authorization Code workflow is supported
* (technically, Password Grant workflow is also supported, for now)
* view some farmOS data directly
* limited data is fetched via farmOS API for several views
* performance isn't bad, but data is not very "complete"
* more data could be fetched, but not sure this is the best way..?
Screenshots
-----------
.. image:: https://wuttaproject.org/images/screenshot.png

62
docs/narr/install.rst Normal file
View file

@ -0,0 +1,62 @@
==============
Installation
==============
For now, these instructions mostly reflect my own dev workflow. It
uses a Python virtual environment but no (Docker) containers.
Eventually it may make sense to add production deployment steps using
Docker etc. - but that will wait for now.
Requirements
------------
WuttaFarm is designed to run on a (Debian-based) Linux machine; YMMV
with others.
farmOS
~~~~~~
First you must have a *production* `farmOS`_ instance running
somewhere. For more on that see `Hosting farmOS`_.
.. _farmOS: https://farmos.org
.. _Hosting farmOS: https://farmos.org/hosting/
This must use HTTPS for the OAuth2 workflows to work correctly. (Not
sure but it may also need to be at the root of the domain, i.e. no
subpath.)
Database
~~~~~~~~
You also must create a PostgreSQL (or MySQL) database for the
WuttaFarm app to use. See also :ref:`wuttjamaican:create-appdb`.
App Setup
---------
The short version:
.. code-block:: sh
python3 -m venv ./venv
./venv/bin/pip install WuttaFarm
./venv/bin/wuttafarm install
The app installer (last command above) will prompt you for DB
credentials, and the farmOS URL.
One of the questions is about data versioning with
:doc:`wutta-continuum:index`. This feature will be leveraged more in
the future but for the moment doesn't do a whole lot in this app. You
are encouraged to enable it anyway.
When the installer completes it will output a command you can then use
to run the web app. Do that and you can then view the app in a
browser at http://localhost:9080

View file

@ -37,6 +37,10 @@ dependencies = [
]
[project.optional-dependencies]
docs = ["Sphinx", "furo"]
[project.scripts]
"wuttafarm" = "wuttafarm.cli:wuttafarm_typer"

View file

@ -40,6 +40,7 @@ class ImageWidget(Widget):
self.alt_text = alt_text
def serialize(self, field, cstruct, **kw):
""" """
readonly = kw.get("readonly", self.readonly)
if readonly:
if cstruct in (colander.null, None):
@ -60,6 +61,7 @@ class AnimalTypeWidget(Widget):
self.request = request
def serialize(self, field, cstruct, **kw):
""" """
readonly = kw.get("readonly", self.readonly)
if readonly:
if cstruct in (colander.null, None):
@ -86,6 +88,7 @@ class StructureWidget(Widget):
self.request = request
def serialize(self, field, cstruct, **kw):
""" """
readonly = kw.get("readonly", self.readonly)
if readonly:
if cstruct in (colander.null, None):
@ -112,6 +115,7 @@ class UsersWidget(Widget):
self.request = request
def serialize(self, field, cstruct, **kw):
""" """
readonly = kw.get("readonly", self.readonly)
if readonly:
if cstruct in (colander.null, None):

6
tox.ini Normal file
View file

@ -0,0 +1,6 @@
[testenv:docs]
basepython = python3.11
extras = docs
changedir = docs
commands = sphinx-build -b html -d {envtmpdir}/doctrees -W -T . {envtmpdir}/docs