To export a data structure (dict, list), dump it as a string,
in a serialization format:
https://en.wikipedia.org/wiki/Serialization
https://en.wikipedia.org/wiki/XML
https://en.wikipedia.org/wiki/JSON
https://en.wikipedia.org/wiki/YAML
https://en.wikipedia.org/wiki/TOML
Then, you can re-import the serialized plain text string,
and have your data structure back!
Serializing I/O with programs improves composability and
abstraction.
The classic Unix philosopy stated that programs should input and output
plain text,
so they may be piped and composed.
Recent innovative programming languages extend that notion,
by piping serialized plain text:
https://www.nushell.sh/
Classic BSD-socket clients and servers, input and output plain-text
data,
in networking protocols.
Recent networking protocls extent that notion,
by tunneling serialized plain text.
Serializing I/O with network endpoints streamlines protocol design and
interoperability.
https://en.wikipedia.org/wiki/User_interface
A computer’s user interface is for a person.
https://en.wikipedia.org/wiki/API
https://www.redhat.com/en/topics/api/what-are-application-programming-interfaces
An API defines how computer programs or components communicate with each
other.
It is a software interface, offering an automated service to other
pieces of software.
An API specification is describes how to build or use the
interface.
A system that meets this standard is said to implement, or expose, an
API.
A client program may call or execute parts of the API.
The calls that make up the API are also known as:
subroutines, methods, requests, or endpoints.
An API specification defines these calls,
meaning that it explains how to use or implement them.
In addition to local software APIs via libraries, modules,
etc.,
one can see the following as APIs:
plaint-text networking protocols,
POSIX sockets,
POSIX itself,
etc.
Rather than use a web browser,
or write HTTP requests and responses manually,
one can use an HTTP library,
which allows a higher level interface to custom HTTP messages:
https://docs.python-requests.org/en/latest/index.html
Demo this in class:
import requests
r = requests.get("http://info.cern.ch")
r.text
r.content
r.raw
r = requests.get("https://api.github.com/events")
r.url
r.text
r.json()
# To pretty print:
print(json.dumps(r.json(), indent=4))
# Custom headers:
url = "https://api.github.com/some/endpoint"
headers = {"user-agent": "my-app/0.0.1"}
r = requests.get(url, headers=headers)
# Post headers:
payload = {"key1": "value1", "key2": "value2"}
r = requests.post("https://httpbin.org/post", data=payload)
print(r.text)
Remote APIs allow developers to manipulate remote resources,
through programs that use networked protocols.
An API call, executed locally on a proxy object,
invokes the corresponding method on the remote object,
using the remote protocol,
and acquires the result to be used locally,
potentially changing the object remotely.
An application programming interface can be synchronous or asynchronous.
A synchronous API call is a design pattern,
where the call site is blocked,
while waiting for the called code to finish.
With an asynchronous API call,
the call site is not blocked while waiting for the called code to
finish,
and instead, when the reply arrives, the calling thread is notified.
https://en.wikipedia.org/wiki/Microservices
Loosely coupled services accessed through public APIs.
https://en.wikipedia.org/wiki/API#Web_APIs
https://en.wikipedia.org/wiki/Web_API
Web APIs are a service accessed from client devices (mobile phones,
laptops, etc.),
connecting to a web server, using the Hypertext Transfer Protocol
(HTTP).
Client devices send a request in the form of an HTTP request,
and are met with a response message,
usually in JavaScript Object Notation (JSON) or
Extensible Markup Language (XML) format.
A server-side web API consists of one or more publicly exposed
endpoints,
to a defined request–response message system,
typically expressed in JSON or XML.
The web API is exposed most commonly by means of an HTTP-based web
server.
https://en.wikipedia.org/wiki/SOAP
SOAP is an acronym for Simple Object Access Protocol.
It is a messaging protocol specification for exchanging structured
information.
It uses XML Information Set for its message format,
and relies on application layer protocols,
most often Hypertext Transfer Protocol (HTTP),
although some legacy systems communicate over Simple Mail Transfer
Protocol (SMTP),
for message negotiation and transmission.
https://en.wikipedia.org/wiki/Service-oriented_architecture
https://en.wikipedia.org/wiki/Resource-oriented_architecture
https://en.wikipedia.org/wiki/GraphQL
https://en.wikipedia.org/wiki/REST
https://en.wikipedia.org/wiki/Overview_of_RESTful_API_Description_Languages
https://www.redhat.com/en/topics/api/what-is-a-rest-api
https://en.wikipedia.org/wiki/OpenAPI_Specification
https://stackoverflow.com/questions/671118/what-exactly-is-restful-programming
REST (Representational State Transfer) APIs tunnel json data through
HTTP.
A REST API allows remote functions (endpoints) to be called via
urls.
Lookups should use GET
requests.
PUT
, POST
, and DELETE
requests
should be used for
mutation, creation, and deletion respectively.
The json data often contains information about the needed HTTP methods
(GET, PUT, etc.).
The formal REST constraints are as follows:
Client/Server:
Client are separated from servers by a well-defined interface.
Stateless:
A specific client does not consume server storage when it is “at
rest”.
Cache:
Responses indicate their own cacheability.
Uniform Interface:
Individual resources are identified in requests using URIs.
Layered System:
A client cannot ordinarily tell whether it is connected directly to the
end server,
or to an intermediary along the way.
Code on Demand (optional):
Servers are able to temporarily extend or customize the functionality of
a client,
by transferring logic to the client that can be executed within a
standard virtual machine.
NASA has some accessible APIs:
https://api.nasa.gov/
For example, Astronomy Picture Of the Day (APoD):
https://api.nasa.gov/planetary/apod
The documentation states that this endpoint accepts GET
requests.
It requires one piece of information from the user, an API key,
and accepts several other optional pieces of information.
Such pieces of information are known as parameters.
The parameters for this API are written in a format known as a query
string,
which is separated by a question mark character (?) from the
endpoint.
An ampersand (&) separates the parameters in the query string from
each other.
Together, the endpoint and the query string form a URL,
that determines how the API will respond.
This URL is also known as a query or an API call.
In the below example,
two parameters are transmitted (or passed) to the API via the query
string.
The first is the required API key, api_key
,
and the second date
is an optional parameter,
the date of the photograph requested.
Open this in a browser (thus using GET request):
https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY&date=1996-12-03
Or, run this in python:
import requests
import json
r = requests.get("https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY&date=1996-12-03")
print(json.dumps(r.json(), indent=4))
https://www.weather.gov/documentation/services-web-api
https://weather-gov.github.io/api/
https://en.wikipedia.org/wiki/Webhook
https://www.redhat.com/en/topics/automation/what-is-a-webhook
Instead of asking the server for data,
as the server to send data when a condition is met.
Despite their nicknames, webhooks are not APIs;
they work together.
An application must have an API to use a webhook.
Three class-related examples follow:
https://docs.gitlab.com/ee/api/rest/
https://docs.gitlab.com/ee/api/repositories.html
Project examples, we use for your assignments:
https://github.com/behindthebrain/assigner
https://canvas.instructure.com/doc/api/
https://community.canvaslms.com/t5/Canvas-Developers-Group/Canvas-APIs-Getting-started-the-practical-ins-and-outs-gotchas/ba-p/263685
Project example, we use for your assignments:
https://gitlab.com/classroomcode/cahoot
https://gitlab.com/classroomcode/discuss
https://github.com/behindthebrain/assigner
We use this software to manage your assignments:
https://github.com/redkyn/assigner
It uses web requests as a client to both the Canvas and Gitlab REST
APIs.
Show this in class!
We can think of the security of API interaction in two parts:
1. The network connection
2. The endpoints (server and client)
In any HTTPS connection, first a TLS connection is made,
and then HTTP data are tunneled through it.
Thus, if you are using any modern library, for example
requests
,
then the network part of the token is secured.
Issues arise if you browser, or the server, log any access token, key,
or password,
based on the way you send it in code, or the way you store it on
disk.
Demo this with wget, curl, python requests, in Wireshark.
https://api.nasa.gov/
Others just rely on a token via requests:
https://docs.gitlab.com/ee/api/personal_access_tokens.html
https://canvas.instructure.com/doc/api/file.oauth.html#using-access-tokens
Some have their own library API for the REST API:
https://zulip.com/api/configuring-python-bindings
How do you improve the security of tokens stored on disk?
Background: discuss the way RSAa and GnuPG Keys are secured on disk.
Demo securing the NASA API above.
This is the ideal way to interact with GnuPG in code:
https://www.gnupg.org/software/gpgme/index.html
https://www.gnupg.org/documentation/howtos.html
https://www.gnupg.org/documentation/manuals/gpgme/
Here’s an example:
http://files.au.adversary.org/crypto/gpgme-python-howto.html#howto-basic-decryption
Where API_TOKEN_KEY.gpg
is a gpg2 encrypted text file
containing the decrypted token:
DEMO_KEY
To generate:
echo "DEMO_KEY" >temp
gpg2 --gen-key # Name: bob, Email: bob@alice@com, Password: 1234
gpg2 --encrypt --output API_TOKEN_KEY.gpg --recipient bob@alice.com temp
rm temp
And a python script: secure_rest_client.py
:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import requests
import json
import gpg
with open("API_TOKEN_KEY.gpg", "rb") as ciphertext_file:
try:
key, result, verify_result = gpg.Context().decrypt(ciphertext_file)
key = key.decode().strip()
except gpg.errors.GPGMEError as e:
key = None
print(e)
r = requests.get(f'https://api.nasa.gov/planetary/apod?api_key={key}&date=2024-05-01')
print(r.text, "\n")
print(r.content, "\n")
print(r.raw, "\n")
print(json.dumps(r.json(), indent=4))
https://www.mediawiki.org/wiki/MediaWiki
https://en.wikipedia.org/wiki/MediaWiki
MediaWiki is used for many Wikis, and it has a REST API:
https://www.mediawiki.org/wiki/API:REST_API
For example:
https://www.snpedia.com/
https://en.wikipedia.org/wiki/SNPedia
https://www.snpedia.com/index.php/Bulk
https://bots.snpedia.com/api.php
Discussed in more depth here:
../../Bioinformatics/Content/25-WGS.html
https://www.reddit.com/r/ProgrammerHumor/comments/6pylb0/hello_id_like_to_hear_a_restful_api_joke/