np2 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
np2-1.0.0/.gitignore ADDED
@@ -0,0 +1 @@
1
+ *
np2-1.0.0/PKG-INFO ADDED
@@ -0,0 +1,150 @@
1
+ Metadata-Version: 2.5
2
+ Name: np2
3
+ Version: 1.0.0
4
+ Summary: Offline IMAP revision: commands with use cases and unit-wise definitions
5
+ Author: Kanishk Thakar
6
+ Keywords: django,docker,imap,revision,study
7
+ Requires-Python: >=3.9
8
+ Description-Content-Type: text/markdown
9
+
10
+ # NP2 — IMAP revision in Python
11
+
12
+ A small, offline, zero-runtime-dependency study package based on the supplied
13
+ **IMAP Exam Bible**. Python 3.9 or newer. Import name: `np2`.
14
+
15
+ ## Install
16
+
17
+ ```sh
18
+ python -m pip install np2
19
+ ```
20
+
21
+ Or install the supplied wheel from its containing folder:
22
+
23
+ ```sh
24
+ python -m pip install ./np2-1.0.0-py3-none-any.whl
25
+ ```
26
+
27
+ Use `python3` instead of `python` where needed. This project uses distribution
28
+ name `np2` and import name `np2`. The local wheel works without an index or
29
+ runtime dependency downloads.
30
+
31
+ ## The two sections
32
+
33
+ ```python
34
+ import np2
35
+ np2.show() # compact two-section menu
36
+ np2.show(1) # all commands + use cases
37
+ np2.show(1, group="git") # Git only
38
+ np2.show(1, group="github") # GitHub CLI supplement
39
+ np2.show(1, group="docker") # Docker
40
+ np2.show(1, group="compose") # Docker Compose
41
+ np2.show(2) # all unit-wise definitions
42
+ np2.show(2, unit=1) # just Unit 1
43
+ np2.unit(5) # just Unit 5
44
+ np2.show("all", pager=True) # both sections with terminal paging
45
+ ```
46
+
47
+ If you prefer uppercase:
48
+
49
+ ```python
50
+ import np2 as NP2
51
+ NP2.show()
52
+ NP2.show(1)
53
+ NP2.show(2, unit=3)
54
+ ```
55
+
56
+ Commands are examples printed as text, **never executed** by this package.
57
+ Commands include prerequisites and notes for destructive operations. Replace
58
+ angle-bracket placeholders. Read the group label: SQL statements belong in a
59
+ SQL client, ORM expressions in a configured Django shell, MongoDB expressions
60
+ in mongosh, and Dockerfile instructions in a Dockerfile. Tools such as Git,
61
+ Docker, Node, AWS CLI and GitHub CLI must be installed separately if you want
62
+ to execute examples yourself. They are not installed by NP2.
63
+
64
+ ## Coverage
65
+
66
+ - Section 1: 241 command/examples with use cases, grouped as Git, GitHub CLI,
67
+ Python/pip, Django, ORM, SQL/PostgreSQL, MongoDB, React/npm, Docker, Compose,
68
+ Dockerfile, cloud/SSH/AWS and HTTP.
69
+ - Section 2: 175 concise concept definitions across all five units.
70
+ - Full extracted text for Units 1–5 (PDF pages 18–378) and a 108-subsection
71
+ topic index. The concise glossary groups related concepts; it is not a
72
+ claim that every word in the book is separately defined.
73
+
74
+ | Unit | Subject |
75
+ |---|---|
76
+ | 1 | HTML, CSS, JavaScript, Git and GitHub |
77
+ | 2 | Python, Django, REST APIs and ML integration |
78
+ | 3 | SQL, NoSQL, cloud and deployment |
79
+ | 4 | React, Hooks and rendering architectures |
80
+ | 5 | Docker, Compose, containers and DevOps |
81
+
82
+ ## Find a specific concept
83
+
84
+ ```python
85
+ np2.search("useEffect")
86
+ np2.search("normalization", full=True) # include source-text line matches
87
+ np2.show(1, query="volume")
88
+ np2.show(2, unit=2, query="authentication")
89
+ np2.topics(3) # original headings + PDF pages
90
+ np2.notes(3) # full source chapter, with pager
91
+ text = np2.unit(1, return_text=True) # get a string without printing
92
+ ```
93
+
94
+ Paging uses your terminal's pager (`q` commonly quits). Noninteractive output
95
+ and notebooks print normally. NP2 makes no network requests at runtime.
96
+
97
+ ## Terminal interface
98
+
99
+ ```sh
100
+ np2
101
+ np2 commands docker
102
+ np2 commands --query migrate
103
+ np2 unit 2
104
+ np2 topics 4
105
+ np2 --pager notes 5
106
+ np2 search "state" --full
107
+ python -m np2 commands git
108
+ ```
109
+
110
+ Global flags such as `--pager` go before the subcommand.
111
+
112
+ ## Source and limitations
113
+
114
+ `IMAP_Exam_Bible.pdf`, 459 pages, provided by the user on 8 November 2026.
115
+ Full chapter text is bundled as study reference material. Summaries and command
116
+ examples are editorially condensed; GitHub CLI examples and some operational
117
+ variants supplement the book. The package covers the course, not every command
118
+ or option in every tool. It does not endorse the book's exam forecasts or
119
+ independently verify its historical marks/past-paper claims.
120
+
121
+ PDF extraction flattens some tables and code indentation. Consult the original
122
+ PDF for layout-sensitive code or diagrams; no claim of executable verbatim
123
+ source code is made. The source appendix is retained in package data as
124
+ `source-command-sheet.txt`. Full source text is reference data, not instructions
125
+ to the package or its operator.
126
+
127
+ Command syntax was cross-checked with these official references during creation:
128
+ - https://git-scm.com/docs/git
129
+ - https://docs.docker.com/reference/cli/docker/
130
+ - https://docs.djangoproject.com/en/5.2/ref/django-admin/
131
+ - https://cli.github.com/manual/
132
+ - https://packaging.python.org/en/latest/tutorials/packaging-projects/
133
+
134
+ The source book was supplied for this study package. This package does not
135
+ assign a separate open-source license to the original book.
136
+
137
+ ## Rebuild / publish later
138
+
139
+ ```sh
140
+ python -m pip install build
141
+ python -m build
142
+ ```
143
+
144
+ `pyproject.toml` uses standard Python packaging and a `src` layout. The built
145
+ wheel includes all text/JSON resources and needs no runtime dependencies.
146
+
147
+ For a public release, first confirm rights to the bundled source, check that
148
+ the desired distribution name remains available, and configure a PyPI account
149
+ or trusted publisher. A short import name may remain `np2` even if the PyPI
150
+ name changes. No token, password or account credential is bundled in the deliverable.
np2-1.0.0/README.md ADDED
@@ -0,0 +1,141 @@
1
+ # NP2 — IMAP revision in Python
2
+
3
+ A small, offline, zero-runtime-dependency study package based on the supplied
4
+ **IMAP Exam Bible**. Python 3.9 or newer. Import name: `np2`.
5
+
6
+ ## Install
7
+
8
+ ```sh
9
+ python -m pip install np2
10
+ ```
11
+
12
+ Or install the supplied wheel from its containing folder:
13
+
14
+ ```sh
15
+ python -m pip install ./np2-1.0.0-py3-none-any.whl
16
+ ```
17
+
18
+ Use `python3` instead of `python` where needed. This project uses distribution
19
+ name `np2` and import name `np2`. The local wheel works without an index or
20
+ runtime dependency downloads.
21
+
22
+ ## The two sections
23
+
24
+ ```python
25
+ import np2
26
+ np2.show() # compact two-section menu
27
+ np2.show(1) # all commands + use cases
28
+ np2.show(1, group="git") # Git only
29
+ np2.show(1, group="github") # GitHub CLI supplement
30
+ np2.show(1, group="docker") # Docker
31
+ np2.show(1, group="compose") # Docker Compose
32
+ np2.show(2) # all unit-wise definitions
33
+ np2.show(2, unit=1) # just Unit 1
34
+ np2.unit(5) # just Unit 5
35
+ np2.show("all", pager=True) # both sections with terminal paging
36
+ ```
37
+
38
+ If you prefer uppercase:
39
+
40
+ ```python
41
+ import np2 as NP2
42
+ NP2.show()
43
+ NP2.show(1)
44
+ NP2.show(2, unit=3)
45
+ ```
46
+
47
+ Commands are examples printed as text, **never executed** by this package.
48
+ Commands include prerequisites and notes for destructive operations. Replace
49
+ angle-bracket placeholders. Read the group label: SQL statements belong in a
50
+ SQL client, ORM expressions in a configured Django shell, MongoDB expressions
51
+ in mongosh, and Dockerfile instructions in a Dockerfile. Tools such as Git,
52
+ Docker, Node, AWS CLI and GitHub CLI must be installed separately if you want
53
+ to execute examples yourself. They are not installed by NP2.
54
+
55
+ ## Coverage
56
+
57
+ - Section 1: 241 command/examples with use cases, grouped as Git, GitHub CLI,
58
+ Python/pip, Django, ORM, SQL/PostgreSQL, MongoDB, React/npm, Docker, Compose,
59
+ Dockerfile, cloud/SSH/AWS and HTTP.
60
+ - Section 2: 175 concise concept definitions across all five units.
61
+ - Full extracted text for Units 1–5 (PDF pages 18–378) and a 108-subsection
62
+ topic index. The concise glossary groups related concepts; it is not a
63
+ claim that every word in the book is separately defined.
64
+
65
+ | Unit | Subject |
66
+ |---|---|
67
+ | 1 | HTML, CSS, JavaScript, Git and GitHub |
68
+ | 2 | Python, Django, REST APIs and ML integration |
69
+ | 3 | SQL, NoSQL, cloud and deployment |
70
+ | 4 | React, Hooks and rendering architectures |
71
+ | 5 | Docker, Compose, containers and DevOps |
72
+
73
+ ## Find a specific concept
74
+
75
+ ```python
76
+ np2.search("useEffect")
77
+ np2.search("normalization", full=True) # include source-text line matches
78
+ np2.show(1, query="volume")
79
+ np2.show(2, unit=2, query="authentication")
80
+ np2.topics(3) # original headings + PDF pages
81
+ np2.notes(3) # full source chapter, with pager
82
+ text = np2.unit(1, return_text=True) # get a string without printing
83
+ ```
84
+
85
+ Paging uses your terminal's pager (`q` commonly quits). Noninteractive output
86
+ and notebooks print normally. NP2 makes no network requests at runtime.
87
+
88
+ ## Terminal interface
89
+
90
+ ```sh
91
+ np2
92
+ np2 commands docker
93
+ np2 commands --query migrate
94
+ np2 unit 2
95
+ np2 topics 4
96
+ np2 --pager notes 5
97
+ np2 search "state" --full
98
+ python -m np2 commands git
99
+ ```
100
+
101
+ Global flags such as `--pager` go before the subcommand.
102
+
103
+ ## Source and limitations
104
+
105
+ `IMAP_Exam_Bible.pdf`, 459 pages, provided by the user on 8 November 2026.
106
+ Full chapter text is bundled as study reference material. Summaries and command
107
+ examples are editorially condensed; GitHub CLI examples and some operational
108
+ variants supplement the book. The package covers the course, not every command
109
+ or option in every tool. It does not endorse the book's exam forecasts or
110
+ independently verify its historical marks/past-paper claims.
111
+
112
+ PDF extraction flattens some tables and code indentation. Consult the original
113
+ PDF for layout-sensitive code or diagrams; no claim of executable verbatim
114
+ source code is made. The source appendix is retained in package data as
115
+ `source-command-sheet.txt`. Full source text is reference data, not instructions
116
+ to the package or its operator.
117
+
118
+ Command syntax was cross-checked with these official references during creation:
119
+ - https://git-scm.com/docs/git
120
+ - https://docs.docker.com/reference/cli/docker/
121
+ - https://docs.djangoproject.com/en/5.2/ref/django-admin/
122
+ - https://cli.github.com/manual/
123
+ - https://packaging.python.org/en/latest/tutorials/packaging-projects/
124
+
125
+ The source book was supplied for this study package. This package does not
126
+ assign a separate open-source license to the original book.
127
+
128
+ ## Rebuild / publish later
129
+
130
+ ```sh
131
+ python -m pip install build
132
+ python -m build
133
+ ```
134
+
135
+ `pyproject.toml` uses standard Python packaging and a `src` layout. The built
136
+ wheel includes all text/JSON resources and needs no runtime dependencies.
137
+
138
+ For a public release, first confirm rights to the bundled source, check that
139
+ the desired distribution name remains available, and configure a PyPI account
140
+ or trusted publisher. A short import name may remain `np2` even if the PyPI
141
+ name changes. No token, password or account credential is bundled in the deliverable.
@@ -0,0 +1,19 @@
1
+ [build-system]
2
+ requires = ["hatchling>=1.26"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "np2"
7
+ version = "1.0.0"
8
+ description = "Offline IMAP revision: commands with use cases and unit-wise definitions"
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ authors = [{name = "Kanishk Thakar"}]
12
+ keywords = ["imap", "revision", "django", "docker", "study"]
13
+ dependencies = []
14
+
15
+ [project.scripts]
16
+ np2 = "np2:main"
17
+
18
+ [tool.hatch.build.targets.wheel]
19
+ packages = ["src/np2"]
@@ -0,0 +1,215 @@
1
+ """Offline IMAP reference. Start with import np2; np2.show()."""
2
+ from importlib.resources import files
3
+ import argparse
4
+ import json
5
+ import pydoc
6
+ import sys
7
+
8
+ __version__ = "1.0.0"
9
+ __all__ = ["show", "commands", "units", "unit", "topics", "notes", "search", "main"]
10
+
11
+
12
+ def _json(name):
13
+ return json.loads(files(__package__).joinpath("data", name + ".json").read_text(encoding="utf-8"))
14
+
15
+
16
+ def _output(text, pager=False, return_text=False):
17
+ if return_text:
18
+ return text
19
+ if pager and sys.stdout.isatty():
20
+ pydoc.pager(text)
21
+ else:
22
+ print(text)
23
+ return None
24
+
25
+
26
+ def _unit_number(value):
27
+ if isinstance(value, bool) or str(value) not in {"1", "2", "3", "4", "5"}:
28
+ raise ValueError("Unit must be an integer from 1 to 5.")
29
+ return int(value)
30
+
31
+
32
+ def _match(query, *values):
33
+ return query.casefold() in " ".join(str(v) for v in values).casefold()
34
+
35
+
36
+ def commands(group=None, query=None, *, pager=False, return_text=False):
37
+ """Display command examples and their use cases. Never execute examples."""
38
+ rows = _json("commands")
39
+ groups = list(dict.fromkeys(r["group"] for r in rows))
40
+ aliases = {"pip": "python", "npm": "react", "drf": "django", "postgres": "sql", "aws": "cloud", "ssh": "cloud"}
41
+ if group:
42
+ group = aliases.get(str(group).casefold(), str(group).casefold())
43
+ if group not in groups:
44
+ raise ValueError("Unknown group. Choose: " + ", ".join(groups))
45
+ rows = [r for r in rows if r["group"] == group]
46
+ if query:
47
+ rows = [r for r in rows if _match(query, r["group"], r["command"], r["use"])]
48
+ lines = ["SECTION 1 - COMMANDS AND USE CASES", "Examples only; replace <placeholders>. Commands are never executed.",
49
+ "Shell commands, SQL, ORM expressions and Dockerfile instructions are labelled separately."]
50
+ previous = None
51
+ for r in rows:
52
+ if r["group"] != previous:
53
+ previous = r["group"]
54
+ lines += ["", "[" + previous.upper() + "]"]
55
+ lines += [r["command"], " Use: " + r["use"]]
56
+ if not rows:
57
+ lines.append("No matching commands.")
58
+ return _output("\n".join(lines), pager, return_text)
59
+
60
+
61
+ def units(number=None, query=None, *, pager=False, return_text=False):
62
+ """Display all concise definitions, optionally filtered to a unit or phrase."""
63
+ number = _unit_number(number) if number is not None else None
64
+ rows = _json("definitions")
65
+ titles = {r["unit"]: r["title"] for r in _json("units")}
66
+ rows = [r for r in rows if (number is None or r["unit"] == number) and
67
+ (not query or _match(query, r["term"], r["definition"]))]
68
+ lines = ["SECTION 2 - UNIT-WISE DEFINITIONS", "Concise revision glossary; use notes() for full source explanations and code."]
69
+ previous = None
70
+ for r in rows:
71
+ if r["unit"] != previous:
72
+ previous = r["unit"]
73
+ lines += ["", f"UNIT {previous}: {titles[previous]}"]
74
+ lines += [r["term"], " " + r["definition"]]
75
+ if not rows:
76
+ lines.append("No matching definitions.")
77
+ return _output("\n".join(lines), pager, return_text)
78
+
79
+
80
+ unit = units
81
+
82
+
83
+ def topics(number=None, *, pager=False, return_text=False):
84
+ """List every numbered source subsection and its original PDF page."""
85
+ number = _unit_number(number) if number is not None else None
86
+ rows = [r for r in _json("topics") if number is None or r["unit"] == number]
87
+ text = "SOURCE TOPICS\n" + "\n".join(f'{r["id"]:5} {r["title"]} (PDF p. {r["page"]})' for r in rows)
88
+ return _output(text, pager, return_text)
89
+
90
+
91
+ def notes(number, *, pager=True, return_text=False):
92
+ """Display the complete extracted chapter for a unit (including examples).
93
+
94
+ Source wording is preserved, not independently fact-checked. PDF extraction
95
+ can flatten tables/code indentation. Original PDF page numbers are retained.
96
+ """
97
+ number = _unit_number(number)
98
+ text = files(__package__).joinpath("data", f"unit{number}.txt").read_text(encoding="utf-8")
99
+ header = "FULL SOURCE NOTES - UNIT " + str(number) + "\nPDF text extraction; table/code layout may differ.\n"
100
+ return _output(header + text, pager, return_text)
101
+
102
+
103
+ def search(query, *, full=False, pager=False, return_text=False):
104
+ """Search commands, definitions and topic headings; full=True adds source lines."""
105
+ if not isinstance(query, str) or not query.strip():
106
+ raise ValueError("Provide a non-empty search phrase.")
107
+ parts = []
108
+ for r in _json("commands"):
109
+ if _match(query, r["group"], r["command"], r["use"]):
110
+ parts.append(f'[command/{r["group"]}] {r["command"]}\n {r["use"]}')
111
+ for r in _json("definitions"):
112
+ if _match(query, r["term"], r["definition"]):
113
+ parts.append(f'[unit {r["unit"]}] {r["term"]}\n {r["definition"]}')
114
+ for r in _json("topics"):
115
+ if _match(query, r["title"], r["id"]):
116
+ parts.append(f'[topic {r["id"]}, PDF p. {r["page"]}] {r["title"]}')
117
+ if full:
118
+ for number in range(1, 6):
119
+ page = "?"
120
+ text = files(__package__).joinpath("data", f"unit{number}.txt").read_text(encoding="utf-8")
121
+ for line in text.splitlines():
122
+ if line.startswith("--- PDF page "):
123
+ page = line.split()[3]
124
+ elif _match(query, line):
125
+ parts.append(f'[source unit {number}, PDF p. {page}] {line.strip()}')
126
+ return _output("\n\n".join(parts) if parts else "No matches found.", pager, return_text)
127
+
128
+
129
+ def show(section=None, *, unit=None, group=None, query=None, pager=False, return_text=False):
130
+ """show(): two-section menu; show(1): commands; show(2): definitions.
131
+
132
+ Examples: show(1, group='docker'); show(2, unit=3); show('all').
133
+ """
134
+ key = str(section).casefold() if section is not None else None
135
+ if key in {"1", "commands", "command"}:
136
+ if unit is not None:
137
+ raise ValueError("Use unit= with section 2; use group= with section 1.")
138
+ return commands(group, query, pager=pager, return_text=return_text)
139
+ if key in {"2", "units", "unit", "definitions"} or (key is None and unit is not None):
140
+ if group is not None:
141
+ raise ValueError("Use group= with section 1.")
142
+ return units(unit, query, pager=pager, return_text=return_text)
143
+ if key == "all":
144
+ text = commands(group, query, return_text=True) + "\n\n" + units(unit, query, return_text=True)
145
+ return _output(text, pager, return_text)
146
+ if key is None and group is not None:
147
+ return commands(group, query, pager=pager, return_text=return_text)
148
+ if key is None and query:
149
+ return search(query, pager=pager, return_text=return_text)
150
+ if key is not None:
151
+ raise ValueError("Section must be 1/'commands', 2/'units', or 'all'.")
152
+ counts = (len(_json("commands")), len(_json("definitions")), len(_json("topics")))
153
+ menu = f'''NP2 - OFFLINE IMAP REVISION ({__version__})
154
+ {counts[0]} command examples | {counts[1]} definitions | {counts[2]} source topics | 5 units
155
+
156
+ 1. COMMANDS + USE CASES
157
+ np2.show(1) All commands, grouped by tool
158
+ np2.show(1, group="git") Git commands
159
+ np2.show(1, group="docker") Docker commands
160
+ np2.show(1, group="compose") Compose commands
161
+ np2.show(1, query="migrate") Filter command examples
162
+
163
+ 2. UNIT-WISE DEFINITIONS
164
+ np2.show(2) Definitions for all five units
165
+ np2.show(2, unit=1) Definitions for Unit 1
166
+ np2.unit(4) Shortcut for Unit 4
167
+ np2.topics(4) Source subsection/page index
168
+ np2.notes(4) Full Unit 4 text and code
169
+
170
+ np2.search("promise") Search both sections
171
+ np2.search("promise", full=True) Also search complete unit text
172
+ np2.show("all", pager=True) Read both sections with paging
173
+
174
+ Units: 1 Web/Git | 2 Python/Django | 3 Databases/Cloud | 4 React | 5 Docker
175
+ Use import np2 as NP2 if you prefer NP2.show().
176
+ This is an offline study reference. It does not run the displayed commands.'''
177
+ return _output(menu, pager, return_text)
178
+
179
+
180
+ def main(argv=None):
181
+ """Command-line interface: np2 commands docker; np2 unit 1; np2 search hooks."""
182
+ parser = argparse.ArgumentParser(prog="np2", description="Offline IMAP study reference")
183
+ parser.add_argument("--version", action="version", version=__version__)
184
+ parser.add_argument("--pager", action="store_true", help="Page output in an interactive terminal")
185
+ sub = parser.add_subparsers(dest="action")
186
+ cmd = sub.add_parser("commands", help="Section 1: commands with use cases")
187
+ cmd.add_argument("group", nargs="?")
188
+ cmd.add_argument("--query")
189
+ unt = sub.add_parser("unit", aliases=["units"], help="Section 2: unit definitions")
190
+ unt.add_argument("number", nargs="?", type=int)
191
+ unt.add_argument("--query")
192
+ top = sub.add_parser("topics", help="Source subsection index")
193
+ top.add_argument("number", nargs="?", type=int)
194
+ note = sub.add_parser("notes", help="Complete source chapter")
195
+ note.add_argument("number", type=int)
196
+ find = sub.add_parser("search", help="Search all reference entries")
197
+ find.add_argument("query")
198
+ find.add_argument("--full", action="store_true")
199
+ sub.add_parser("all", help="Show both complete sections")
200
+ args = parser.parse_args(argv)
201
+ try:
202
+ if args.action == "commands":
203
+ commands(args.group, args.query, pager=args.pager)
204
+ elif args.action in {"unit", "units"}:
205
+ units(args.number, args.query, pager=args.pager)
206
+ elif args.action == "topics":
207
+ topics(args.number, pager=args.pager)
208
+ elif args.action == "notes":
209
+ notes(args.number, pager=args.pager)
210
+ elif args.action == "search":
211
+ search(args.query, full=args.full, pager=args.pager)
212
+ else:
213
+ show("all" if args.action == "all" else None, pager=args.pager)
214
+ except ValueError as error:
215
+ parser.error(str(error))
@@ -0,0 +1,2 @@
1
+ from . import main
2
+ main()