Book 6 — Working with APIs

Python for All

Chapter One — What is an API?

Thanasis Troboukis  ·  All Books

Book Six · Chapter One

What is an API?

Websites publish data for humans to read. APIs publish data for programs to read. In this book you will learn how to speak that language — how to send a request to an API, read the structured data it sends back, and turn it into something useful. The running example is Diavgeia, the Greek government's transparency registry.

The Waiter Analogy

Imagine you are sitting in a restaurant. You don't walk into the kitchen to get your food. Instead, you tell the waiter what you want — the waiter goes to the kitchen, the kitchen prepares the meal, and the waiter brings it back to your table.

An API works exactly the same way. Your program is the customer. The API is the waiter. The server or database is the kitchen. You ask for something specific, the kitchen prepares the answer, and the waiter delivers it — in a format your program can read.

API stands for Application Programming Interface. The word "interface" is the important one. It is a defined contract: you ask in a specific way, and you always get the answer in a specific, predictable format. You never have to know what is happening inside the kitchen.

API vs web scraping: When you scraped Kathimerini in Book 5, you fetched an HTML page designed for a human browser, then picked through the markup to find what you needed. An API skips all that. The server sends you structured data directly — no HTML, no parsing tags, no fragile selectors.

Anatomy of an API Request

An API request is just a URL. You visit it with your browser — or your Python program — and the server responds with data. Let's look at a real one.

Diavgeia is the Greek government's online transparency registry. Every official government decision — contracts, appointments, spending — must be published there by law. Diavgeia provides a public API so that anyone can query this data programmatically, without an account and without any special permission.

A search request to the Diavgeia API looks like this:

https://diavgeia.gov.gr/luminapi/api/search?q=subject:"κλιματισμός"&size=5

Let's break it into its parts:

Part Example What it means
Base URL https://diavgeia.gov.gr/luminapi/api/ The address of the API server
Endpoint search The specific action you are requesting — here, a search
? ? Separates the endpoint from the parameters
Parameter q=subject:"κλιματισμός" The search query — Diavgeia expects a field name (subject) followed by the search term in quotes
& & Separates multiple parameters
Parameter size=5 How many results to return

You can think of the endpoint as the waiter's notepad category ("I'd like something from the seafood section"), and the parameters as your specific order ("grilled, medium, no lemon").

The q parameter has its own mini-syntax: Diavgeia's search engine expects you to name the field you are searching inside. subject:"κλιματισμός" searches the decision title. q:"κλιματισμός" does a general full-text search. ada:"6ΛΩΖ7ΛΞ-ΦΨΥ" looks up a specific decision by its unique code. You will see all three patterns used in practice.
Try it in your browser: APIs that don't require authentication can be called directly from the browser address bar. Paste https://diavgeia.gov.gr/luminapi/api/search?q=subject:"κλιματισμός"&size=3 into a new tab. You will see the raw response — a wall of structured text called JSON.

The Response — JSON

When the API server answers, it doesn't send HTML. It sends a structured text format called JSON — JavaScript Object Notation. Despite the name, JSON is language-agnostic: Python, JavaScript, R, and most other programming languages can read it natively.

Here is a small, realistic piece of what the Diavgeia API returns for a search request:

{
  "info": {
    "total": 1842
  },
  "decisions": [
    {
      "ada": "ΨΦΔΔ46ΜΤΛΡ-ΑΩΣ",
      "subject": "Ανάληψη υποχρέωσης για την προμήθεια κλιματιστικών μονάδων",
      "issueDate": "2025-06-10",
      "submissionTimestamp": "2025-06-11T09:15:00.000+0300",
      "documentUrl": "https://diavgeia.gov.gr/doc/ΨΦΔΔ46ΜΤΛΡ-ΑΩΣ",
      "documentType": "pdf",
      "organization": {
        "label": "ΔΗΜΟΣ ΑΘΗΝΑΙΩΝ"
      },
      "decisionType": {
        "label": "Ανάληψη Υποχρέωσης"
      }
    }
  ]
}

This might look unfamiliar at first, but you already know most of the patterns. JSON is built from two structures:

JSON structure Python equivalent How to recognise it
Object dict Curly braces { } with "key": value pairs
Array list Square brackets [ ] with comma-separated values
String str Always double-quoted: "like this"
Number int / float No quotes: 1842, 14500.00
Boolean bool true / false (lowercase in JSON)
Null None null

When Python reads JSON, it converts each of those structures automatically to the Python equivalent. A JSON object becomes a dict. A JSON array becomes a list. A JSON string becomes a str. You don't have to do anything special — Python handles the conversion for you.

Reading JSON with Python

Python's built-in json module converts a JSON string into a Python object with a single function call: json.loads(). The s in loads stands for "string" — you are loading from a string.

Python · Try it

      

The JSON string becomes a Python dictionary. You access its values exactly as you would any other dict — with square brackets and the key name.

Now let's try a more realistic response — the kind Diavgeia actually returns, with a nested structure and a list of decisions:

Python · Try it

      

Notice two things about that code. First, data["info"]["total"] — you chain square brackets to navigate into nested objects. The same works for decision["organization"]["label"]: organization is itself a dict with a label key inside it. Second, data["decisions"] is a Python list, so you can loop over it with for exactly as you would any other list.

json.loads() vs json.load(): json.loads() parses a string. json.load() (no s) reads from a file object. You will use loads() when you get the response from an API, and load() if you ever open a saved .json file from disk.

Your Turn — Navigate the Response

The cell below contains a Diavgeia-style response with three decisions. Your task: loop through them and print the ADA code, the organisation name, and the decision type label for each one. The organisation name and decision type label are nested one level deep — use the bracket-chaining technique you just saw.

Python · Your turn

      
What you learned in this chapter: an API is a structured, machine-readable interface to data — like a waiter who always answers in a predictable format. An API request is a URL made up of a base URL, an endpoint, and parameters. The response almost always comes back as JSON — which Python reads with json.loads() and turns into familiar dictionaries and lists. In the next chapter you will send a real request to the Diavgeia API using Python's requests library.

Chapter Navigation

Move between chapters.

Loading Python environment — this may take a moment…