Skip to content

Commit fe77983

Browse files
authored
Merge pull request #252 from dfarrow0/dfarrow_dev
update dev guides
2 parents 3f1c7d2 + 3348e51 commit fe77983

File tree

2 files changed

+85
-10
lines changed

2 files changed

+85
-10
lines changed

docs/epidata_development.md

Lines changed: 82 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ nav_order: 4
66
# Epidata API Development Guide
77

88
**Prerequisite:** this guide assumes that you have read the
9-
[frontend development guide](https://github.com/cmu-delphi/operations/blob/master/docs/frontend_development.md).
9+
[frontend development guide](https://github.com/cmu-delphi/operations/blob/main/docs/frontend_development.md).
1010

1111
This guide describes how to write and test code for the Epidata API. For
1212
preliminary steps,
13-
[install docker and create a virtual network](https://github.com/cmu-delphi/operations/blob/master/docs/frontend_development.md#setup).
13+
[install docker and create a virtual network](https://github.com/cmu-delphi/operations/blob/main/docs/frontend_development.md#setup).
1414

1515
After reading this guide, you may want to visit
1616
[the `fluview_meta` tutorial](new_endpoint_tutorial.md) for an example of how
@@ -28,7 +28,7 @@ You likely won't need to modify the `operations` repo, so cloning directly from
2828
`cmu-delphi` is usually sufficient. However, since you _are_ going to be
2929
modifying `delphi-epidata` sources, you'll first need to fork the repository
3030
and then clone your personal fork. For more details, see the Delphi-specific
31-
[discussion on forking and branching](https://github.com/cmu-delphi/operations/blob/master/docs/backend_development.md#everyone).
31+
[discussion on forking and branching](https://github.com/cmu-delphi/operations/blob/main/docs/backend_development.md#everyone).
3232

3333
Here's an example of how to setup your local workspace. Note that you will need
3434
to use your own GitHub username where indicated.
@@ -124,9 +124,9 @@ docker run --rm -p 127.0.0.1:10080:80 \
124124
Unit tests are self-contained, and do not depend on external services like
125125
databases or web servers. You can run unit tests at any time according to the
126126
instructions in the
127-
[backend development guide](https://github.com/cmu-delphi/operations/blob/master/docs/backend_development.md).
127+
[backend development guide](https://github.com/cmu-delphi/operations/blob/main/docs/backend_development.md).
128128

129-
First, [build the `delphi_python` image](https://github.com/cmu-delphi/operations/blob/master/docs/backend_development.md#creating-an-image).
129+
First, [build the `delphi_python` image](https://github.com/cmu-delphi/operations/blob/main/docs/backend_development.md#creating-an-image).
130130
Your test sources will live in, and be executed from within, this image.
131131

132132
Then run the tests in a container based on that image:
@@ -242,7 +242,7 @@ point for additional tests. For example, see the tests for the
242242

243243
To run the existing tests and any new tests that you write, you must
244244
follow the
245-
[backend development guide](https://github.com/cmu-delphi/operations/blob/master/docs/backend_development.md)
245+
[backend development guide](https://github.com/cmu-delphi/operations/blob/main/docs/backend_development.md)
246246
_within the same workspace_, so that the `delphi_python` image is created with
247247
any changes you have made (e.g. adding new integration tests). That image will
248248
contain the test driver and the source code of your integration tests. Then,
@@ -259,7 +259,7 @@ More concretely, you can run Epidata API integration tests like this:
259259
above.
260260

261261
3. Build the `delphi_python` image per the
262-
[backend development guide](https://github.com/cmu-delphi/operations/blob/master/docs/backend_development.md#creating-an-image).
262+
[backend development guide](https://github.com/cmu-delphi/operations/blob/main/docs/backend_development.md#creating-an-image).
263263
Your test sources will live in, and be executed from within, this image.
264264

265265
4. Run integration tests in a container based on the `delphi_python` image:
@@ -285,3 +285,78 @@ More concretely, you can run Epidata API integration tests like this:
285285
```
286286

287287
5. Bring down the servers, for example with the `docker stop` command.
288+
289+
# rapid iteration
290+
291+
The workflow described above requires containers to be stopped, rebuilt, and
292+
restarted each time code (including tests) is changed, which can be tedious. To
293+
reduce friction, it's possible to
294+
[bind-mount](https://docs.docker.com/storage/bind-mounts/) your local source
295+
files into a container, which replace the corresponding files from the image.
296+
This allows your code changes to be reflected immediately, without needing to
297+
rebuild containers.
298+
299+
There are some drawbacks however, as discussed in the
300+
[Epicast development guide](https://github.com/cmu-delphi/www-epicast/blob/main/docs/epicast_development.md#develop).
301+
For example:
302+
303+
- Code running in the container is able to read (and possibly also write) your local filesystem.
304+
- The command line specification of bind-mounts is quite tedious.
305+
- Bind mounts do not interact well with `selinux` on some systems, leading to
306+
various access denials at runtime. As a workaround, you may have to use the
307+
[dangerous "Z" flag](https://docs.docker.com/storage/bind-mounts/#configure-the-selinux-label),
308+
or temporarily disable `selinux` -- neither of which is advised.
309+
310+
## bind-mounting
311+
312+
### non-server code
313+
314+
Python sources (e.g. data acquisition, API clients, and tests), can be
315+
bind-mounted into a `delphi_python` container as follows:
316+
317+
```bash
318+
docker run --rm --network delphi-net \
319+
--mount type=bind,source="$(pwd)"/repos/delphi/delphi-epidata,target=/usr/src/app/repos/delphi/delphi-epidata,readonly \
320+
--mount type=bind,source="$(pwd)"/repos/delphi/delphi-epidata/src,target=/usr/src/app/delphi/epidata,readonly \
321+
delphi_python \
322+
python3 -m undefx.py3tester.py3tester --color \
323+
repos/delphi/delphi-epidata/integrations
324+
```
325+
326+
The command above maps two local directories into the container:
327+
328+
- `/repos/delphi/delphi-epidata`: The entire repo, notably including unit and
329+
integration test sources.
330+
- `/repos/delphi/delphi-epidata/src`: Just the source code, which forms the
331+
container's `delphi.epidata` python package.
332+
333+
### server code
334+
335+
Local web sources (e.g. PHP files) can be bind-mounted into a
336+
`delphi_web_epidata` container as follows:
337+
338+
```bash
339+
docker run --rm -p 127.0.0.1:10080:80 \
340+
--mount type=bind,source="$(pwd)"/repos/delphi/delphi-epidata/src/server/api.php,target=/var/www/html/epidata/api.php,readonly \
341+
--mount type=bind,source="$(pwd)"/repos/delphi/delphi-epidata/src/server/api_helpers.php,target=/var/www/html/epidata/api_helpers.php,readonly \
342+
--network delphi-net --name delphi_web_epidata \
343+
delphi_web_epidata
344+
```
345+
346+
The command above mounts two specific files into the image. It may be tempting
347+
to bind mount the `src/server` directory rather than specific files, however
348+
that is currently problematic for a couple of reasons:
349+
350+
1. `server/.htaccess` [from the local repository](../src/server/.htaccess) uses
351+
the `Header` directive, however the web server in the container doesn't have
352+
the corresponding module enabled. This causes the server to deny access to
353+
the API.
354+
2. `server/database_config.php`
355+
[in the image](../dev/docker/web/epidata/assets/database_config.php) contains
356+
database credentials for use in conjunction with the
357+
`delphi_database_epidata` container during development. However, the same
358+
file from [the local repository](../src/server/database_config.php) only
359+
contains placeholder values. This prevents communication with the database.
360+
361+
There is currently no benefit to bind-mounting sources into the database
362+
container because schema changes require restarting the container anyway.

docs/new_endpoint_tutorial.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ In this tutorial we'll create a brand new endpoint for the Epidata API:
2121
# setup
2222

2323
Follow
24-
[the backend guide](https://github.com/cmu-delphi/operations/blob/master/docs/backend_development.md)
24+
[the backend guide](https://github.com/cmu-delphi/operations/blob/main/docs/backend_development.md)
2525
and [the epidata guide](epidata_development.md) to install Docker and get your
2626
workspace ready for development. Before continuing, your workspace should look
2727
something like the following:
@@ -174,7 +174,7 @@ Now that we've changed several files, we need to make sure that the changes
174174
work as intended _before_ submitting code for review or committing code to the
175175
repository. Given that the code spans multiple components and languages, this
176176
needs to be an integration test. See more about integration testing in Delphi's
177-
[frontend development guide](https://github.com/cmu-delphi/operations/blob/master/docs/frontend_development.md#integration).
177+
[frontend development guide](https://github.com/cmu-delphi/operations/blob/main/docs/frontend_development.md#integration).
178178
179179
Create an integration test for the new endpoint by creating a new file
180180
`integrations/server/test_fluview_meta.py`. There's a good amount of
@@ -245,7 +245,7 @@ the following row in the appropriate place (i.e. next to the row for
245245
Finally, we just need to run all new and existing tests. It is recommended to
246246
start with the unit tests because they are faster to build, run, and either
247247
succeed or fail. Follow the
248-
[backend development guide](https://github.com/cmu-delphi/operations/blob/master/docs/backend_development.md#running-a-container).
248+
[backend development guide](https://github.com/cmu-delphi/operations/blob/main/docs/backend_development.md#running-a-container).
249249
In summary:
250250

251251
```bash

0 commit comments

Comments
 (0)