Libraries & APIs
Very little real-world software is built entirely from scratch. Libraries provide reusable, pre-written functionality, and APIs define the precise contract for how to use that functionality (or communicate with an entirely separate system) correctly.
A library is a collection of pre-written code that provides useful functionality you can use in your own program instead of writing it yourself. An API (Application Programming Interface) is the specific, defined set of functions, methods, or endpoints a library, service, or system exposes for other code to use — essentially, the agreed-upon rules for how to interact with it.
Writing every piece of functionality from absolute scratch — date formatting, network requests, image processing, mathematical functions — would be an enormous, wasteful duplication of effort that thousands of other programmers have already solved well. Libraries let you build on that existing, tested work; APIs make clear exactly how to use it correctly, without needing to understand its internal implementation.
Using a math library instead of implementing trigonometric functions by hand, using a web framework's API to define a website's routes, calling a weather service's web API to get a forecast for a specific city, using an operating system's API to open a file or create a network connection.
An API is like a restaurant's menu: it tells you exactly what you can order (the available operations) and what you'll get back, without requiring you to know anything about how the kitchen actually prepares the food. You don't need to know the chef's exact recipe (the library's internal implementation) — you just need to know what's on the menu and how to order it correctly.
math is Python's built-in math library. sqrt is one function in its API — you don't need to know how square roots are actually computed internally; you just need to know sqrt(x) takes a number and returns its square root.
An SDK (Software Development Kit) is typically a broader bundle than a single library — often including one or more libraries, documentation, sample code, and development/debugging tools, all aimed at building for a specific platform or service (a mobile OS's SDK, a cloud provider's SDK).
A web API frequently follows the REST architectural style (using standard HTTP methods like GET, POST, PUT, DELETE against defined URLs/endpoints, typically exchanging data as JSON), though other styles (GraphQL, gRPC, SOAP) are also common depending on the system's requirements.
API versioning (v1, v2 in a URL, or a version header) lets a service evolve its API over time while giving existing client code time to migrate, rather than breaking every existing integration the moment something changes.
A well-designed API aims for a stable, well-documented, minimal-surprise contract — hiding internal implementation details so the underlying implementation can change freely (be optimized, rewritten, or fixed) without breaking code that only depends on the API's documented behavior, not its internals.
Relying on a library's or API's undocumented internal behavior (rather than its documented, guaranteed contract), which can break silently in a future update with no warning, since the maintainers never promised that behavior would stay the same.
Not handling error responses or exceptions from an external API call, assuming a network request or library function will always succeed — a highly fragile assumption in real-world software, since networks and external services fail regularly.
Pulling in a large, heavy library for a very small piece of needed functionality, adding unnecessary complexity, size, and potential security surface to a project.
Ignoring an API's rate limits or authentication requirements, leading to requests being unexpectedly rejected or throttled in production.
Reading a library's or API's official documentation and changelog before integrating it, rather than reverse-engineering its behavior through trial and error alone.
Wrapping calls to an external API in your own thin abstraction layer, so that if the underlying API or library ever needs to be replaced, only that one wrapper needs to change, not every place in the codebase that used it directly.
Handling network and API failures explicitly (timeouts, retries with backoff, clear error messages) rather than assuming every external call will always succeed.
An API is a source-level contract — the functions, their names, and their expected behavior, as seen by code being compiled against them. An ABI (Application Binary Interface) is a lower-level, binary-compatible contract — the exact calling conventions, data layouts, and symbol naming a compiled library exposes, needed when linking already-compiled code together without recompiling from source. Two libraries can have API-compatible source interfaces while being ABI-incompatible at the binary level, which matters enormously for how shared libraries and dynamic linking work, covered fully in the future ABI and Calling Conventions and Linker modules.
API design as a long-term commitment Once an API is public and other code depends on it, changing it becomes expensive: a breaking change forces every downstream user to update their code, while a purely additive, backward-compatible change (adding a new optional parameter, a new endpoint) generally doesn't. This asymmetry is why experienced API designers spend disproportionate effort getting an interface right before it's widely adopted, and why deprecation (marking something as discouraged but still functional, ahead of eventual removal) is a standard, deliberate practice rather than an afterthought.
System calls as the ultimate low-level API At the very bottom of the API stack, a system call is the interface between a user-space program and the operating system's kernel — arguably the most foundational 'API' any program on that OS ultimately depends on for I/O, memory allocation, and process management, covered fully in the future Operating System Connection module.
What's the difference between an API and an SDK?
An API is the specific set of functions, methods, or endpoints exposed for interacting with a library, service, or system. An SDK is typically a broader bundle that may include one or more APIs/libraries, along with documentation, tools, and sample code, aimed at building for a specific platform.
What's the difference between an API and an ABI?
An API is a source-level contract (function signatures and behavior visible to code being compiled against it). An ABI is a binary-level contract (exact calling conventions, memory layouts, and symbol names) needed for already-compiled code to be linked together correctly without recompilation — two things can be API-compatible while being ABI-incompatible.
Why is breaking API compatibility considered costly?
Because any code depending on that API must be updated to keep working — for a widely used API, that cost is multiplied across every downstream user, which is why API designers favor additive, backward-compatible changes and use deliberate deprecation processes rather than abrupt breaking changes.
import math
result = math.sqrt(16)
print(result) # 4.0