Skip to content

Commit a96e6d1

Browse files
[CIVIS-7617] ENH first release (#1)
* ENH first release * DOC note about private github repo * ENH demo app to be in this repo * ENH update demo app * DEP refresh demo app requirements * FIX check if api key is available for local test app * MAINT update changelog * address code review feedback * MAINT update changelog * ENH simplify demo app set-up
1 parent b65b9a6 commit a96e6d1

15 files changed

+451
-1
lines changed

.circleci/config.yml

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
version: 2.1
2+
3+
jobs:
4+
build:
5+
docker:
6+
# The Python version of this CircleCI image doesn't matter too much,
7+
# because we're going to build our image from our own Dockerfile
8+
# and run everything inside this image.
9+
- image: cimg/python:3.12
10+
steps:
11+
- checkout
12+
- setup_remote_docker
13+
- run:
14+
name: Build image
15+
command: docker build --target test -t testimage .
16+
- run:
17+
name: Check that the demo app can run inside the image
18+
command: docker run testimage /app/demo_app/test_demo_app_on_ci.sh
19+
20+
workflows:
21+
build-and-test:
22+
jobs:
23+
- build

.github/pull_request_template.md

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
2+
3+
---
4+
5+
**Note:** This GitHub repo is public.
6+
7+
- [ ] (For Civis employees) Reference to an internal ticket number (in the form of `[CIVIS-xxxx]`) in the pull request title.
8+
- [ ] Changelog entry added to `CHANGELOG.md` at the repo's root level.
9+
- [ ] Description of change in the PR description.
10+
- [ ] The CircleCI builds have passed.

CHANGELOG.md

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7+
8+
## [Unreleased]
9+
10+
### Added
11+
### Changed
12+
### Deprecated
13+
### Removed
14+
### Fixed
15+
### Security
16+
17+
## [1.0.0] - 2024-05-23
18+
19+
First release!

CODE_OF_CONDUCT.md

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Contributor Code of Conduct
2+
3+
As contributors and maintainers of this project, and in the interest of
4+
fostering an open and welcoming community, we pledge to respect all people who
5+
contribute through reporting issues, posting feature requests, updating
6+
documentation, submitting pull requests or patches, and other activities.
7+
8+
We are committed to making participation in this project a harassment-free
9+
experience for everyone, regardless of level of experience, gender, gender
10+
identity and expression, sexual orientation, disability, personal appearance,
11+
body size, race, ethnicity, age, religion, or nationality.
12+
13+
Examples of unacceptable behavior by participants include:
14+
15+
* The use of sexualized language or imagery
16+
* Personal attacks
17+
* Trolling or insulting/derogatory comments
18+
* Public or private harassment
19+
* Publishing other's private information, such as physical or electronic
20+
addresses, without explicit permission
21+
* Other unethical or unprofessional conduct
22+
23+
Project maintainers have the right and responsibility to remove, edit, or
24+
reject comments, commits, code, wiki edits, issues, and other contributions
25+
that are not aligned to this Code of Conduct, or to ban temporarily or
26+
permanently any contributor for other behaviors that they deem inappropriate,
27+
threatening, offensive, or harmful.
28+
29+
By adopting this Code of Conduct, project maintainers commit themselves to
30+
fairly and consistently applying these principles to every aspect of managing
31+
this project. Project maintainers who do not follow or enforce the Code of
32+
Conduct may be permanently removed from the project team.
33+
34+
This Code of Conduct applies both within project spaces and in public spaces
35+
when an individual is representing the project or its community.
36+
37+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
38+
reported by contacting a project maintainer at [email protected].
39+
All complaints will be reviewed and investigated and will result in a response
40+
that is deemed necessary and appropriate to the circumstances. Maintainers are
41+
obligated to maintain confidentiality with regard to the reporter of an
42+
incident.
43+
44+
45+
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
46+
version 1.3.0, available at
47+
[http://contributor-covenant.org/version/1/3/0/][version]
48+
49+
[homepage]: http://contributor-covenant.org
50+
[version]: http://contributor-covenant.org/version/1/3/0/

Dockerfile

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
FROM --platform=linux/x86_64 python:3.12.3-slim AS base
2+
3+
4+
# Supress pip user warnings:
5+
# https://stackoverflow.com/a/72551258
6+
ENV PIP_ROOT_USER_ACTION=ignore
7+
8+
RUN apt-get update && apt-get install -y \
9+
git \
10+
&& rm -rf /var/lib/apt/lists/*
11+
12+
WORKDIR /app
13+
14+
# Environmental variables that must be set when deploying
15+
# the Streamlit service on Civis Platform.
16+
# For all Streamlit config options:
17+
# https://docs.streamlit.io/develop/api-reference/configuration/config.toml
18+
ENV STREAMLIT_CLIENT_SHOW_ERROR_DETAILS=false \
19+
STREAMLIT_SERVER_PORT=3838 \
20+
STREAMLIT_BROWSER_GATHER_USAGE_STATS=false
21+
22+
# Suppress the "Welcome to Streamlit" message at startup asking for an email address:
23+
# https://discuss.streamlit.io/t/streamlit-showing-me-welcome-to-streamlit-message-when-executing-it-with-docker/26168/2
24+
RUN mkdir -p ~/.streamlit/ && \
25+
echo "[general]\nemail = \"\"" > ~/.streamlit/credentials.toml
26+
27+
FROM base AS production
28+
COPY ./entrypoint.sh /
29+
ENTRYPOINT ["/entrypoint.sh"]
30+
31+
FROM base AS test
32+
COPY ./demo_app/ /app/demo_app/
33+
34+
# Defaults to production as the final stage
35+
FROM production

LICENSE.txt

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
Copyright (c) 2024, Civis Analytics
2+
All rights reserved.
3+
4+
Redistribution and use in source and binary forms, with or without
5+
modification, are permitted provided that the following conditions are met:
6+
7+
1. Redistributions of source code must retain the above copyright notice, this
8+
list of conditions and the following disclaimer.
9+
10+
2. Redistributions in binary form must reproduce the above copyright notice,
11+
this list of conditions and the following disclaimer in the documentation
12+
and/or other materials provided with the distribution.
13+
14+
3. Neither the name of the copyright holder nor the names of its contributors
15+
may be used to endorse or promote products derived from this software
16+
without specific prior written permission.
17+
18+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

README.md

+102-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,103 @@
11
# civis-services-streamlit
2-
Civis Services Docker Image for Streamlit
2+
3+
This repository provides the following components:
4+
5+
* A Docker image to support Streamlit applications on Civis Platform
6+
* A demo Streamlit app that's readily deployable on Civis Platform
7+
8+
## Quickstart Using the Demo Application
9+
10+
To get a sense of what a Streamlit app looks like on Civis Platform:
11+
12+
* Log on to Civis Platform.
13+
* From the top navigation bar, click "Publish".
14+
* Under "Services", click "Streamlit Demo".
15+
16+
These steps create a new Civis Platform service configured for a Streamlit demo app
17+
pointing to this GitHub repository.
18+
The app is now ready to be deployed.
19+
Please follow [these instructions](https://support.civisanalytics.com/hc/en-us/articles/360001335031-Civis-Service-Deployment#StartaService/PreviewaDeployment)
20+
for service deployment.
21+
22+
If you would like to start making the demo app your own
23+
by making code changes,
24+
you may [fork this GitHub repository](https://github.com/civisanalytics/civis-services-streamlit/fork)
25+
where the demo app's source code is in the directory [`demo_app/`](demo_app).
26+
If you would like to host and use your own Docker image,
27+
[`Dockerfile`](Dockerfile) and [`entrypoint.sh`](entrypoint.sh) from this GitHub repository
28+
define the `civisanalytics/civis-services-streamlit` image that you may like to modify
29+
and then host on your own DockerHub account.
30+
31+
## Building and Deploying Your Streamlit Application
32+
33+
If you would like to build your own Streamlit application from scratch
34+
and deploy it on Civis Platform,
35+
here are the requirements.
36+
37+
1. Your Streamlit application must have its source code hosted on a GitHub repository.
38+
The Civis Platform user account that's going to deploy this Streamlit app must have
39+
access to this GitHub repo.
40+
2. The following explains the expected files for your app:
41+
42+
* `app.py`
43+
44+
A required file.
45+
`app.py` is your Streamlit app's entry point.
46+
For which Python version you should use (e.g., Python 3.12),
47+
it is determined by which Docker image name and tag you're going to use
48+
to deploy your app on Civis Platform.
49+
The Python version is specified by the base image in the file `Dockerfile`
50+
of this GitHub repo.
51+
52+
* `requirements.txt`
53+
54+
A strongly recommended file, though not strictly required.
55+
`requirements.txt` specifies the Python dependencies to be installed for your Streamlit app to work.
56+
Note that `streamlit` itself should be one of the packages specified
57+
(so that you can pin the specific Streamlit version for your use case).
58+
If `requirements.txt` is present,
59+
the command `pip install -r requirements.txt` will be run to install these dependencies.
60+
61+
* `pyproject.toml`
62+
63+
An optional file.
64+
If a Python package needs to be installed in order for your Streamlit app to work,
65+
`pyproject.toml` plus the associated package code must be present.
66+
If `pyproject.toml` is detected,
67+
`pip install --no-deps -e .` will be run to install your Python package
68+
(`--no-deps` for not installing dependencies defined in `pyproject.toml`,
69+
because they should already be specified in `requirements.txt` above).
70+
71+
* `.streamlit/config.toml`
72+
73+
An optional file.
74+
These are Streamlit options, if you need to configure them. Reference:
75+
https://docs.streamlit.io/develop/api-reference/configuration/config.toml
76+
77+
3. Once your app code is on a GitHub repo, either create a new service on Civis Platform
78+
by following [this page](https://support.civisanalytics.com/hc/en-us/articles/360001335031-Civis-Service-Deployment),
79+
or launch a Streamlit template service from Civis Platform's top navigation bar -> Publish
80+
-> Services -> Streamlit Demo.
81+
Specify or adjust the GitHub repo URL as well as the Git tag (or branch, or Git commit hash).
82+
4. If your code is at a directory in your repo (rather than directly at the root level of your repo),
83+
specify the directory path that points to where the app code is located.
84+
(For the demo app in the previous section above, the directory path would be `demo_app` from this current repo.)
85+
5. For the Docker image, the name is `civisanalytics/civis-services-streamlit`,
86+
and the tag is one of those [listed on DockerHub](https://hub.docker.com/repository/docker/civisanalytics/civis-services-streamlit/tags).
87+
Note that the specific Docker image name and tag you've chosen determines which Python version
88+
your app is going to run on.
89+
90+
## Support
91+
92+
For feature inquiries, bug reports, and other questions,
93+
Civis client users should reach out to [email protected].
94+
95+
## Changelog
96+
97+
See [CHANGELOG.md](CHANGELOG.md).
98+
99+
## License
100+
101+
BSD-3
102+
103+
See [LICENSE.txt](LICENSE.txt).

buildspec/merge_main.yaml

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
version: 0.2
2+
phases:
3+
pre_build:
4+
commands:
5+
- echo Logging in to Amazon ECR...
6+
- aws ecr get-login-password --region ${AWS_DEFAULT_REGION} | docker login --username AWS --password-stdin ${FIPS_REPOSITORY_URI}
7+
build:
8+
commands:
9+
- echo Building the Docker image...
10+
- docker build -t ${FIPS_REPOSITORY_URI}:latest .
11+
- docker push ${FIPS_REPOSITORY_URI}
12+
post_build:
13+
commands:
14+
- echo Build completed!

buildspec/push.yaml

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
version: 0.2
2+
phases:
3+
pre_build:
4+
commands:
5+
- echo Logging in to Amazon ECR...
6+
- aws ecr get-login-password --region ${AWS_DEFAULT_REGION} | docker login --username AWS --password-stdin ${FIPS_REPOSITORY_URI}
7+
- export COMMIT_HASH_SHORT="$(echo $COMMIT_HASH | cut -c 1-7)"
8+
build:
9+
commands:
10+
- echo Building the Docker image...
11+
- docker build --tag ${FIPS_REPOSITORY_URI}:${COMMIT_HASH_SHORT} --tag ${FIPS_REPOSITORY_URI}:${BRANCH_NAME} .
12+
- docker push ${FIPS_REPOSITORY_URI}:${COMMIT_HASH_SHORT}
13+
- docker push ${FIPS_REPOSITORY_URI}:${BRANCH_NAME}
14+
post_build:
15+
commands:
16+
- echo Build completed!
17+
- printf '{"tag":"%s"}' $COMMIT_HASH_SHORT > build.json

buildspec/release.yaml

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
version: 0.2
2+
phases:
3+
pre_build:
4+
commands:
5+
- echo Logging in to Amazon ECR...
6+
- aws ecr get-login-password --region ${AWS_DEFAULT_REGION} | docker login --username AWS --password-stdin ${FIPS_REPOSITORY_URI}
7+
build:
8+
commands:
9+
- echo Building the Docker image...
10+
- PATCH_TAG=${TAG_NAME#"v"} # major.minor.patch
11+
- MINOR_TAG=${PATCH_TAG%.*} # major.minor
12+
- MAJOR_TAG=${MINOR_TAG%.*} # major
13+
- docker build -t ${FIPS_REPOSITORY_URI}:${PATCH_TAG} -t ${FIPS_REPOSITORY_URI}:${MINOR_TAG} -t ${FIPS_REPOSITORY_URI}:${MAJOR_TAG} .
14+
- docker push ${FIPS_REPOSITORY_URI}
15+
post_build:
16+
commands:
17+
- echo Build completed!
18+
- printf '{"tag":"%s"}' $TAG_NAME > build.json

demo_app/README.md

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
## Python dependency management
2+
3+
We strongly recommend pinning the exact package versions
4+
(i.e., using double-equals `==`) in `requirements.txt`.
5+
6+
For stability in production, especially if you have more complicated requirements,
7+
we recommend pinning the exact versions of both the dependencies
8+
your code imports and their transitive dependencies.
9+
For this purpose, we recommend [pip-tools](https://pip-tools.readthedocs.io/en/latest/)
10+
to generate `requirements.txt`.
11+
12+
## Running the demo app locally
13+
14+
```shell
15+
pip install -r requirements.txt
16+
streamlit run app.py
17+
```

0 commit comments

Comments
 (0)