Deploy ML Models with Python, Hugging Face and Anvil
Updated on December 03, 2025 9 minutes read
Finishing a machine learning project is satisfying, but the real impact comes when other people can actually use your model. In 2026, that usually means turning your notebook into something interactive that teammates, stakeholders, or users can open in a browser.
In this guide, you will deploy a simple machine translation model using only Python. You will combine Hugging Face Transformers for NLP with Anvil, a Python-first web framework, to ship a shareable web app without touching HTML, CSS, or JavaScript.
Along the way you will move from experiment to demo, a skill that is increasingly expected from data scientists and ML engineers. The example uses German to English translation, but you can extend it to other languages with the same pattern.
What You Will Build
By the end of this tutorial, you will have: A machine translation model based on Hugging Face's MarianMT family. A simple web UI built in Anvil with dropdowns, a text box, and a result area. A Python backend connected via Anvil Uplink that runs your model on your own machine.
This approach is ideal for prototypes, internal tools, and portfolio projects. For high-traffic production systems, you would later migrate the same model to a more traditional API stack.
If you want structured support while learning these skills, you can also explore our Data Science & AI Bootcamp at Code Labs Academy.
Prerequisites
You can follow this tutorial if you are comfortable writing basic Python and running scripts or notebooks. No frontend experience is required, and we will keep the tooling lightweight.
You will need:
- Python 3.9+ installed on your machine.
pipavailable to install packages.- A free Hugging Face account (optional but useful for browsing models).
- A free Anvil account to create and host the web app.
Make sure you have a stable internet connection. The translation model is a few hundred megabytes, so the first download may take a few minutes depending on your connection.
Step 1: Set Up a Machine Translation Model with Hugging Face
Machine translation is the task of automatically translating text from one language to another. In this tutorial we will use MarianMT models, which are part of the Hugging Face Transformers ecosystem and designed specifically for translation tasks.
At a high level, MarianMT is a transformer-based encoder-decoder model. The encoder reads your source sentence, and the decoder generates the target sentence one token at a time.
1.1 Install the required Python packages
Create and activate a virtual environment if you like, then install the core libraries:
pip install torch
pip install transformers
pip install anvil-uplink
If the tokenizer later complains about missing dependencies, install any extra packages mentioned in the error message, such as sentencepiece for some models that rely on it.
1.2 Load a MarianMT model for German to English
Now load a pre-trained MarianMT model that translates from German to English. MarianMT models follow a naming pattern like Helsinki-NLP/opus-mt-{src}-{tgt}, where src and tgt are language codes such as de for German and en for English.
from typing import List
from transformers import MarianTokenizer, MarianMTModel
src = "de"
tgt = "en"
model_name = f"Helsinki-NLP/opus-mt-{src}-{tgt}"
tokenizer = MarianTokenizer.from_pretrained(model_name)
model = MarianMTModel.from_pretrained(model_name)
The first run will download the model weights and tokenizer. Later runs will reuse the cached files on your machine instead of downloading again.
1.3 Test the translation model locally
Run a quick translation to confirm everything works. Recent versions of Transformers recommend calling the tokenizer directly instead of using the older prepare_seq2seq_batch helper, which has been deprecated.
text = "ich habe keine ahnung"
# Tokenize and move text into tensors
batch = tokenizer(text, return_tensors="pt")
# Generate translated tokens
generated_tokens = model.generate(**batch)
# Decode into readable text
translations: List[str] = tokenizer.batch_decode(
generated_tokens,
skip_special_tokens=True,
)
print(translations[0])
You should see an English translation such as "I have no idea" printed to the console. Exact wording may vary slightly depending on the model version and decoding options you use.
1.4 (Optional) Save the model locally
To speed up future startup times, you can save the model and tokenizer to a dedicated folder under ./models. This avoids repeated network calls for the same weights.
model.save_pretrained("./models/de_en")
tokenizer.save_pretrained("./models/de_en/tok")
Later, you can reload them from disk using the same API you used with the model hub:
from transformers import MarianTokenizer, MarianMTModel
tokenizer = MarianTokenizer.from_pretrained("./models/de_en/tok")
model = MarianMTModel.from_pretrained("./models/de_en")
In the next steps, your Anvil-connected backend will use these local paths so that you do not need to re-download the model each time the server starts.
Step 2: Build a Web UI in Anvil Using Only Python
Anvil is a Python-based framework and online editor for building web apps with a drag-and-drop UI builder. You design the interface in the browser, write Python for client and server logic, and Anvil hosts the frontend for you.
Here you will create a simple interface that lets a user choose source and target languages, type text, and see the translated result in their browser.
2.1 Create your Anvil app
To create the app:
- Log in to Anvil and click New Blank App.
- Choose the Material Design theme.
- You will see a design view with a blank form in the centre and components on the left.
Think of this form as the page where users will interact with your translation service and see your model in action.
2.2 Design the translation form
Drag the following components onto the form:
- Two DropDown components for source and target languages.
- One TextBox for the input text.
- One RichText (or Label) to show the translated text.
- One Button labeled “Translate”.
To keep your code readable, give each component a clear ID in the properties panel. Use these IDs so that your Python code matches the examples in this tutorial.
Initialize the dropdown items with labels like “German”, “English”, “French”, and “Spanish”. Make sure the dropdown selected_value values match the labels used in your backend mapping.
2.3 Wire up the "Translate" button
Select the Translate button in the designer. In the properties panel, scroll to the events section. In the box next to click, type translate and click the arrow; Anvil will create a translate method in your form’s Python code.
Replace the auto-generated function with something like this:
import anvil.server
class MainForm(MainFormTemplate):
def translate(self, **event_args):
"""Called when the Translate button is clicked."""
# Read values from the UI
src_lang = self.source_lang.selected_value
dest_lang = self.dest_lang.selected_value
text = self.source_text.text or ""
if not text:
self.translated_text.content = "Please enter some text to translate."
return
# Call the backend translation function
translated_text = anvil.server.call(
"translation",
text,
src_lang,
dest_lang,
)
# Display the result in the UI
self.translated_text.content = translated_text
This function does three things: it collects input from the form, sends it to a server function called translation, and writes the translated text back into the RichText component.
In the next step, you will implement that translation function on your own machine using Anvil Uplink.
Step 3: Connect Your Backend with Anvil Uplink
The Anvil Uplink lets your hosted Anvil app call Python functions running anywhere: your laptop, a Jupyter notebook, or a remote server. This is the bridge between your web UI and the machine translation model running locally.
3.1 Enable Uplink in your Anvil app
In the online Anvil editor:
- Click the gear icon at the top right and choose Uplink….
- Enable Uplink for this app if it is not already enabled.
- Copy the secret Uplink key that Anvil shows you.
Keep this key private, because anyone with the key can call your registered server functions as if they were part of the app.
3.2 Write the backend script with your model
Create a new Python script on your local machine, for example backend.py. This script will connect to your Anvil app, load the translation model, and expose a translation function for the UI to call.
Here is a simple but efficient version:
import anvil.server
from typing import List
from transformers import MarianTokenizer, MarianMTModel
# Map dropdown labels to language codes
LANG_CODES = {
"English": "en",
"German": "de",
"French": "fr",
"Spanish": "es",
}
# Cache models so they are not reloaded on every call
_model_cache: dict[tuple[str, str], tuple[MarianMTModel, MarianTokenizer]] = {}
def load_model(src_lang: str, dest_lang: str) -> tuple[MarianMTModel, MarianTokenizer]:
src_code = LANG_CODES[src_lang]
dest_code = LANG_CODES[dest_lang]
key = (src_code, dest_code)
if key not in _model_cache:
model_dir = f"./models/{src_code}_{dest_code}"
tokenizer = MarianTokenizer.from_pretrained(f"{model_dir}/tok")
model = MarianMTModel.from_pretrained(model_dir)
_model_cache[key] = (model, tokenizer)
return _model_cache[key]
@anvil.server.callable
def translation(text: str, src_lang: str, dest_lang: str) -> str:
"""Translate text from src_lang to dest_lang using a MarianMT model."""
model, tokenizer = load_model(src_lang, dest_lang)
batch = tokenizer(text, return_tensors="pt")
generated_tokens = model.generate(**batch)
translations: List[str] = tokenizer.batch_decode(
generated_tokens,
skip_special_tokens=True,
)
return translations[0]
This code assumes that you have saved a MarianMT checkpoint for each language pair under ./models/{src}_{dest} such as ./models/de_en. If you only downloaded the German to English model, make sure your dropdowns only expose that pair until you add more models.
3.3 Connect the script to Anvil
Still in backend.py, add your Uplink connection and start the server loop. This keeps the script running so it can respond to calls from the UI.
import anvil.server
anvil.server.connect("YOUR_UPLINK_KEY_HERE")
print("Backend connected. Waiting for calls from Anvil...")
anvil.server.wait_forever()
Run this script from a terminal:
python backend.py
As long as this process is running and connected, your Anvil app can call the translation function and receive results in real time without redeploying anything.
Step 4: Run and Publish Your Translation App
You now have three pieces working together: a translation model, a local backend exposing it via Uplink, and a hosted web UI in Anvil.
To test everything end to end:
- Make sure
backend.pyis running and shows a connected message. - In the Anvil editor, click the Run button to open a preview of your app.
- Choose a language pair, enter some text, and press Translate.
If everything is configured correctly, the translated text should appear in the result area within a second or two, depending on model size and your hardware.
When you are ready to share the app:
- Click Publish this app in the top-right corner of the Anvil editor.
- Choose a public URL or a private link, depending on who should access it.
- Share the link with colleagues, stakeholders, or potential employers.
Remember that your Python script must stay running for the app to work, because the translation function lives on your machine. For more permanent demos, consider running the backend on a small cloud instance instead of a laptop.
Next Steps and Production Considerations
This Python-only stack is perfect for quick demos, classroom exercises, and internal tools. You avoid deployment complexity while still giving users a polished web interface they can access from any browser.
For production workloads with many users, you will eventually want to:
Expose the model via an API using frameworks like FastAPI or Flask.
Containerize your service with Docker and deploy it to cloud infrastructure. Add logging, monitoring, and rate-limiting to keep the service reliable.
The good news is that everything you have done here carries over. The core translation code does not change; only the way you expose it to the outside world evolves as your needs grow.
Learn More with Code Labs Academy
If this mini-project sparked your curiosity, it fits nicely into a broader data science learning path. In our Data Science & AI Bootcamp, you move from Python fundamentals to deploying models and building portfolio-ready projects.
Master machine learning with Code Labs Academy. Join our flexible online bootcamps
And turn projects like this translation app into the first steps of your tech career.