Skip to content

Commit 4824880

Browse files
committed
finish build steps
1 parent e7d6225 commit 4824880

29 files changed

+361
-238
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,4 @@ a.md
2626
new_app/
2727
vgcore.*
2828
.vscode/
29+
*.test

README.md

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,26 @@
33
<div align="center"><h2>The Batteries-Detachable Web Framework</h2></div>
44

55
> [!Warning]
6-
> view.py is in very early stages and not yet considered to be ready for production.
7-
> If you would like to follow development progress, join [the discord](https://discord.gg/tZAfuWAbm2).
8-
> For contributing to view.py, please see our [CONTRIBUTING.md](https://github.com/ZeroIntensity/view.py/blob/master/CONTRIBUTING.md)
6+
> view.py is currently in alpha, and may be lacking some features.
7+
> If you would like to follow development progress, be sure to join [the discord](https://discord.gg/tZAfuWAbm2).
98
109
<div align="center">
1110
<a href="https://clientarea.space-hosting.net/aff.php?aff=303"><img width=150 height=auto src="https://cdn-dennd.nitrocdn.com/fygsTSpFNuiCdXWNTtgOTVMRlPWNnIZx/assets/images/optimized/rev-758b0f8/www.space-hosting.net/wp-content/uploads/2023/02/cropped-Icon.png"></a>
1211
<h3>view.py is affiliated with <a href="https://clientarea.space-hosting.net/aff.php?aff=303">Space Hosting</a></h3>
1312
</div>
1413

15-
- [Docs](https://view.zintensity.dev)
16-
- [Source](https://github.com/ZeroIntensity/view.py)
17-
- [PyPI](https://pypi.org/project/view.py)
18-
- [Discord](https://discord.gg/tZAfuWAbm2)
14+
- [Docs](https://view.zintensity.dev)
15+
- [Source](https://github.com/ZeroIntensity/view.py)
16+
- [PyPI](https://pypi.org/project/view.py)
17+
- [Discord](https://discord.gg/tZAfuWAbm2)
1918

2019
## Features
2120

22-
- Batteries Detachable: Don't like our approach to something? No problem! We aim to provide native support for all your favorite libraries, as well as provide APIs to let you reinvent the wheel as you wish.
23-
- Lightning Fast: Powered by [pyawaitable](https://github.com/ZeroIntensity/pyawaitable), view.py is the first web framework to implement ASGI in pure C, without the use of external transpilers.
24-
- Developer Oriented: view.py is developed with ease of use in mind, providing a rich documentation, docstrings, and type hints.
21+
- Batteries Detachable: Don't like our approach to something? No problem! We aim to provide native support for all your favorite libraries, as well as provide APIs to let you reinvent the wheel as you wish.
22+
- Lightning Fast: Powered by [pyawaitable](https://github.com/ZeroIntensity/pyawaitable), view.py is the first web framework to implement ASGI in pure C, without the use of external transpilers.
23+
- Developer Oriented: view.py is developed with ease of use in mind, providing a rich documentation, docstrings, and type hints.
24+
25+
See [why I wrote it](https://view.zintensity.dev/#why-did-i-build-it) on the docs.
2526

2627
## Examples
2728

@@ -62,20 +63,20 @@ def create(name: str, books: dict[str, str]):
6263

6364
**Python 3.8+ is required.**
6465

65-
### Development
66+
### Development
6667

67-
```
68+
```console
6869
$ pip install git+https://github.com/ZeroIntensity/view.py
6970
```
7071

71-
### Linux/macOS
72+
### PyPI
7273

73-
```
74-
$ python3 -m pip install -U view.py
74+
```console
75+
$ pip install view.py
7576
```
7677

77-
### Windows
78+
### Pipx
7879

79-
```
80-
> py -3 -m pip install -U view.py
80+
```console
81+
$ pipx install view.py
8182
```

docs/building-projects/build_steps.md

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,53 @@ requires = ["php"]
120120
command = "php -f payment.php"
121121
```
122122

123+
## Platform-Dependent Steps
124+
125+
Many commands are different based on the platform used. For example, to read from a file on the Windows shell would be `type`, while on Linux and Mac it would be `cat`. If you add multiple step entries (in the form of an [array of tables](https://toml.io/en/v1.0.0-rc.2#array-of-tables)) with `platform` values, view.py will run the entry based on the platform the app was run on.
126+
127+
For example, using the file reading example from above:
128+
129+
Notice the double brackets next to `[[build.steps.read_from_file]]`, specifying an array of tables.
130+
131+
```toml
132+
# view.toml
133+
134+
[[build.steps.read_from_file]]
135+
platform = ["mac", "linux"]
136+
command = "cat whatever.txt"
137+
138+
[[build.steps.read_from_file]]
139+
platform = "windows"
140+
command = "type whatever.txt"
141+
```
142+
143+
The `platform` value can be one of three things per entry:
144+
145+
- A list of platforms.
146+
- A string containing a single platform.
147+
- `None`, meaning to use this entry if no other platforms match.
148+
149+
For example, with a `None` platform set (on multiple entries), the above could be rewritten as:
150+
151+
```toml
152+
# view.toml
153+
154+
[[build.steps.read_from_file]]
155+
# Windows ONLY runs this step
156+
platform = "windows"
157+
command = "type whatever.txt"
158+
159+
[[build.steps.read_from_file]]
160+
# All other platforms run this!
161+
command = "cat whatever.txt"
162+
```
163+
164+
Note that only one step entry can have a `None` platform value, otherwise view.py will throw an error.
165+
166+
!!! note
167+
168+
The only recognized operating systems for `platform` are the big three: Windows, Mac, and any Linux based system. If you want more fine-grained control (for example, using `pacman` or `apt` depending on the Linux distro), use a custom build script that knows how to read the Linux distribution.
169+
123170
## Build Requirements
124171

125172
As you've seen above, build requirements are specified via the `requires` value. Out of the box, view.py supports a number of different build tools, compilers, and interpreters. To specify a requirement for one, simply add the name of their executable (_i.e._, how you access their CLI). For example, since `pip` is accessed via using the `pip` command in your terminal, `pip` is the name of the requirement.
@@ -165,7 +212,7 @@ async def __view_requirement__() -> bool:
165212

166213
The above could actually be used via both `script+check_310.py` and `mod+check_310`.
167214

168-
!!! tip
215+
!!! note
169216

170217
Don't use the view.py build system to check the Python version or if a Python package is installed. Instead, use the `dependencies` section of a `pyproject.toml` file, or [PEP 723](https://peps.python.org/pep-0723/) script metadata.
171218

docs/building-projects/request_data.md

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,17 @@ If you've used a framework like [Django](https://djangoproject.com) or [FastAPI]
66

77
The `Context` instance contains information about the incoming request, including:
88

9-
- The headers.
10-
- The cookies.
11-
- The HTTP version.
12-
- The request method.
13-
- The URL path.
14-
- The client and server address.
9+
- The headers.
10+
- The cookies.
11+
- The HTTP version.
12+
- The request method.
13+
- The URL path.
14+
- The client and server address.
1515

1616
!!! info
1717

1818
`Context` is an [extension type](https://docs.python.org/3/extending/newtypes_tutorial.html), and is defined in the `_view` module. It's Python signatures are defined in the `_view` type stub.
1919

20-
2120
## Context Input
2221

2322
The context can be added to a route via a route input, which is done through the `context` decorator. Note that `context` has a standard and direct variation (`App.context` is available to prevent imports).
@@ -76,7 +75,7 @@ app.run()
7675

7776
!!! info
7877

79-
`App.test` is a more internal detail, but is available to use publically. It looks like this:
78+
`App.test` is a more internal detail, but is available for public use. It looks like this:
8079

8180
```py
8281
from view import new_app
@@ -175,11 +174,11 @@ app.run()
175174

176175
`Context` contains eight attributes:
177176

178-
- `headers`, of type `dict[str, str]`.
179-
- `cookies`, of type `dict[str, str]`.
180-
- `client`, of type `ipaddress.IPv4Address`, `ipaddress.IPv6Address`, or `None`.
181-
- `server`, of type `ipaddress.IPv4Address`, `ipaddress.IPv6Address`, or `None`.
182-
- `method`, of type `StrMethodASGI` (uppercase string containing the method, such as `"GET"`).
183-
- `path`, of type `str`.
184-
- `scheme`, which can be the string `"http"`, `"https"`.
185-
- `http_version`, which can be the string `"1.0"`, `"1.1"`, `"2.0"`, `"view_test"`.
177+
- `headers`, of type `dict[str, str]`.
178+
- `cookies`, of type `dict[str, str]`.
179+
- `client`, of type `ipaddress.IPv4Address`, `ipaddress.IPv6Address`, or `None`.
180+
- `server`, of type `ipaddress.IPv4Address`, `ipaddress.IPv6Address`, or `None`.
181+
- `method`, of type `StrMethodASGI` (uppercase string containing the method, such as `"GET"`).
182+
- `path`, of type `str`.
183+
- `scheme`, which can be the string `"http"`, `"https"`.
184+
- `http_version`, which can be the string `"1.0"`, `"1.1"`, `"2.0"`, `"view_test"`.

docs/contributing.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
hide:
3+
- navigation
4+
---
5+
6+
--8<-- "CONTRIBUTING.md"

docs/index.md

Lines changed: 89 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,54 +11,119 @@ Here, you can learn how to use view.py and its various features.
1111
- [PyPI](https://pypi.org/project/view.py)
1212
- [Discord](https://discord.gg/tZAfuWAbm2)
1313

14-
!!! warning
14+
## Showcase
1515

16-
view.py is in very early stages and not yet considered to be ready for production.
17-
If you would like to follow development progress, join [the discord](https://discord.gg/tZAfuWAbm2).
18-
For contributing to view.py, please see our [contributors file](https://github.com/ZeroIntensity/view.py/blob/master/CONTRIBUTING.md)
16+
```py
17+
from view import new_app
1918

20-
## Quickstart
19+
app = new_app()
2120

22-
Install view.py:
21+
@app.get("/")
22+
async def index():
23+
return await app.template("index.html", engine="jinja")
2324

24-
```
25-
$ pip install -U view.py
25+
app.run()
2626
```
2727

28-
Initialize your project:
28+
```py
29+
# routes/index.py
30+
from view import get, HTML
2931

32+
# Build TypeScript Frontend
33+
@get(steps=["typescript"], cache_rate=1000)
34+
async def index():
35+
return await HTML.from_file("dist/index.html")
3036
```
31-
$ view init
37+
38+
```py
39+
from dataclasses import dataclass
40+
from view import body, post
41+
42+
@dataclass
43+
class User:
44+
name: str
45+
password: str
46+
47+
@post("/signup")
48+
@body("data", User)
49+
def create(data: User):
50+
# Use database of your choice...
51+
return JSON({"message": "Successfully created your account."}), 201
3252
```
3353

34-
**Note:** If this yields unexpected results, you may need to use `py -m view init` instead.
54+
```py
55+
from view import new_app, Context, Error, JSON
56+
57+
app = new_app()
58+
59+
@app.get("/")
60+
@app.context
61+
async def index(ctx: Context):
62+
auth = ctx.headers.get("Authorization")
63+
if not auth:
64+
raise Error(400)
65+
66+
return JSON({"data": "..."})
3567

36-
Write your first app:
68+
app.run()
69+
```
3770

3871
```py
3972
from view import new_app
4073

4174
app = new_app()
4275

43-
@app.query("greeting", str, default="hello")
44-
@app.query("name", str, default="world")
45-
@app.get("/")
46-
async def index(greeting: str, name: str):
47-
return f"{greeting}, {name}!"
76+
@app.post("/login")
77+
@app.query("username", doc="Username for your account.")
78+
@app.query("password", doc="Password for your account.")
79+
async def index():
80+
"""Log in to your account."""
81+
...
4882

4983
app.run()
5084
```
5185

52-
## Why View?
86+
```html
87+
<view if="user.type == 'admin'">
88+
<view template="admin_panel" />
89+
</view>
90+
<view elif="user.type == 'moderator'">
91+
<view template="mod_panel" />
92+
</view>
93+
<view else>
94+
<p>You must be logged in.</p>
95+
</view>
96+
```
97+
98+
```toml
99+
# view.toml
100+
[build]
101+
default_steps = ["nextjs"]
102+
# Only NextJS will be built on startup
103+
104+
[build.steps.nextjs]
105+
requires = ["npm"]
106+
command = "npm run build"
107+
108+
[build.steps.php]
109+
requires = ["php"]
110+
command = "php -f payment.php"
111+
```
112+
113+
## Why did I build it?
114+
115+
!!! warning
116+
117+
This section may seem boring to some. If you don't like reading, skip to the next page.
53118

54-
As of now, view.py is still in alpha. Lot's of development progress is being made, but a production-ready stable release is still a bit far off. With that being said, anything mentioned in this documentation has been deemed already stable. In that case, why choose view.py over other frameworks?
119+
This is a question I get a lot when it comes to view.py. I originally got the idea for view.py back in 2021, but it was planned to be a library for _only_ designing UI's in Python (hence the name "view"), since the only way you could do it at the time was pretty much just merging HTML and Python using [Jinja](https://jinja.palletsprojects.com/en/3.1.x/), or some other flavor of template engine. Don't get me wrong, Jinja is a great template engine, but it feels a bit lacking once you've tried [JSX](https://react.dev/learn/writing-markup-with-jsx) in one of the large JavaScript frameworks.
55120

56-
If you've used a framework like [Django](https://djangoproject.com), you're likely already familiar with the "batteries included" idea, meaning that it comes with everything you could need right out of the box. View takes a different approach: batteries-detachable. It aims to provide you everything you need, but gives you a choice to use it or not, as well as actively supporting external libraries. This ideology is what makes View special. In batteries detachable, you can use whatever you like right out of the box, but if you don't like View's approach to something or like another library instead, you may easily use it.
121+
A year later, in 2022, I enrolled in a coding class at my school, which was basically a course for the basics of Python. For most Python developers, including me, it would have felt like sitting down and going over your ABC's. Long story short, my teacher let me do some sort of project instead of the actual class (this was in 8th grade, mind you).
57122

58-
## Should I use it?
123+
At the time, my [pointers.py](https://github.com/ZeroIntensity/pointers.py) library had gained a lot of traction on GitHub, which was quite cool to me, but I felt like I didn't make any real world contributions (it is a joke library, anyway). I wanted to contribute something to the world, and since I was being allocated school time during the week to work on a project of my choice, I decided that a full web framework was what I wanted to do.
59124

60-
For a big project, **not yet**, as View is not currently ideal for working with a big codebase. However, **that doesn't mean you should forget about it**. view.py will soon be stable and production ready, and you should keep it in mind. To support view.py's development, you can either [sponsor me](https://github.com/sponsors/ZeroIntensity) or [star the project](https://github.com/zerointensity/view.py/stargazers).
125+
In my eyes, Python's web ecosystem was nowhere near that of JavaScript's. I had grown particularly fond of [NextJS](https://nextjs.org/), which served as an inspiration for a lot of view.py's features. To this day, [FastAPI](https://fastapi.tiangolo.com/) remains as my favorite Python web framework, apart from View. In fact, if you don't like view.py, I highly recommend trying it. Anyways, at the time, FastAPI was somewhat lacking when it comes to batteries-included parts, compared to [Django](https://www.djangoproject.com/), at least.
61126

62-
## Developing View
127+
Now, this opinion is a bit controversial, but I really don't like Django's approach to a lot of things (such as it's way of routing), as well as the massive boilerplate that comes with Django projects. It just doesn't feel [pythonic](https://ifunny.co/picture/other-programmers-python-programmer-that-s-not-the-most-pythonic-EUE0IBzz8) to me. Although, what I do admire about Django (and probably why so many people like it), is it's batteries-included philosophy. So, I wanted to develop a web framework with the speed and elegancy of FastAPI, with the sheer robust-ness of Django. view.py is the result of that idea.
63128

64-
As stated earlier, view.py is very new and not yet at a stable 1.0.0 release. Whether you're completely new to GitHub contribution or an experienced developer, view.py has something you could help out with. If you're interested in contributing or helping out with anything, be sure to read [the contributors file](https://github.com/ZeroIntensity/view.py/blob/master/CONTRIBUTING.md) and/or joining the [discord](https://discord.gg/tZAfuWAbm2).
129+
Note that I don't want to replace Django or FastAPI. In fact, if you're already familiar with one of those, learning view.py might not be a good idea! However, I would like to fill the gap that you might feel when using a Python framework after coming from JavaScript. Nowadays, JavaScript web frameworks get rewritten every year (for example, Next's move from `pages` to the `app` router), and are filled with big companies fighting each other to "be the best." In my eyes, development in all fields, especially open source, should be _collaborative_, not competitive, and I'm glad that Python has stayed true to that, but the gap in web development is visible.
-3.19 KB
Binary file not shown.
-7.69 KB
Binary file not shown.

html/favicons/apple-touch-icon.png

-2.3 KB
Binary file not shown.

html/favicons/browserconfig.xml

Lines changed: 0 additions & 9 deletions
This file was deleted.

0 commit comments

Comments
 (0)