Inspiration

Event organisers pick artists, food, and experiences for an audience mostly from popularity rankings. Those rankings say what is popular, not what belongs together culturally. I wanted to see whether Qloo's cultural data could answer the second question, and whether the answer could be shown to a judge rather than asserted.

What it does

CultureMix takes a city, a budget, and an artist name. It searches Qloo's hackathon API for related entities and their tags, draws a network in which entities that share a Qloo tag are linked (with the shared tags on each edge), and asks Gemini to draft an event concept. Every recommendation is checked against the Qloo results before it is shown. Anything that did not come from Qloo is labelled as an LLM hypothesis. A budget check uses planning estimates, and the same brief can be run without Qloo for a side-by-side comparison.

How we built it

  • Qloo client: a thin wrapper around the search endpoint with the X-Api-Key header, timeouts, and error handling for auth, rate limits, and non-JSON responses.
  • Normalisation: Qloo returns types as a list and tags as objects. I map these to flat rows with the entity ID kept for traceability.
  • Planner: builds a prompt from the brief and the Qloo rows, asks Gemini for JSON, and validates the result. A recommendation marked as Qloo-backed must match a real Qloo name, or the plan is rejected.
  • Interface: Streamlit, with a 3D network built in Three.js and a 2D Graphviz diagram as a fallback.
  • Tests: 12 offline unit tests covering budget arithmetic, plan validation, and response normalisation.

Challenges we ran into

  • The key arrived late. Hackathon keys are issued manually, so the first live call was only possible after the build had started. I built the planner and interface against labelled mock data first.
  • The response shape was not what I assumed. My first client expected a type string; the live API returns types as a list, and the tags are objects. The first live run showed every result as "unknown" until I checked a real response.
  • Config was read in two places. The Gemini client read .env, but the Qloo client read only environment variables, so the sidebar showed LIVE while the app reported the key as missing.
  • Free-tier model access. One Gemini model was closed to new accounts, and the replacement returned temporary "high demand" errors. The client now retries those.
  • Deployment. The app ran locally but failed on Streamlit Cloud because the Gemini package was missing from requirements.txt. Streamlit Cloud only installs what that file lists.

Accomplishments that we're proud of

What we learned

  • Check an API against a real response before writing code that depends on it. Third-party examples were not reliable enough.
  • A model's output needs a validation step before it is shown as data. Without the grounding check, the plan would have looked grounded whether or not it was.
  • Labelling matters as much as the feature. Mock, live, and hypothesis data look different in the interface so no one mistakes one for another.

What's next for CultureMix

  • Verify more Qloo entity types and affinity queries, rather than relying on name search.
  • Record results for a fixed set of briefs, and report them as they are.
  • Let organisers add their own vendor quotes to the budget check.

Built With

  • google-gemini
  • python
  • qloo-api
  • streamlit
Share this project:

Updates

Submission history