Session Summary: CWVA Server Python Retooling Project Plan

5 May 2026 – 8 June 2026


Context and Motivation

The session began with a request to port the CWVA main server from Groovy/Jetty to Python, driven by three converging pressures: Apache Jena's JSON-LD 1.0→1.1 breaking change (requiring a Java upgrade the Groovy server couldn't easily absorb), the desire for an open-source publishable codebase, and GCP deployment simplification. The existing server was live at visualartsdna.org v4.0.4 throughout development, serving as a comparison baseline.


Architecture Decisions

FastAPI + Uvicorn was chosen over Flask for async support and Claude Code compatibility. RDFLib + owlrl replaced Apache Jena for RDF storage and RDFS inferencing. The two-server architecture (main port 80 + function port 8080) was retained in concept but the Python port consolidated the main server as a standalone deliverable. The JSON-LD intermediate serialization used in the Groovy Browser page was replaced with a direct RDFLib graph → property/value dict approach via a new rdf2html.py module. Static assets served from the main server via FastAPI's StaticFiles mount — no CDN.

The SPARQL browser remained delegated to the function server (intentionally, as an abuse protection boundary), while all operational SPARQL queries run within the main server.


Development Stages Executed

Five of the planned seven stages were completed in this session:

Stage 1 — Foundation: Server bootstrap, RSON config loading, GCP bucket sync, TTL folder loading into discrete stores, HTTP routing skeleton.

Stage 2 — Data Layer: Merged common store with owlrl RDFS inferencing, policy updates (license/copyright append, skos:Collection creation), URI rehosting for local/dev vs. production.

Stage 3 — Gallery & Browser: Gallery pagination and filtering, Browser page via rdf2html.py, JSON-LD replaced with direct RDFLib rendering.

Stage 4 — Concepts, Explore, About: Vocabulary tree, Cytoscape.js + dagre interactive ontology/thesaurus graphs (replacing static Graphviz SVGs), SPARQL browser proxy, metrics dashboard, About page.

Stage 5 — Hardening: Token-authenticated admin endpoints (/cmd, /status/os), GCP snapshot-on-shutdown, cross-language Java-to-Python token validation, logging.

Stages 6 (Ask page / AI agent) and 7 (formal open source release hardening) were scoped but deferred.


Significant Technical Issues Resolved

owlrl boolean expansion bug — the most involved diagnostic in the session. Four tensegrity properties declared rdfs:range xsd:int caused owlrl to materialize both xsd:integer and xsd:int shadow triples for every boolean value in the graph, massively inflating the store. Diagnosed through progressive testing before fix.

Metrics pipeline rewrite — original RDFLib/TTL approach took 24 minutes; replaced with pure Python aggregation running in 7.5 seconds. Extracted as standalone metricsCompiler.py.

WSL2 networking — root-relative URLs required throughout all generated HTML due to WSL2 port-proxy behavior.

RDFLib timezone grouping bugstr(?dt) cast required for correct date sorting in SPARQL.

Namespace prefix auto-generation (ns1/ns2) — fixed by copying namespace bindings from source graph to derived graphs before serialization.

JavaScript const redeclaration — SyntaxError in gallery JS, resolved during hardening.


Project Completion and Publication

Three successful smoke tests including a Windows bare-bones deployment. Sample data created with fictional artist "John van Gough." Published to GitHub at visualartsdna-org/cwvaServer-py under MIT license.

Content structure established: metacontent (model/vocab) in a separate cwvaMetacontent repository; user content in cwvaContent; images excluded via .gitignore.


Documentation Produced


Late-Session: Concept Agent Design

The final portion of the session scoped concept_agent.py — a curation and tagging pipeline querying Fuseki via SPARQL and calling the Anthropic API. Key design decisions: SKOS thesaurus integration, validation pipeline, RDF origin records for each tagged concept.

A vad:hasSummary document summary feature was added: a 100–150 word critical abstract generated in the same Claude API call as the tagging, stored as a datatype property in TTL, rendered by rdf2html.py as a styled block above the property table for criticism document instances. Two entries were written for concept_agent_design.md (Section 14) and ROADMAP.md capturing this design.


Conclusions

The port succeeded fully through Stage 5. The primary technical risk — the owlrl inferencing behavior with typed properties — was uncovered and resolved during development rather than in production. The metrics pipeline rewrite was an unplanned but significant improvement. The architecture is cleaner than the Groovy original: single framework, no Java version dependency, open-source ready, GCP-deployable. The concept agent work at the end of the session established the foundation for what became the extended concept_agent.py development arc in subsequent sessions.




visualartsdna@gmail.com
Copyright © 2026 visualartsdna.org. All Rights Reserved.
v 5.0.0