Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions .copier-answers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ custom_install: true
enforce_style:
- ruff_lint
- ruff_format
failure_notification:
- email
failure_notification: []
include_benchmarks: false
include_docs: true
include_notebooks: true
Expand All @@ -19,7 +18,6 @@ project_license: MIT
project_name: jump-starter
project_organization: lincc-frameworks
python_versions:
- '3.9'
- '3.10'
- '3.11'
- '3.12'
Expand Down
37 changes: 2 additions & 35 deletions .github/workflows/smoke-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
python-version: ['3.10', '3.11', '3.12', '3.13']

steps:
- uses: actions/checkout@v4
Expand All @@ -39,37 +39,4 @@ jobs:
pip list
- name: Run unit tests with pytest
run: |
python -m pytest
- name: Send status to author's email
if: ${{ failure() }} && github.event_name != 'workflow_dispatch' }} # Only email if the workflow failed and was not manually started. Customize this as necessary.
uses: dawidd6/action-send-mail@v3
with:
# Required mail server address if not connection_url:
server_address: smtp.gmail.com
# Server port: (uses TLS by default if server_port is 465)
server_port: 465

# Mail server username:
username: ${{secrets.MAIL_USERNAME}}
# Mail server password:
password: ${{secrets.MAIL_PASSWORD}}
# Required recipients' addresses:
to: seanmcgu@andrew.cmu.edu

# Required mail subject:
subject: Smoke test ${{ job.status }} in ${{github.repository}}
# Required sender full name:
from: GitHub Actions Report
# Optional body:
html_body: |
<!DOCTYPE html>
<html>
<body>
<h3>Smoke test ${{ job.status }}</h3>
<p>The smoke test in <b>${{ github.repository }}</b> has completed with result: <b>${{ job.status }}</b></p>
<p><a href="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}">
${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
</a></p>
</body>
</html>

python -m pytest
6 changes: 3 additions & 3 deletions .github/workflows/testing-and-coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
python-version: ['3.10', '3.11', '3.12', '3.13']

steps:
- uses: actions/checkout@v4
Expand All @@ -41,10 +41,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python 3.9
- name: Set up Python 3.10
uses: actions/setup-python@v5
with:
python-version: '3.9'
python-version: '3.10'
- name: Install dependencies
run: |
sudo apt-get update
Expand Down
1 change: 1 addition & 0 deletions .idea/jump-starter.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@

# jump-starter
# JuMP-Starter

The Jupyter Managed Project Starter allows you to create an interactive jupyter questionnaire to help users
quickly get started with your package.

[![Template](https://img.shields.io/badge/Template-LINCC%20Frameworks%20Python%20Project%20Template-brightgreen)](https://lincc-ppt.readthedocs.io/en/latest/)

Expand Down
13 changes: 11 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,14 @@ classifiers = [
"Programming Language :: Python",
]
dynamic = ["version"]
requires-python = ">=3.9"
requires-python = ">=3.10"
dependencies = [
"ipywidgets>=8.0",
"pydantic>=2.0",
"pyyaml>=6.0",
"markdown>=3.4",
"pygments>=2.0",
"jinja2>=3.0"
]

[project.urls]
Expand All @@ -30,7 +36,10 @@ dev = [
"pre-commit", # Used to run checks before finalizing a git commit
"pytest",
"pytest-cov", # Used to report total code coverage
"pytest-mock", # Used to mock objects in tests
"ruff", # Used for static linting of files
"types-Markdown", # Type information for markdown
"types-PyYAML", # Type information for pyyaml
]

[build-system]
Expand All @@ -53,7 +62,7 @@ addopts = "--doctest-modules --doctest-glob=*.rst"

[tool.ruff]
line-length = 110
target-version = "py39"
target-version = "py310"
[tool.ruff.lint]
select = [
# pycodestyle
Expand Down
3 changes: 3 additions & 0 deletions src/jump_starter/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from .questionnaire import QuestionnaireWidget

__all__ = ["QuestionnaireWidget"]
74 changes: 74 additions & 0 deletions src/jump_starter/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
from datetime import datetime
from typing import Union

from pydantic import BaseModel, Field


class Template(BaseModel):
"""Represents a template for code replacement in the questionnaire."""

replacement: str
code: str


class Answer(BaseModel):
"""Represents an answer to a question in the questionnaire."""

answer: str
tooltip: str = ""
templates: list[Template] = Field(default_factory=list)
followups: list[Union["Question", "Switch"]] = Field(default_factory=list)
commentary: str = ""


class Question(BaseModel):
"""Represents a question in the questionnaire."""

question: str
variable: str | None = None
answers: list[Answer]


class Case(BaseModel):
"""Represents a case in a switch statement within the questionnaire."""

value: int | None = None
questions: list[Union[Question, "Switch"]]


class Switch(BaseModel):
"""Represents a switch statement in the questionnaire."""

switch: str
cases: list[Case]


# Rebuild models to support self-referencing types and forward references
Question.model_rebuild()
Answer.model_rebuild()
Case.model_rebuild()
Switch.model_rebuild()


class QuestionAnswer(BaseModel):
"""Represents a user's answer to a question."""

question: str
answer: str
value: int


class QuestionAnswers(BaseModel):
"""Represents a collection of user answers to questions."""

answers: list[QuestionAnswer] = Field(default_factory=list)
timestamp: datetime = Field(default_factory=datetime.now)


class Questionnaire(BaseModel):
"""Represents a questionnaire with an initial template and a list of questions."""

initial_template: str
initial_commentary: str = ""
feedback_url: str | None = None
questions: list[Question | Switch]
Loading