Deploying projects and dependencies
Deploying projects
To deploy a Scrapy project to Scrapy Cloud, navigate into the project’s folder and run:
shub deploy [TARGET]
where [TARGET] is either a project name defined in scrapinghub.yml or a
numerical Scrapinghub project ID. If you have configured a default target in
your scrapinghub.yml, you can leave out the parameter completely:
$ shub deploy
Packing version 3af023e-master
Deploying to Scrapy Cloud project "12345"
{"status": "ok", "project": 12345, "version": "3af023e-master", "spiders": 1}
Run your spiders at: https://app.zyte.com/p/12345/
You can also build your project’s Python egg without deploying it, and deploy your project from an existing egg:
$ shub build-egg egg_name
Writing egg to egg_name
$ shub deploy --egg egg_name --version 1.0.0
Using egg: egg_name
Deploying to Scrapy Cloud project "12345"
{"status": "ok", "project": 12345, "version": "1.0.0", "spiders": 1}
Run your spiders at: https://app.zyte.com/p/12345/
shub build-egg builds the egg of your project only. It does not build or
deploy the libraries your project depends on, see Deploying dependencies
for that. Unlike shub deploy, it does not need a target or an API key,
because it does not talk to Scrapy Cloud.
If your project is inside a git repository, the egg is built from a copy of
the working directory that leaves out anything git considers ignored (e.g.
via .gitignore), so build artifacts, local secrets, and stray
virtualenvs don’t end up in the deploy. Uncommitted changes to tracked
files, and new untracked files that aren’t gitignored, are still included.
Projects that aren’t inside a git repository deploy the working directory
as-is, unchanged from before.
To deploy only the files committed to git HEAD, leaving out uncommitted
changes and untracked files, use --from-head:
shub deploy --from-head
Deploying dependencies
Sometimes your project will depend on third party libraries that are not available on Scrapy Cloud. You can easily upload these by specifying a requirements file:
# project_directory/scrapinghub.yml
projects:
default: 12345
prod: 33333
requirements:
file: requirements.txt
Your requirements file should also include the packages of your Scrapy Cloud
stack, pinned to their stack versions, and freeze all indirect dependencies,
e.g. compiled with pip-tools from a requirements.in file that lists
your stack packages and your additional packages. That way, your additional
packages get versions compatible with those of your stack packages. See
SCP24: Missing stack requirements and SCP13: Incomplete requirements freeze.
In case you use pipenv you may also specify a Pipfile:
# project_directory/scrapinghub.yml
projects:
default: 12345
prod: 33333
requirements:
file: Pipfile
In this case the Pipfile must be locked and pipenv available in the
environment.
Note
To install pipenv tool, use pip install pipenv or check its documentation.
A requirements.txt file will be created out of the Pipfile, so like the
requirements file above, it should include the packages of your stack.
If you use Poetry you can specify your pyproject.toml:
# project_directory/scrapinghub.yml
projects:
default: 12345
prod: 33333
requirements:
file: pyproject.toml
This will use Poetry’s export command to create a requirements.txt file. For
Poetry >= 2.0 this command is no longer installed by default and needs to manually
added as described in the
plugin’s documentation.
If poetry.lock does not exist yet, it will be created during this process.
Note
Poetry is a tool for dependency management and packaging in Python.
If you declare your dependencies in setup.py (install_requires) or
in the [project] table of a pyproject.toml file without a
[tool.poetry] table (dependencies), you can specify that file instead:
Added in version VERSION.
scrapinghub.ymlrequirements:
file: setup.py
Those dependencies are not frozen, so prefer a requirements file as described above.
When your dependencies cannot be specified in a requirements file, e.g. because they are not publicly available, you can supply them as Python eggs:
# project_directory/scrapinghub.yml
projects:
default: 12345
prod: 33333
requirements:
file: requirements.txt
eggs:
- privatelib.egg
- path/to/otherlib.egg
Alternatively, if you cannot or don’t want to supply Python eggs, you can also build your own Docker image to be used on Scrapy Cloud. See Deploying custom Docker images.
Choosing a Scrapy Cloud stack
You can specify the Scrapy Cloud stack to deploy your spider to by adding a
stack entry to your configuration:
# project_directory/scrapinghub.yml
projects:
default: 12345
stack: scrapy:1.3-py3
It is also possible to define the stack per project for advanced use cases:
# project_directory/scrapinghub.yml
projects:
default:
id: 12345
stack: scrapy:1.3-py3
prod: 33333 # will use Scrapinghub's default stack
Run shub list-stacks to see the available stacks.
Projects without a configured stack use Scrapy Cloud’s default stack, which
can be much older than the latest one. That is why, when shub deploy
creates a new scrapinghub.yml for a project that does not use a
custom Docker image, it sets stack to the
latest Scrapy stack released in the scrapinghub-stack-scrapy repository,
unless a default stack is already configured, e.g. in ~/.scrapinghub.yml.
The stack is frozen to its release date, e.g. scrapy:2.18-20261026, so that
your deploys keep using the same environment until you change it. If the list
of stacks cannot be fetched, e.g. while offline, the latest stack at the time
your version of shub was released is used instead. shub never adds a stack to
an existing scrapinghub.yml.