Compare commits

..

No commits in common. "ea7e3087cd8556811d205d722845d50b0a1d1d38" and "3745cfe3f07cb02895ec4a86d192751bbf408989" have entirely different histories.

6 changed files with 150 additions and 163 deletions

View file

@ -18,11 +18,9 @@ jobs:
volumes: volumes:
- "uv_cache:/root/.cache/uv" - "uv_cache:/root/.cache/uv"
- "ca-cert:/etc/containers/certs.d" - "ca-cert:/etc/containers/certs.d"
services: services:
treetrail-database: treetrail-database:
image: code.philo.ydns.eu/philorg/treetrail-database image: code.philo.ydns.eu/philorg/treetrail-database
steps: steps:
- name: Echo env - name: Echo env
if: ${{ inputs.verbose }} if: ${{ inputs.verbose }}
@ -45,34 +43,40 @@ jobs:
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Install the latest version of uv - name: Get the version from git
uses: astral-sh/setup-uv@v4 id: version
with: run: echo "version=$(git describe --dirty --tags)" >> $GITHUB_OUTPUT
version: "0.6.6"
- name: Install - name: Check if the container should be built
run: uv sync id: builder
env:
RUN: ${{ toJSON(inputs.build || !contains(steps.version.outputs.version, '-')) }}
run: |
echo "run=$RUN" >> $GITHUB_OUTPUT
echo "Run build: $RUN"
- name: Get version - name: Info - version and test if the git version is clean (then python package and image container should be built)
run: echo "VERSION=$(.venv/bin/dunamai from any --style semver)" >> $GITHUB_ENV env:
VERSION: ${{ steps.version.outputs.version }}
RUN: ${{ steps.builder.outputs.run }}
FORCE: ${{ toJSON(inputs.build) }}
run: |
echo "Version $VERSION, force (manual input): $FORCE, run the build: $RUN"
- name: Version - name: Set the version in pyproject.toml (workaround for uv not supporting dynamic version)
run: echo $VERSION if: fromJSON(steps.builder.outputs.run)
env:
- name: Get distance from tag VERSION: ${{ steps.version.outputs.version }}
run: echo "DISTANCE=$(.venv/bin/dunamai from any --format '{distance}')" >> $GITHUB_ENV run: sed "s/0.0.0/${VERSION}/" -i pyproject.toml
- name: Distance
run: echo $DISTANCE
- name: Workaround for bug of podman-login - name: Workaround for bug of podman-login
if: env.DISTANCE == '0' if: fromJSON(steps.builder.outputs.run)
run: | run: |
mkdir -p $HOME/.docker mkdir -p $HOME/.docker
echo "{ \"auths\": {} }" > $HOME/.docker/config.json echo "{ \"auths\": {} }" > $HOME/.docker/config.json
- name: Log in to the container registry (with another workaround) - name: Log in to the container registry (with another workaround)
if: env.DISTANCE == '0' if: fromJSON(steps.builder.outputs.run)
uses: actions/podman-login@v1 uses: actions/podman-login@v1
with: with:
registry: ${{ vars.REGISTRY }} registry: ${{ vars.REGISTRY }}
@ -81,31 +85,37 @@ jobs:
auth_file_path: /tmp/auth.json auth_file_path: /tmp/auth.json
- name: Build the container image - name: Build the container image
if: env.DISTANCE == '0' if: fromJSON(steps.builder.outputs.run)
uses: actions/buildah-build@v1 uses: actions/buildah-build@v1
with: with:
image: treetrail-backend image: treetrail-backend
oci: true oci: true
labels: treetrail-backend labels: treetrail-backend
tags: latest env.VERSION tags: latest ${{ steps.version.outputs.version }}
containerfiles: | containerfiles: |
./Containerfile ./Containerfile
build-args: |
APP_VERSION=${{ steps.version.outputs.version }}
- name: Push the image to the registry - name: Push the image to the registry
if: env.DISTANCE == '0' if: fromJSON(steps.builder.outputs.run)
uses: actions/push-to-registry@v2 uses: actions/push-to-registry@v2
with: with:
registry: "docker://${{ vars.REGISTRY }}/${{ vars.ORGANISATION }}" registry: "docker://${{ vars.REGISTRY }}/${{ vars.ORGANISATION }}"
image: treetrail-backend image: treetrail-backend
tags: latest env.VERSION tags: latest ${{ steps.version.outputs.version }}
- name: Build wheel - name: Install uv
if: env.DISTANCE == '0' uses: astral-sh/setup-uv@v4
with:
version: "0.5.5"
- name: Build python package
if: fromJSON(steps.builder.outputs.run)
run: uv build --wheel run: uv build --wheel
- name: Publish Python package (home) - name: Publish Python package (home)
if: env.DISTANCE == '0' if: fromJSON(steps.builder.outputs.run)
env: env:
LOCAL_PYPI_TOKEN: ${{ secrets.LOCAL_PYPI_TOKEN }} LOCAL_PYPI_TOKEN: ${{ secrets.LOCAL_PYPI_TOKEN }}
run: uv publish --publish-url https://code.philo.ydns.eu/api/packages/philorg/pypi --token $LOCAL_PYPI_TOKEN run: uv publish --publish-url https://code.philo.ydns.eu/api/packages/philorg/pypi --token $LOCAL_PYPI_TOKEN
continue-on-error: true

View file

@ -1,80 +1,77 @@
[project] [project]
name = "treetrail-backend" name = "treetrail-backend"
dynamic = ["version"] version = "0.0.0"
#dynamic = ["version"]
description = "A fun and pedagogic tool to discover the trails and trees around" description = "A fun and pedagogic tool to discover the trails and trees around"
authors = [{ name = "Philippe May", email = "phil.treetrail@philome.mooo.com" }] authors = [
{ name = "Philippe May", email = "phil.treetrail@philome.mooo.com" }
]
dependencies = [ dependencies = [
"aiofiles", "aiofiles",
"aiohttp-client-cache", "aiohttp-client-cache",
"aiosqlite", "aiosqlite",
"asyncpg", "asyncpg",
"fastapi", "fastapi",
"geoalchemy2", "geoalchemy2",
"geopandas", "geopandas",
"httptools>=0.6.1", "httptools>=0.6.1",
"orjson", "orjson",
"pandas", "pandas",
"passlib[bcrypt]", "passlib[bcrypt]",
"pillow", "pillow",
"psycopg2-binary", "psycopg2-binary",
"pyarrow>=19.0.1", "pyarrow",
"pydantic-settings", "pydantic-settings",
"python-jose[cryptography]", "python-jose[cryptography]",
"python-multipart", "python-multipart",
"requests", "requests",
"sqlalchemy[asyncio]", "sqlalchemy[asyncio]",
"sqlmodel", "sqlmodel",
"uvicorn[standard]", "uvicorn[standard]",
"uvloop", "uvloop",
] ]
requires-python = ">=3.11" requires-python = ">=3.11"
readme = "README.md" readme = "README.md"
license = { text = "MIT" } license = {text = "MIT"}
classifiers = [ classifiers = [
"Development Status :: 3 - Alpha", "Development Status :: 3 - Alpha",
"Framework :: FastAPI", "Framework :: FastAPI",
"Environment :: Web Environment", "Environment :: Web Environment",
"Intended Audience :: Developers", "Intended Audience :: Developers",
"License :: OSI Approved :: GNU General Public License (GPL)", "License :: OSI Approved :: GNU General Public License (GPL)",
"Programming Language :: Python :: 3", "Programming Language :: Python :: 3",
"Operating System :: MacOS :: MacOS X", "Operating System :: MacOS :: MacOS X",
"Operating System :: POSIX", "Operating System :: POSIX",
"Programming Language :: Python", "Programming Language :: Python",
] ]
#[project.scripts] #[project.scripts]
#treetrail-backend = "treetrail_backend:main" #treetrail-backend = "treetrail_backend:main"
[dependency-groups]
dev = ["dunamai>=1.23.0", "ipdb>=0.13.13"]
[build-system] [build-system]
requires = ["hatchling", "uv-dynamic-versioning"] requires = ["hatchling"]
build-backend = "hatchling.build" build-backend = "hatchling.build"
[tool.hatch.version]
source = "uv-dynamic-versioning"
[tool.hatch.build.targets.wheel] [tool.hatch.build.targets.wheel]
packages = ["src/treetrail"] packages = ["src/treetrail"]
[tool.uv-dynamic-versioning]
style = "semver"
[tool.uv] [tool.uv]
package = true package = true
dev-dependencies = [ dev-dependencies = [
"httpx", "httpx",
"ipdb", "ipdb",
"pandas-stubs", "pandas-stubs",
"pytest", "pytest",
"types-Pillow", "types-Pillow",
"types-PyYAML", "types-PyYAML",
"types-aiofiles", "types-aiofiles",
"types-passlib", "types-passlib",
"types-python-jose", "types-python-jose",
"types-requests", "types-requests",
] ]
[tool.black] #[tool.pdm.version]
line-length = 98 #source = "scm"
#write_to = "treetrail/_version.py"
#write_template = "__version__ = '{}'"
#

View file

@ -1,8 +1,3 @@
import importlib.metadata from treetrail.utils import get_version
try: __version__ = get_version()
from dunamai import Version, Style
__version__ = Version.from_git().serialize(style=Style.SemVer, dirty=True)
except ImportError:
__version__ = importlib.metadata.version("treetrail-backend")

View file

@ -7,19 +7,19 @@ import pandas as pd
from sqlalchemy.ext.declarative import DeclarativeMeta from sqlalchemy.ext.declarative import DeclarativeMeta
from sqlalchemy.engine.row import Row from sqlalchemy.engine.row import Row
from sqlalchemy.sql.selectable import Select from sqlalchemy.sql.selectable import Select
import geopandas as gpd # type: ignore import geopandas as gpd # type: ignore
from treetrail.config import conf from treetrail.config import conf
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class AlchemyEncoder(json.JSONEncoder): class AlchemyEncoder(json.JSONEncoder):
def default(self, obj): def default(self, obj):
if isinstance(obj.__class__, DeclarativeMeta): if isinstance(obj.__class__, DeclarativeMeta):
# an SQLAlchemy class # an SQLAlchemy class
fields = {} fields = {}
for field in [x for x in dir(obj) if not x.startswith("_") and x != "metadata"]: for field in [x for x in dir(obj)
if not x.startswith('_') and x != 'metadata']:
data = obj.__getattribute__(field) data = obj.__getattribute__(field)
try: try:
# this will fail on non-encodable values, like other classes # this will fail on non-encodable values, like other classes
@ -50,30 +50,24 @@ def get_attachment_root(type: str):
def get_attachment_tree_root(): def get_attachment_tree_root():
return get_attachment_root("tree") return get_attachment_root('tree')
def get_attachment_trail_root(): def get_attachment_trail_root():
return get_attachment_root("trail") return get_attachment_root('trail')
def get_attachment_poi_root(): def get_attachment_poi_root():
return get_attachment_root("poi") return get_attachment_root('poi')
def pandas_query(session, query): def pandas_query(session, query):
return pd.read_sql_query(query, session.connection()) return pd.read_sql_query(query, session.connection())
def geopandas_query(session, query: Select, model, *,
def geopandas_query( # simplify_tolerance: float|None=None,
session, crs=None, cast=True,
query: Select, ):
model,
*,
# simplify_tolerance: float|None=None,
crs=None,
cast=True,
):
## XXX: I could not get the add_columns work without creating a subquery, ## XXX: I could not get the add_columns work without creating a subquery,
## so moving the simplification to geopandas - see in _get_df ## so moving the simplification to geopandas - see in _get_df
# if simplify_tolerance is not None: # if simplify_tolerance is not None:
@ -84,11 +78,34 @@ def geopandas_query(
# query = query.add_columns(new_column) # query = query.add_columns(new_column)
return gpd.GeoDataFrame.from_postgis(query, session.connection(), crs=crs) return gpd.GeoDataFrame.from_postgis(query, session.connection(), crs=crs)
def mkdir(dir: Path | str) -> Path: def mkdir(dir: Path | str) -> Path:
path = Path(dir) path = Path(dir)
if not path.is_dir(): if not path.is_dir():
logger.info(f"Create directory {path}") logger.info(f'Create directory {path}')
path.mkdir(parents=True, exist_ok=True) path.mkdir(parents=True, exist_ok=True)
return path return path
def get_version() -> str:
version_file_src = Path(__file__).parent / 'version.txt'
version_file_in_container = Path("/app") / 'version.txt'
if version_file_src.exists():
with open(version_file_src) as version:
return version.read().strip()
if version_file_in_container.exists():
with open(version_file_in_container) as version:
return version.read().strip()
else:
logger.debug('No version file, using git')
try:
from subprocess import run
git_version_cmd = run(['git', 'describe', '--broken', '--tags', '--always', '--dirty'],
capture_output=True)
if git_version_cmd.returncode == 0:
return git_version_cmd.stdout.strip().decode()
else:
logger.debug('git returns with the error below, version set as 0.0.0')
logger.debug(git_version_cmd.stderr.decode())
return '0.0.0'
except FileNotFoundError as err:
logger.debug('git not found: version set as 0.0.0')
return '0.0.0'

View file

@ -2,12 +2,6 @@ apiVersion: v1
kind: Service kind: Service
metadata: metadata:
name: treetrail name: treetrail
annotations:
io.kubernetes.cri-o.SandboxID/gisaf-backend: treetrail-cri-o
io.kubernetes.cri-o.SandboxID/gisaf-database: treetrail-cri-o
io.kubernetes.cri-o.SandboxID/gisaf-frontend: treetrail-cri-o
io.kubernetes.cri-o.SandboxID/gisaf-redis: treetrail-cri-o
io.podman.annotations.infra.name: treetrail-infra
labels: labels:
app: treetrail app: treetrail
spec: spec:

70
uv.lock generated
View file

@ -1,5 +1,4 @@
version = 1 version = 1
revision = 1
requires-python = ">=3.11" requires-python = ">=3.11"
resolution-markers = [ resolution-markers = [
"python_full_version < '3.12'", "python_full_version < '3.12'",
@ -343,7 +342,7 @@ name = "click"
version = "8.1.7" version = "8.1.7"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "colorama", marker = "sys_platform == 'win32'" }, { name = "colorama", marker = "platform_system == 'Windows'" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/96/d3/f04c7bfcf5c1862a2a5b845c6b2b360488cf47af55dfa79c98f6a6bf98b5/click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de", size = 336121 } sdist = { url = "https://files.pythonhosted.org/packages/96/d3/f04c7bfcf5c1862a2a5b845c6b2b360488cf47af55dfa79c98f6a6bf98b5/click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de", size = 336121 }
wheels = [ wheels = [
@ -397,18 +396,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/d5/50/83c593b07763e1161326b3b8c6686f0f4b0f24d5526546bee538c89837d6/decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186", size = 9073 }, { url = "https://files.pythonhosted.org/packages/d5/50/83c593b07763e1161326b3b8c6686f0f4b0f24d5526546bee538c89837d6/decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186", size = 9073 },
] ]
[[package]]
name = "dunamai"
version = "1.23.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "packaging" },
]
sdist = { url = "https://files.pythonhosted.org/packages/06/4e/a5c8c337a1d9ac0384298ade02d322741fb5998041a5ea74d1cd2a4a1d47/dunamai-1.23.0.tar.gz", hash = "sha256:a163746de7ea5acb6dacdab3a6ad621ebc612ed1e528aaa8beedb8887fccd2c4", size = 44681 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/21/4c/963169386309fec4f96fd61210ac0a0666887d0fb0a50205395674d20b71/dunamai-1.23.0-py3-none-any.whl", hash = "sha256:a0906d876e92441793c6a423e16a4802752e723e9c9a5aabdc5535df02dbe041", size = 26342 },
]
[[package]] [[package]]
name = "ecdsa" name = "ecdsa"
version = "0.19.0" version = "0.19.0"
@ -1122,7 +1109,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/ce/ac/5b1ea50fc08a9df82de7e1771537557f07c2632231bbab652c7e22597908/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:bb89f0a835bcfc1d42ccd5f41f04870c1b936d8507c6df12b7737febc40f0909", size = 2822712 }, { url = "https://files.pythonhosted.org/packages/ce/ac/5b1ea50fc08a9df82de7e1771537557f07c2632231bbab652c7e22597908/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:bb89f0a835bcfc1d42ccd5f41f04870c1b936d8507c6df12b7737febc40f0909", size = 2822712 },
{ url = "https://files.pythonhosted.org/packages/c4/fc/504d4503b2abc4570fac3ca56eb8fed5e437bf9c9ef13f36b6621db8ef00/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f0c2d907a1e102526dd2986df638343388b94c33860ff3bbe1384130828714b1", size = 2920155 }, { url = "https://files.pythonhosted.org/packages/c4/fc/504d4503b2abc4570fac3ca56eb8fed5e437bf9c9ef13f36b6621db8ef00/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f0c2d907a1e102526dd2986df638343388b94c33860ff3bbe1384130828714b1", size = 2920155 },
{ url = "https://files.pythonhosted.org/packages/b2/d1/323581e9273ad2c0dbd1902f3fb50c441da86e894b6e25a73c3fda32c57e/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f8157bed2f51db683f31306aa497311b560f2265998122abe1dce6428bd86567", size = 2959356 }, { url = "https://files.pythonhosted.org/packages/b2/d1/323581e9273ad2c0dbd1902f3fb50c441da86e894b6e25a73c3fda32c57e/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f8157bed2f51db683f31306aa497311b560f2265998122abe1dce6428bd86567", size = 2959356 },
{ url = "https://files.pythonhosted.org/packages/08/50/d13ea0a054189ae1bc21af1d85b6f8bb9bbc5572991055d70ad9006fe2d6/psycopg2_binary-2.9.10-cp313-cp313-win_amd64.whl", hash = "sha256:27422aa5f11fbcd9b18da48373eb67081243662f9b46e6fd07c3eb46e4535142", size = 2569224 },
] ]
[[package]] [[package]]
@ -1145,37 +1131,27 @@ wheels = [
[[package]] [[package]]
name = "pyarrow" name = "pyarrow"
version = "19.0.1" version = "17.0.0"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/7f/09/a9046344212690f0632b9c709f9bf18506522feb333c894d0de81d62341a/pyarrow-19.0.1.tar.gz", hash = "sha256:3bf266b485df66a400f282ac0b6d1b500b9d2ae73314a153dbe97d6d5cc8a99e", size = 1129437 } dependencies = [
{ name = "numpy" },
]
sdist = { url = "https://files.pythonhosted.org/packages/27/4e/ea6d43f324169f8aec0e57569443a38bab4b398d09769ca64f7b4d467de3/pyarrow-17.0.0.tar.gz", hash = "sha256:4beca9521ed2c0921c1023e68d097d0299b62c362639ea315572a58f3f50fd28", size = 1112479 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/a0/55/f1a8d838ec07fe3ca53edbe76f782df7b9aafd4417080eebf0b42aab0c52/pyarrow-19.0.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:cc55d71898ea30dc95900297d191377caba257612f384207fe9f8293b5850f90", size = 30713987 }, { url = "https://files.pythonhosted.org/packages/f9/46/ce89f87c2936f5bb9d879473b9663ce7a4b1f4359acc2f0eb39865eaa1af/pyarrow-17.0.0-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:1c8856e2ef09eb87ecf937104aacfa0708f22dfeb039c363ec99735190ffb977", size = 29028748 },
{ url = "https://files.pythonhosted.org/packages/13/12/428861540bb54c98a140ae858a11f71d041ef9e501e6b7eb965ca7909505/pyarrow-19.0.1-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:7a544ec12de66769612b2d6988c36adc96fb9767ecc8ee0a4d270b10b1c51e00", size = 32135613 }, { url = "https://files.pythonhosted.org/packages/8d/8e/ce2e9b2146de422f6638333c01903140e9ada244a2a477918a368306c64c/pyarrow-17.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2e19f569567efcbbd42084e87f948778eb371d308e137a0f97afe19bb860ccb3", size = 27190965 },
{ url = "https://files.pythonhosted.org/packages/2f/8a/23d7cc5ae2066c6c736bce1db8ea7bc9ac3ef97ac7e1c1667706c764d2d9/pyarrow-19.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0148bb4fc158bfbc3d6dfe5001d93ebeed253793fff4435167f6ce1dc4bddeae", size = 41149147 }, { url = "https://files.pythonhosted.org/packages/3b/c8/5675719570eb1acd809481c6d64e2136ffb340bc387f4ca62dce79516cea/pyarrow-17.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b244dc8e08a23b3e352899a006a26ae7b4d0da7bb636872fa8f5884e70acf15", size = 39269081 },
{ url = "https://files.pythonhosted.org/packages/a2/7a/845d151bb81a892dfb368bf11db584cf8b216963ccce40a5cf50a2492a18/pyarrow-19.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f24faab6ed18f216a37870d8c5623f9c044566d75ec586ef884e13a02a9d62c5", size = 42178045 }, { url = "https://files.pythonhosted.org/packages/5e/78/3931194f16ab681ebb87ad252e7b8d2c8b23dad49706cadc865dff4a1dd3/pyarrow-17.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b72e87fe3e1db343995562f7fff8aee354b55ee83d13afba65400c178ab2597", size = 39864921 },
{ url = "https://files.pythonhosted.org/packages/a7/31/e7282d79a70816132cf6cae7e378adfccce9ae10352d21c2fecf9d9756dd/pyarrow-19.0.1-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:4982f8e2b7afd6dae8608d70ba5bd91699077323f812a0448d8b7abdff6cb5d3", size = 40532998 }, { url = "https://files.pythonhosted.org/packages/d8/81/69b6606093363f55a2a574c018901c40952d4e902e670656d18213c71ad7/pyarrow-17.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:dc5c31c37409dfbc5d014047817cb4ccd8c1ea25d19576acf1a001fe07f5b420", size = 38740798 },
{ url = "https://files.pythonhosted.org/packages/b8/82/20f3c290d6e705e2ee9c1fa1d5a0869365ee477e1788073d8b548da8b64c/pyarrow-19.0.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:49a3aecb62c1be1d822f8bf629226d4a96418228a42f5b40835c1f10d42e4db6", size = 42084055 }, { url = "https://files.pythonhosted.org/packages/4c/21/9ca93b84b92ef927814cb7ba37f0774a484c849d58f0b692b16af8eebcfb/pyarrow-17.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:e3343cb1e88bc2ea605986d4b94948716edc7a8d14afd4e2c097232f729758b4", size = 39871877 },
{ url = "https://files.pythonhosted.org/packages/ff/77/e62aebd343238863f2c9f080ad2ef6ace25c919c6ab383436b5b81cbeef7/pyarrow-19.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:008a4009efdb4ea3d2e18f05cd31f9d43c388aad29c636112c2966605ba33466", size = 25283133 }, { url = "https://files.pythonhosted.org/packages/30/d1/63a7c248432c71c7d3ee803e706590a0b81ce1a8d2b2ae49677774b813bb/pyarrow-17.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:a27532c38f3de9eb3e90ecab63dfda948a8ca859a66e3a47f5f42d1e403c4d03", size = 25151089 },
{ url = "https://files.pythonhosted.org/packages/78/b4/94e828704b050e723f67d67c3535cf7076c7432cd4cf046e4bb3b96a9c9d/pyarrow-19.0.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:80b2ad2b193e7d19e81008a96e313fbd53157945c7be9ac65f44f8937a55427b", size = 30670749 }, { url = "https://files.pythonhosted.org/packages/d4/62/ce6ac1275a432b4a27c55fe96c58147f111d8ba1ad800a112d31859fae2f/pyarrow-17.0.0-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:9b8a823cea605221e61f34859dcc03207e52e409ccf6354634143e23af7c8d22", size = 29019418 },
{ url = "https://files.pythonhosted.org/packages/7e/3b/4692965e04bb1df55e2c314c4296f1eb12b4f3052d4cf43d29e076aedf66/pyarrow-19.0.1-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:ee8dec072569f43835932a3b10c55973593abc00936c202707a4ad06af7cb294", size = 32128007 }, { url = "https://files.pythonhosted.org/packages/8e/0a/dbd0c134e7a0c30bea439675cc120012337202e5fac7163ba839aa3691d2/pyarrow-17.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f1e70de6cb5790a50b01d2b686d54aaf73da01266850b05e3af2a1bc89e16053", size = 27152197 },
{ url = "https://files.pythonhosted.org/packages/22/f7/2239af706252c6582a5635c35caa17cb4d401cd74a87821ef702e3888957/pyarrow-19.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d5d1ec7ec5324b98887bdc006f4d2ce534e10e60f7ad995e7875ffa0ff9cb14", size = 41144566 }, { url = "https://files.pythonhosted.org/packages/cb/05/3f4a16498349db79090767620d6dc23c1ec0c658a668d61d76b87706c65d/pyarrow-17.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0071ce35788c6f9077ff9ecba4858108eebe2ea5a3f7cf2cf55ebc1dbc6ee24a", size = 39263026 },
{ url = "https://files.pythonhosted.org/packages/fb/e3/c9661b2b2849cfefddd9fd65b64e093594b231b472de08ff658f76c732b2/pyarrow-19.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3ad4c0eb4e2a9aeb990af6c09e6fa0b195c8c0e7b272ecc8d4d2b6574809d34", size = 42202991 }, { url = "https://files.pythonhosted.org/packages/c2/0c/ea2107236740be8fa0e0d4a293a095c9f43546a2465bb7df34eee9126b09/pyarrow-17.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:757074882f844411fcca735e39aae74248a1531367a7c80799b4266390ae51cc", size = 39880798 },
{ url = "https://files.pythonhosted.org/packages/fe/4f/a2c0ed309167ef436674782dfee4a124570ba64299c551e38d3fdaf0a17b/pyarrow-19.0.1-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:d383591f3dcbe545f6cc62daaef9c7cdfe0dff0fb9e1c8121101cabe9098cfa6", size = 40507986 }, { url = "https://files.pythonhosted.org/packages/f6/b0/b9164a8bc495083c10c281cc65064553ec87b7537d6f742a89d5953a2a3e/pyarrow-17.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:9ba11c4f16976e89146781a83833df7f82077cdab7dc6232c897789343f7891a", size = 38715172 },
{ url = "https://files.pythonhosted.org/packages/27/2e/29bb28a7102a6f71026a9d70d1d61df926887e36ec797f2e6acfd2dd3867/pyarrow-19.0.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:b4c4156a625f1e35d6c0b2132635a237708944eb41df5fbe7d50f20d20c17832", size = 42087026 }, { url = "https://files.pythonhosted.org/packages/f1/c4/9625418a1413005e486c006e56675334929fad864347c5ae7c1b2e7fe639/pyarrow-17.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:b0c6ac301093b42d34410b187bba560b17c0330f64907bfa4f7f7f2444b0cf9b", size = 39874508 },
{ url = "https://files.pythonhosted.org/packages/16/33/2a67c0f783251106aeeee516f4806161e7b481f7d744d0d643d2f30230a5/pyarrow-19.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:5bd1618ae5e5476b7654c7b55a6364ae87686d4724538c24185bbb2952679960", size = 25250108 }, { url = "https://files.pythonhosted.org/packages/ae/49/baafe2a964f663413be3bd1cf5c45ed98c5e42e804e2328e18f4570027c1/pyarrow-17.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:392bc9feabc647338e6c89267635e111d71edad5fcffba204425a7c8d13610d7", size = 25099235 },
{ url = "https://files.pythonhosted.org/packages/2b/8d/275c58d4b00781bd36579501a259eacc5c6dfb369be4ddeb672ceb551d2d/pyarrow-19.0.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:e45274b20e524ae5c39d7fc1ca2aa923aab494776d2d4b316b49ec7572ca324c", size = 30653552 },
{ url = "https://files.pythonhosted.org/packages/a0/9e/e6aca5cc4ef0c7aec5f8db93feb0bde08dbad8c56b9014216205d271101b/pyarrow-19.0.1-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:d9dedeaf19097a143ed6da37f04f4051aba353c95ef507764d344229b2b740ae", size = 32103413 },
{ url = "https://files.pythonhosted.org/packages/6a/fa/a7033f66e5d4f1308c7eb0dfcd2ccd70f881724eb6fd1776657fdf65458f/pyarrow-19.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ebfb5171bb5f4a52319344ebbbecc731af3f021e49318c74f33d520d31ae0c4", size = 41134869 },
{ url = "https://files.pythonhosted.org/packages/2d/92/34d2569be8e7abdc9d145c98dc410db0071ac579b92ebc30da35f500d630/pyarrow-19.0.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a21d39fbdb948857f67eacb5bbaaf36802de044ec36fbef7a1c8f0dd3a4ab2", size = 42192626 },
{ url = "https://files.pythonhosted.org/packages/0a/1f/80c617b1084fc833804dc3309aa9d8daacd46f9ec8d736df733f15aebe2c/pyarrow-19.0.1-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:99bc1bec6d234359743b01e70d4310d0ab240c3d6b0da7e2a93663b0158616f6", size = 40496708 },
{ url = "https://files.pythonhosted.org/packages/e6/90/83698fcecf939a611c8d9a78e38e7fed7792dcc4317e29e72cf8135526fb/pyarrow-19.0.1-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:1b93ef2c93e77c442c979b0d596af45e4665d8b96da598db145b0fec014b9136", size = 42075728 },
{ url = "https://files.pythonhosted.org/packages/40/49/2325f5c9e7a1c125c01ba0c509d400b152c972a47958768e4e35e04d13d8/pyarrow-19.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:d9d46e06846a41ba906ab25302cf0fd522f81aa2a85a71021826f34639ad31ef", size = 25242568 },
{ url = "https://files.pythonhosted.org/packages/3f/72/135088d995a759d4d916ec4824cb19e066585b4909ebad4ab196177aa825/pyarrow-19.0.1-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:c0fe3dbbf054a00d1f162fda94ce236a899ca01123a798c561ba307ca38af5f0", size = 30702371 },
{ url = "https://files.pythonhosted.org/packages/2e/01/00beeebd33d6bac701f20816a29d2018eba463616bbc07397fdf99ac4ce3/pyarrow-19.0.1-cp313-cp313t-macosx_12_0_x86_64.whl", hash = "sha256:96606c3ba57944d128e8a8399da4812f56c7f61de8c647e3470b417f795d0ef9", size = 32116046 },
{ url = "https://files.pythonhosted.org/packages/1f/c9/23b1ea718dfe967cbd986d16cf2a31fe59d015874258baae16d7ea0ccabc/pyarrow-19.0.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f04d49a6b64cf24719c080b3c2029a3a5b16417fd5fd7c4041f94233af732f3", size = 41091183 },
{ url = "https://files.pythonhosted.org/packages/3a/d4/b4a3aa781a2c715520aa8ab4fe2e7fa49d33a1d4e71c8fc6ab7b5de7a3f8/pyarrow-19.0.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a9137cf7e1640dce4c190551ee69d478f7121b5c6f323553b319cac936395f6", size = 42171896 },
{ url = "https://files.pythonhosted.org/packages/23/1b/716d4cd5a3cbc387c6e6745d2704c4b46654ba2668260d25c402626c5ddb/pyarrow-19.0.1-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:7c1bca1897c28013db5e4c83944a2ab53231f541b9e0c3f4791206d0c0de389a", size = 40464851 },
{ url = "https://files.pythonhosted.org/packages/ed/bd/54907846383dcc7ee28772d7e646f6c34276a17da740002a5cefe90f04f7/pyarrow-19.0.1-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:58d9397b2e273ef76264b45531e9d552d8ec8a6688b7390b5be44c02a37aade8", size = 42085744 },
] ]
[[package]] [[package]]
@ -1613,6 +1589,7 @@ wheels = [
[[package]] [[package]]
name = "treetrail-backend" name = "treetrail-backend"
version = "0.0.0"
source = { editable = "." } source = { editable = "." }
dependencies = [ dependencies = [
{ name = "aiofiles" }, { name = "aiofiles" },
@ -1641,7 +1618,6 @@ dependencies = [
[package.dev-dependencies] [package.dev-dependencies]
dev = [ dev = [
{ name = "dunamai" },
{ name = "httpx" }, { name = "httpx" },
{ name = "ipdb" }, { name = "ipdb" },
{ name = "pandas-stubs" }, { name = "pandas-stubs" },
@ -1669,7 +1645,7 @@ requires-dist = [
{ name = "passlib", extras = ["bcrypt"] }, { name = "passlib", extras = ["bcrypt"] },
{ name = "pillow" }, { name = "pillow" },
{ name = "psycopg2-binary" }, { name = "psycopg2-binary" },
{ name = "pyarrow", specifier = ">=19.0.1" }, { name = "pyarrow" },
{ name = "pydantic-settings" }, { name = "pydantic-settings" },
{ name = "python-jose", extras = ["cryptography"] }, { name = "python-jose", extras = ["cryptography"] },
{ name = "python-multipart" }, { name = "python-multipart" },
@ -1682,10 +1658,8 @@ requires-dist = [
[package.metadata.requires-dev] [package.metadata.requires-dev]
dev = [ dev = [
{ name = "dunamai", specifier = ">=1.23.0" },
{ name = "httpx" }, { name = "httpx" },
{ name = "ipdb" }, { name = "ipdb" },
{ name = "ipdb", specifier = ">=0.13.13" },
{ name = "pandas-stubs" }, { name = "pandas-stubs" },
{ name = "pytest" }, { name = "pytest" },
{ name = "types-aiofiles" }, { name = "types-aiofiles" },