Skip to content
David Foster edited this page Mar 31, 2023 · 11 revisions

Crystal can be launched with an interactive Python shell. This allows you to perform advanced manipulations on a project manually, and to manipulate projects with automated scripts.

Tell Crystal to open a shell by passing the --shell CLI option:

$ crystal --shell
Crystal 1.5.0b (Python 3.8.10)
Type "help" for more information.
Variables "project" and "window" are available.
Use exit() or Ctrl-D (i.e. EOF) to exit.
>>> 

After a project is opened, you can manipulate it in the shell:

>>> project
<crystal.model.Project object at 0x115a61bb0>
>>> help(project)  # display interactive help

>>> list(project.root_resources)
[RootResource('Home Page','https://xkcd.com/')]

>>> list(project.resource_groups)
[ResourceGroup('Comic','https://xkcd.com/#/')]

>>> len(project.resources)
16313
>>> list(project.resources)[0]
Resource('https://xkcd.com/')

>>> first_comic = project.get_resource('https://xkcd.com/1/')
>>> first_comic
Resource('https://xkcd.com/1/')

>>> first_comic.revisions()
[<ResourceRevision 14 for 'https://xkcd.com/1/'>]
>>> first_comic.default_revision()
<ResourceRevision 14 for 'https://xkcd.com/1/'>

>>> project.get_resource('https://xkcd.com/99/')
>>> # not in project
>>> from crystal.model import Resource
>>> some_comic = Resource(project, 'https://xkcd.com/99/')
>>> some_comic
Resource('https://xkcd.com/99/')

>>> some_comic.revisions()
[]
>>> some_comic.default_revision()
>>> # no default revision
>>> revision_future = some_comic.download()
>>> revision = revision_future.result()  # keep result() separate from download(); will deadlock otherwise
>>> revision
<ResourceRevision 18 for 'https://xkcd.com/99/'>
>>> import pprint
>>> pprint.pprint(revision.metadata)
{'headers': [['Connection', 'keep-alive'],
             ['Content-Length', '8297'],
             ['Server', 'nginx'],
             ['Content-Type', 'text/html; charset=UTF-8'],
             ['Last-Modified', 'Sat, 16 Jul 2022 01:52:42 GMT'],
             ['ETag', '"62d219ea-2069"'],
             ['Expires', 'Mon, 18 Jul 2022 15:18:54 GMT'],
             ['Cache-Control', 'max-age=300'],
             ['Via', '1.1 varnish, 1.1 varnish'],
             ['Accept-Ranges', 'bytes'],
             ['Date', 'Mon, 18 Jul 2022 15:13:54 GMT'],
             ['Age', '0'],
             ['X-Served-By', 'cache-dfw18663-DFW, cache-bfi-krnt7300049-BFI'],
             ['X-Cache', 'MISS, MISS'],
             ['X-Cache-Hits', '0, 0'],
             ['X-Timer', 'S1658157234.020196,VS0,VE58'],
             ['Vary', 'Accept-Encoding']],
 'http_version': 11,
 'reason_phrase': 'OK',
 'status_code': 200}
>>> with revision.open() as f:
...     body = f.read()
>>> body[:141]
b'<!DOCTYPE html>\n<html>\n<head>\n<link rel="stylesheet" type="text/css" href="/s/7d94e0.css" title="Default"/>\n<title>xkcd: Binary Heart</title>'

When you're done, exit the shell by pressing Ctrl-D (on macOS and Linux), Ctrl-Z and Return (on Windows), or by running the exit() command:

>>> ^D
now waiting for main window to close...

There is no officially supported API on the shell at the moment. If you want to write automated scripts that run in the shell, avoid using methods/attributes whose name starts with an underscore (_) because those methods/attributes are private or unstable.

Clone this wiki locally