API Documentation¶
Providers¶
- class micawber.providers.Provider(endpoint[, timeout=3.0[, user_agent=None[, **kwargs]]])¶
The
Providerobject is responsible for retrieving metadata about a given URL. It implements a method calledrequest(), which takes a URL and any parameters, which it sends off to an endpoint. The endpoint should return a JSON dictionary containing metadata about the resource, which is returned to the caller.- Parameters:
endpoint – the API endpoint which should return information about requested links
timeout (float) – socket timeout, in seconds, for requests to the endpoint.
user_agent (str) – value sent in the
User-Agentheader.kwargs – any additional url parameters to send to the endpoint on each request, used for providing defaults. An example use-case might be for providing an API key on each request.
- request(url, **extra_params)¶
Retrieve information about the given url. By default, will make a HTTP GET request to the endpoint. The url will be sent to the endpoint, along with any parameters specified in the
extra_paramsand those parameters specified when the class was instantiated.Raises
ProviderExceptionwhen the request fails. The subclass says why, so a caller can cache a 404, report a 401, and retry a timeout:ProviderHTTPExceptionfor a non-2xx response, with the code on.statusProviderTimeoutExceptionwhen the endpoint does not answer in timeInvalidResponseExceptionwhen the body is not a JSON objectProviderExceptionitself for anything else, such as a refused connection or a bad charset
The underlying error is on
__cause__.- Parameters:
url – URL to retrieve metadata for
extra_params – additional parameters to pass to the endpoint, for example a maxwidth or an API key. A
maxwidthgiven without amaxheightimplies amaxheightof 16/9 the width, tall enough that a portrait embed is not squashed.
- Return type:
a dictionary of JSON data
- class micawber.providers.ProviderRegistry([cache=None[, max_workers=None[, negative_ttl=300]]])¶
A registry for encapsulating a group of
Providerinstances, with optional caching support.Handles matching regular expressions to providers. URLs are sent to the registry via its
request()method, it checks to see if it has a provider that matches the URL, and if so, requests the metadata from the provider instance.Exposes methods for parsing various types of text (including HTML), and either rendering oembed media inline or extracting embeddable links.
- Parameters:
cache – the cache simply needs to implement two methods,
.get(key)and.set(key, value).max_workers (int) – fetch the URLs in a document concurrently, using a thread pool of this size. Unset, requests are made one at a time.
negative_ttl (int) – seconds to remember that a provider failed for a URL, so a dead link is not re-requested on every render. Within that window the request raises
ProviderExceptionwithout touching the provider.0disables it. Needs nothing from the cache beyondgetandset.
- register(regex, provider[, skip_invalid=False])¶
Register the provider with the following regex. The regex is compiled once here rather than on every lookup.
Example:
registry = ProviderRegistry() registry.register( 'https://\S*.youtu(\.be|be\.com)/watch\S*', Provider('https://www.youtube.com/oembed'), )
- Parameters:
regex – a regex for matching URLs of a given type
provider – a
Providerinstanceskip_invalid (bool) – log a warning and skip the provider when the regex will not compile, rather than raising
re.error. Used when registering patterns from a third-party provider list, where one bad pattern should not cost the whole list. Patterns you write yourself should raise.
- request(url, **extra_params)¶
Retrieve information about the given url if it matches a regex in the instance’s registry. If no provider matches the URL, a
ProviderExceptionis thrown, otherwise the URL and parameters are dispatched to the matching provider’sProvider.request()method.If a cache was specified, the resulting metadata will be cached.
- Parameters:
url – URL to retrieve metadata for
extra_params – additional parameters to pass to the endpoint, for example a maxwidth or an API key.
- Return type:
a dictionary of JSON data
- request_many(urls, **extra_params)¶
Retrieve information about each url, concurrently when
max_workersis set. Returns a dict of url to metadata holding only the urls that resolved. Duplicates are requested once. This is what the parsers call, once per document.- Parameters:
urls – an iterable of URLs
extra_params – additional parameters to pass to each provider
- Return type:
dict
- parse_text_full(text[, urlize_all=True[, handler=full_handler[, urlize_params=None[, **params]]]])¶
Parse a block of text, converting all links by passing them to the given handler. Links contained within a block of text (i.e. not on their own line) will be handled as well.
Example input and output:
IN: 'this is a pic http://example.com/some-pic/' OUT: 'this is a pic <a href="http://example.com/some-pic/"><img src="http://example.com/media/some-pic.jpg" /></a>'
- Parameters:
text (str) – a string to parse
urlize_all (bool) – convert unmatched urls into links
handler – function to use to convert metadata back into a string representation
urlize_params (dict) – keyword arguments to be used to construct a link when a provider is not found and urlize is enabled.
params – any additional parameters to use when requesting metadata, i.e. a maxwidth or maxheight.
- parse_text(text[, urlize_all=True[, handler=full_handler[, block_handler=inline_handler[, urlize_params=None[, **params]]]]])¶
Very similar to
parse_text_full()except URLs on their own line are rendered using the givenhandler, whereas URLs within blocks of text are passed to theblock_handler. The default behavior renders full content for URLs on their own line (e.g. a video player), whereas URLs within text are rendered simply as links so as not to disrupt the flow of text.URLs on their own line are converted into full representations
URLs within blocks of text are converted into clickable links
- Parameters:
text (str) – a string to parse
urlize_all (bool) – convert unmatched urls into links
handler – function to use to convert links found on their own line
block_handler – function to use to convert links found within blocks of text
urlize_params (dict) – keyword arguments to be used to construct a link when a provider is not found and urlize is enabled.
params – any additional parameters to use when requesting metadata, i.e. a maxwidth or maxheight.
- parse_html(html[, urlize_all=True[, handler=full_handler[, block_handler=inline_handler[, urlize_params=None[, **params]]]]])¶
Parse HTML intelligently, rendering items on their own within block elements as full content (e.g. a video player), whereas URLs within text are passed to the
block_handlerwhich by default will render a simple link. URLs that are already enclosed within a<a>tag are skipped over.URLs that are already within <a> tags are passed over
URLs on their own in block tags are converted into full representations
URLs interspersed with text are converted into clickable links
Note
requires BeautifulSoup or beautifulsoup4
- Parameters:
html (str) – a string of HTML to parse
urlize_all (bool) – convert unmatched urls into links
handler – function to use to convert links found on their own within a block element
block_handler – function to use to convert links found within blocks of text
urlize_params (dict) – keyword arguments to be used to construct a link when a provider is not found and urlize is enabled.
params – any additional parameters to use when requesting metadata, i.e. a maxwidth or maxheight.
- extract(text, **params)¶
Extract all URLs from a block of text, and additionally get any metadata for URLs we have providers for.
- Parameters:
text (str) – a string to parse
params – any additional parameters to use when requesting metadata, i.e. a maxwidth or maxheight.
- Return type:
returns a 2-tuple containing a list of all URLs and a dict keyed by URL containing any metadata. If a provider was not found for a URL it is not listed in the dictionary.
- extract_html(html, **params)¶
Extract all URLs from an HTML string, and additionally get any metadata for URLs we have providers for.
extract()but for HTML.Note
URLs within <a> tags will not be included.
- Parameters:
html (str) – a string to parse
params – any additional parameters to use when requesting metadata, i.e. a maxwidth or maxheight.
- Return type:
returns a 2-tuple containing a list of all URLs and a dict keyed by URL containing any metadata. If a provider was not found for a URL it is not listed in the dictionary.
- micawber.providers.bootstrap_basic([cache=None[, registry=None[, max_workers=None]]])¶
Create a
ProviderRegistrywith the major platforms registered: YouTube, Vimeo, X, TikTok, Instagram, Facebook, Reddit, Spotify, Bluesky, SoundCloud, Flickr, Giphy, Pinterest, Tumblr, Dailymotion, Apple Podcasts, Apple Music and WordPress.com. Every endpoint was verified live against a real URL. No request is made by this function itself. For the long tail, usebootstrap_oembed().- Parameters:
cache – an object that implements simple
getandsetregistry – a
ProviderRegistryinstance, which will be updated with the list of supported providers. If not specified, an emptyProviderRegistrywill be used.max_workers (int) – thread pool size for the registry this function creates, as
ProviderRegistrytakes it. Ignored whenregistryis given, since that registry already has its own.
- Return type:
a
ProviderRegistrywith a handful of providers registered
- micawber.providers.bootstrap_oembed([cache=None[, registry=None[, refresh=False[, timeout=3.0[, providers_file=None[, max_workers=None[, **kwargs]]]]]])¶
Create a
ProviderRegistryand register as many providers as are described in the oembed.com providers list.By default the list is read from the copy shipped with micawber, so no request is made. To use a newer list without waiting for a release, either pass
refresh=Trueto fetch it live, or regenerate a local copy and pointproviders_fileat it:python -m micawber my_providers.json
Run with no argument, that command updates the copy inside the installed package instead. The same thing is available as
refresh_providers().- Parameters:
cache – an object that implements simple
getandsetregistry – a
ProviderRegistryinstance, which will be updated with the list of supported providers. If not specified, an emptyProviderRegistrywill be used.max_workers (int) – thread pool size for the registry this function creates, as
ProviderRegistrytakes it. Ignored whenregistryis given, since that registry already has its own.refresh (bool) – fetch the list from oembed.com instead of reading a file. The result is stored in
cacheif one is given.providers_file (str) – path to a provider list to read instead of the shipped one. Ignored when
refreshis set.timeout (float) – socket timeout, in seconds, applied to the provider-list request made by this function and to the providers it registers. Without a bounded default, a provider-list server that accepts the connection and never replies blocks forever.
kwargs – any default keyword arguments to use with providers
- Return type:
a ProviderRegistry with support for noembed
- micawber.providers.refresh_providers([path])¶
Download the current oembed.com provider list and write it to
path, which defaults to the copy inside the installed package. The download is checked to be a JSON array before anything is overwritten. Returns the path written.
- micawber.providers.bootstrap_embedly([cache=None[, registry=None[, refresh=False[, timeout=3.0[, max_workers=None[, **kwargs]]]]])¶
Create a
ProviderRegistryand register as many providers as are supported by embed.ly. Valid services are fetched from http://api.embed.ly/1/services/python and parsed then registered.Note
This function makes a request over the internet whenever it is called.
- Parameters:
cache – an object that implements simple
getandsetregistry – a
ProviderRegistryinstance, which will be updated with the list of supported providers. If not specified, an emptyProviderRegistrywill be used.max_workers (int) – thread pool size for the registry this function creates, as
ProviderRegistrytakes it. Ignored whenregistryis given, since that registry already has its own.refresh (bool) – force refreshing the provider data rather than attempting to load it from cache (if cache is used).
timeout (float) – socket timeout, in seconds, applied to the provider-list request made by this function and to the providers it registers. Without a bounded default, a provider-list server that accepts the connection and never replies blocks forever.
kwargs – any default keyword arguments to use with providers, useful for specifying your API key
- Return type:
a ProviderRegistry with support for embed.ly
# if you have an API key, you can specify that here pr = bootstrap_embedly(key='my-embedly-key') pr.request('https://www.youtube.com/watch?v=54XHDUOHuzU')
- micawber.providers.bootstrap_noembed([cache=None[, registry=None[, refresh=False[, timeout=3.0[, max_workers=None[, **kwargs]]]]])¶
Create a
ProviderRegistryand register as many providers as are supported by noembed.com. Valid services are fetched from https://noembed.com/providers and parsed then registered.Note
This function makes a request over the internet whenever it is called.
- Parameters:
cache – an object that implements simple
getandsetregistry – a
ProviderRegistryinstance, which will be updated with the list of supported providers. If not specified, an emptyProviderRegistrywill be used.max_workers (int) – thread pool size for the registry this function creates, as
ProviderRegistrytakes it. Ignored whenregistryis given, since that registry already has its own.refresh (bool) – force refreshing the provider data rather than attempting to load it from cache (if cache is used).
timeout (float) – socket timeout, in seconds, applied to the provider-list request made by this function and to the providers it registers. Without a bounded default, a provider-list server that accepts the connection and never replies blocks forever.
kwargs – any default keyword arguments to use with providers, useful for passing the
nowrapoption to noembed.
- Return type:
a ProviderRegistry with support for noembed
# if you have an API key, you can specify that here pr = bootstrap_noembed(nowrap=1) pr.request('https://www.youtube.com/watch?v=54XHDUOHuzU')
- micawber.providers.bootstrap_iframely([cache=None[, registry=None[, max_workers=None[, **kwargs]]]])¶
Create a
ProviderRegistrythat routes requests through iframely, a commercial oEmbed proxy supporting roughly 1900 domains. Iframely recommends sending all URLs to its API rather than matching against a list of supported providers, so a single catch-all pattern is registered. Unlike the other schema-based helpers, this function does not make a request over the internet when called.An iframely API key is required, passed as either
api_keyorkey(the md5 hexdigest of the api key).- Parameters:
cache – an object that implements simple
getandsetregistry – a
ProviderRegistryinstance, which will be updated with the list of supported providers. If not specified, an emptyProviderRegistrywill be used.max_workers (int) – thread pool size for the registry this function creates, as
ProviderRegistrytakes it. Ignored whenregistryis given, since that registry already has its own.kwargs – any default keyword arguments to use with providers - must include
api_keyorkey.
- Return type:
a ProviderRegistry with support for iframely
pr = bootstrap_iframely(api_key='my-iframely-key') pr.request('https://www.youtube.com/watch?v=54XHDUOHuzU')
Note
Because providers registered later take precedence, passing an existing
registryto this function will cause the catch-all iframely provider to shadow any previously-registered providers.
Cache¶
- class micawber.cache.Cache([timeout=None[, max_size=1024]])¶
A reference implementation for the cache interface used by the
ProviderRegistry.- Parameters:
timeout (int) – seconds a value stays fresh. Unset, values never expire and are only dropped to stay within
max_size.max_size (int) – how many entries to keep. Once full, the least-recently-used entry is evicted.
0orNoneis unbounded.
from micawber import Cache, bootstrap_oembed cache = Cache() # Simple in-memory cache. # Entries expire after an hour, and at most 4096 are kept. cache = Cache(timeout=3600, max_size=4096) # Now our oembed provider will cache the responses for each URL we # request, which can provide a significant speedup. pr = bootstrap_oembed(cache=cache)
- get(key)¶
Retrieve the key from the cache or
Noneif not present or expired.
- set(key, value[, timeout=None])¶
Set the cache key
keyto the givenvalue.- Parameters:
timeout (int) – expiration for this value, overriding the cache default.
- class micawber.cache.PickleCache([filename='cache.db'[, timeout=None[, max_size=None]]])¶
A cache that uses pickle to store data. Accepts the same
timeoutandmax_sizeasCache, and by default keeps every entry.Note
To use this cache class be sure to call
load()when initializing your cache andsave()before your app terminates to persist cached data.- load()¶
Load the pickled data into memory
- save()¶
Store the internal cache to an external file
- class micawber.cache.RedisCache([namespace='micawber'[, timeout=None[, **conn]]])¶
A cache that uses Redis to store data
Note
requires the redis-py library,
pip install redis- Parameters:
namespace – prefix for cache keys
timeout (int) – expiration timeout in seconds (optional), applied to every value written.
set()can override it per-value.conn – keyword arguments to pass when initializing redis connection