Skip to main content

Recap and final exam

Ten modules to move from an empty file to a churn dashboard the sales team opens every morning. Here is the course condensed, then the threads that run through it, and finally the exam.

The course at a glance

ModuleThe essential point
1. Execution modelThe whole script re-runs on every interaction; st.set_page_config first, session_state for persistence, @st.cache_* for expensive work
2. ComponentsWidgets are functions that return the current value; st.metric for KPIs, delta_color="inverse" when up is bad
3. LayoutColumns, tabs, sidebar and expanders are containers; hidden tabs still execute their code on rerun
4. Charts and tablesNative for quick, Plotly for interactive, Altair for the grammar; always use_container_width=True
5. Cachingcache_data copies (values), cache_resource shares (objects); underscore prefix skips hashing
6. State and formssession_state is the tab-scoped dict; st.form batches inputs and silences on_change
7. Upload and downloadsep=None, engine="python" handles the CSV quirks; validate before scoring; cache the serialization
8. Calling a modelLocal behind cache_resource, remote behind requests with a mandatory timeout=
9. Theme and pages.streamlit/config.toml and st.logo for the brand; st.navigation for a multipage app
10. DeploymentCommunity Cloud or Docker with --server.address=0.0.0.0; secrets in st.secrets, never in git

The threads running through the course

Everything comes back to the rerun model. A stateless top-to-bottom re-execution on every gesture is what makes Streamlit small enough to learn in a day. Every mechanism the framework adds — caches, session state, forms, callbacks — exists to give you controlled escapes from that model when the top-to-bottom default is not what you need. Knowing that one fact makes every module deducible rather than memorizable.

Widgets and state share a namespace. A widget with key="x" writes to st.session_state["x"] and reads back from it. That single sentence explains why you pre-fill a widget by writing to session state, why renaming a label resets a widget, and why two widgets cannot share a key. Most of the confusion around forms, callbacks and multipage apps disappears once that connection is internalized.

Local versus remote is not a coding decision, it is an operational one. Loading a model with joblib is fifteen lines; hitting an inference API is fifteen lines; the difference is who owns the release cycle and who pays for the hardware. Course 40 covers the API side of that decision; here, the client side is what the app must handle — timeouts, error messages, a spinner and a cache with a short TTL.

Deployment is when access control becomes real. A shared password gate takes five lines and is good enough for a low-value internal tool; anything more requires an identity provider, and the OIDC or reverse-proxy path is the industry answer. Whichever path you take, authorization belongs inside the app, not only at the door — an authenticated user is not necessarily a whitelisted one.

Before you share the dashboard

A quick checklist to run through before pushing the URL to the sales team channel:

  • Rerun: no top-level counter, session_state initialized once with a guard, @st.cache_resource on the model, @st.cache_data on the DataFrames.
  • Layout: layout="wide" if you have KPI cards, one primary button per screen, a sidebar that stays readable when collapsed, no widget the app strictly needs hidden behind an expander.
  • State and forms: every widget in a long form has a stable key=; every callback is a state change, not slow work.
  • Upload and download: file size cap set explicitly, columns validated before scoring, results downloadable as UTF-8 CSV.
  • Model call: every requests.post has a timeout=, every failure writes a user-friendly st.error, no traceback in the browser.
  • Theme: primaryColor matches the brand, a favicon and a logo, toasts for background events, tooltips (help=) on every input the user might misread.
  • Deployment: .streamlit/secrets.toml in .gitignore, model not in the repo, --server.address=0.0.0.0 in the Dockerfile, an identity provider in front of anything that touches customer data.

The final exam

The exam has 40 questions covering the ten modules: the execution model and its consequences, choosing the right widget for the right input, laying out a page with columns and tabs, choosing between the three chart tiers, cache_data versus cache_resource, session_state and forms, uploading and validating a CSV, calling a local or remote model, theming and multipage navigation, and finally deployment with secrets and access control.

Several questions present situations to diagnose: a page that lags because the model loads on every rerun, a "wrong password" branch that leaks the password by timing, a session_state reset because the widget key changed, a Plotly chart that overflows its column. It is judgment that is assessed, not the recitation of API signatures.

On success, your certificate of completion is issued immediately; its number is verifiable by any third party on the platform.

Before you start

Take the table above and, for each row, ask yourself "how would I see that I am wrong here?". If you can say why a model reloads on every keystroke, why a shared password compared with == leaks over the network, why a widget resets when you rename its label, and why --server.address=0.0.0.0 matters in a container, you are ready. Good luck!

Final exam

Ready to validate this course?

40 questions drawn at random from the course bank · passing score 70% · verifiable PDF certificate issued immediately on success.

Start the exam

You need to be signed in to your InSkillML account with an active subscription. You can also start the exam from My courses.