### Install Dependencies and Start Docs Server
Source: https://github.com/internetarchive/openlibrary/wiki/everyone/documentation
Install project dependencies and start the local documentation development server using npm.
```bash
npm i
npm run docs:dev
```
--------------------------------
### Example Log Output
Source: https://github.com/internetarchive/openlibrary/blob/master/docker/README.md
This is an example of the log output you should see once the environment has finished loading and is ready.
```log
infobase_1 | 172.19.0.5:45716 - - [16/Feb/2023 16:54:10] "HTTP/1.1 GET /openlibrary.org/log/2023-02-16:0" - 200 OK
infobase_1 | 172.19.0.5:45730 - - [16/Feb/2023 16:54:15] "HTTP/1.1 GET /openlibrary.org/log/2023-02-16:0" - 200 OK
infobase_1 | 172.19.0.5:41790 - - [16/Feb/2023 16:54:20] "HTTP/1.1 GET /openlibrary.org/log/2023-02-16:0" - 200 OK
```
--------------------------------
### Run Open Library with Local Infogami
Source: https://github.com/internetarchive/openlibrary/blob/master/docker/README.md
This command sequence stops existing containers, starts the Open Library with a local Infogami setup using specified compose files, and follows the web service logs.
```sh
# Run Open Library using a local copy of Infogami for development
docker compose down && \
docker compose -f compose.yaml -f compose.override.yaml -f compose.infogami-local.yaml up -d && \
docker compose logs -f --tail=10 web
```
--------------------------------
### Install and Configure openlibrary-client
Source: https://github.com/internetarchive/openlibrary/wiki/advanced/data-importing
Install the openlibrary-client library and configure it with your archive.org/openlibrary.org credentials. This is necessary for programmatic data imports.
```sh
git clone https://github.com/internetarchive/openlibrary-client.git && cd openlibrary-client && pip -q install .
ol --configure --email youremail@example.com
```
--------------------------------
### Test Docker Installation
Source: https://github.com/internetarchive/openlibrary/blob/master/docker/README.md
Run the 'hello-world' container to verify that Docker is installed and configured correctly. This command pulls the 'hello-world:latest' image and runs it.
```sh
docker run hello-world
```
--------------------------------
### Install Dependencies and Run Unit Tests for opds.openlibrary.org
Source: https://github.com/internetarchive/openlibrary/blob/master/docs/ai/opds/index.md
Install the necessary dependencies for the opds.openlibrary.org project and run the unit tests. The unit tests are fast as they do not require network access. Approximately 158 tests are expected to pass in about 8 seconds.
```bash
cd ~/Projects/opds.openlibrary.org
pip install -r requirements.txt
# Unit tests (fast, no network)
python3 -m pytest tests/ -m "not e2e" -q
```
--------------------------------
### Install Pre-Commit Hooks
Source: https://github.com/internetarchive/openlibrary/wiki/everyone/documentation
Install pre-commit hooks to ensure code quality and consistency before committing changes. Refer to the Pre-Commit Guide for more details.
```bash
pre-commit install
```
--------------------------------
### Batch Import JSONL Example
Source: https://github.com/internetarchive/openlibrary/wiki/advanced/data-importing
This is an example of the JSONL format accepted by the batch import endpoint. Each line represents a single record, and comments starting with '#' are allowed.
```json
{"identifiers": {"open_textbook_library": ["1581"]}, "source_records": ["open_textbook_library:1581"], "title": "Legal Fundamentals of Healthcare Law", "languages": ["eng"], "subjects": ["Medicine", "Law"], "publishers": ["University of West Florida Pressbooks"], "publish_date": "2024", "authors": [{"name": "Tiffany Jackman"}], "lc_classifications": ["RA440", "KF385.A4"]}
{"identifiers": {"open_textbook_library": ["1580"]}, "source_records": ["open_textbook_library:1580"], "title": "Introduction to Literature: Fairy Tales, Folk Tales, and How They Shape Us", "languages": ["eng"], "subjects": ["Humanities", "Literature, Rhetoric, and Poetry"], "publishers": ["University of West Florida Pressbooks"], "publish_date": "2023", "authors": [{"name": "Judy Young"}], "lc_classifications": ["PE1408"]}
```
--------------------------------
### Install Project Dependencies with npm
Source: https://github.com/internetarchive/openlibrary/wiki/developers/tools/index
Installs necessary npm packages for the project, including Prettier. Run this command in your project's root directory.
```sh
npm install --no-audit
```
--------------------------------
### Install pre-commit with uv
Source: https://github.com/internetarchive/openlibrary/wiki/developers/tools/pre-commit
Install pre-commit using uv, a fast Python package manager. The `--with pre-commit-uv` flag enables uv for installing Python-based hooks, significantly speeding up the process.
```sh
# Install uv: https://docs.astral.sh/uv/getting-started/installation/
uv tool install pre-commit --with pre-commit-uv
pre-commit install
```
--------------------------------
### Install Bubblewrap CLI
Source: https://github.com/internetarchive/openlibrary/blob/master/conf/twa/README.md
Install the Bubblewrap CLI globally using npm. The `--no-audit` flag skips audit checks during installation.
```shell
npm i --no-audit -g @bubblewrap/cli
```
--------------------------------
### Interactive Loading Demo
Source: https://github.com/internetarchive/openlibrary/blob/master/openlibrary/templates/design/button.html
An interactive example showing how to toggle the loading state of a button and simulate a request.
```javascript
document.getElementById('demo-button-loading').addEventListener('click', function(e) {
var btn = e.currentTarget;
if (btn.loading) return;
btn.loading = true;
setTimeout(function() {
btn.loading = false;
}, 1500);
});
```
--------------------------------
### Setup for Production Script
Source: https://github.com/internetarchive/openlibrary/wiki/developers/misc/coding-recipes
Use this code to set up the Open Library environment for scripts running in production. It requires the production configuration file.
```python
import web
from openlibrary.setup import setup_for_script
setup_for_script('/olsystem/etc/openlibrary.yml')
from infogami import config
```
--------------------------------
### Using `curl` (local development example)
Source: https://github.com/internetarchive/openlibrary/wiki/advanced/data-importing
Import book data using `curl` command-line tool. This method requires a `cookies.txt` file for authentication.
```APIDOC
## POST /api/import (using curl)
### Description
Imports book data into Open Library using `curl`. Requires a `cookies.txt` file for session authentication.
### Method
POST
### Endpoint
http://localhost:8080/api/import
### Parameters
#### Request Headers
- **Content-Type**: application/json
- **-b cookies.txt**: Specifies the cookie file for authentication.
### Request Body
- **title** (string) - Required - The title of the book.
- **authors** (array of objects) - Required - A list of author objects, each with 'name', 'birth_date', and 'death_date' fields.
- **name** (string) - Required - The author's name.
- **birth_date** (string) - Optional - The author's birth date.
- **death_date** (string) - Optional - The author's death date.
- **isbn_10** (array of strings) - Optional - A list of ISBN-10 identifiers.
- **publishers** (array of strings) - Optional - A list of publisher names.
- **source_records** (array of strings) - Optional - Identifiers for source records.
- **subjects** (array of strings) - Optional - A list of subjects.
- **description** (string) - Optional - A description of the book.
- **publish_date** (string) - Optional - The publication date.
### Request Example
```sh
curl -X POST http://localhost:8080/api/import \
-H "Content-Type: application/json" \
-b cookies.txt \
-d '{
"title": "Super Great Book",
"authors": [{"name": "Author McAuthor", "birth_date": "1806", "death_date": "1871"}],
"isbn_10": ["1234567890"],
"publishers": ["Burgess and Hill"],
"source_records": ["amazon:123456790"],
"subjects": ["Trees", "Peaches"],
"description": "A book with a description",
"publish_date": "1829"
}'
```
### Response
#### Success Response (200)
- **authors** (array of objects) - Information about created or found authors.
- **key** (string) - The API key for the author.
- **name** (string) - The author's name.
- **status** (string) - The status of the author (e.g., 'created').
- **success** (boolean) - Indicates if the import was successful.
- **edition** (object) - Information about the created or found edition.
- **key** (string) - The API key for the edition.
- **status** (string) - The status of the edition (e.g., 'created').
- **work** (object) - Information about the created or found work.
- **key** (string) - The API key for the work.
- **status** (string) - The status of the work (e.g., 'created').
### Response Example
```json
{"authors": [{"key": "/authors/OL15A", "name": "Author McAuthor", "status": "created"}], "success": true, "edition": {"key": "/books/OL19M", "status": "created"}, "work": {"key": "/works/OL9W", "status": "created"}}
```
```
--------------------------------
### Query Database Directly
Source: https://github.com/internetarchive/openlibrary/wiki/developers/backend/understanding-the-data-model
Demonstrates how to get a database connection and execute a raw SQL query. Use this for direct database access when needed.
```python
from openlibrary.core import db
oldb = db.get_db() # i.e. web.database(**web.config.db_parameters)
query = "SELECT count(*) from bookshelves_books"
oldb.query(query)
```
--------------------------------
### Initialize Details Header Time Measurement
Source: https://github.com/internetarchive/openlibrary/blob/master/openlibrary/templates/account/view.html
Starts timing the rendering of the details header section for performance analysis.
```python
$ mb.component_times['Details header'] = time()
```
--------------------------------
### Import API Endpoint Example
Source: https://github.com/internetarchive/openlibrary/wiki/advanced/the-import-pipeline
This example shows how a record passes through the public import API endpoint, leading to parsing, augmentation, and validation by the 'Validator'.
```python
from openlibrary.plugins.importapi.code import process_import
# Example usage (assuming 'request' and 'response' objects are available)
# process_import(request, response)
```
--------------------------------
### Run Docker Compose in Foreground
Source: https://github.com/internetarchive/openlibrary/blob/master/docker/README.md
Starts the Open Library services in the foreground. Press Ctrl-C to stop the services.
```sh
docker compose up # Ctrl-C to stop
```
--------------------------------
### Start Specific Docker Service
Source: https://github.com/internetarchive/openlibrary/blob/master/docker/README.md
Starts a specific service (e.g., solr) without bringing up its dependencies. Useful for restarting individual components.
```sh
docker compose up --no-deps -d solr
```
--------------------------------
### Basic Tooltip Example
Source: https://github.com/internetarchive/openlibrary/blob/master/openlibrary/templates/design/tooltip.html
Displays a simple tooltip with default settings (top placement, 150ms delay) when hovering or focusing the button.
```html
```
--------------------------------
### Run Development Mode with Hot Reload
Source: https://github.com/internetarchive/openlibrary/blob/master/CLAUDE.md
Start the development server in watch mode for continuous development with hot reloading, using npm.
```bash
npm run watch
```
--------------------------------
### Serve Component with Hot Reloading (Standalone)
Source: https://github.com/internetarchive/openlibrary/blob/master/openlibrary/components/README.md
Install dependencies and run a development server for a specific component with hot reloading enabled, outside the Docker environment.
```shell
npm install --no-audit
COMPONENT="HelloWorld" npm run serve
```
```shell
COMPONENT="LibraryExplorer" npm run serve
# Then open http://localhost:5173/?ol_base=openlibrary.org
```
--------------------------------
### Table of Contents Formatting Example
Source: https://github.com/internetarchive/openlibrary/blob/master/openlibrary/templates/books/edit/edition.html
Demonstrates the formatting syntax for the table of contents input. Use '*' for indentation, '|' for columns, and line breaks for new entries.
```html
$# detect-missing-i18n-skip-line
* Part 1 | THIS WORLD | 1
** Chapter 1 | Of the Nature of Flatland | 3
** Chapter 2 | Of the Climate and Houses in Flatland | 5
* Part 2 | OTHER WORLDS | 42
```
--------------------------------
### Get Memcached Entry
Source: https://github.com/internetarchive/openlibrary/wiki/developers/backend/general
Retrieves a specific entry from memcache using its key. The example shows fetching author data.
```python
mc.get('/authors/OL18319A')
```
--------------------------------
### Query Unarchived Covers with Limit
Source: https://github.com/internetarchive/openlibrary/blob/master/openlibrary/coverstore/README.md
Adjust the cover query to batch unarchived items using a limit to prevent timeouts during archival. This example specifies a starting ID.
```python
covers = _db.select('cover', where='archived=$f and id>6708293', order='id', vars={'f': False}, limit=1000)
```
--------------------------------
### Register and Activate New User Account
Source: https://github.com/internetarchive/openlibrary/wiki/advanced/local-user-setup
Register a new user with a username, display name, email, and password, then activate the account on the server. Note the email for login.
```python
# Set your username (modify this as needed):
username = 'test_username'
# Register the user:
web.ctx.site.register(username, 'test_displayname', 'test@example.com', 'test_password')
# Output:
# 0.0 (5): SELECT * FROM store WHERE key='account/test_username'
# 0.03 (2): 200 POST /openlibrary.org/account/register {'username': 'test_username', 'displayname': 'test_displayname', 'email': 'test@example.com', 'password': 'test_password'}
#
# Activate the account on the server:
site = server.get_site('openlibrary.org')
site.account_manager.activate(username)
```
--------------------------------
### Define a New Route with GET Method
Source: https://github.com/internetarchive/openlibrary/blob/master/openlibrary/plugins/README.md
Define a new route by creating a class that extends `delegate.page`. Implement the `GET` method to handle HTTP GET requests and render a template with query parameters.
```python
class search_many(delegate.page):
path = '/search/many'
def GET(self):
i = web.input(q='')
return render_template('search/many', q=i.q)
```
--------------------------------
### Initialize Infogami Configuration
Source: https://github.com/internetarchive/openlibrary/wiki/advanced/local-user-setup
Load Infogami configuration for local development. Ensure the correct configuration file path is used.
```bash
docker compose exec web python
```
```python
import web
import infogami
from openlibrary.config import load_config
load_config('conf/openlibrary.yml') # for local dev
# load_config('/olsystem/etc/openlibrary.yml') # for prod
infogami._setup()
from infogami import config
from infogami.infobase import server
# Verify setup - should return a Site object:
web.ctx.site
# Output:
```
--------------------------------
### Setup for Local Development Script
Source: https://github.com/internetarchive/openlibrary/wiki/developers/misc/coding-recipes
Use this code to set up the Open Library environment for scripts running in a local development environment. It requires the local development configuration file.
```python
import web
from openlibrary.setup import setup_for_script
setup_for_script('config/etc/openlibrary.yml')
from infogami import config
```
--------------------------------
### Build and Run Open Library with Docker
Source: https://github.com/internetarchive/openlibrary/wiki/developers/quick-start
Build the Docker images for Open Library and start the services in detached mode. This may take a significant amount of time on the first run.
```sh
docker compose build # 15-30 min on first run
docker compose up -d
```
--------------------------------
### Install Development Dependencies
Source: https://github.com/internetarchive/openlibrary/blob/master/docs/ai/tag-system/dev-setup.md
Install the tags package in editable mode along with development dependencies like pytest and requests.
```bash
pip install -e ".[dev]"
```
--------------------------------
### Build All Project Components
Source: https://github.com/internetarchive/openlibrary/blob/master/docs/ai/README.md
Use this command to build all project assets including CSS, JavaScript, and web components. It's a comprehensive build command for the entire project.
```bash
make all
```
--------------------------------
### Get and Display Stats Summary
Source: https://github.com/internetarchive/openlibrary/blob/master/openlibrary/templates/site/stats.html
Retrieves a summary of statistics and formats them as key-value pairs. Use this to get an overview of available stats.
```Python
$ stats = stats_summary()
$for k in stats:
$k: $dict(stats[k])
```
--------------------------------
### Domain-Aware Lit Component Example
Source: https://github.com/internetarchive/openlibrary/wiki/developers/frontend/building-components
An example of a Lit component that includes domain-specific logic, wrapping a design-system primitive and interacting with a service module.
```js
// openlibrary/plugins/openlibrary/js/my-books/components/MyBooksDeleteButton.js
import { LitElement, html } from "lit";
import { removeItem } from "../../lists/ListService";
/**
* Delete button scoped to the My Books feature. Wraps `ol-button` and
* calls `removeItem` from the List service internally.
*
* @element my-books-delete-button
* @fires my-books-delete-button-delete - Fired after the book is deleted. detail: { bookId: string }
*/
class MyBooksDeleteButton extends LitElement {
static properties = {
/** ID of the book this button will remove */
bookId: { type: String, attribute: "book-id" },
};
render() {
return html`Delete`;
}
async _delete() {
await removeItem(this.bookId);
this.dispatchEvent(
new CustomEvent("my-books-delete-button-delete", {
detail: { bookId: this.bookId },
bubbles: true,
composed: true,
}),
);
}
}
customElements.define("my-books-delete-button", MyBooksDeleteButton);
```
--------------------------------
### Initialize Memcache Client
Source: https://github.com/internetarchive/openlibrary/wiki/developers/backend/general
Initializes a memcache client using configuration from openlibrary-docker.yml. Ensure the configuration file is accessible.
```python
import yaml
from openlibrary.utils import olmemcache
with open('/openlibrary/conf/openlibrary-docker.yml') as in_file:
y = yaml.safe_load(in_file)
mc = olmemcache.Client(y['memcache_servers'])
```
--------------------------------
### Run Full Add Book Test Suite with Docker
Source: https://github.com/internetarchive/openlibrary/blob/master/docs/ai/imports/add-book-internals.md
Execute the complete test suite for the add_book functionality within a Docker environment. The `-xvs` flags enable stopping on the first failure, verbose output, and skipping known good tests, respectively.
```bash
docker compose run --rm home python -m pytest openlibrary/catalog/add_book/tests/ -xvs
```
--------------------------------
### Install Node.js Modules in Docker
Source: https://github.com/internetarchive/openlibrary/blob/master/docker/README.md
Install Node.js modules within the Docker environment to resolve potential errors during testing. This ensures npm jobs run inside the container.
```sh
# Install Node.js modules (if you get an error running tests)
# Important: npm jobs need to be run inside the Docker environment.
docker compose run --rm home npm install --no-audit
```
--------------------------------
### Initialize Android Project with Bubblewrap
Source: https://github.com/internetarchive/openlibrary/blob/master/conf/twa/README.md
Initialize a new Android project using Bubblewrap CLI. Provide the URL to your web app's manifest file. The CLI will also prompt for signing key details.
```shell
bubblewrap init --manifest https://openlibrary.org/static/manifest.json
```
--------------------------------
### Memcached Configuration Example
Source: https://github.com/internetarchive/openlibrary/wiki/advanced/production-service-architecture
This note provides guidance on how to configure the memory allocation for memcached servers. It suggests increasing the `-m` setting in `/etc/memcached.conf` based on available machine resources, recommending to leave approximately 300MB for the OS.
```bash
memcached -m 9300
```
--------------------------------
### Accept GET Parameters in Controller
Source: https://github.com/internetarchive/openlibrary/wiki/projects/developing-the-reading-log
Modify controller methods to accept additional GET parameters, such as 'search', alongside existing ones like 'page'. This is useful for adding new filtering or sorting options.
```python
i = web.input(page=1, search=None)
```
--------------------------------
### Load Affiliate Links Component
Source: https://github.com/internetarchive/openlibrary/blob/master/openlibrary/templates/type/edition/view.html
Prepares and loads the Affiliate Links component, gathering necessary data like ISBNs and ASIN.
```Python
$ prices = edition.key.startswith('/books/')
$ isbn_13 = edition.get_isbn13() or None
$ isbn_10 = edition.get_isbn10() or None
$ asin = None
$if edition.get('identifiers'):
$if edition.identifiers.get('amazon'):
$ asin = edition.identifiers.amazon[0]
$if isbn_10 and not asin:
$ asin = isbn_10
$ affiliate_links = macros.AffiliateLinksLoadingIndicator(edition.title, isbn_13, asin, prices)
```
--------------------------------
### Install Npm Packages in Temporary Container
Source: https://github.com/internetarchive/openlibrary/blob/master/docker/README.md
Run this command to install or update npm packages within a temporary container, useful after code changes affecting frontend dependencies. The `--no-audit` flag is used as per issue #2032.
```bash
docker compose run --rm home npm install --no-audit
```
--------------------------------
### Manually Start opds.openlibrary.org Service
Source: https://github.com/internetarchive/openlibrary/blob/master/docs/ai/opds/index.md
Manually start the opds.openlibrary.org development service using uvicorn. This command allows for manual testing and verification. It sets `CACHE_ENABLED` to `false` and `OL_BASE_URL` to the production Open Library URL. The health endpoint should return a 200 status code.
```bash
# Manual: start the service
CACHE_ENABLED=false OL_BASE_URL=https://openlibrary.org \
uvicorn app.main:app --host 127.0.0.1 --port 8090
curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:8090/health
```
--------------------------------
### Deploy Sitemaps using Rsync
Source: https://github.com/internetarchive/openlibrary/wiki/advanced/sitemap-generation
Use rsync to copy the generated sitemaps from the temporary directory on ol-home to the sitemaps directory on the web server.
```bash
sudo rsync -av rsync://ol-home/var_1/tmp/sitemaps/sitemaps /1/var/lib/openlibrary/sitemaps/
```
--------------------------------
### Get Plugin Information
Source: https://github.com/internetarchive/openlibrary/blob/master/openlibrary/templates/type/template/view.html
Retrieves plugin information, defaulting to 'upstream' if not specified.
```python
$_("plugin")
$page.get("plugin", "upstream")
```
--------------------------------
### GET /search/inside.json
Source: https://github.com/internetarchive/openlibrary/blob/master/docs/ai/solr/index.md
Full-text search endpoint, allowing searching within the content of books.
```APIDOC
## GET /search/inside.json
### Description
Full-text search endpoint, allowing searching within the content of books.
### Method
GET
### Endpoint
/search/inside.json
### Parameters
#### Query Parameters
- **q** (string) - Required - The full-text query.
- **limit** (integer) - Optional - Maximum number of results to return.
- **offset** (integer) - Optional - Offset for pagination.
### Response
#### Success Response (200)
- **docs** (array) - An array of documents matching the full-text query.
```
--------------------------------
### GET /search/lists.json
Source: https://github.com/internetarchive/openlibrary/blob/master/docs/ai/solr/index.md
List search endpoint. Use `?api=next` for the new response shape.
```APIDOC
## GET /search/lists.json
### Description
List search endpoint. Use `?api=next` for the new response shape.
### Method
GET
### Endpoint
/search/lists.json
### Parameters
#### Query Parameters
- **q** (string) - Required - The list query.
- **api** (string) - Optional - Use `next` for the new response shape.
- **limit** (integer) - Optional - Maximum number of results to return.
- **offset** (integer) - Optional - Offset for pagination.
### Response
#### Success Response (200)
- **lists** (array) - An array of list objects, each containing list details.
```
--------------------------------
### Connect to Open Library Database
Source: https://github.com/internetarchive/openlibrary/wiki/developers/backend/general
Use these commands to connect to the PostgreSQL triplestore database. Ensure you have the necessary permissions.
```sh
su postgres
psql openlibrary
```
--------------------------------
### Initialize Greeting Element in JavaScript
Source: https://github.com/internetarchive/openlibrary/wiki/everyone/internationalization
In the main JavaScript file, query for the greeting element. If it exists, dynamically import the greeting module and initialize it, passing the element as an argument.
```javascript
const greetingElement = document.querySelector(".greeting-example");
if (greetingElement) {
import("greeting").then((module) => module.initGreeting(greetingElement));
}
```
--------------------------------
### GET /search/authors.json
Source: https://github.com/internetarchive/openlibrary/blob/master/docs/ai/solr/index.md
Author search endpoint. Strips the `/authors/` prefix from the key in results.
```APIDOC
## GET /search/authors.json
### Description
Author search endpoint. Strips the `/authors/` prefix from the key in results.
### Method
GET
### Endpoint
/search/authors.json
### Parameters
#### Query Parameters
- **q** (string) - Required - The author query.
- **limit** (integer) - Optional - Maximum number of results to return.
- **offset** (integer) - Optional - Offset for pagination.
### Response
#### Success Response (200)
- **docs** (array) - An array of author objects, each containing author details and a key.
```
--------------------------------
### GET /search/subjects.json
Source: https://github.com/internetarchive/openlibrary/blob/master/docs/ai/solr/index.md
Subject search endpoint. Returns `type` and `count` compatibility fields.
```APIDOC
## GET /search/subjects.json
### Description
Subject search endpoint. Returns `type` and `count` compatibility fields.
### Method
GET
### Endpoint
/search/subjects.json
### Parameters
#### Query Parameters
- **q** (string) - Required - The subject query.
- **limit** (integer) - Optional - Maximum number of results to return.
- **offset** (integer) - Optional - Offset for pagination.
### Response
#### Success Response (200)
- **subjects** (array) - An array of subject objects, each containing `name` and `count`.
```
--------------------------------
### Loading Affiliate Links Component
Source: https://github.com/internetarchive/openlibrary/blob/master/openlibrary/templates/type/work/view.html
Prepares and loads the affiliate links component, which requires edition details like title, ISBNs, and ASIN. It determines if prices should be shown based on the edition's key.
```python
$prices = edition.key.startswith('/books/')
$isbn_13 = edition.get_isbn13() or None
$isbn_10 = edition.get_isbn10() or None
$asin = None
$if edition.get('identifiers'):
$if edition.identifiers.get('amazon'):
$asin = edition.identifiers.amazon[0]
$if isbn_10 and not asin:
$asin = isbn_10
$affiliate_links = macros.AffiliateLinksLoadingIndicator(edition.title, isbn_13, asin, prices)
```
--------------------------------
### Full Width Button
Source: https://github.com/internetarchive/openlibrary/blob/master/openlibrary/templates/design/button.html
Example of an ol-button configured to take up the full available width.
```html
Continue
```
--------------------------------
### Input for Place Subjects
Source: https://github.com/internetarchive/openlibrary/blob/master/openlibrary/templates/books/edit/about.html
Provides an input field for subjects related to places, with examples.
```html
$"Note any places mentioned?"
$: _('For example: _[London](/subjects/place:London), [Atlantis](/subjects/place:Atlantis), [Omaha](/subjects/place:Omaha)_')
$ config = {'name': 'subject_places', 'facet': 'place', 'data': work.subject_places if len(work.subject_places) else []}
$:render_subject_field(config['name'], config['data'])
```
--------------------------------
### Input for People Subjects
Source: https://github.com/internetarchive/openlibrary/blob/master/openlibrary/templates/books/edit/about.html
Provides an input field for subjects related to people, with examples.
```html
$"A person? Or, people?"
$: _('For example: _[Theodore Roosevelt](/subjects/person:Theodore_Roosevelt), [Julian of Norwich](/subjects/person:Julian_of_Norwich), [Tintin](/subjects/person:Tintin)_')
$ config = {'name': 'subject_people', 'facet': 'person', 'data': work.subject_people if len(work.subject_people) else []}
$:render_subject_field(config['name'], config['data'])
```
--------------------------------
### Run Phase 1 Scan on a Sample
Source: https://github.com/internetarchive/openlibrary/blob/master/docs/ai/tag-system/debugging.md
Test the scan phase with a small subset of the dump file to quickly diagnose formatting or parsing issues.
```bash
head -10000 dump.txt | python3 scripts/backfill_genre_tags.py scan --dump /dev/stdin
```
--------------------------------
### Input for Time Period Subjects
Source: https://github.com/internetarchive/openlibrary/blob/master/openlibrary/templates/books/edit/about.html
Provides an input field for subjects related to time periods, with examples.
```html
$"When is it set or about?"
$: _('For example: _[1984](/subjects/time:1984), [The Middle Ages](/subjects/time:the_middle_ages), [1810-1890](/subjects/time:1810-1890)_')
$ config = {'name': 'subject_times', 'facet': 'time', 'data': work.subject_times if len(work.subject_times) else []}
$:render_subject_field(config['name'], config['data'])
```
--------------------------------
### Build and Watch Lit Components
Source: https://github.com/internetarchive/openlibrary/blob/master/docs/ai/web-components.md
Use these commands for local development and building Lit components. 'npm run watch:lit-components' enables continuous development mode, while 'make lit-components' performs a one-off build.
```bash
npm run watch:lit-components # Dev mode
```
```bash
make lit-components # One-off build
```
--------------------------------
### Single Record Import Response
Source: https://github.com/internetarchive/openlibrary/blob/master/docs/ai/imports/api.md
Examples of successful and unsuccessful responses from the single-record import API endpoint.
```json
{"success": true, "edition": {"key": "/books/OL123M", "status": "created"}}
```
```json
{"success": false, "error_code": "missing-required-field", "error": "..."}
```
--------------------------------
### Test Affiliate API with Amazon
Source: https://github.com/internetarchive/openlibrary/wiki/developers/misc/coding-recipes
Initializes and tests the Amazon affiliate API by fetching product information. Requires API credentials and configuration.
```python
import web
import infogami
from openlibrary.config import load_config
load_config('/olsystem/etc/openlibrary.yml')
infogami._setup()
from infogami import config
from openlibrary.core.vendors import AmazonAPI
web.amazon_api = AmazonAPI(*[config.amazon_api.get('key'), config.amazon_api.get('secret'),config.amazon_api.get('id')], throttling=0.9)
book = web.amazon_api.get_products(["1666568287"], serialize=True)
```
--------------------------------
### Run Python Tests
Source: https://github.com/internetarchive/openlibrary/wiki/developers/tools/testing
Execute only Python tests for faster feedback on Python-only changes. Requires `pytest` to be installed.
```bash
docker compose run --rm home pytest
```
--------------------------------
### Run pyopds2_openlibrary Test Suite
Source: https://github.com/internetarchive/openlibrary/blob/master/docs/ai/opds/index.md
Execute the full test suite for pyopds2_openlibrary. This command should be run before every push to ensure code quality. It is expected to pass approximately 282 tests in about 40 seconds.
```bash
cd ~/Projects/pyopds2_openlibrary
# Full test suite before every push
python3 -m pytest tests/ -x -q
```
--------------------------------
### Define Fibonacci Function
Source: https://github.com/internetarchive/openlibrary/wiki/advanced/using-cache
A recursive implementation of the Fibonacci sequence. This function is computationally expensive and serves as an example for caching.
```python
def fibonacci(n):
return (
fibonacci(n - 1) + fibonacci(n - 2)
if n >= 1
else (1 if n > 0 else 0)
)
```
--------------------------------
### Example ONIX Product Entry
Source: https://github.com/internetarchive/openlibrary/wiki/advanced/processing-onix-feeds
This XML snippet demonstrates a complete ONIX product record, including details about identifiers, titles, authors, subjects, pricing, and publisher information. It is useful for understanding the structure and content of ONIX feeds.
```xml
019852081603Cambridge University Press02019852081603978019852081815978019852081802BCB102New Surveys in the Classics3401Roman Art1A01Peter StewartStewart, PeterPeterStewartCourtauld Institute of Art, London01engART0150602.2122.0ACG0122709/.3703N5760 .S66 200405040301http://assets.cambridge.org/97801985/20818/cover/9780198520818.jpg01Cambridge University Press codeOUPOxford University Press01Oxford University PressOxfordGB042004042201ROW03KP019.25in026.14in03.43in08.6lbCambridge University PressIP213001ACUPRP 02P0221.99GBPZ0.0021.990.00Z0.000.000.0001ACUPRP 02P0225.66EURCambridge University Press02C
```
--------------------------------
### Build Docker Images
Source: https://github.com/internetarchive/openlibrary/blob/master/docker/README.md
Run this command in the project root to build the Docker images for the project. The build may take a significant amount of time.
```sh
docker compose build
```
--------------------------------
### Enable Performance Profiling for URLs
Source: https://github.com/internetarchive/openlibrary/wiki/advanced/debugging-and-performance-profiling
Add `_profile=true` to a URL to include a profile report detailing front-end and back-end load times.
```text
http://localhost:8080/your-page?_profile=true
```