xitzin 0.1.2__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.
xitzin-0.1.2/PKG-INFO ADDED
@@ -0,0 +1,118 @@
1
+ Metadata-Version: 2.3
2
+ Name: xitzin
3
+ Version: 0.1.2
4
+ Summary: A Gemini Application Framework
5
+ Keywords: gemini,protocol,framework,async,geminispace
6
+ Author: Alan Velasco
7
+ Author-email: Alan Velasco <alanvelasco.a@gmail.com>
8
+ License: MIT
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Topic :: Internet
18
+ Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
19
+ Classifier: Typing :: Typed
20
+ Requires-Dist: jinja2>=3.1.0
21
+ Requires-Dist: nauyaca>=0.3.2
22
+ Requires-Dist: rich>=14.2.0
23
+ Requires-Dist: typing-extensions>=4.15.0
24
+ Requires-Python: >=3.10
25
+ Project-URL: Changelog, https://xitzin.readthedocs.io/changelog/
26
+ Project-URL: Documentation, https://xitzin.readthedocs.io
27
+ Project-URL: Homepage, https://github.com/alanbato/xitzin
28
+ Project-URL: Issues, https://github.com/alanbato/xitzin/issues
29
+ Project-URL: Repository, https://github.com/alanbato/xitzin.git
30
+ Description-Content-Type: text/markdown
31
+
32
+ # Xitzin
33
+
34
+ **Application Framework for the Geminispace**
35
+
36
+ Xitzin brings a modern Python developer experience to the [Gemini protocol](https://geminiprotocol.net/). Build Gemini capsules with familiar patterns: decorators for routing and type-annotated path parameters.
37
+
38
+ ```python
39
+ from xitzin import Xitzin, Request
40
+
41
+ app = Xitzin()
42
+
43
+ @app.gemini("/")
44
+ def home(request: Request):
45
+ return "# Welcome to my capsule!"
46
+
47
+ @app.gemini("/user/{username}")
48
+ def profile(request: Request, username: str):
49
+ return f"# {username}'s Profile"
50
+
51
+ @app.input("/search", prompt="Enter query:")
52
+ def search(request: Request, query: str):
53
+ return f"# Results for: {query}"
54
+
55
+ if __name__ == "__main__":
56
+ app.run()
57
+ ```
58
+
59
+ ## Features
60
+
61
+ - **Decorator-based routing** with `@app.gemini()` and automatic path parameter extraction
62
+ - **User input handling** via `@app.input()` for Gemini's status 10/11 prompts
63
+ - **Certificate authentication** with `@require_certificate` and fingerprint whitelisting
64
+ - **Jinja2 templates** with Gemtext-aware filters (links, headings, lists)
65
+ - **Middleware support** for logging, rate limiting, and custom processing
66
+ - **Testing utilities** with in-memory `TestClient`
67
+ - **Async support** for both sync and async handlers
68
+
69
+ ## Installation
70
+
71
+ ```bash
72
+ pip install xitzin
73
+ ```
74
+
75
+ Or with [uv](https://docs.astral.sh/uv/):
76
+
77
+ ```bash
78
+ uv add xitzin
79
+ ```
80
+
81
+ ## Quick Start
82
+
83
+ 1. Create `app.py`:
84
+
85
+ ```python
86
+ from xitzin import Xitzin, Request
87
+
88
+ app = Xitzin()
89
+
90
+ @app.gemini("/")
91
+ def home(request: Request):
92
+ return "# Hello, Geminispace!"
93
+
94
+ if __name__ == "__main__":
95
+ app.run()
96
+ ```
97
+
98
+ 2. Generate TLS certificates:
99
+
100
+ ```bash
101
+ openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes -subj "/CN=localhost"
102
+ ```
103
+
104
+ 3. Run your capsule:
105
+
106
+ ```bash
107
+ python app.py
108
+ ```
109
+
110
+ 4. Visit `gemini://localhost/` with a Gemini client like [Astronomo](https://github.com/alanbato/astronomo/).
111
+
112
+ ## Documentation
113
+
114
+ Full documentation is available at [xitzin.readthedocs.io](https://xitzin.readthedocs.io/).
115
+
116
+ ## License
117
+
118
+ MIT
xitzin-0.1.2/README.md ADDED
@@ -0,0 +1,87 @@
1
+ # Xitzin
2
+
3
+ **Application Framework for the Geminispace**
4
+
5
+ Xitzin brings a modern Python developer experience to the [Gemini protocol](https://geminiprotocol.net/). Build Gemini capsules with familiar patterns: decorators for routing and type-annotated path parameters.
6
+
7
+ ```python
8
+ from xitzin import Xitzin, Request
9
+
10
+ app = Xitzin()
11
+
12
+ @app.gemini("/")
13
+ def home(request: Request):
14
+ return "# Welcome to my capsule!"
15
+
16
+ @app.gemini("/user/{username}")
17
+ def profile(request: Request, username: str):
18
+ return f"# {username}'s Profile"
19
+
20
+ @app.input("/search", prompt="Enter query:")
21
+ def search(request: Request, query: str):
22
+ return f"# Results for: {query}"
23
+
24
+ if __name__ == "__main__":
25
+ app.run()
26
+ ```
27
+
28
+ ## Features
29
+
30
+ - **Decorator-based routing** with `@app.gemini()` and automatic path parameter extraction
31
+ - **User input handling** via `@app.input()` for Gemini's status 10/11 prompts
32
+ - **Certificate authentication** with `@require_certificate` and fingerprint whitelisting
33
+ - **Jinja2 templates** with Gemtext-aware filters (links, headings, lists)
34
+ - **Middleware support** for logging, rate limiting, and custom processing
35
+ - **Testing utilities** with in-memory `TestClient`
36
+ - **Async support** for both sync and async handlers
37
+
38
+ ## Installation
39
+
40
+ ```bash
41
+ pip install xitzin
42
+ ```
43
+
44
+ Or with [uv](https://docs.astral.sh/uv/):
45
+
46
+ ```bash
47
+ uv add xitzin
48
+ ```
49
+
50
+ ## Quick Start
51
+
52
+ 1. Create `app.py`:
53
+
54
+ ```python
55
+ from xitzin import Xitzin, Request
56
+
57
+ app = Xitzin()
58
+
59
+ @app.gemini("/")
60
+ def home(request: Request):
61
+ return "# Hello, Geminispace!"
62
+
63
+ if __name__ == "__main__":
64
+ app.run()
65
+ ```
66
+
67
+ 2. Generate TLS certificates:
68
+
69
+ ```bash
70
+ openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes -subj "/CN=localhost"
71
+ ```
72
+
73
+ 3. Run your capsule:
74
+
75
+ ```bash
76
+ python app.py
77
+ ```
78
+
79
+ 4. Visit `gemini://localhost/` with a Gemini client like [Astronomo](https://github.com/alanbato/astronomo/).
80
+
81
+ ## Documentation
82
+
83
+ Full documentation is available at [xitzin.readthedocs.io](https://xitzin.readthedocs.io/).
84
+
85
+ ## License
86
+
87
+ MIT
@@ -0,0 +1,58 @@
1
+ [project]
2
+ name = "xitzin"
3
+ version = "0.1.2"
4
+ description = "A Gemini Application Framework"
5
+ readme = "README.md"
6
+ license = { text = "MIT" }
7
+ authors = [
8
+ { name = "Alan Velasco", email = "alanvelasco.a@gmail.com" }
9
+ ]
10
+ requires-python = ">=3.10"
11
+ keywords = ["gemini", "protocol", "framework", "async", "geminispace"]
12
+ classifiers = [
13
+ "Development Status :: 4 - Beta",
14
+ "Intended Audience :: Developers",
15
+ "License :: OSI Approved :: MIT License",
16
+ "Programming Language :: Python :: 3",
17
+ "Programming Language :: Python :: 3.10",
18
+ "Programming Language :: Python :: 3.11",
19
+ "Programming Language :: Python :: 3.12",
20
+ "Programming Language :: Python :: 3.13",
21
+ "Topic :: Internet",
22
+ "Topic :: Software Development :: Libraries :: Application Frameworks",
23
+ "Typing :: Typed",
24
+ ]
25
+ dependencies = [
26
+ "jinja2>=3.1.0",
27
+ "nauyaca>=0.3.2",
28
+ "rich>=14.2.0",
29
+ "typing-extensions>=4.15.0",
30
+ ]
31
+
32
+ [project.urls]
33
+ Homepage = "https://github.com/alanbato/xitzin"
34
+ Documentation = "https://xitzin.readthedocs.io"
35
+ Repository = "https://github.com/alanbato/xitzin.git"
36
+ Issues = "https://github.com/alanbato/xitzin/issues"
37
+ Changelog = "https://xitzin.readthedocs.io/changelog/"
38
+
39
+ [build-system]
40
+ requires = ["uv_build>=0.9.10,<0.10.0"]
41
+ build-backend = "uv_build"
42
+
43
+ [dependency-groups]
44
+ dev = [
45
+ "pre-commit>=4.5.1",
46
+ "pytest>=9.0.2",
47
+ "pytest-asyncio>=0.24.0",
48
+ "pytest-cov>=7.0.0",
49
+ "ruff>=0.14.10",
50
+ "ty>=0.0.8",
51
+ ]
52
+ docs = [
53
+ "mkdocs>=1.6.1",
54
+ "mkdocs-material>=9.5.0",
55
+ "mkdocstrings[python]>=0.24.0",
56
+ "mkdocs-git-revision-date-localized-plugin>=1.2.0",
57
+ "pymdown-extensions>=10.20",
58
+ ]
@@ -0,0 +1,78 @@
1
+ """Xitzin - A Gemini Application Framework.
2
+
3
+ Xitzin is a framework for building Gemini protocol applications.
4
+ It uses Nauyaca for Gemini protocol communication.
5
+
6
+ Example:
7
+ from xitzin import Xitzin, Request
8
+
9
+ app = Xitzin()
10
+
11
+ @app.gemini("/")
12
+ def home(request: Request):
13
+ return "# Welcome to Gemini!"
14
+
15
+ @app.gemini("/user/{username}")
16
+ def profile(request: Request, username: str):
17
+ return f"# {username}'s Profile"
18
+
19
+ if __name__ == "__main__":
20
+ app.run()
21
+ """
22
+
23
+ from .application import Xitzin
24
+ from .cgi import CGIConfig, CGIHandler, CGIScript
25
+ from .exceptions import (
26
+ BadRequest,
27
+ CertificateNotAuthorized,
28
+ CertificateNotValid,
29
+ CertificateRequired,
30
+ CGIError,
31
+ GeminiException,
32
+ Gone,
33
+ InputRequired,
34
+ NotFound,
35
+ PermanentFailure,
36
+ ProxyError,
37
+ ProxyRequestRefused,
38
+ SensitiveInputRequired,
39
+ ServerUnavailable,
40
+ SlowDown,
41
+ TemporaryFailure,
42
+ )
43
+ from .requests import Request
44
+ from .responses import Input, Link, Redirect, Response
45
+
46
+ __all__ = [
47
+ # Main application
48
+ "Xitzin",
49
+ # Request/Response
50
+ "Request",
51
+ "Response",
52
+ "Input",
53
+ "Redirect",
54
+ "Link",
55
+ # CGI support
56
+ "CGIConfig",
57
+ "CGIHandler",
58
+ "CGIScript",
59
+ # Exceptions
60
+ "GeminiException",
61
+ "InputRequired",
62
+ "SensitiveInputRequired",
63
+ "TemporaryFailure",
64
+ "ServerUnavailable",
65
+ "CGIError",
66
+ "ProxyError",
67
+ "SlowDown",
68
+ "PermanentFailure",
69
+ "NotFound",
70
+ "Gone",
71
+ "ProxyRequestRefused",
72
+ "BadRequest",
73
+ "CertificateRequired",
74
+ "CertificateNotAuthorized",
75
+ "CertificateNotValid",
76
+ ]
77
+
78
+ __version__ = "0.1.0"