diff --git a/notebooks/API_Training_Exercises/01_Simple_Report.ipynb b/notebooks/API_Training_Exercises/01_Simple_Report.ipynb
new file mode 100644
index 0000000..34dafc5
--- /dev/null
+++ b/notebooks/API_Training_Exercises/01_Simple_Report.ipynb
@@ -0,0 +1,256 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "```\n",
+ "This script can be used for any purpose without limitation subject to the\n",
+ "conditions at http://www.ccdc.cam.ac.uk/Community/Pages/Licences/v2.aspx\n",
+ "\n",
+ "This permission notice and the following statement of attribution must be\n",
+ "included in all copies or substantial portions of this script.\n",
+ "\n",
+ "2024-09-11: Made available by the Cambridge Crystallographic Data Centre.\n",
+ "\n",
+ "```"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# International Report\n",
+ "\n",
+ "This notebook talks through how to create a report that reports a CSD entry ... but uses google translate to translate headings into the language of user choice.\n",
+ "You could use the ideas her to convert the 'simple_report.py script into an international report\n",
+ "\n",
+ "#### Prerequisites\n",
+ "\n",
+ "First install the CSD Python API and googletrans into your conda or pip environment. This should only be needed the before you run the script."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Now we are ready to start some python coding. We need to import some modules. We are writing a script that ultimately will be used in Mercury so we will want some of \n",
+ "the special utilities available for writing reports."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from ccdc.utilities import html_table\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We can create a translator for the script to use, and define our language of choice. Lets write a little function to do the translation"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from googletrans import Translator\n",
+ "\n",
+ "translator = Translator()\n",
+ "def tr(text, lang):\n",
+ " if lang is None:\n",
+ " return text\n",
+ " try:\n",
+ " return translator.translate(str(text),src=\"en\",dest=lang).text\n",
+ " except Exception as e:\n",
+ " return text"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Let's try it out:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "\n",
+ "tr(\"Mary had a little lamb\", \"ar\") # Lets try arabic!"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "So now we can create a report on a CSD entry that is international. The following function will work in a Mercury API script. Note how it defines an interface object"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def get_coordinates(molecule, round_digits=None):\n",
+ " \"\"\"Yield the label and fractional coordinates of all atoms in the molecule.\n",
+ "\n",
+ " :param molecule: (:obj:`ccdc.molecule.Molecule`) The molecule for which to return coordinates.\n",
+ " :param round_digits: (:obj:`int`) How many decimal digits coordinates should be rounded to.\n",
+ " :returns: (:obj:`list`) List of the label and fractional x/y/z coordinates for each atom\n",
+ " in the molecule in format ['Atom label', 'X coordinate', 'Y coordinate', 'Z coordinate'].\n",
+ " \"\"\"\n",
+ " for atom in molecule.atoms:\n",
+ " try:\n",
+ " x, y, z = atom.fractional_coordinates\n",
+ " yield [atom.label,\n",
+ " x if round_digits is None else round(x, round_digits),\n",
+ " y if round_digits is None else round(y, round_digits),\n",
+ " z if round_digits is None else round(z, round_digits)]\n",
+ " except TypeError:\n",
+ " continue\n",
+ "\n",
+ "\n",
+ "def main(interface=None, lang=None):\n",
+ " \"\"\"Generate a simple report based on the entry currently selected in the Mercury UI.\n",
+ "\n",
+ " :param interface: (:obj:`ccdc.utility.ApplicationInterface`) An ApplicationInterface instance.\n",
+ " \"\"\"\n",
+ " if interface is None:\n",
+ " from ccdc.utilities import ApplicationInterface\n",
+ " interface = ApplicationInterface()\n",
+ "\n",
+ " entry = interface.current_entry\n",
+ "\n",
+ " # Open a HTML report. This will create the file, copy the CSD Python API\n",
+ " # default template for reports and fill in the headline/page title.\n",
+ " with interface.html_report(title=tr('Simple report on ',lang)+ ' ' + entry.identifier) as report:\n",
+ "\n",
+ " # Write the section header for Entry Details\n",
+ " report.write_section_header(tr('Entry Details',lang))\n",
+ " # Assemble a list of information and labels to go into the \"Entry Details\" table\n",
+ " entry_details = [\n",
+ " [''+tr('Chemical name',lang)+'', entry.chemical_name],\n",
+ " [''+tr('Synonyms',lang)+'', entry.synonyms],\n",
+ " [''+tr('Formula',lang)+'', entry.formula],\n",
+ " [''+tr('R-factor',lang)+'', entry.r_factor],\n",
+ " [''+tr('Disorder',lang)+'', tr(entry.disorder_details,lang)],\n",
+ " [''+tr('Polymorphism',lang)+'', tr(entry.polymorph,lang)],\n",
+ " [''+tr('3D structure',lang)+'', tr(entry.has_3d_structure,lang)],\n",
+ " [''+tr('Organic',lang)+'', tr(entry.is_organic,lang)],\n",
+ " [''+tr('Polymeric',lang)+'', tr(entry.is_polymeric,lang)],\n",
+ " [''+tr('Bioactivity',lang)+'', tr(entry.bioactivity,lang)],\n",
+ " [''+tr('Source',lang)+'', tr(entry.source,lang)],\n",
+ " [''+tr('Habit',lang)+'', tr(entry.habit,lang)],\n",
+ " ]\n",
+ " # Generate a HTML table from the entry details and write it to the report\n",
+ " report.write(html_table(data=entry_details, table_id='entry_details'))\n",
+ "\n",
+ " # Write the section header for Fractional Coordinates\n",
+ " report.write_section_header(tr('Fractional Coordinates',lang))\n",
+ " # Get the coordinates of all the atoms from the entry and write them to a HTML table\n",
+ " report.write(html_table(data=list(get_coordinates(entry.molecule, round_digits=3)),\n",
+ " table_id='fractional_coordinates',\n",
+ " header=[tr('Atom',lang), 'x', 'y', 'z']))\n",
+ "\n",
+ " # Write the section header for Publication Details\n",
+ " report.write_section_header(tr('Publication Details',lang))\n",
+ " # Assemble a list of information and labels for the Publication Details table\n",
+ " publication_details = [\n",
+ " [''+tr('Reference',lang)+'', '%s Volume %s, %s' % (getattr(entry.publication, 'journal_name', ''),\n",
+ " entry.publication.volume,\n",
+ " entry.publication.year)],\n",
+ " [''+tr('Authors', lang)+'', entry.publication.authors],\n",
+ " [''+tr('Document Object Identifier',lang)+'', entry.publication.doi]\n",
+ " ]\n",
+ " # Write the publication details to a HTML table\n",
+ " report.write(html_table(publication_details, table_id='publication_details'))\n",
+ "\n",
+ " # Write the section header for Basic Crystallographic Information\n",
+ " report.write_section_header(tr('Basic Crystallographic Information',lang))\n",
+ " # Assemble a list of basic crystal information and labels for the table\n",
+ " crystallographic_data = [\n",
+ " [''+tr('Crystal System',lang)+'', entry.crystal.crystal_system],\n",
+ " [''+tr('Space Group',lang) + '', entry.crystal.spacegroup_symbol],\n",
+ " [''+tr('Cell Volume',lang)+ '', '%s ų' % round(entry.crystal.cell_volume, 3)],\n",
+ " ['Z, Z\\'', entry.crystal.z_prime],\n",
+ " ]\n",
+ " # Write the crystallographic details to a HTML table\n",
+ " report.write(html_table(crystallographic_data, table_id='crystallographic_information'))\n",
+ "\n",
+ " # Once the HTMLReport is closed (e.g. when the with: branch above ends),\n",
+ " # it will automatically write the appropriate HTML footer."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Lets use our function. As we are in a notebook, we will have to define a dummy interface file:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import time\n",
+ "from ccdc.utilities import ApplicationInterface\n",
+ "interface = ApplicationInterface(parse_commandline=False)\n",
+ "interface.identifier = \"AABHTZ\"\n",
+ "interface.output_html_file = f'{interface.identifier}_{time.strftime(\"%H%M%S\", time.gmtime())}_report.html'\n",
+ "\n",
+ "main(interface,\"ar\") # Arabic "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Finally use Jupyter to display it:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from IPython.display import HTML\n",
+ "HTML(interface.output_html_file)"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.9.20"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}