Skip to content

Commit b3a5291

Browse files
committed
Merge branch 'dev' into 1088-api-tests-for-token-verification-request-accuracy-response-parsing-and-error-handling
2 parents 0085df7 + 9ffb37c commit b3a5291

File tree

135 files changed

+16280
-1128
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

135 files changed

+16280
-1128
lines changed

.dockerignore

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,13 @@
77
.pre-commit-config.yaml
88
.readthedocs.yml
99
.travis.yml
10-
venv
1110
.git
11+
12+
# ignore local python environments
13+
venv
14+
.venv
15+
16+
# prevent large backup files from being copied into the image
17+
/backups
18+
*.sql
19+
*.gz
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: Django Test Suite on PR
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- dev
7+
8+
jobs:
9+
run-tests:
10+
runs-on: ubuntu-latest
11+
12+
services:
13+
docker:
14+
image: docker:24.0.5
15+
options: --privileged
16+
ports:
17+
- 5432:5432
18+
19+
steps:
20+
- name: Check out merged code
21+
uses: actions/checkout@v2
22+
23+
- name: Set up Docker Compose
24+
run: |
25+
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
26+
sudo chmod +x /usr/local/bin/docker-compose
27+
28+
- name: Build the Docker environment
29+
run: docker-compose -f local.yml build
30+
31+
- name: Run test suite
32+
env:
33+
DJANGO_ENV: test
34+
run: docker-compose -f local.yml run --rm django bash ./init.sh
35+
36+
- name: Cleanup
37+
run: docker-compose -f local.yml down --volumes

.gitignore

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -292,8 +292,7 @@ config_generation/config.py
292292
# Model's inference files
293293
Document_Classifier_inference/model.pt
294294

295-
# Database backup
296-
backup.json
297-
298-
# Prod backup
299-
prod_backup-20240423.json
295+
# Ignore Database Backup files
296+
/backups
297+
*.sql
298+
*.gz

.pre-commit-config.yaml

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ repos:
88
- id: trailing-whitespace
99
- id: end-of-file-fixer
1010
- id: check-yaml
11+
- id: check-merge-conflict
12+
- id: debug-statements
1113

1214
- repo: https://github.com/asottile/pyupgrade
1315
rev: v3.17.0
@@ -37,14 +39,41 @@ repos:
3739
hooks:
3840
- id: mypy
3941
args: ["--strict"]
40-
# ignoring everything for now
41-
exclude: .
42-
additional_dependencies: [django-stubs, celery, django-environ, django-extensions, django-crispy-forms,
43-
crispy-bootstrap5, django-allauth, django-celery-beat, djangorestframework, djangorestframework-datatables,
44-
django-debug-toolbar, psycopg2-binary, python-slugify, xmltodict, PyGithub, boto3, scrapy, types-requests]
42+
exclude: "."
43+
additional_dependencies:
44+
- django-stubs
45+
- celery
46+
- django-environ
47+
- django-extensions
48+
- django-crispy-forms
49+
- crispy-bootstrap5
50+
- django-allauth
51+
- django-celery-beat
52+
- djangorestframework
53+
- djangorestframework-datatables
54+
- django-debug-toolbar
55+
- psycopg2-binary
56+
- python-slugify
57+
- xmltodict
58+
- PyGithub
59+
- boto3
60+
- scrapy
61+
- types-requests
62+
63+
- repo: https://github.com/PyCQA/bandit
64+
rev: '1.7.0'
65+
hooks:
66+
- id: bandit
67+
args: ['-r', '--configfile=bandit-config.yml']
68+
69+
- repo: https://github.com/zricethezav/gitleaks
70+
rev: 'v8.0.4'
71+
hooks:
72+
- id: gitleaks
73+
args: ['--config=gitleaks-config.toml']
74+
4575

4676

47-
# sets up .pre-commit-ci.yaml to ensure pre-commit dependencies stay up to date
4877
ci:
4978
autoupdate_schedule: weekly
5079
skip: []

CODE_STANDARDS.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Coding Standards and Conventions for COSMOS
2+
3+
## Overview
4+
To maintain high-quality code and ensure consistency across the entire COSMOS project, we have established coding standards and conventions. This document outlines the key standards and practices that all contributors are expected to follow. Adhering to these guidelines helps us to achieve a codebase that appears as if it were written by a single entity, regardless of the number of contributors.
5+
6+
## Coding Standards
7+
8+
### Formatting Standards
9+
- **Line Length**: Maximum of 120 characters per line to ensure readability across various environments.
10+
- **Code Formatting**: Utilize tools like Black for Python code to ensure consistent formatting across the entire codebase.
11+
- **Import Ordering**: Follow a consistent import order:
12+
- Standard library imports.
13+
- Third-party imports.
14+
- Application-specific imports.
15+
16+
### Naming Conventions
17+
- **Variables and Functions**: Use `snake_case`.
18+
- **Classes and Exceptions**: Use `CamelCase`.
19+
- **Constants**: Use `UPPER_CASE`.
20+
21+
### Commenting
22+
- Inline comments should be used sparingly and only when necessary to explain "why" something is done, not "what" is done.
23+
- All public methods, classes, and modules should include docstrings that follow the [Google style guide](https://google.github.io/styleguide/pyguide.html).
24+
25+
### Error Handling
26+
- Explicit is better than implicit. Raise exceptions rather than returning None or any error codes.
27+
- Use custom exceptions over generic exceptions when possible to make error handling more predictive.
28+
29+
## Tool Configurations and Pre-commit Hooks
30+
31+
To automate and enforce these standards, the following tools are configured with pre-commit hooks in our development process:
32+
33+
### Pre-commit Hooks Setup
34+
35+
To ensure that these tools are run automatically on every commit, contributors must set up pre-commit hooks locally. Run the following commands to install and configure pre-commit hooks:
36+
37+
```bash
38+
pip install pre-commit
39+
pre-commit install
40+
pre-commit run --all-files
41+
```
42+
43+
The following pre-commit hooks are configured:
44+
45+
- trailing-whitespace, end-of-file-fixer, check-yaml, check-merge-conflict, debug-statements: Checks for common formatting issues.
46+
- pyupgrade: Automatically upgrades syntax for newer versions of the language.
47+
- black: Formats Python code to ensure consistent styling.
48+
- isort: Sorts imports alphabetically and automatically separated into sections.
49+
- flake8: Lints code to catch styling errors and potential bugs.
50+
- mypy: Checks type annotations to catch potential bugs.
51+
- bandit: Scans code for common security issues.
52+
- gitleaks: Prevents secrets from being committed to the repository.
53+
- hadolint: Lints Dockerfiles to ensure best practices and common conventions are followed.
54+
55+
## Continuous Integration (CI)
56+
When a commit is pushed to a branch that is part of a Pull Request, our Continuous Integration (CI) pipeline automatically runs specified tools to check code quality, style, security and other standards. If these checks fail, the PR cannot be merged until all issues are resolved.
57+
58+
## Quality Standards Enforcement
59+
- PRs must pass all checks from the configured pre-commit hooks and CI pipeline to be eligible for merging.
60+
- Code reviews additionally focus on logical errors and code quality beyond what automated tools can detect.
61+
62+
## Conclusion
63+
By adhering to these standards and utilizing the tools set up, we maintain the high quality and consistency of our codebase, making it easier for developers to collaborate effectively.

README.md

Lines changed: 93 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ $ docker-compose -f local.yml build
1818
```bash
1919
$ docker-compose -f local.yml up
2020
```
21-
2221
### Non-Docker Local Setup
2322

2423
If you prefer to run the project without Docker, follow these steps:
@@ -69,57 +68,103 @@ $ docker-compose -f local.yml run --rm django python manage.py createsuperuser
6968
#### Creating Additional Users
7069

7170
Create additional users through the admin interface (/admin).
71+
## Database Backup and Restore
72+
73+
COSMOS provides dedicated management commands for backing up and restoring your PostgreSQL database. These commands handle both compressed and uncompressed backups and work seamlessly in both local and production environments using Docker.
7274

73-
### Loading Fixtures
75+
### Backup Directory Structure
7476

75-
To load collections:
77+
All backups are stored in the `/backups` directory at the root of your project. This directory is mounted as a volume in both local and production Docker configurations, making it easy to manage backups across different environments.
7678

79+
- Local development: `./backups/`
80+
- Production server: `/path/to/project/backups/`
81+
82+
If the directory doesn't exist, create it:
7783
```bash
78-
$ docker-compose -f local.yml run --rm django python manage.py loaddata sde_collections/fixtures/collections.json
84+
mkdir backups
7985
```
8086

81-
### Manually Creating and Loading a ContentTypeless Backup
82-
Navigate to the server running prod, then to the project folder. Run the following command to create a backup:
87+
### Creating a Database Backup
88+
89+
To create a backup of your database:
8390

8491
```bash
85-
docker-compose -f production.yml run --rm --user root django python manage.py dumpdata --natural-foreign --natural-primary --exclude=contenttypes --exclude=auth.Permission --indent 2 --output /app/backups/prod_backup-20240812.json
92+
# Create a compressed backup (recommended)
93+
docker-compose -f local.yml run --rm django python manage.py database_backup
94+
95+
# Create an uncompressed backup
96+
docker-compose -f local.yml run --rm django python manage.py database_backup --no-compress
97+
98+
# Specify custom output location within backups directory
99+
docker-compose -f local.yml run --rm django python manage.py database_backup --output my_custom_backup.sql
86100
```
87-
This will have saved the backup in a folder outside of the docker container. Now you can copy it to your local machine.
101+
102+
The backup command will automatically:
103+
- Detect your server environment (Production/Staging/Local)
104+
- Use database credentials from your environment settings
105+
- Generate a dated filename if no output path is specified
106+
- Save the backup to the mounted `/backups` directory
107+
- Compress the backup by default (can be disabled with --no-compress)
108+
109+
### Restoring from a Database Backup
110+
111+
To restore your database from a backup, it will need to be in the `/backups` directory. You can then run the following command:
88112

89113
```bash
90-
mv ~/prod_backup-20240812.json <project_path>/prod_backup-20240812.json
91-
scp sde:/home/ec2-user/sde_indexing_helper/backups/prod_backup-20240812.json prod_backup-20240812.json
114+
# Restore from a backup (handles both .sql and .sql.gz files)
115+
docker-compose -f local.yml run --rm django python manage.py database_restore backups/backup_file_name.sql.gz
92116
```
93117

94-
Finally, load the backup into your local database:
118+
The restore command will:
119+
- Automatically detect if the backup is compressed (.gz)
120+
- Terminate existing database connections
121+
- Drop and recreate the database
122+
- Restore all data from the backup
123+
- Handle all database credentials from your environment settings
124+
125+
### Working with Remote Servers
95126

127+
When working with production or staging servers:
128+
129+
1. First, SSH into the appropriate server:
96130
```bash
97-
docker-compose -f local.yml run --rm django python manage.py loaddata prod_backup-20240812.json
131+
# For production
132+
ssh user@production-server
133+
cd /path/to/project
98134
```
99135

100-
### Loading the Database from an Arbitrary Backup
136+
2. Create a backup on the remote server:
137+
```bash
138+
docker-compose -f production.yml run --rm django python manage.py database_backup
139+
```
101140

102-
1. Build the project and run the necessary containers (as documented above).
103-
2. Clear out content types using the Django shell:
141+
3. Copy the backup from the remote server's backup directory to your local machine:
142+
```bash
143+
scp user@remote-server:/path/to/project/backups/backup_name.sql.gz ./backups/
144+
```
104145

146+
4. Restore locally:
105147
```bash
106-
$ docker-compose -f local.yml run --rm django python manage.py shell
107-
>>> from django.contrib.contenttypes.models import ContentType
108-
>>> ContentType.objects.all().delete()
109-
>>> exit()
148+
docker-compose -f local.yml run --rm django python manage.py database_restore backups/backup_name.sql.gz
110149
```
111150

112-
3. Load your backup database:
151+
### Alternative Methods
152+
153+
While the database_backup and database_restore commands are the recommended approach, you can also use Django's built-in fixtures for smaller datasets:
113154

114155
```bash
115-
$ docker cp /path/to/your/backup.json container_name:/path/inside/container/backup.json
116-
$ docker-compose -f local.yml run --rm django python manage.py loaddata /path/inside/the/container/backup.json
117-
$ docker-compose -f local.yml run --rm django python manage.py migrate
156+
# Create a backup excluding content types
157+
docker-compose -f production.yml run --rm django python manage.py dumpdata \
158+
--natural-foreign --natural-primary \
159+
--exclude=contenttypes --exclude=auth.Permission \
160+
--indent 2 \
161+
--output backups/prod_backup-$(date +%Y%m%d).json
162+
163+
# Restore from a fixture
164+
docker-compose -f local.yml run --rm django python manage.py loaddata backups/backup_name.json
118165
```
119-
### Restoring the Database from a SQL Dump
120-
If the JSON file is particularly large (>1.5GB), Docker might struggle with this method. In such cases, you can use SQL dump and restore commands as an alternative, as described [here](./SQLDumpRestoration.md).
121-
122166

167+
Note: For large databases (>1.5GB), the database_backup and database_restore commands are strongly recommended over JSON fixtures as they handle large datasets more efficiently.
123168

124169
## Additional Commands
125170

@@ -180,6 +225,7 @@ $ pip install pre-commit
180225
$ pre-commit install
181226
$ pre-commit run --all-files
182227
```
228+
For detailed information on the coding standards and conventions we enforce, please see our [Coding Standards and Conventions](CODE_STANDARDS.md).
183229

184230
### Sentry Setup
185231

@@ -208,3 +254,24 @@ Eventually, job creation will be done seamlessly by the webapp. Until then, edit
208254
- JavaScript: `/sde_indexing_helper/static/js`
209255
- CSS: `/sde_indexing_helper/static/css`
210256
- Images: `/sde_indexing_helper/static/images`
257+
258+
259+
## Running Long Scripts on the Server
260+
```shell
261+
tmux new -s docker_django
262+
```
263+
Once you are inside, you can run dmshell or for example a managment command:
264+
265+
```shell
266+
docker-compose -f production.yml run --rm django python manage.py deduplicate_urls
267+
```
268+
269+
Later, you can do this to get back in.
270+
```shell
271+
tmux attach -t docker_django
272+
```
273+
274+
To delete the session:
275+
```shell
276+
tmux kill-session -t docker_django
277+
```

0 commit comments

Comments
 (0)